Skip to content

Sign in with PerSQL

PerSQL is an OpenID Connect (OIDC) provider. You can let people sign in to your own product with their PerSQL account: register a client, send users to PerSQL to authorize, and receive a signed id_token carrying their identity.

Signing in establishes who the user is — it does not grant your app access to their databases. The access token returned alongside the id_token can read the user’s profile from /userinfo and nothing else.

In the console, open a workspace and go to Sign in with PerSQL → New app.

  • Name — shown to users on the consent screen.
  • Redirect URIs — exact-match callback URLs. HTTPS only, except http://localhost for local development.
  • Client type:
    • Confidential — a server-side app. You receive a client_secret (shown once) and send it when exchanging the code.
    • Public — a single-page app or native client with no secret. PKCE (S256) is required.

You get a client_id immediately and, for confidential clients, a one-time client_secret. Rotate the secret any time from the same screen.

Discovery document (everything below is advertised here):

https://api.persql.com/.well-known/openid-configuration
Issuerhttps://api.persql.com
Authorizationhttps://api.persql.com/oauth/authorize
Tokenhttps://api.persql.com/oauth/token
UserInfohttps://api.persql.com/userinfo
JWKShttps://api.persql.com/.well-known/jwks.json

For the staging environment, swap api.persql.com for api-staging.persql.com.

Scopes: openid (required), email, profile. Claims: sub (stable user id), email, email_verified, name, picture. id_tokens are signed with RS256; verify them against the JWKS.

Standard OIDC authorization-code flow. Send the user to the authorization endpoint:

https://api.persql.com/oauth/authorize
?response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https://yourapp.com/callback
&scope=openid%20email%20profile
&state=RANDOM
&nonce=RANDOM
&code_challenge=BASE64URL_SHA256_OF_VERIFIER
&code_challenge_method=S256

After the user approves, PerSQL redirects back with ?code=...&state=.... Exchange the code for tokens:

Terminal window
curl -X POST https://api.persql.com/oauth/token \
-d grant_type=authorization_code \
-d code=THE_CODE \
-d redirect_uri=https://yourapp.com/callback \
-d client_id=YOUR_CLIENT_ID \
-d client_secret=YOUR_CLIENT_SECRET \
-d code_verifier=THE_PKCE_VERIFIER

The response contains an id_token (the user’s identity) and an access_token (good only for /userinfo):

{
"id_token": "eyJ…",
"access_token": "psqlid_…",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "openid email profile"
}

Verify the id_token signature against the JWKS, then read sub, email, and name from its claims — or call /userinfo with the access token:

Terminal window
curl https://api.persql.com/userinfo -H "Authorization: Bearer psqlid_…"

PKCE is required for public clients and optional (but verified when present) for confidential clients. Confidential clients may send the secret as a client_secret form field or via HTTP Basic auth.

PerSQL works as a generic OIDC provider — no plugin required:

// auth.ts (Auth.js v5)
import NextAuth from "next-auth";
export const { handlers, signIn, signOut, auth } = NextAuth({
providers: [
{
id: "persql",
name: "PerSQL",
type: "oidc",
issuer: "https://api.persql.com",
clientId: process.env.PERSQL_CLIENT_ID,
clientSecret: process.env.PERSQL_CLIENT_SECRET,
authorization: { params: { scope: "openid email profile" } },
},
],
});

Register the redirect URI Auth.js uses — https://yourapp.com/api/auth/callback/persql — as a redirect URI on your client.