Skip to main content

0053: S2S-First IAM Architecture

Date: 2025-11-24

Status: Proposed

Context

The iam-service has two potential responsibilities: authenticating end-users (via tokens) and authenticating service-to-service (S2S) calls. When a single service handles both, it can lead to complexity. For example, endpoints must differentiate between a user context and a service context, which can complicate authorization logic and increase the surface area for security vulnerabilities.

Previous architectural decisions (ADR-0023, ADR-0024) established iam-service as a claims enrichment engine, which simplified its role by removing direct user authentication flows. However, the authorization model within the service still needs clarification. We need a clear, simple, and scalable pattern for how services interact with IAM and how user-level authorization is performed.

This ADR proposes a "S2S-First" model to further simplify the iam-service and clarify the separation of concerns between it and consumer services like the Admin BFF.

Decision

We will adopt a "S2S-First" authentication and authorization pattern for the iam-service.

  1. iam-service is S2S Only: The iam-service will only handle server-to-server (S2S) authenticated requests. It will not process end-user JWTs or manage user-level permissions directly for incoming API calls. Its endpoints will be protected by middleware that expects and validates a service identity (e.g., via an API key or a machine-to-machine JWT).

  2. BFFs Handle User Authorization: Backend-for-Frontend (BFF) services, like admin-bff, are responsible for handling all user-facing authentication and authorization.

    • The BFF will validate the end-user's token.
    • It will check the user's roles and permissions (e.g., "is this user a Super Admin?").
    • If the user is authorized to perform an action, the BFF will then make a S2S call to the iam-service on the user's behalf.
  3. Event Emission for Audit Trail: All state changes within the iam-service (e.g., TenantCreated, RoleAssigned) must trigger the emission of a domain event. This creates a non-repudiable audit trail of all actions performed, regardless of which service initiated the S2S call.

  4. Progressive Complexity (SaaS → PaaS → IaaS): This architecture provides a simple baseline that can be extended:

    • SaaS: The simple model of user auth in the BFF and S2S calls to IAM is sufficient.
    • PaaS: Resource-level permissions can be added later by integrating a dedicated permissions-service (ReBAC).
    • IaaS: For maximum complexity, a full-blown IAM model can be built on top of these primitives.

Consequences

Positive

  • Simplified iam-service: The service has a single, clear responsibility, reducing its complexity and attack surface.
  • Clear Separation of Concerns: User authorization logic is cleanly separated from core IAM policy management.
  • Improved Security: iam-service endpoints are not directly exposed to end-user tokens.
  • Scalability: The pattern allows for simple use cases now while providing a clear path to more complex authorization models (PaaS/IaaS) in the future.

Negative

  • Extra Hop: The BFF introduces an additional network hop, but this is an acceptable trade-off for the clear separation of concerns.
  • BFF Responsibility: The BFF becomes a critical security checkpoint and must be built and tested accordingly.