Authentication Flow
End-to-end flows for login, registration, token refresh, and ZITADEL integration.
Services Involved
auth-service, user-service (proxied to user-base-ms), Firebase, ZITADEL, Redis
Login (Firebase)
Steps
- Client calls
POST /api/v1/iam/exchangeon auth-service with email + password - auth-service validates credentials against Firebase (Admin SDK
verifyIdTokenorsignInWithEmailAndPassword) - auth-service calls user-service
GET /user/by-email?email=to fetch the user record - user-service proxies to user-base-ms
GET /api/v1/users?email= - auth-service generates JWT access token (RS256) and refresh token
- Sets
accessTokenandrefreshTokenas HTTP-only cookies - Returns user data in response body (tokens are in cookies only)
Client --> auth-service --> Firebase (validate)
--> user-service --> user-base-ms (fetch user)
<-- JWT tokens (cookies + body)
Registration (Firebase)
Steps
- Client calls
POST /api/v1/iam/registeron auth-service with email + password + name - auth-service creates the user in Firebase (Admin SDK
createUser) - auth-service calls user-service
POST /userto create the user record - user-service proxies to user-base-ms
POST /api/v1/users - auth-service generates JWT tokens
- Returns tokens
If step 3 fails (user-service creation), auth-service rolls back by deleting the Firebase account.
Client --> auth-service --> Firebase (create account)
--> user-service --> user-base-ms (create user record)
<-- JWT tokens
Login (ZITADEL)
Steps
- Client completes ZITADEL OAuth flow and gets ZITADEL access/ID tokens
- Client calls
POST /api/v1/iam/zitadel/exchangeon auth-service with ZITADEL tokens - auth-service validates the ZITADEL access token via token introspection
- auth-service validates the ZITADEL ID token via JWKS
- auth-service calls user-service
GET /user/zitadel/:zitadelUserIdto find existing user - If not found, creates the user via
POST /user/zitadel - Creates a session in Redis (
zitadel/{provider}/{orgId}/{userId}) - Generates Jeen JWT tokens
- Returns tokens
Client --> auth-service --> ZITADEL (introspect + JWKS)
--> user-service --> user-base-ms (find/create user)
--> Redis (create session)
<-- JWT tokens
Token Refresh
Steps
- Client calls
POST /api/v1/iam/token/refreshon auth-service - auth-service reads the
refreshTokencookie - Validates the refresh token against the in-memory token store
- Generates a new access token + refresh token pair
- Sets new cookies (
accessToken,refreshToken) - Returns user data
Client --> auth-service (validate refresh token)
<-- New JWT tokens (cookies + body)
Logout
Steps
- Client calls
POST /api/v1/iam/logouton auth-service (with JWT) - auth-service invalidates the refresh token in the token store
- Deletes the Redis session (if ZITADEL)
- Clears
accessTokenandrefreshTokencookies - Returns success
JWT Token Contents
The access token payload includes:
| Field | Description |
|---|---|
| sub | User ID (UUID) |
| User email | |
| organizationId | Organization UUID |
| roles | Array of role IDs |
| iat | Issued at timestamp |
| exp | Expiration timestamp |
Signed with RS256 using a private key. Verified by other services using the corresponding public key.