Connections
Stored credentials — encrypted per organization, testable, rotatable, and never returned to a client.
A connection stores the credentials a piece needs — an API key, a database URL, an OAuth grant. Steps reference a connection by id; the credential itself is resolved only at execution time, on a worker.
Security model
- Values are sealed with envelope encryption: each organization has its own data-encryption key, and no credential is ever stored or returned in the clear. Deleting an organization destroys its key, which makes its secrets unrecoverable by construction.
- Credential values are never returned by any API — reads carry metadata only (id, name, piece, status).
- Every decryption is written to the audit log (
connection.decrypt): who, which connection, which piece, when.
Creating and testing
The add-connection dialog knows each piece's auth model — API key, basic, OAuth2, connection string — and Create and test proves the credential against the real service before you rely on it. Status (active / error / untested) shows on the connections page.
Managed OAuth (click-Connect)
Providers with a managed OAuth app show a zero-credential "Connect with X" button — no client id to paste. A connection carrying its own client id stays fully bring-your-own. Tokens refresh automatically either way.
Rotation
When a credential leaks: create a new connection, then Replace the old one — every reference is rewritten in drafts and republished into live versions, so production rotates immediately rather than "at the next publish". GET /api/connections/{id}/usage shows what references a connection before you touch it.
Scope
Connections are workspace-scoped. Templates never carry credentials: "Save as template" strips nothing because secrets were never in the definition to begin with, and using a template in another workspace leaves the credential slots empty and marked for completion.