Skip to main content

iam-service-facade-philosophy

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.


0020: IAM Service Facade Philosophy & Boundaries

Date: 2025-08-13

Status: Proposed

Context

The iam-service is designed to sit in front of a powerful, feature-rich upstream Identity Provider (IdP) like R-Auth. This has raised a critical architectural question: if the upstream IdP is already so capable, why introduce this facade layer? There is a significant risk that the iam-service's scope could expand, leading to it becoming a "mini-IdP" that duplicates features and adds unnecessary complexity. We must clearly define the purpose and boundaries of the iam-service to prevent this.

Decision

The iam-service is explicitly defined as a Policy and Transformation Layer, not an identity protocol engine. It is an intelligent, domain-aware client of the upstream IdP. Its purpose is to harness and control the power of the upstream IdP for the specific needs of the Citadel ecosystem.

The responsibilities of the iam-service are strictly limited to the following four areas:

  1. Provide a Stable API Contract: The facade offers a single, permanent, and branded set of OIDC endpoints (/authorize, /token, etc.) to all first-party and third-party clients. This decouples all clients from the underlying IdP, allowing the upstream IdP to be swapped (e.g., from R-Auth to Keycloak) with zero impact on client applications.

  2. Enforce Citadel-Specific Policies: The facade is the central point for enforcing business rules that are specific to the Citadel domain and unknown to the generic upstream IdP. This includes:

    • Client Lifecycle Management: Managing the registration, status (active, blocked), and configuration of all downstream clients in its own database.
    • Tenant-Specific Rules: Applying different policies (e.g., token lifetimes, allowed scopes) based on a tenant's subscription tier or configuration.
  3. Transform and Enrich Claims: This is a primary function. The facade receives a generic token from the upstream IdP (containing claims like email and sub). It then enriches this identity by looking up the user in its own database to add critical, Citadel-specific claims like tenant_id and roles. It then issues a new, context-rich token that is consumed by all downstream Citadel services.

  4. Simplify and Abstract Upstream Features: The facade abstracts the complexity of the upstream IdP's advanced features. Through its one-to-one client provisioning model, it can expose a curated set of powerful upstream features (e.g., custom login screens, token types, MFA enforcement) through its own simplified client management API. This provides a standard developer experience while harnessing the full power of the underlying IdP.

Explicit Non-Goals (Boundaries)

To prevent scope creep, the iam-service will never:

  • Store user passwords or any form of primary credential.
  • Implement core identity protocols (OIDC, SAML, OAuth2) from scratch. It delegates this to the upstream IdP.
  • Manage the user's primary authentication session. This is managed by the upstream IdP.

Consequences

Positive

  • Architectural Stability: Decouples clients from the IdP, enabling future migrations.
  • Centralized Policy: All Citadel-specific identity policies are in one place.
  • Superior Developer Experience: Provides a simple, stable, and unified API.
  • Clear Separation of Concerns: The upstream IdP handles "who you are" (authentication), while the iam-service handles "what you can do within Citadel" (policy and context).

Negative

  • Added Latency: Introduces an additional network hop in the authentication flow.
  • Requires Discipline: The development team must be disciplined to avoid adding features that cross the boundary and belong in the upstream IdP. This ADR serves as the primary guardrail against such scope creep.