Service Accounts in Waldur
Overview
Service accounts provide automated, programmatic access to Waldur resources at various organizational levels. This feature is optional and can be enabled to support integration with external authentication systems and automation workflows.
Architecture
Core Components
1. ServiceAccountMixin
Located in src/waldur_core/structure/models.py
, this mixin provides the foundational capability for service account management:
1 2 3 4 5 6 7 8 9 10 |
|
This mixin is applied to both Customer
and Project
models, enabling service account limits at organizational and project levels.
2. Service Account Hierarchy
1 2 3 4 5 |
|
- BaseServiceAccount: Abstract base providing common fields (username, description, state)
- ScopedServiceAccount: Extends BaseServiceAccount with email and preferred_identifier
- ProjectServiceAccount: Service accounts scoped to specific projects
- CustomerServiceAccount: Service accounts scoped to customer organizations
- RobotAccount: Automated accounts for resource-level access
State Management
Service accounts use a finite state machine with three states:
- OK (0): Account is active and operational
- CLOSED (1): Account has been closed/deactivated
- ERRED (2): Account is in error state
State transitions:
set_state_ok()
: ERRED → OKset_state_closed()
: OK/ERRED → CLOSEDset_state_erred()
: * → ERRED
Backend Integration
Configuration Settings
Service account functionality requires the following settings in WALDUR_CORE
:
1 2 3 4 5 6 7 8 |
|
Mock Mode
For development and testing, a mock backend can be enabled:
1 |
|
This simulates service account operations without requiring external backend connections.
Backend API Requirements
When SERVICE_ACCOUNT_USE_API
is enabled, the backend must implement the following endpoints:
1. Authentication Endpoint
POST {SERVICE_ACCOUNT_TOKEN_URL}
Request:
1 2 3 4 5 |
|
Response:
1 2 3 |
|
2. Create Service Account
POST {SERVICE_ACCOUNT_URL}
Headers:
1 2 |
|
Request Body:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Response:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
3. Update Service Account
PUT {SERVICE_ACCOUNT_URL}/{username}
Headers:
1 2 |
|
Request Body:
1 2 3 4 |
|
4. Close Service Account
PUT {SERVICE_ACCOUNT_URL}/{username}/close
Headers:
1 |
|
Response:
1 2 3 4 5 6 |
|
5. Rotate API Key
PUT {SERVICE_ACCOUNT_URL}/{username}/rotate-api-key
Headers:
1 |
|
Response:
1 2 3 4 5 6 7 8 |
|
6. Get Service Account
GET {SERVICE_ACCOUNT_URL}/{username}
Headers:
1 |
|
Response: Same as create response structure
API Endpoints (Frontend)
Project Service Accounts
- List:
GET /api/marketplace-project-service-accounts/
- Create:
POST /api/marketplace-project-service-accounts/
- Retrieve:
GET /api/marketplace-project-service-accounts/{uuid}/
- Update:
PATCH /api/marketplace-project-service-accounts/{uuid}/
- Delete:
DELETE /api/marketplace-project-service-accounts/{uuid}/
- Rotate API Key:
POST /api/marketplace-project-service-accounts/{uuid}/rotate_api_key/
Customer Service Accounts
- List:
GET /api/marketplace-customer-service-accounts/
- Create:
POST /api/marketplace-customer-service-accounts/
- Retrieve:
GET /api/marketplace-customer-service-accounts/{uuid}/
- Update:
PATCH /api/marketplace-customer-service-accounts/{uuid}/
- Delete:
DELETE /api/marketplace-customer-service-accounts/{uuid}/
- Rotate API Key:
POST /api/marketplace-customer-service-accounts/{uuid}/rotate_api_key/
Permissions
Service account operations require the MANAGE_SERVICE_ACCOUNT
permission at the appropriate scope:
- Project Service Accounts: Permission required at project or customer level
- Customer Service Accounts: Permission required at customer level
Lifecycle Management
Automatic Cleanup
Service accounts are automatically closed when their parent scope is deleted:
- Project Deletion: All associated ProjectServiceAccounts are closed
- Customer Deletion: All associated CustomerServiceAccounts are closed
This is handled by Django signal handlers:
close_service_accounts_on_project_deletion
close_customer_service_accounts_on_customer_deletion
Account Limits
Organizations can enforce service account limits:
- Project Level: Set
max_service_accounts
on the Project model - Customer Level: Set
max_service_accounts
on the Customer model
When limits are set, attempts to create accounts beyond the limit will be rejected with a validation error.
Error Handling
Service accounts track errors through:
- state: Transitions to ERRED state on failures
- error_message: Human-readable error description
- error_traceback: Full error traceback for debugging
Failed operations automatically transition accounts to ERRED state, which can be recovered using set_state_ok()
after resolving issues.
Integration with GLAuth
Service accounts can be exported for GLAuth synchronization through the offering endpoint:
GET /api/marketplace-offerings/{uuid}/glauth_users_config/
This generates configuration records for:
- Offering users
- Robot accounts (including service accounts)
Implementation Checklist
When implementing a service account backend, ensure:
- OAuth2 token endpoint is available and returns bearer tokens
- Service account creation endpoint generates unique usernames
- API keys are returned with expiration information
- Update operations modify only allowed fields (email, description)
- Close operation marks accounts as disabled
- Get operation returns current account status
- Rotate operation generates new API keys
- Error responses use standard HTTP status codes
- All endpoints validate bearer token authentication
- Account status transitions are logged appropriately
Security Considerations
- API Keys: Generated keys are returned only once during creation. Store securely.
- Token Expiration: API keys should have reasonable TTL (default: 30 days)
- Permission Checks: All operations validate user permissions at appropriate scope
- Audit Logging: All service account operations are logged for audit trails
- Cleanup: Accounts are automatically closed when parent resources are deleted
Testing
Mock mode can be enabled for testing without external dependencies:
1 2 |
|
This simulates all backend operations locally, useful for:
- Unit tests
- Development environments
- Demo installations