39. OpenFGA Permission Inheritance for Service Principals
Date: 2025-01-28Status
AcceptedCategory
Authentication & AuthorizationContext
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
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 withacts_as relation enabling service principals to inherit permissions from associated user principals while maintaining distinct identities.
Architecture
OpenFGA Permission Inheritance Flow
Core Principles
- Explicit Association:
acts_astuples created deliberately (not automatic) - Transitive Permissions: Service inherits all user permissions
- Distinct Identity: Service actions logged as service (not user)
- Audit Trail: Both service and associated user tracked
- Revocable: Disabling user revokes service permissions
- Ownership Tracking: Services have owners for management
OpenFGA Model Extension
New Type: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_asrelationships (5-min TTL, high hit rate) - Clear logging of inherited access
- UI showing effective permissions for service principals
- Documentation with clear examples
Alternatives Considered
- Token Impersonation: Rejected - complex OAuth2 token exchange, admin credentials required
- Shared Credentials: Rejected - security risk, poor audit trail
- Copy Permissions: Rejected - sync overhead, permission drift
- Service-Specific Permissions: Rejected - doesn’t support user context
Implementation
OpenFGA Model Update (src/mcp_server_langgraph/auth/openfga.py:287-377):
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