Authentication & Authorization
apptor flow supports two authentication methods and a permission-based authorization system.
Authentication Methods
1. JWT / OIDC (Browser UI)
Used by the Angular frontend. The platform integrates with an external OIDC provider via Micronaut Security.
How it works:
- User navigates to
/loginor is redirected to the OIDC provider - OIDC provider authenticates the user and redirects to
/auth/callbackwith an authorization code - The frontend exchanges the code for a JWT access token
- All subsequent API requests include the token:
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...
JWT validation: The CustomJwtValidator and JWKSResolver verify the token signature against the OIDC provider's JWKS endpoint. Tokens are cached in KeyCache to avoid repeated JWKS lookups.
Token payload contains: userId, email, organizationId, and role/permission claims.
2. API Key (Machine-to-Machine)
Used for programmatic API access — server-to-server integrations, automated scripts, and workflow triggers.
Format:
apk_{keyId}_{secret}
Header:
X-API-Key: apk_key123_abcde...
Authentication flow:
ApiKeyAuthenticationFilterintercepts requests matching/process/**and/api/taskserver/**- Extracts the
X-API-Keyheader value - Looks up
keyIdin theapi_keystable - Verifies
secretagainst the stored bcrypt hash (keyHash) - Validates the key is
ACTIVE, not expired (expiresAt), and within rate limits - Attaches
AuthenticationContext.AuthInfoto the request withisApiKeyAuth: true
System API Key: A special system-level API key can be configured via app.system-api-key and app.system-org-id in application config. This key bypasses the database lookup and is used for internal service-to-service calls.
Authorization — Permission-Based RBAC
Authorization is checked by AuthenticationContext.hasPermission(authInfo, Permission) in each controller.
Permission Structure
Permissions follow the format RESOURCE_ACTION:
Workflow Permissions
| Permission | Description |
|---|---|
WORKFLOW_CREATE | Create new workflows |
WORKFLOW_READ | View workflow definitions |
WORKFLOW_UPDATE | Edit workflow definitions |
WORKFLOW_DELETE | Delete workflows |
WORKFLOW_PUBLISH | Publish workflow versions |
WORKFLOW_EXECUTE | Trigger workflow executions |
User Permissions
| Permission | Description |
|---|---|
USER_CREATE | Invite new users |
USER_READ | View user list |
USER_UPDATE | Edit user profile |
USER_DELETE | Deactivate users |
USER_MANAGE | Manage user roles and groups |
Organization Permissions
| Permission | Description |
|---|---|
ORG_READ | View organization settings |
ORG_UPDATE | Edit organization settings |
ORG_SETTINGS | Manage advanced org settings |
API Key Permissions
| Permission | Description |
|---|---|
APIKEY_CREATE | Create API keys |
APIKEY_READ | View API keys (redacted) |
APIKEY_REVOKE | Revoke/delete API keys |
Secret Permissions
| Permission | Description |
|---|---|
SECRET_CREATE | Create secrets |
SECRET_READ | View secret names (never values) |
SECRET_UPDATE | Update secret values |
SECRET_DELETE | Delete secrets |
Integration Permissions
| Permission | Description |
|---|---|
INTEGRATION_CREATE | Add new integrations |
INTEGRATION_READ | View integration configurations |
INTEGRATION_UPDATE | Edit integration settings |
INTEGRATION_DELETE | Remove integrations |
Execution Permissions
| Permission | Description |
|---|---|
EXECUTION_READ | View execution history and logs |
EXECUTION_CANCEL | Cancel running executions |
Admin Permissions (Super Admin only)
| Permission | Description |
|---|---|
ADMIN_READ | Read system-wide admin data |
ADMIN_WRITE | Write system-wide admin data |
USER_READ_ALL | Read users across all organizations |
USER_CREATE_ALL | Create users in any organization |
ORG_READ_ALL | Read all organizations |
ORG_CREATE_ALL | Create new organizations |
APIKEY_READ_ALL | View API keys across all organizations |
INTEGRATION_READ_ALL | View integrations across all organizations |
IDP_READ_ALL | View identity providers across all organizations |
Multi-Tenant Isolation
Every database entity has an organizationId column. All queries are scoped to the authenticated user's organizationId from their JWT or API Key context.
AuthInfo fields resolved per request:
public class AuthInfo {
String userId;
String email;
String organizationId; // tenant isolation key
boolean isApiKeyAuth;
}
A user cannot access another organization's data — even if they know the IDs — because all repository queries include WHERE org_id = :organizationId.
Identity Provider (IDP) Management
Organizations can configure custom identity providers via /admin/idps. Supported IDP types are managed through the organization_auth_configs and idp_connections tables. This allows organizations to bring their own OIDC/SAML provider (e.g., Okta, Azure AD) instead of using the default apptor ID.
API Key Lifecycle
API keys in REVOKED state cannot be reactivated. Rate limits are enforced per minute (rateLimitPerMinute) and per hour (rateLimitPerHour). Exceeding the limit returns HTTP 429.
OAuth Credentials for Integrations
Third-party integrations (Google Drive, CRM systems, etc.) use OAuth 2.0 credentials managed via the oauth_credentials table. The OAuth flow is handled by apptor-oauth and the callback is at /integrations/oauth. Credentials are stored encrypted and refreshed automatically before expiry.