Overview
Service principals are first-class identities separate from users, designed for:- Batch ETL Jobs: Multi-hour data processing tasks
- Streaming Connections: WebSocket connections requiring persistent auth
- Background Processors: Queue processors with continuous authentication
- Scheduled Reports: Automated report generation on behalf of users
- CI/CD Pipelines: Deployment automation
- API Integrations: Third-party systems with programmatic access
Authentication Modes
Mode 1: Client Credentials (Recommended)
OAuth2 client credentials flow using Keycloak client configuration. Use when:- Dedicated service or microservice
- OAuth2 compliance required
- Rotating credentials needed
Mode 2: Service Account User
Special user account marked as service principal. Use when:- Legacy system migration
- Mixed authentication needs
- Simpler deployment (username/password)
Permission Inheritance
Service principals can inherit permissions from user principals via theacts_as relationship.
Example Scenario
Alice owns a conversation. She creates a service principal for scheduled reports:Long-Lived Sessions
Service principals support 30-day refresh tokens for persistent authentication.Configuration
Client Implementation
Management Operations
List Service Principals
Rotate Secret
Delete Service Principal
Best Practices
Security
- ✅ Store client secrets in secrets manager (not environment variables)
- ✅ Rotate secrets every 90 days
- ✅ Use IP whitelisting for sensitive services
- ✅ Monitor service principal usage
- ✅ Revoke unused service principals
Permissions
- ✅ Use least privilege (only associate with user if needed)
- ✅ Document permission inheritance in service description
- ✅ Audit inherited access regularly
- ✅ Create dedicated users for services when possible
Operations
- ✅ Name services descriptively (e.g., “nightly-etl-job”)
- ✅ Document purpose in description field
- ✅ Tag owner for accountability
- ✅ Monitor token refresh failures
- ✅ Set alerts for authentication errors
Troubleshooting
Authentication Fails
Symptom:401 Unauthorized when authenticating
Solutions:
- Verify client_id matches service_id
- Check client_secret is correct
- Ensure service principal is enabled
- Verify Keycloak realm and endpoint URLs
Permission Denied
Symptom:403 Forbidden when accessing resources
Solutions:
- Check if service has direct permissions
- Verify acts_as relationship exists (if using inheritance)
- Confirm associated user has required permissions
- Check OpenFGA tuples:
openfga-cli check
Token Expired
Symptom:401 Unauthorized with “Token has expired”
Solutions:
- Implement automatic refresh before expiration
- Check system clock synchronization (NTP)
- Verify refresh token hasn’t expired (30 days)
- Re-authenticate if refresh token expired
Examples
Seeexamples/service_principals/ for complete examples:
batch_job_example.py- Batch processing with 12-hour runtimestreaming_example.py- WebSocket streaming with persistent authscheduled_task_example.py- Cron job with user permission inheritance
References
Architecture & API Docs
- ADR: ADR-0033: Service Principal Design
- API Reference: Service Principals API
- Keycloak Docs: Service Accounts
- OpenFGA: ADR-0039: Permission Inheritance
Related Guides
- API Key Management - Alternative authentication for simpler use cases
- Identity Federation - Federated service principal authentication
- SCIM Provisioning - Automated service principal provisioning
- OpenFGA Setup - Fine-grained authorization and permission inheritance