Authorize

#Secrets

A secret (an API key, a provider token) is stored write-only and is never returned by any API again. Your workflows and apps don't read secrets directly — they read a reference you wire into their activation config. There are three moves, always in this order.

Authenticate with a Personal Access Token (HTTP Basic auth) — enter it once in the Authorize bar above and every Try it below uses it.

#1. Store the value

Store a value under an UPPER_SNAKE name. It defaults to tenant scope; pass a different scope (and a scope_id for team / company / app) to target one. Re-storing the same name overwrites it (rotation).

POST/access/secretsStore a secret valueAPI docs ↗Try it

The value is encrypted at rest and never comes back out of the API — GET /access/secrets lists names only, and no role or grant can retrieve a stored value. Values surface only inside a running workflow/app action.

#2. Wire a reference into activation config

Put a scoped reference{{ secrets.<scope>.<NAME> }} — into a named slot of the activation config (a workflow's config env, or an app's config). The presence of that reference in config is the read authorization: there is no separate "read secret" permission, and a workflow/app may resolve only the references its tenant wired into config (a reference arriving any other way — form input, an action result — is refused).

For a workflow, wire it into the tenant config env:

PUT/workflows/{id}/configWire a secret into a workflow's envAPI docs ↗Try it

For an app, wire it into the app config (or an integration / principal config):

PUT/apps/{specId}/configWire a secret into an app's configAPI docs ↗Try it

#3. Read the config key from the definition

The workflow/job/action body or the app spec reads the config key — never secrets.*. A workflow action references config.env.PROVIDER_API_KEY; an app spec references the config slot you wired (e.g. config.app.provider_token). At run time the wired reference resolves, the value is injected into server-side execution only, and it is scrubbed out of any output or response.

A {{ secrets.* }} reference may live ONLY in config. Putting one in a workflow definition or app spec is rejected on save (SECRET_REF_IN_DEFINITION). A bare, scope-less {{ secrets.NAME }} is always rejected — every reference must name a scope, so a user's STRIPE_KEY and the tenant's STRIPE_KEY can never collide or leak.

#Scopes

A reference always names the scope it reads from:

Scope Reference Resolves to
tenant {{ secrets.tenant.NAME }} the tenant-wide value
company {{ secrets.company.NAME }} the caller's own company (implicit at run time)
user {{ secrets.user.NAME }} the caller's own user — one wired reference serves every user with their own value
app {{ secrets.app.NAME }} the current app activation (implicit)
team {{ secrets.team.<TEAM_ID>.NAME }} a specific team (always an explicit team id)

The implicit scopes (user / company / app) make the same wired reference resolve to a different value per caller, so a reference can never leak across users, companies, or apps. When you store a team / company / app secret via the API, pass its scope_id; tenant and user are derived from you.

#Rotate, list, and delete

  • RotatePUT /access/secrets with the same name and a new value (or just re-POST). Wired references pick up the new value on the next run.
  • List (names only) — GET /access/secrets (optionally ?scope=company).
  • DeleteDELETE /access/secrets/{name} (add ?scope=&scope_id= for a non-tenant scope).

#API reference

Every secret operation, with full schemas and an interactive console, is in the API reference.