AuthPassDocumentation

Integrate AuthPass

AuthPass is a standards-based OpenID Connect provider. Register an app, get aclient_id/client_secret, and add “Login with AuthPass” to anything that speaks OIDC.

OIDC endpointsDiscovery URL, scopes, and claims
Everything is discoverable from the issuer:
Discovery:  https://authpass.site/.well-known/openid-configuration
Authorize:  https://authpass.site/api/oidc/authorize
Token:      https://authpass.site/api/oidc/token
UserInfo:   https://authpass.site/api/oidc/userinfo
JWKS:       https://authpass.site/api/oidc/jwks
Revoke:     https://authpass.site/api/oidc/revoke

Scopes: openid profile email offline_access · Flow: Authorization Code (+ optional PKCE) · Grants: authorization_code, refresh_token.

Add the offline_access scope to receive a refresh_token. Refresh tokens rotate on every use (the old one is revoked), and reusing a rotated token revokes the whole chain. Revoke a token any time at https://authpass.site/api/oidc/revoke (RFC 7009).

Machine-to-machine (no user)

For server-to-server / agents / cron, use the client_credentials grant. You get a self-contained JWT access token (subject = your app, verify it against the JWKS) — no user, no browser.

curl -X POST https://authpass.site/api/oidc/token \
  -d grant_type=client_credentials \
  -d client_id=ap_xxx -d client_secret=aps_xxx \
  -d scope="read:things" -d audience="https://your-api"

ID token / userinfo claims

ClaimTypeDescription
substringStable unique user ID — use this as the account key.
emailstringThe user's email address.
email_verifiedbooleanWhether the email has been verified.
namestringDisplay name.
rolestringThe user's role in the connected app (from RBAC).
QuickstartFrom zero to a working login in 4 steps
  1. Dashboard → Connected appsRegister an app.
  2. Copy the Client ID & Client Secret (the secret is shown only once).
  3. Add one or more redirect URIs — one per environment (production, staging, localhost).
  4. Point your framework's OIDC config at the issuer https://authpass.site — endpoints auto-discover.

💡 Add both your production URL and http://localhost:3000/... as redirect URIs so the same app works in development and production.

How login works for your usersWhat happens when someone clicks “Login with AuthPass” — including if they have no account

AuthPass is a shared identity provider — like “Sign in with Google.” Your users sign in with their AuthPass account, not a per-site password. You don't build any sign-up or password UI — AuthPass hosts all of it.

The flow

  1. User clicks your Login with AuthPass button → they land on the AuthPass sign-in page (it shows “continue to Your App”).
  2. No AuthPass account? The page has a “Create your AuthPass” link. They sign up (or use Google/GitHub), and are sent straight back to your app, logged in. You write no code for this.
  3. Your callback receives a code, exchanges it, and reads the user's profile. On first login you typically create a matching local user (see the platform guides).

✅ You never handle “user has no account” yourself — AuthPass shows the create-account step and returns them to you once they're signed in.

Who is allowed in — the “Any AuthPass user may sign in” toggle

Each app has an Any AuthPass user may sign in switch (in the app settings):

  • ON (open sign-in): anyone with an AuthPass account can log in and is auto-added as a member with your default role. Best for public apps.
  • OFF (invite-only): only people you've added under the app's Members can log in. Everyone else is bounced back to your app with an access_denied error — so grant access first, or turn the toggle on.

Errors your callback should handle

Per the OIDC spec, failures come back to your redirect_uri as query params (?error=...&error_description=...) — not as a page on AuthPass. Handle at least:

  • access_denied — the user isn't allowed on this app (invite-only). Show “ask an admin for access.”
  • invalid_grant — the code expired or was reused; restart the login.
// example: reading the error on your callback
const err = new URL(request.url).searchParams.get("error");
if (err === "access_denied") return redirect("/login?msg=no-access");
Platform integrationsCopy-pasteNext.js · Laravel · WordPress · Wix · any OIDC

Expand a platform for a step-by-step guide. They all use the same OIDC endpoints above.

Next.js (Auth.js v5)
Auth.js auto-discovers everything from the issuer — no manual endpoint wiring. Redirect URI: {origin}/api/auth/callback/authpass
// auth.ts
import NextAuth from "next-auth";

export const { handlers, signIn, signOut, auth } = NextAuth({
  providers: [{
    id: "authpass", name: "AuthPass", type: "oidc",
    issuer: "https://authpass.site",
    clientId: process.env.AUTH_AUTHPASS_ID,
    clientSecret: process.env.AUTH_AUTHPASS_SECRET,
    // avoids OAuthAccountNotLinked — safe: AuthPass emails are verified
    allowDangerousEmailAccountLinking: true,
  }],
});

