Flow de autenticación
Prysm:ID habla OIDC estándar (perfil OAuth 2.0 de OpenID Connect). Si tu librería favorita habla OIDC, habla con nosotros sin glue code propietario.
El flow estándar (Authorization Code + PKCE)
Sección titulada «El flow estándar (Authorization Code + PKCE)»Es el flow recomendado para apps web, móviles y SPAs. Para apps puramente backend-to-backend usás client credentials (ver al final).
┌──────────┐ ┌────────────────────┐ │ Tu app │ │ auth.acme. │ │ (browser │ │ prysmid.com │ │ o BE) │ │ (instancia) │ └────┬─────┘ └─────────┬──────────┘ │ │ │ 1. usuario clic "Login" │ │ → redirect a /authorize │ │ con client_id, redirect_uri, │ │ scope=openid profile email, │ │ state, code_challenge (PKCE) │ ├──────────────────────────────────────────────────▶│ │ │ │ 2. login UI: usuario ingresa email/pwd │ │ o elige IdP social (Google/GitHub) │ │ │ │ 3. instance autentica │ │ → redirect a redirect_uri │ │ con code + state │ │◀──────────────────────────────────────────────────┤ │ │ │ 4. POST /token │ │ code, code_verifier, client_id+secret │ ├──────────────────────────────────────────────────▶│ │ │ │ 5. responde id_token (JWT) │ │ + access_token + refresh_token │ │◀──────────────────────────────────────────────────┤ │ │ │ 6. tu BE valida id_token con JWKS │ │ (verifica firma, aud, exp, iss) │ │ │Qué viene en el id_token
Sección titulada «Qué viene en el id_token»El id_token es un JWT firmado (RS256 por default). Decodificado, el payload típico:
{ "iss": "https://auth.acme.prysmid.com", "sub": "294857293874598734", "aud": "275893745987345987@my-saas-dev", "exp": 1738000000, "iat": 1737996400, "auth_time": 1737996398, "email_verified": true, "name": "Fernando", "preferred_username": "fernando"}sub: identificador estable del usuario en tu workspace. Persistilo. No usesemailcomo clave — los emails cambian.iss: el issuer. Debe ser exactamentehttps://auth.<slug>.prysmid.com. Si validás contra otro string, vas a aceptar tokens forjados.aud: tuclient_id. Si recibís un token conauddistinto al tuyo, lo rechazás.
Cómo validar el JWT en tu backend →
Scopes que importan
Sección titulada «Scopes que importan»| Scope | Qué te da |
|---|---|
openid | Obligatorio. Sin esto no recibís id_token. |
profile | name, preferred_username, picture. |
email | email, email_verified. |
offline_access | Te devuelve refresh_token para sesiones largas. |
urn:zitadel:iam:org:project:roles | Roles del usuario en el project asociado a tu app. (Es la URN canónica del claim, no la cambies en tu validador.) |
Refresh tokens
Sección titulada «Refresh tokens»Si pediste offline_access, recibís un refresh_token además del id_token. Lo intercambiás por un nuevo id_token cuando el actual expira:
curl -X POST https://auth.acme.prysmid.com/oauth/v2/token \ -u "$CLIENT_ID:$CLIENT_SECRET" \ -d "grant_type=refresh_token" \ -d "refresh_token=$REFRESH_TOKEN"El refresh token rota en cada uso. Guardá el nuevo, descartá el viejo.
Para apps backend-to-backend (sin usuario)
Sección titulada «Para apps backend-to-backend (sin usuario)»Si tu app llama a otra app sin un humano detrás (machine-to-machine), usás client_credentials:
curl -X POST https://auth.acme.prysmid.com/oauth/v2/token \ -u "$CLIENT_ID:$CLIENT_SECRET" \ -d "grant_type=client_credentials" \ -d "scope=openid"No vas a recibir id_token (no hay usuario), solo access_token. Ver también machine keys para agentes si lo que querés es que un agente IA opere el plano de control.
GET https://auth.acme.prysmid.com/oidc/v1/end_session ?id_token_hint=<id_token> &post_logout_redirect_uri=https://yourapp.com/logoutEl post_logout_redirect_uri debe estar registrado en tu app. La instance termina la sesión en su lado, después rebota a tu URI.