.agents/features/embed.md
Embed Onboarding lets a platform admin configure embedded workflows. The admin UI at /platform/security/embed (packages/web/src/app/routes/platform/security/embed/) renders a stepper:
embed_subdomain), verify DNS, set allowedEmbedDomains (frame-ancestors), create signing keys.allowedEmbedDomains, create signing keys (no hostname/DNS — self-hosted uses FRONTEND_URL).The cryptographic core is Signing Keys: RSA-4096 key pairs generated server-side for the Managed Auth flow. The platform admin creates a signing key — the private key is returned exactly once and must be saved by the admin; only the public key is stored. The vendor's backend uses the private key to sign JWTs that Activepieces verifies using the stored public key when POST /v1/managed-authn/external-token is called. Whole feature gated by platform.plan.embeddingEnabled.
allowedEmbedDomains lives on the platform table (alongside allowedAuthDomains) and is updated via POST /v1/platforms/:id (UpdatePlatformRequestBody.allowedEmbedDomains). The embed-security Fastify hook (packages/server/api/src/app/helper/embed-security.ts) reads this list per request to set the Content-Security-Policy: frame-ancestors header. See managed-auth.md for the JWT verification flow.
packages/server/api/src/app/ee/signing-key/signing-key-module.ts — module registration with embeddingEnabled guardpackages/server/api/src/app/ee/signing-key/signing-key-controller.ts — REST controller (CRUD + audit event on create)packages/server/api/src/app/ee/signing-key/signing-key-service.ts — service (add, list, get, delete)packages/server/api/src/app/ee/signing-key/signing-key-generator.ts — RSA-4096 key pair generation using Node.js cryptopackages/server/api/src/app/ee/signing-key/signing-key-entity.ts — TypeORM entitypackages/shared/src/lib/ee/signing-key/signing-key-model.ts — SigningKey type and KeyAlgorithm enumpackages/shared/src/lib/ee/signing-key/signing-key-response.ts — AddSigningKeyResponse type (includes privateKey)packages/shared/src/lib/ee/signing-key/signing-key.request.ts — AddSigningKeyRequestBody schemapackages/web/src/features/platform-admin/api/signing-key-api.ts — frontend API clientpackages/web/src/features/platform-admin/hooks/signing-key-hooks.ts — React query hookspackages/web/src/features/platform-admin/components/new-signing-key-dialog.tsx — UI dialog showing the private key once on creationpackages/web/src/app/routes/platform/security/embed/ — platform admin UI page (Embed Onboarding)Enterprise and Cloud. Gated by platform.plan.embeddingEnabled. Module hook: platformMustHaveFeatureEnabled((platform) => platform.plan.embeddingEnabled).
RSA (the only supported algorithm, using RS256 for JWT signing).id of the signing key, embedded in the JWT header by the vendor so Activepieces knows which public key to use for verification.Table name: signing_key
| Column | Type | Notes |
|---|---|---|
| id | ApId | PK |
| created | string | From BaseColumnSchemaPart |
| updated | string | From BaseColumnSchemaPart |
| platformId | ApId | FK to platform (RESTRICT on delete/update) |
| displayName | string | Human-readable label |
| publicKey | string | PEM-encoded RSA-4096 public key (PKCS#1 format) |
| algorithm | string | KeyAlgorithm enum — currently always RSA |
All mount under /v1/signing-keys. All require platformAdminOnly([USER]).
| Method | Path | Auth | Response | Description |
|---|---|---|---|---|
| POST | /v1/signing-keys | Platform admin | AddSigningKeyResponse (201) | Generate a new key pair; private key returned once |
| GET | /v1/signing-keys | Platform admin | SeekPage<SigningKey> | List all public keys for platform |
| GET | /v1/signing-keys/:id | Platform admin | SigningKey | Get a single signing key |
| DELETE | /v1/signing-keys/:id | Platform admin | 200 | Delete a signing key |
AddSigningKeyResponse extends SigningKey with the one-time privateKey: string field.
Creating a key fires a SIGNING_KEY_CREATED audit event.
add({ platformId, displayName }) — generates an RSA-4096 key pair (PKCS#1 PEM format), saves the public key, returns AddSigningKeyResponse with privateKey.list({ platformId? }) — returns all signing keys for the platform. Not paginated internally (wrapped in SeekPage with null cursors).get({ id }) — fetches a single key by ID (no platformId filter — used by token extraction where only the kid is known).delete({ platformId, id }) — deletes by platform + id; throws ENTITY_NOT_FOUND if not found.Uses Node.js crypto.generateKeyPair with:
rsaThe private key is never stored and is only included in the creation response. The algorithm field is set to KeyAlgorithm.RSA for future extensibility.
Signing Keys are the cryptographic foundation for the Managed Auth flow:
kid set to the key's id.POST /v1/managed-authn/external-token, externalTokenExtractor reads kid from the JWT header, fetches the public key via signingKeyService.get, and verifies the JWT using RS256.