Reference

HTTPS API reference

Requests, responses, scopes and failure behavior for the workspace Secrets API.

Base URL: https://app.asyncflux.com/api/secrets. Paths below are relative to this base. All endpoints require authentication. Use a workspace automation token in Authorization: Bearer as shown in Connect a machine or agent.

A token selects one workspace. URL-encode path components. Browser integrations use their signed-in session, the selected workspace ID in X-Vikings-Workspace, and the session's CSRF token for writes; do not reuse a browser cookie as a machine credential.

Send Content-Type: application/json on every POST, PATCH and PUT, including read operations implemented as POST. Reveal requires a JSON body; {} is sufficient. Untrusted browser origins and cross-site browser requests are refused.

Permissions and responses

The tables show scopes for scoped API tokens. Metadata requires an eligible workspace actor; mutation and plaintext operations require an owner/admin actor and the corresponding live grants. Scope names do not include an environment. See Permissions for legacy credentials and role constraints.

Unless stated otherwise, success is HTTP 200 with a JSON object. Create operations below return 201; successful deletes return 204 without a response body. Request schema failures return 422. Check both the HTTP status and per-item results on bulk operations.

There is no GET-one-plaintext endpoint. Use list for metadata, and an explicit reveal request for plaintext. Reveals, exports and comparisons with reveal: true carry Cache-Control: no-store; the client must still handle their output carefully.

Status and types

Method Path Scope Result
GET /status secrets:read available, status, health and, when permitted, workspace; service failures may include detail
GET /types secrets:read types: entries with id, label, redaction

/status reports an unavailable Secrets service as available: false, rather than a service-unavailable HTTP 503. Authentication and authorization can still fail. Its diagnostic payload may contain deployment details; do not post it publicly without reviewing it.

The HTTPS types catalog lists opaque, token, connection_string, private_key, json_credential, certificate and publishable. connection_string uses partial redaction; certificate and publishable are unmasked; the other listed types are fully masked.

The underlying service also supports config, an unmasked configuration value. Existing config entries can appear in lists even though this type is currently omitted from the HTTPS types catalog and dashboard selector. Do not use the catalog as proof that all returned display values are masked.

Workspace and environments

Method Path Scope Request and result
GET /workspace secrets:read Returns slug, name, registered, envs
POST /workspace secrets:edit Body {} or {"envs":["dev","prd"]}; returns workspace description, 201
POST /workspace/envs secrets:edit Body {"name":"docs-demo"}; returns workspace description, 201
DELETE /workspace/envs/{env} secrets:edit Optional ?force=true; 204

Each envs entry in the workspace response has name and count. Before Secrets is enabled, registered is false and envs is empty. Omitted, null or empty envs on enable selects dev and prd. Enabling an already registered workspace returns 409. The name compare is reserved by the HTTPS interface.

Removing a nonempty environment requires force=true, which deletes its secrets. The service refuses removal of the last environment. Review the target carefully before using force. This API has no workspace creation, workspace rename or environment rename route.

List and create secrets

GET /envs/{env}/secrets requires secrets:read and returns:

{
  "workspace": "docs-demo",
  "env": "dev",
  "secrets": [
    {
      "name": "DOCS_EXAMPLE_TOKEN",
      "workspace": "docs-demo",
      "env": "dev",
      "namespace": "docs-demo/dev",
      "type": "token",
      "version": 1,
      "display": "***"
    }
  ]
}

This is an illustrative subset of metadata fields. Rows are sorted by name and can also include note, created_at, updated_at, updated_by, rotate_via and last_rotated. Optional fields may be absent. display follows the type's redaction policy and can contain plaintext. Names and notes are visible metadata.

POST /envs/{env}/secrets requires secrets:edit. Required fields are name and value, both strings. Optional fields are type and note.

{
  "name": "DOCS_EXAMPLE_TOKEN",
  "value": "example-only-not-a-credential",
  "type": "token",
  "note": "Disposable documentation example"
}

Success returns 201 with {"secret":{"name":"DOCS_EXAMPLE_TOKEN","type":"token","type_inferred":false}}. Omitting type lets the service infer it. Values must satisfy their type's validation; an empty value cannot create a secret. For names that also work with .env and JSON import, use letters, digits and underscores, starting with a letter or underscore, such as DOCS_EXAMPLE_TOKEN.

