Skip to main content

39. OpenFGA Permission Inheritance for Service Principals

Date: 2025-01-28

Status

Accepted

Category

Authentication & Authorization

Context

Service principals (ADR-0033) need to act on behalf of users for scenarios like:
  • Scheduled reports generated for specific users
  • Batch jobs processing user data with user’s permissions
  • Background tasks accessing user conversations
  • Service-to-service calls maintaining user context
Challenge: Service principals have their own identity (service:batch-job) but need user permissions without password sharing or impersonation tokens. Current OpenFGA model supports direct user→object permissions but not delegation/inheritance.

Decision

Extend OpenFGA authorization model with acts_as relation enabling service principals to inherit permissions from associated user principals while maintaining distinct identities.

Architecture

OpenFGA Permission Inheritance Flow

Core Principles

  1. Explicit Association: acts_as tuples created deliberately (not automatic)
  2. Transitive Permissions: Service inherits all user permissions
  3. Distinct Identity: Service actions logged as service (not user)
  4. Audit Trail: Both service and associated user tracked
  5. Revocable: Disabling user revokes service permissions
  6. Ownership Tracking: Services have owners for management

OpenFGA Model Extension

New Type:
Relationship Tuples:

Permission Check Implementation

Enhanced Authorization (src/mcp_server_langgraph/auth/openfga.py):

Configuration

Consequences

Positive Consequences

  • Service principals can act on behalf of users (no password sharing)
  • Clear audit trail (service identity + associated user)
  • Flexible permissions (service can act as multiple users)
  • Revocation propagates (disable user → service loses permissions)
  • Standard ReBAC model (no custom authorization logic)

Negative Consequences

  • Additional authorization complexity (extra tuple lookups)
  • Performance impact (two permission checks instead of one)
  • Potential permission confusion (non-obvious inheritance)
  • Authorization model more complex (additional relation types)

Mitigation Strategies

  • Cache acts_as relationships (5-min TTL, high hit rate)
  • Clear logging of inherited access
  • UI showing effective permissions for service principals
  • Documentation with clear examples

Alternatives Considered

  1. Token Impersonation: Rejected - complex OAuth2 token exchange, admin credentials required
  2. Shared Credentials: Rejected - security risk, poor audit trail
  3. Copy Permissions: Rejected - sync overhead, permission drift
  4. Service-Specific Permissions: Rejected - doesn’t support user context

Implementation

OpenFGA Model Update (src/mcp_server_langgraph/auth/openfga.py:287-377):
Tuple Creation (in ServicePrincipalManager):
Authorization Check Enhancement:

References

  • OpenFGA Integration: src/mcp_server_langgraph/auth/openfga.py
  • Service Principal Manager: src/mcp_server_langgraph/auth/service_principal.py (to be created)
  • Related ADRs: ADR-0002, ADR-0033
  • External: OpenFGA Docs, ReBAC