.agents/features/oauth-apps.md
OAuth Apps allow platform owners to register their own OAuth 2.0 application credentials (client ID and client secret) for pieces that support OAuth. When a platform has a custom OAuth app registered for a piece, the connection dialog uses those credentials instead of Activepieces' shared credentials. This gives vendors full control over OAuth consent screens, rate limits, and branding. The client secret is encrypted at rest using the platform's encryption key. There is no plan flag gate — the module is available to all authenticated platform users.
packages/server/api/src/app/ee/oauth-apps/oauth-app.module.ts — module registration + controller (both in one file)packages/server/api/src/app/ee/oauth-apps/oauth-app.service.ts — CRUD service with encryptionpackages/server/api/src/app/ee/oauth-apps/oauth-app.entity.ts — TypeORM entitypackages/shared/src/lib/ee/oauth-apps/oauth-app.ts — OAuthApp, UpsertOAuth2AppRequest, ListOAuth2AppRequest typespackages/web/src/features/connections/api/oauth-apps.ts — frontend API clientpackages/web/src/features/connections/hooks/oauth-apps-hooks.ts — React query hookspackages/web/src/app/routes/platform/setup/pieces/update-oauth2-dialog.tsx — UI dialog for configuring OAuth app credentialsNo explicit plan flag gate. The module is available to all platform users (list endpoint uses publicPlatform security; create/delete use platformAdminOnly).
@activepieces/piece-google-sheets) that this credential applies to.jsonb, decrypted on use.Table name: oauth_app
| Column | Type | Notes |
|---|---|---|
| id | ApId | PK |
| created | string | From BaseColumnSchemaPart |
| updated | string | From BaseColumnSchemaPart |
| pieceName | string | Piece identifier |
| platformId | ApId | FK to platform (CASCADE DELETE) |
| clientId | string | OAuth client ID |
| clientSecret | jsonb | Encrypted EncryptedObject |
Unique index: idx_oauth_app_platformId_pieceName on (platformId, pieceName) — enforces one credential set per piece per platform.
All mount under /v1/oauth-apps.
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /v1/oauth-apps | Any platform member (publicPlatform) | List OAuth apps for platform (paginated) |
| POST | /v1/oauth-apps | Platform admin only | Upsert (create or replace) credentials for a piece |
| DELETE | /v1/oauth-apps/:id | Platform admin only | Remove credentials |
upsert({ platformId, request }) — uses TypeORM upsert on (platformId, pieceName) conflict target. Encrypts clientSecret before saving. Returns the saved record without the secret.getWithSecret({ platformId, pieceName, clientId? }) — fetches the record and decrypts the clientSecret. Used internally when performing OAuth token exchanges.list({ platformId, request }) — paginated list of OAuth apps for a platform. Secrets are not included in list responses.delete({ platformId, id }) — deletes by platform + id; throws ENTITY_NOT_FOUND if not found.clientId is returned in list/get responses; clientSecret is only used server-side during OAuth flows.