Skip to main content

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:

  1. User navigates to /login or is redirected to the OIDC provider
  2. OIDC provider authenticates the user and redirects to /auth/callback with an authorization code
  3. The frontend exchanges the code for a JWT access token
  4. 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:

  1. ApiKeyAuthenticationFilter intercepts requests matching /process/** and /api/taskserver/**
  2. Extracts the X-API-Key header value
  3. Looks up keyId in the api_keys table
  4. Verifies secret against the stored bcrypt hash (keyHash)
  5. Validates the key is ACTIVE, not expired (expiresAt), and within rate limits
  6. Attaches AuthenticationContext.AuthInfo to the request with isApiKeyAuth: 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

PermissionDescription
WORKFLOW_CREATECreate new workflows
WORKFLOW_READView workflow definitions
WORKFLOW_UPDATEEdit workflow definitions
WORKFLOW_DELETEDelete workflows
WORKFLOW_PUBLISHPublish workflow versions
WORKFLOW_EXECUTETrigger workflow executions

User Permissions

PermissionDescription
USER_CREATEInvite new users
USER_READView user list
USER_UPDATEEdit user profile
USER_DELETEDeactivate users
USER_MANAGEManage user roles and groups

Organization Permissions

PermissionDescription
ORG_READView organization settings
ORG_UPDATEEdit organization settings
ORG_SETTINGSManage advanced org settings

API Key Permissions

PermissionDescription
APIKEY_CREATECreate API keys
APIKEY_READView API keys (redacted)
APIKEY_REVOKERevoke/delete API keys

Secret Permissions

PermissionDescription
SECRET_CREATECreate secrets
SECRET_READView secret names (never values)
SECRET_UPDATEUpdate secret values
SECRET_DELETEDelete secrets

Integration Permissions

PermissionDescription
INTEGRATION_CREATEAdd new integrations
INTEGRATION_READView integration configurations
INTEGRATION_UPDATEEdit integration settings
INTEGRATION_DELETERemove integrations

Execution Permissions

PermissionDescription
EXECUTION_READView execution history and logs
EXECUTION_CANCELCancel running executions

Admin Permissions (Super Admin only)

PermissionDescription
ADMIN_READRead system-wide admin data
ADMIN_WRITEWrite system-wide admin data
USER_READ_ALLRead users across all organizations
USER_CREATE_ALLCreate users in any organization
ORG_READ_ALLRead all organizations
ORG_CREATE_ALLCreate new organizations
APIKEY_READ_ALLView API keys across all organizations
INTEGRATION_READ_ALLView integrations across all organizations
IDP_READ_ALLView 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.