Creating a secret with a note performs the create and note update separately. If the second operation fails, the secret may already exist. Check metadata before retrying a failed request.

Update, rename and delete

PATCH /envs/{env}/secrets/{name} requires secrets:edit. All fields are optional:

Field Behavior
value Replacement string; omission or null keeps the stored value
type A nonempty type changes the recorded type; omission keeps it
note Omission keeps the note; null or "" clears it; text sets it
new_name A nonempty different name renames the secret before other edits

Example body:

{"new_name":"DOCS_RENAMED_TOKEN","note":"Disposable renamed example"}

Returns {"secret":{"name":"DOCS_RENAMED_TOKEN"}}, with type also present when a value/type/note update was performed. A rename and subsequent update are separate operations; an update failure can leave the rename applied. Refresh metadata before retrying. A type-only change to weaker redaction requires re-entering the value and can otherwise be refused. Do not send "" to erase a value: empty-value updates are not a supported way to clear secrets.

DELETE /envs/{env}/secrets/{name} requires secrets:edit and returns 204. Deletion removes the secret; it is not a historical-version restore operation.

Reveal a value

POST /envs/{env}/secrets/{name}/reveal requires secrets:values and an owner/admin actor. Send {} for the current value, or {"version":1} for a retained version. Omitted, null or zero version selects current.

{
  "name": "DOCS_EXAMPLE_TOKEN",
  "type": "token",
  "version": 1,
  "value": "example-only-not-a-credential"
}

The example is disposable. Real responses contain plaintext. Reveal is audited and returns Cache-Control: no-store.

History and rollback

GET /envs/{env}/secrets/{name}/history requires secrets:read. It returns name, current_version and versions. Each version row contains version, updated_at, updated_by, client_id, actor, replaced_by and current. Fields without recorded data can be null.

The current version comes first; earlier versions follow in descending version order. updated_by identifies the version's author when known. replaced_by identifies who replaced an older version, not who originally wrote it. The history response contains no values. History retention depends on service configuration; do not assume every former value is retained.

POST /envs/{env}/secrets/{name}/rollback requires both secrets:edit and secrets:values, plus owner/admin authority. Body: {"version":1}. version is required; zero selects the newest retained previous version. Prefer an explicit version chosen from history.

Returns {"version":3} for an illustrative new current version. Rollback restores a historical value as a new version, retaining the current type. It is a write, not a read or a renumbering of history.

Save multiple changes

POST /envs/{env}/changes requires secrets:edit. Each top-level array defaults to empty:

{
  "deletes": [],
  "renames": [{"name":"DOCS_EXAMPLE_TOKEN","new_name":"DOCS_RENAMED_TOKEN"}],
  "upserts": [{"name":"DOCS_RENAMED_TOKEN","value":"example-only-replacement","type":"token"}],
  "notes": [{"name":"DOCS_RENAMED_TOKEN","note":"Disposable example"}]
}

The application order is deletes, renames, upserts carrying values, upserts without values, then note edits. Upserts with values use an overwriting import; upserts without values update type or note on an existing secret. Use notes with note: "" to clear a note explicitly. A rename failure skips dependent edits to its intended new name.

{
  "applied": 1,
  "results": [
    {"op":"rename","name":"DOCS_EXAMPLE_TOKEN","ok":true},
    {"op":"upsert","name":"DOCS_RENAMED_TOKEN","ok":false,"error":"Example rejection"}
  ]
}

This illustrative partial result still has HTTP 200. Inspect every ok flag. Failures do not undo successful items. If the service is unavailable and no item applied, the request returns 503 instead. Re-read state after a timeout before retrying; the operation may have reached the service.

Import and export

POST /envs/{env}/import requires secrets:edit:

{
  "format": "env",
  "content": "DOCS_EXAMPLE_TOKEN=example-only-not-a-credential\n",
  "overwrite": false
}

content is required. format is env (default) or json; overwrite defaults to false. JSON input is an object of names to values. String values are used directly; non-null objects, arrays, numbers and booleans are converted to JSON strings. Null values and invalid names produce item errors.

