Skip to main content

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​

  1. Client calls POST /api/v1/iam/exchange on auth-service with email + password
  2. auth-service validates credentials against Firebase (Admin SDK verifyIdToken or signInWithEmailAndPassword)
  3. auth-service calls user-service GET /user/by-email?email= to fetch the user record
  4. user-service proxies to user-base-ms GET /api/v1/users?email=
  5. auth-service generates JWT access token (RS256) and refresh token
  6. Sets accessToken and refreshToken as HTTP-only cookies
  7. 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​

  1. Client calls POST /api/v1/iam/register on auth-service with email + password + name
  2. auth-service creates the user in Firebase (Admin SDK createUser)
  3. auth-service calls user-service POST /user to create the user record
  4. user-service proxies to user-base-ms POST /api/v1/users
  5. auth-service generates JWT tokens
  6. 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​

  1. Client completes ZITADEL OAuth flow and gets ZITADEL access/ID tokens
  2. Client calls POST /api/v1/iam/zitadel/exchange on auth-service with ZITADEL tokens
  3. auth-service validates the ZITADEL access token via token introspection
  4. auth-service validates the ZITADEL ID token via JWKS
  5. auth-service calls user-service GET /user/zitadel/:zitadelUserId to find existing user
  6. If not found, creates the user via POST /user/zitadel
  7. Creates a session in Redis (zitadel/{provider}/{orgId}/{userId})
  8. Generates Jeen JWT tokens
  9. Returns tokens
Client --> auth-service --> ZITADEL (introspect + JWKS)
--> user-service --> user-base-ms (find/create user)
--> Redis (create session)
<-- JWT tokens

Token Refresh​

Steps​

  1. Client calls POST /api/v1/iam/token/refresh on auth-service
  2. auth-service reads the refreshToken cookie
  3. Validates the refresh token against the in-memory token store
  4. Generates a new access token + refresh token pair
  5. Sets new cookies (accessToken, refreshToken)
  6. Returns user data
Client --> auth-service (validate refresh token)
<-- New JWT tokens (cookies + body)

Logout​

Steps​

  1. Client calls POST /api/v1/iam/logout on auth-service (with JWT)
  2. auth-service invalidates the refresh token in the token store
  3. Deletes the Redis session (if ZITADEL)
  4. Clears accessToken and refreshToken cookies
  5. Returns success

JWT Token Contents​

The access token payload includes:

FieldDescription
subUser ID (UUID)
emailUser email
organizationIdOrganization UUID
rolesArray of role IDs
iatIssued at timestamp
expExpiration timestamp

Signed with RS256 using a private key. Verified by other services using the corresponding public key.