EUREKA-588 Spike - Investigate options for m2m calls based on defined module permissions

EUREKA-588 Spike - Investigate options for m2m calls based on defined module permissions

Spike Overview

ID: EUREKA-588

Overview

In the current FOLIO implementation, cross-module communication is handled by sidecars that enhance requests using system tokens.

Currently, sidecars in the Eureka platform include an overly privileged system token in module-to-module (M2M) calls. This setup compromises security boundaries because:

  • Any sidecar can invoke any endpoint of any module.

  • The intended module-specific permissions (modulePermissions) are effectively ignored.

  • Fine-grained control at the endpoint level is lacking, even though modulePermissions were designed to support this.

Background

Eureka's architecture uses sidecars to handle authorization by validating tokens before forwarding requests to downstream services.

The OKAPI platform dynamically adjusts tokens in-flight to include module-specific permissions. This supports more granular and secure access control, aligning better with the principle of least privilege.

Problem Statement

Using a globally privileged token in sidecars weakens FOLIO’s security posture by:

  • Allowing unrestricted access to internal APIs.

  • Increasing the risk of lateral movement if a sidecar is compromised.

  • Permitting modules to invoke endpoints they were never explicitly granted access to.

This approach violates the principle of least privilege and complicates efforts to reason about and audit access boundaries across the system.

Scope

This spike investigates and evaluates different M2M authorization strategies for FOLIO using Keycloak and module descriptors. The goal is to define a secure, scalable, and maintainable mechanism for module-to-module communication. The implementation should:

  • Support endpoint-level permissions via modulePermissions.

  • Avoid requiring manual permission logic in each module.

  • Minimize the number of Keycloak clients and service accounts.

  • Keep token handling lightweight.

  • Be backward-compatible or require minimal changes for module developers.

  • Work with existing Keycloak and Okapi capabilities (or with minimal enhancements).

Proposed Solutions

Option 1: Token Exchange via Keycloak

Leverage Keycloak’s OAuth 2.0 Token Exchange protocol (RFC 8693) to issue short-lived tokens that represent a combination of user and module-level permissions.

Token Composition Strategy ("Effective Token")

Replace the static system token with a dynamic, composite token that includes:

  • The original user token (from the incoming request).

  • Additional claims specific to the target module and endpoint (e.g., modulePermissions).

This results in an "effective token" that represents:
User Identity + Module-Specific Capabilities

Authorization decisions can then be made based on the intersection of user and module endpoint permissions.

Implementation Steps
  1. Enable Token Exchange in Keycloak:

    • Navigate to Clients > Your Client > Settings in Keycloak.

    • Enable Token Exchange.

    • Configure required permissions to allow the sidecar to impersonate or exchange tokens.

  2. Sidecar Performs Token Exchange:

    http POST /auth/realms/myrealm/protocol/openid-connect/token Content-Type: application/x-www-form-urlencoded grant_type=urn:ietf:params:oauth:grant-type:token-exchange &subject_token=<<USER_ACCESS_TOKEN>> &subject_token_type=urn:ietf:params:oauth:token-type:access_token &requested_token_type=urn:ietf:params:oauth:token-type:access_token &audience=module-client-id &scope=module-specific-permission &client_id=sidecar-client-id &client_secret=sidecar-client-secret

     

    • subject_token: original user access token

    • audience: client ID of the target module

    • scope: module-specific permissions

  3. Sidecar Uses the Effective Token for Authorization:

    • Token includes user claims + permissions scoped to the target module and endpoint.

    • Authorization checks are based on the intersection of both.

Pros and Cons

Aspect

Pros

Cons

Aspect

Pros

Cons

Security

Ensures fine-grained access control per user and endpoint

Adds complexity in token handling and Keycloak configuration

Flexibility

Easily adaptable via client scopes and protocol mappers

Token exchange introduces network latency

Separation

Clean distinction between user and module authorization responsibilities

Requires robust handling of protocol mappers and scopes

Centralized Auth

Authorization decisions are token-driven and consistent across modules

Larger tokens may exceed HTTP header limits (e.g., 16 MB)

Standards-Based

Based on OAuth 2.0 Token Exchange (RFC 8693), supported by Keycloak

Requires extra development for custom protocol mappers

Option 2: Per-Module Keycloak Clients + Roles

Define one Keycloak client per module, and assign roles based on endpoint-level access.

Each client is responsible for maintaining its allowed scopes/permissions. Authorization is enforced by assigning the correct client credentials (with pre-defined roles) when invoking downstream modules.

Pros:

  • Clear boundaries between modules and their permissions

  • Simplifies token validation at the receiving module

Cons:

  • Increases the number of clients to manage in Keycloak

  • Requires changes in deployment or provisioning processes to issue and rotate credentials

Conclusion and Next Steps

The most promising approach is token exchange via Keycloak, where a module-specific token is generated by combining the user’s token with the necessary module permissions. This offers the most accurate and secure way to enforce access boundaries while preserving the user context.

However, this adds an extra round-trip to Keycloak and potentially increases token size. We must ensure tokens remain lightweight and compatible with HTTP header size limitations.

Next steps:

  • Prototype token exchange using Keycloak’s RFC 8693 support

  • Define and test protocol mappers for injecting modulePermissions

  • Assess token size and performance impact in real scenarios

  • Explore caching techniques to mitigate added latency

Spike Status: IN Progress