The .env parser accepts blank lines, comments, an optional export prefix and single/double-quoted multiline values. Single quotes are literal. Double quotes recognize newline, carriage-return, tab, quote and backslash escapes. Duplicate names keep the last parsed value. Unquoted inline comments begin at whitespace followed by #.

Returns created, updated, skipped and errors arrays. Error entries have name and message. Parse errors and item errors are combined; valid items can still be written. With overwrite disabled, existing names are skipped. This is not an atomic import.

POST /envs/{env}/export requires secrets:values. Body {} defaults to env; {"format":"json"} or {"format":"yaml"} selects another output. Returns {"format":"json","content":"..."} with Cache-Control: no-store. The content string contains plaintext name/value pairs, sorted by name. It does not include notes, history or access rules and is not a full service backup. Every export is audited.

Compare environments

POST /compare requires secrets:read:

{"configs":[{"env":"dev"},{"env":"prd"}],"reveal":false}

configs is required and must contain at least one entry; the dashboard asks for two or more. Each entry has env. reveal defaults to false. Returns workspace, configs in request order and name-sorted rows.

Each row has name, cells in configuration order and differs. A cell contains present, type, version, updated_at and display. Missing cells have present: false and null metadata. Default comparison checks presence, type and display; two masked values can appear equal while their underlying values differ.

With reveal: true, also require secrets:values and an owner/admin actor. Present cells include value; comparison uses actual values in place of display. This exports each environment, is audited once per export, and returns Cache-Control: no-store.

Audit activity

GET /envs/{env}/activity requires secrets:read. Optional query parameters:

Parameter Meaning
name Filter to one secret name
action Filter by an action identifier, for example secret_reveal
tail Recent-entry limit; defaults to 200 and is clamped to 1–1000

Returns {"entries":[...]}. Entries include timestamp, action and success; namespace, secret_name, client_id, actor, lease_id and details can also appear. Audit records are designed to describe the action without including its value. Do not place credentials in names or other metadata.

API activity is attributed with a token credential ID and actor ID; browser activity uses the dashboard actor ID. The daemon's client_id is its separately authenticated service identity; actor carries the bridge's attribution. Attribution is not an extra authorization grant.

Authentication endpoints

These paths are relative to https://app.asyncflux.com/api, outside the Secrets base:

Method Path Access and result
GET /work/auth/token-self API token; returns only that credential's metadata, never its secret
GET /work/auth/token-options Human workspace owner/admin; workspace, eligible actors, permission catalog and expiry limits
GET /work/auth/tokens Human workspace owner/admin; items of token metadata
POST /work/auth/tokens Human workspace owner/admin; creates a token, 201, one-time token disclosure
POST /work/auth/tokens/{token_id}/revoke Human workspace owner/admin; returns id, revoked, closed_streams
GET /work/auth/secrets-skill Human workspace owner/admin; downloads the maintained agent instructions

For scoped creation, send name (1–120 characters, not blank), nonempty scopes, optional actor_id, and optional expires_in_seconds (60–31536000; default 2592000). Example: {"name":"docs-demo-client","scopes":["secrets:read"],"expires_in_seconds":3600}. The human session must supply the selected workspace header and CSRF for writes. Scoped tokens cannot call these management endpoints or mint more tokens.

Errors

Authentication errors contain error, code and a correlation identifier; domain errors contain error and may include details. Validation errors can use FastAPI's detail list. Do not assume every error has the same JSON shape.

Status Check
400 Missing workspace selection, reserved environment name or invalid request context
401 Missing, invalid, expired or revoked credential
403 Role, grant, module scope or browser-origin refusal
404 Resource not found or workspace not visible to the caller
409 Secrets already enabled for this workspace
413 Request exceeds the Secrets service message limit
415 A POST/PATCH/PUT body was not sent as JSON
422 Invalid request fields or a service parameter rejection
501 The deployed Secrets service does not support this operation
502 Other Secrets service error; review its message rather than assuming a transient network fault
503 The API bridge cannot reach the Secrets service

Safe troubleshooting explains what to collect without disclosing a credential or value.

AsyncFlux Secrets documentation
Search documentation