brain/wiki/connections-auth/index.md
How Activepieces stores credentials and authenticates users, across CE/EE/Cloud. Multi-tenant rule throughout: connection queries filter by project via ArrayContains([projectId]) on the projectIds[] array (never a scalar projectId), or by scope = PLATFORM for shared ones.
Encrypted credential records (AES-256) that flow steps use to call external services. Types: OAUTH2, CLOUD_OAUTH2 (token exchange via secrets.activepieces.com), PLATFORM_OAUTH2, SECRET_TEXT, BASIC_AUTH, CUSTOM_AUTH, NO_AUTH, OIDC.
AppConnection has projectIds[] (multi-project) + scope (PROJECT/PLATFORM). PROJECT connections queried with ArrayContains([projectId]); flows reference by stable externalId (survives rename).${platformId}_${externalId} (project-invariant so shared connections serialize). Refresh_token/client_secret always stripped from API responses. CUSTOM_AUTH pieces can opt into refresh via a refresh callback (worker EXECUTE_TOKEN_REFRESH job).POST /v1/worker/oidc-token issues RS256 JWTs; public /.well-known/openid-configuration + jwks.json. Signing key auto-generated into the flag table (first-writer-wins, zero setup).POST /replace rewires flow refs between connections; PLATFORM source can't be deleted via replace (403); deleting a project source 409s while a published flow still uses it. Deleting a connection does NOT cascade — flows fail at runtime.App connections with scope = PLATFORM, shared across projects, managed from platform admin. Gated by platform.plan.globalConnectionsEnabled. Same app_connection table (the scope column distinguishes them); projectIds[] lists who can use it, preSelectForNewProjects auto-assigns new projects. All endpoints under /v1/global-connections require platform admin (USER or SERVICE key). Delegates to shared appConnectionService with projectId: null.
Platform owners register their own OAuth client_id/secret per piece so connections use vendor-branded consent instead of AP's shared creds. Table oauth_app, unique (platformId, pieceName), clientSecret encrypted (jsonb). No plan flag. List is readable by any platform member (dialog needs to know which pieces have custom creds); create/delete are admin-only. Secret only used server-side during token exchange.
User identity, sign-in, JWT sessions. UserIdentity = canonical email+password+provider (one per email, shared across platforms); User = platform-scoped membership. First sign-up auto-creates a Platform + personal Project + ADMIN user. JWT is 7-day, signed with a shared secret; rotating tokenVersion on UserIdentity invalidates all sessions. accessTokenManager also mints long-lived engine/worker tokens. Endpoints: /v1/authentication/sign-up|sign-in|switch-platform. PrincipalTypes: USER/ENGINE/WORKER/SERVICE/UNKNOWN.
Extends CE with SSO + RBAC. SAML 2.0 (/v1/authn/saml/login → IdP → ACS /acs) and Google/GitHub federated OAuth both funnel into authenticationService.federatedAuthn(); gated by ssoEnabled. Per-project RBAC via assertPrincipalAccessToProject() and assertUserHasPermissionToFlow(). Config stored on platform.federatedAuthProviders. Authz hooks: platformMustHaveFeatureEnabled (402), projectMustBeTeamType, platformMustBeOwnedByCurrentUser. OTP (email verify + password reset) lives here but is available in CE too.
Lets SaaS vendors embed the AP builder. Vendor backend signs a short-lived JWT with an RSA private key (Signing Key); SDK exchanges it at public POST /v1/managed-authn/external-token. AP verifies against stored public key (by kid), auto-provisions project + user + membership, returns a 7-day AP token. Managed user emails are deterministic SHA-256 of managed_<platformId>_<externalUserId> (never real emails). Token payload versions v2/v3/v4 (union ordered v4→v3→v2); v4 carries a pieceSet key. Gated by embeddingEnabled (via signing keys).
Platform-scoped sk- service credentials for machine-to-machine calls. 64 chars, stored only as SHA-256 hash (plaintext returned once on create); last 4 chars kept for display; lastUsedAt updated per request. Table api_key, admin-only under /v1/api-keys. Gated by apiKeysEnabled.
Platform owners / members with WRITE_INVITATION invite users to a platform (grants PlatformRole) or a project (grants named ProjectRole). Invitation link = 7-day JWT to /invitation?token=...; sent by email if SMTP configured, else link returned in the API response. Auto-accept for SERVICE key callers and already-registered users invited to a project. On accept, provisionUserInvitation sets platformRole or upserts a ProjectMember, then deletes the invite. Project invites need projectRolesEnabled + team project.
User ties a UserIdentity to one platform (unique (platformId, identityId)). PlatformRole: ADMIN (all projects), MEMBER (own + team), OPERATOR (read all except others' personal). Session = user ACTIVE + identity verified + tokenVersion match; logout increments tokenVersion. GET/POST /v1/users/me (CE); platform admin user CRUD (list/role/status/delete) is EE.
IdP-driven provisioning (Okta/Azure AD/Google). SCIM User → AP User+UserIdentity (provider SAML); SCIM Group → AP TEAM project. Auth = API key as Bearer (platformAdminOnly SERVICE); MIME application/scim+json. Endpoints under /v1/scim/v2/Users|Groups + discovery. DELETE user = deactivate (status INACTIVE), not hard delete. Group members added with SCIM_DEFAULT_PROJECT_ROLE (default EDITOR). Supports Patch + Filter (max 100); no bulk/sort/password. Gated by scimEnabled.
sk- prefixed