oauth2-client-strategy
ARCHIVED AND SUPERSEDED
This ADR is obsolete and has been superseded by ADR-0023: IAM Service as a Policy and Authorization Claims Engine. The content below is for historical purposes only.
0006: OAuth2 Client Strategy
Date: 2025-08-10
Status: Accepted
Context
The Citadel platform consists of user-facing frontend applications and internal backend services. Both need to interact with the iam-service for authentication and authorization, but their security profiles and requirements are different. We must define a clear, secure, and standard strategy for how each type of application registers and authenticates as an OAuth2 client.
This decision complements ADR-0004, which focuses on Service-to-Service authentication, by explicitly defining the strategy for user-facing applications.
Decision
We will adopt a two-pronged client strategy based on client type:
-
User-Facing Applications (Public Clients):
- All user-facing applications where the source code is exposed (e.g., browser-based SPAs, native mobile apps) are considered public clients.
- This client will be registered in the
iam-serviceas a public client, meaning it does not have a client secret. - They must use the Authorization Code Flow with PKCE (Proof Key for Code Exchange) for user authentication. The
iam-servicewill enforce PKCE validation for all public clients to mitigate authorization code interception attacks. - Extensibility: For advanced first-party use cases (e.g., a white-labeled fork of the shell app), the architecture supports dynamically using a different
client_idduring the login flow. This requires the alternative client to be registered in the IdP and to have the shell's callback URI (/auth-callback) added to its list of allowed redirect URIs.
-
Backend Services (Confidential Clients):
- As defined in
ADR-0004, each backend service (e.g., BFFs, domain services) that needs to communicate with another service will be registered as its own confidential client. - Each confidential client will have a
client_idand aclient_secret, which can be securely stored on the server. - They will use the Client Credentials Flow to obtain their own access tokens for service-to-service communication.
- As defined in
-
Third-Party Applications (External Clients):
- To provide a seamless developer experience, the
iam-servicewill act as a full OIDC Provider Facade. - Third-party applications (e.g., partner mobile apps or web SPAs) will configure their standard OIDC libraries to point directly to the
iam-service's public endpoints (/authorize,/token, etc.). They will be completely unaware of any upstream Identity Providers. - The
iam-serviceis responsible for internally managing the authentication flow with an upstream IdP. It will proxy the user to the upstream IdP for login and handle the subsequent token exchange entirely on the backend, transparently to the third-party client. - The final
id_tokenandaccess_tokenissued to the third-party client will be from theiam-service's issuer. This allows the client to use standard OIDC libraries for token management (storage, refresh, etc.) without any custom logic. - This pattern ensures the best possible developer experience while maintaining a strong security boundary, as all tokens used to access the Citadel ecosystem are issued and controlled by the
iam-service.
- To provide a seamless developer experience, the
Consequences
Positive
- Security Best Practices: This approach aligns with OAuth 2.0 security best practices by correctly identifying and configuring public (browser) and confidential (server) clients.
- Clear Separation: It creates a clear distinction between authenticating a human user (via the public client) and authenticating a machine/service (via confidential clients).
- Reduced Complexity: The entire frontend is managed as one client from the IdP's perspective, simplifying configuration.
- Flexibility: The use of PKCE for the public client is a modern standard that enhances security for SPAs.
- Secure Extensibility: The token exchange pattern provides a secure and standard way to integrate third-party applications into the ecosystem without compromising the internal security model.
- Superior Developer Experience: By acting as a true OIDC facade, the
iam-serviceallows third-party developers to use standard, unmodified OIDC libraries, dramatically simplifying integration.