// app/api/auth/[...nextauth]/route.ts
export const { GET, POST } = handlers;
// login button (server action)
import { signIn } from "@/auth";
<form action={async () => { "use server"; await signIn("authpass"); }}>
  <button>Sign in with AuthPass</button>
</form>
Laravel (Socialite)
Use Socialite with a generic OIDC driver that auto-discovers endpoints from the issuer. Redirect URI: {app}/auth/callback
composer require laravel/socialite socialiteproviders/generic
// config/services.php
'authpass' => [
  'base_url'      => env('AUTHPASS_ISSUER'),       // https://authpass.site
  'client_id'     => env('AUTHPASS_CLIENT_ID'),
  'client_secret' => env('AUTHPASS_CLIENT_SECRET'),
  'redirect'      => env('AUTHPASS_REDIRECT_URI'),
],
// routes
Route::get('/auth/redirect', fn () => Socialite::driver('authpass')
  ->scopes(['openid','profile','email'])->redirect());

Route::get('/auth/callback', function () {
  $u = Socialite::driver('authpass')->user();
  $user = User::updateOrCreate(['email' => $u->getEmail()],
    ['name' => $u->getName() ?: $u->getNickname()]);
  Auth::login($user, true);
  return redirect('/dashboard');
});
Full guide in the repo: docs/integrations/laravel.md
WordPressNo plugin
Paste one snippet into functions.php (orwp-content/mu-plugins/authpass.php to survive theme changes). It adds a button to wp-login, an [authpass_login] shortcode, and auto-creates users. Redirect URI: https://YOUR-SITE.com/?authpass=callback
// top of the snippet — change these three values
define('AUTHPASS_ISSUER',        'https://authpass.site');
define('AUTHPASS_CLIENT_ID',     'ap_xxxxxxxxxxxxxxxxxx');
define('AUTHPASS_CLIENT_SECRET', 'aps_xxxxxxxxxxxxxxxxxx');
The snippet discovers the OIDC config, verifies the OAuth state (CSRF), exchanges the code server-to-server, reads userinfo, and signs the user in. Full copy-paste script: docs/integrations/wordpress.md
WixConstraints
Wix is closed — no drop-in button, and Wix always owns the session (linking is by email). Three real paths:
  • Native member SSO (no-code) — Wix Studio Enterprise / Channels only. Paste the discovery URL https://authpass.site/.well-known/openid-configuration.
  • Wix Headless — run OIDC yourself, then getMemberTokensForExternalLogin(email, apiKey).
  • Velo (standard sites) — exchange the code in http-functions.js, then authentication.generateSessionToken(email).
Full guide: docs/integrations/wix.md
Any OIDC framework
AuthPass is standards-based, so anything that speaks OpenID Connect works: point its OIDC client at the issuer https://authpass.site, use scopes openid profile email, and the Authorization Code flow (PKCE optional). Endpoints auto-discover from the discovery URL above.
Management API & MCPAutomate AuthPass with a token or your AI editor
Create a Personal Access Token in Profile → API keys, then call the REST API:
curl -H "Authorization: Bearer apk_…" https://authpass.site/api/v1/me
# read:   GET  /api/v1/me | /api/v1/apps | /api/v1/organizations
# write:  POST /api/v1/apps            (create an app)
#         POST /api/v1/apps/{id}/rotate-secret

Or manage AuthPass from Claude / Cursor / VS Code via the hosted MCP server at https://mcp.authpass.site (Bearer your token) — tools: whoami, list_apps, create_app, rotate_secret, and more. A local stdio server also lives in mcp/.

TroubleshootingThe errors you're most likely to hit
ErrorFix
redirect_uri_mismatchThe redirect URI in your request must exactly match one saved on the app (scheme, host, port, path).
invalid_clientWrong Client ID/Secret, or the secret was rotated. Copy the current values from the app page.
invalid_grantThe authorization code expired or was already used. Start the flow again.
OAuthAccountNotLinkedAuth.js-side (NextAuth): a local user with that email already exists from another method. Add allowDangerousEmailAccountLinking: true to the AuthPass provider — safe, AuthPass returns verified emails.
401 on /jwksServer-side OIDC key isn't configured. Contact the AuthPass admin.
Docs — AuthPass · AuthPass