Skip to content
Registry

secrets

v0.1.4

Local protected secret store. Provider keys and other credentials are encrypted under a master key kept outside the project (secret://NAME) or kept as variables in the project's .env (env://NAME), referenced from versioned configuration and resolved only by the workers each secret allowlists; metadata reads never return a value, and the secrets::changed trigger reports rotations and .env edits.

license: Apache-2.0credentialssecretssecurityvault

Install

bash
iii trigger compose::add worker=secrets@next

Run in your project with the iii engine running. Exact versions are immutable and digest-pinned.

Agent-ready brief for v0.1.4
Install, config, dependencies, readme, skills and API reference, all in one place. Fetch as agent-context.md for an LLM to consume.
The same content rendered as discrete blocks below is exposed as a single markdown document at /workers/secrets.md?version=next. Paste it into an LLM prompt or pipe it through curl from a worker.

Install

iii trigger compose::add worker=secrets@0.1.4

Configuration

iii-config.yaml
- data_dir: data/secrets
  env_file: .env
  key_file: null

Dependencies

Dependency · 1Version

Readme

README.md

secrets

secrets keeps credentials such as provider API keys out of the files you commit. Configuration stores a reference, which is safe to version, and the value lives in one of two stores:

  • vault — secret://ANTHROPIC_API_KEY: encrypted in a local vault. A pasted key goes here by default.
  • env — env://ANTHROPIC_API_KEY: an environment variable, read from the project's env file — .env unless env_file names another, which this worker can also write — or, when it is not there, from this worker's own environment. For people who prefer keeping keys in .env, and for deploys that inject them as variables.

Either way the value is handed only to the workers you allow, such as llm-router. Listing, inspecting and detecting secrets returns masked hints and fingerprints, never a value.

Install

iii trigger compose::add worker=secrets

Compose starts the worker with its configuration dependency. llm-router depends on secrets, so adding the router from the registry adds it too. Wait for secrets::status to register before calling it.

Quickstart

Find a key you already have. secrets::detect looks in the worker's own environment, the project's .env and your login shell, and reports where it found each name:

iii trigger secrets::detect --json '{"names":["ANTHROPIC_API_KEY"]}'
{"results": [{"name": "ANTHROPIC_API_KEY", "stored": false, "sources": [
  {"kind": "dotenv", "location": "/home/me/project/.env",
   "hint": "sk-ant…9f2c", "matches_stored": false}
]}]}

Import it and allow the router to read it. The worker re-reads the value from the source itself; it never passes through the caller or your shell history:

iii trigger secrets::import --json '{
  "name": "ANTHROPIC_API_KEY", "source": "dotenv", "consumers": ["llm-router"]
}'
{"name": "ANTHROPIC_API_KEY", "ref": "secret://ANTHROPIC_API_KEY",
 "consumers": ["llm-router"], "hint": "sk-ant…9f2c",
 "fingerprint": "3f9a0c1d2e4b5a67",
 "created_at": "2026-10-02T18:04:11.532Z", "updated_at": "2026-10-02T18:04:11.532Z"}

Then put the reference, not the key, in the provider's configuration (Settings → Workers → llm-router, stored in ./config):

providers:
  anthropic:
    api_key: secret://ANTHROPIC_API_KEY

To keep the key in .env instead, pass "store": "env". With a value, secrets::set writes ANTHROPIC_API_KEY=… to the project's .env, replacing an existing definition in place (or an empty # ANTHROPIC_API_KEY= placeholder) and leaving every other line as it was. A variable already in .env is shared as it is with secrets::access:

iii trigger secrets::access --json '{
  "name": "ANTHROPIC_API_KEY", "consumers": ["llm-router"], "store": "env"
}'
{"name": "ANTHROPIC_API_KEY", "ref": "env://ANTHROPIC_API_KEY", "store": "env",
 "consumers": ["llm-router"], "hint": "sk-ant…9f2c",
 "location": "/home/me/project/.env",
 "created_at": "2026-10-06T12:04:11.532Z", "updated_at": "2026-10-06T12:04:11.532Z"}

and the provider's configuration gets api_key: env://ANTHROPIC_API_KEY.

The Console's onboarding wizard and every key field are built on the same calls: pasting a key calls secrets::set, picking a detected one calls secrets::import, and keeping a variable as it is calls secrets::access with store: "env". Fingerprints and timestamps above are illustrative.

References

A reference is secret://NAME (the vault) or env://NAME (the env store), where NAME matches ^[A-Za-z_][A-Za-z0-9_.-]{0,127}$; the scheme is case-insensitive. Provider keys reuse their environment variable name: secret://OPENAI_API_KEY, env://TYPESAFE_API_KEY. secrets::resolve also accepts the bare NAME, as a vault secret. The two stores are separate: the same NAME can be in the vault and in .env, and each reference reads its own. III_SECRETS_KEY is reserved and cannot be stored.

Where values and the key live

What Where Why it is not committed
Encrypted values /vault.json, default data/secrets/vault.json in the project data/ is gitignored by the project template; even if copied, every value is XChaCha20-Poly1305 ciphertext
Master key III_SECRETS_KEY (base64, 32 bytes) when set; otherwise ${XDG_CONFIG_HOME:-~/.config}/iii/secrets/.key It never lives in the project. A key_file inside the project directory is refused
Env store values The configured env_file (default /.env), else this worker's environment .env is gitignored by the project template. It is plain text: the vault records only who may read each variable
References and settings ./config/.yaml Paths and secret:// / env:// references only

The vault and the key file are written atomically, owner-only (files 0600, directories 0700). The key file is created the first time a value is stored. Each value is sealed with a fresh nonce and bound to its name, so a ciphertext moved to another record fails to open. The vault header records a check of the key that sealed it: a different key is refused with KEY_MISMATCH, and a missing key file is reported, never silently replaced.

Back up the key file, or use III_SECRETS_KEY from your CI or container secret store. Without the key, stored values cannot be recovered and must be entered again.

The env store reads .env each time a variable is resolved, so an edit made by hand applies at once. It never polls the file: the operating system reports changes to the project directory (inotify, FSEvents or ReadDirectoryChangesW), and an event naming .env re-reads the shared variables and reports what changed on secrets::changed. Where the platform cannot watch, an edit made by hand still applies on the next resolution but is not announced. A value it writes must fit on one line; .env is written atomically and left owner-only (0600).

Functions

Function Purpose Agents
secrets::set Create or rotate {name, value, consumers?, description?, store?}; omitted consumers keep the current list. store: "env" writes the value to .env denied
secrets::import Store a value from process_env, dotenv or login_shell, re-read by the worker. With store: "env", a value already in .env or the worker's environment is shared as it is, and one from the login shell is copied into .env denied
secrets::access Replace a secret's consumers; [] revokes everyone. With store: "env", shares the variable, whether or not it is set yet denied
secrets::delete Delete a secret and revoke all access. With store: "env", stops sharing the variable; it stays in .env denied
secrets::resolve Return {name, value} for secret://NAME or env://NAME to a listed consumer denied
secrets::get / secrets::list Metadata: ref, store, masked hint, fingerprint (vault), location (env), consumers, timestamps, last resolver. get takes store too allowed
secrets::status Vault path, key source (env or file) and key path, count, vault format version, the .env the env store uses and how many variables it shares allowed
secrets::detect Where existing values of the given names are, with masked hints and whether each equals the stored value approval

secrets::resolve errors with INVALID_REFERENCE, SECRET_NOT_FOUND or SECRET_FORBIDDEN. For env://NAME, a variable shared with nobody (or not with the caller) is SECRET_FORBIDDEN, and one that is shared but not set is SECRET_NOT_FOUND. Other codes are INVALID_REQUEST, SOURCE_NOT_FOUND (import), KEY_UNAVAILABLE, KEY_MISMATCH, VAULT_ERROR, DECRYPT_FAILED and CALLER_LOOKUP_FAILED. No error message contains a value. Schemas are available through iii trigger --help.

The "Agents" column is the default in iii-permissions.yaml. The Console calls these functions on the person's behalf.

Access scope

consumers lists the worker names allowed to resolve a secret. An empty list admits nobody, which is the default for a new secret. The same holds for the env store: an env://NAME reference resolves only for the workers its grant lists, never for every worker that asks. The caller is the connection the engine stamps on the invocation (_caller_worker_id, which the engine overwrites on every call), mapped to its worker name through engine::workers::list. A worker registered in another namespace never matches, even with the same name. Each successful resolution records last_resolved_at and last_resolved_by.

Detection sources

kind Reads
process_env The secrets worker's own environment
dotenv /.env (KEY=VALUE, comments, export, single or double quotes, inline # comments)
login_shell $SHELL -ilc printing a marker and env -0, with stdin closed, stderr discarded and a 4 s limit. The shell runs in its own session, with III_RESOLVING_ENVIRONMENT=1 set so a shell profile can skip slow setup

A source that is missing, broken or slow contributes nothing; it never fails the call. Only the requested names are kept from a source, and only masked hints leave the worker. Login-shell detection is Unix-only.

Custom trigger types

Trigger type Fires when Payload to subscribers
secrets::changed A secret is created, rotated, deleted or its consumers change; for the env store, also when an edit to .env sets, changes or removes a shared variable {name, ref, action: "created" | "rotated" | "deleted" | "access_changed", fingerprint?, updated_at}

ref names the store (secret://NAME or env://NAME); env store events carry no fingerprint. The binding config {names?: string[]} narrows delivery to some secrets: a bare name for both stores, a secret:// or env:// reference for one; omit it for every secret. Delivery is fire-and-forget and never carries a value: a subscriber that needs the new value calls secrets::resolve.

How llm-router uses it

llm-router depends on this worker. A provider slice whose api_key is secret://NAME or env://NAME makes the router resolve it through secrets::resolve instead of reading a literal key. Add llm-router to that secret's consumers. The router caches the value, binds secrets::changed to refetch it and refresh that provider's model list (an edit to .env included), and reports credential_source: "secret" with credential_ref (and credential_error when it cannot resolve) in router::provider::list. Other workers can adopt the same pattern, for example judge-typesafe with secret://TYPESAFE_API_KEY (it reads secret:// references only for now).

Configuration

data_dir: data/secrets   # vault folder; relative paths resolve against the project
key_file: null           # master key file; absolute or ~/, outside the project
env_file: .env           # the env file env:// references read and the console writes

Every Compose namespace has its own secrets entry (-secrets), so each environment or namespace can keep its keys in its own env file. Set it in that entry's file, ./config/-secrets.yaml (an edit applies without a restart), with iii trigger configuration::set, or per container in worker-compose.yaml (the ADE has no settings form for this worker yet):

containers:
  secrets:
    worker: package://secrets
    config_override:
      env_file: .env.staging

env_file is relative to the project unless it is absolute or starts with ~/. A missing file is not an error: references then read this worker's environment, and the first key saved through the console creates the file (owner-only). Pointing env_file at another file takes effect at once: the worker follows the new file, and every shared variable whose value differs there is reported on secrets::changed, so consumers stop using the old file's values. Keep every env file out of Git (the project template ignores .env and .env.*).

III_SECRETS_KEY overrides key_file. The worker reads it once at startup and removes it from its own environment, so shells started by secrets::detect do not inherit it.

Limits

This first version is a local protected store, not a hardware-backed vault.

  • The env store is as protected as .env is: plain text, readable by your user account. Its grants decide who may resolve a variable over the engine, not who can read the file. Use the vault for keys that should be encrypted at rest.

  • Anyone who can read both the vault and the key file can decrypt every value. By default that is your own user account and root. File permissions are the only barrier, and they are not narrowed on Windows.

  • Consumer identity is a worker name. Any process that can connect to the engine and register as llm-router in this namespace while the real router is not connected is treated as the router.

  • III_SECRETS_KEY stays readable in the process table entry for the worker (/proc//environ) by the same user, even after the worker removes it from its environment.

  • A resolved value is plaintext in the consumer's memory and crosses the local engine connection. This worker turns off the SDK's payload capture in traces for its own handlers. Each consumer is responsible for not logging the value it receives.

  • There is no master-key rotation or OS keychain integration yet. Rotate an individual secret with secrets::set.

API reference (JSON)

agent-api-reference.json
{
  "functions": [
    {
      "description": "Replace the list of worker names allowed to resolve a secret; [] revokes everyone. With store \"env\", shares the environment variable NAME (env://NAME), whether or not it is set yet.",
      "metadata": {},
      "name": "secrets::access",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "StoreKind": {
            "description": "Where a secret's value lives.",
            "oneOf": [
              {
                "description": "Encrypted in `vault.json`; referenced as `secret://NAME`.",
                "enum": [
                  "vault"
                ],
                "type": "string"
              },
              {
                "description": "An environment variable: the project's `.env`, else this worker's environment; referenced as `env://NAME`. Only who may read it is recorded here.",
                "enum": [
                  "env"
                ],
                "type": "string"
              }
            ]
          }
        },
        "properties": {
          "consumers": {
            "description": "The complete new allowlist of worker names; `[]` revokes everyone.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "name": {
            "type": "string"
          },
          "store": {
            "allOf": [
              {
                "$ref": "#/definitions/StoreKind"
              }
            ],
            "default": "vault",
            "description": "`vault` (default; the secret must exist) or `env` (shares the variable, whether or not it is set yet)."
          }
        },
        "required": [
          "consumers",
          "name"
        ],
        "title": "AccessRequest",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "StoreKind": {
            "description": "Where a secret's value lives.",
            "oneOf": [
              {
                "description": "Encrypted in `vault.json`; referenced as `secret://NAME`.",
                "enum": [
                  "vault"
                ],
                "type": "string"
              },
              {
                "description": "An environment variable: the project's `.env`, else this worker's environment; referenced as `env://NAME`. Only who may read it is recorded here.",
                "enum": [
                  "env"
                ],
                "type": "string"
              }
            ]
          }
        },
        "description": "Everything about a secret except its value.",
        "properties": {
          "consumers": {
            "description": "Worker names allowed to resolve the value. Empty: nobody.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "created_at": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "fingerprint": {
            "description": "First 16 hex characters of HMAC-SHA256(master key, value). Changes on rotation. Vault only: an environment value can change outside this worker.",
            "type": [
              "string",
              "null"
            ]
          },
          "hint": {
            "description": "Masked value, e.g. `sk-ant…9f2c`; `••••` under 12 characters. Empty for an environment variable that is not set.",
            "type": "string"
          },
          "last_resolved_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "last_resolved_by": {
            "description": "Worker name of the last successful resolver.",
            "type": [
              "string",
              "null"
            ]
          },
          "location": {
            "description": "Env store: where the variable's value is read from now (the `.env` path, or this worker's environment); absent when it is not set.",
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "ref": {
            "description": "`secret://NAME` or `env://NAME`, the string to put in versioned configuration.",
            "type": "string"
          },
          "store": {
            "$ref": "#/definitions/StoreKind"
          },
          "updated_at": {
            "type": "string"
          }
        },
        "required": [
          "consumers",
          "created_at",
          "hint",
          "name",
          "ref",
          "store",
          "updated_at"
        ],
        "title": "SecretMeta",
        "type": "object"
      }
    },
    {
      "description": "Delete a secret and revoke every consumer's access to it. With store \"env\", stops sharing the variable; its value stays in .env.",
      "metadata": {},
      "name": "secrets::delete",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "StoreKind": {
            "description": "Where a secret's value lives.",
            "oneOf": [
              {
                "description": "Encrypted in `vault.json`; referenced as `secret://NAME`.",
                "enum": [
                  "vault"
                ],
                "type": "string"
              },
              {
                "description": "An environment variable: the project's `.env`, else this worker's environment; referenced as `env://NAME`. Only who may read it is recorded here.",
                "enum": [
                  "env"
                ],
                "type": "string"
              }
            ]
          }
        },
        "properties": {
          "name": {
            "type": "string"
          },
          "store": {
            "allOf": [
              {
                "$ref": "#/definitions/StoreKind"
              }
            ],
            "default": "vault",
            "description": "`vault` (default) or `env`."
          }
        },
        "required": [
          "name"
        ],
        "title": "NameRequest",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "deleted": {
            "type": "boolean"
          }
        },
        "required": [
          "deleted"
        ],
        "title": "DeleteResponse",
        "type": "object"
      }
    },
    {
      "description": "Look for existing values of the given env var names in this worker's environment, the project's .env and the user's login shell. Reports masked hints and whether each equals the stored value; never a value.",
      "metadata": {},
      "name": "secrets::detect",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "names": {
            "description": "Env var names to look for (also the secret names they would be stored under).",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "names"
        ],
        "title": "DetectRequest",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "DetectResult": {
            "properties": {
              "name": {
                "type": "string"
              },
              "sources": {
                "items": {
                  "$ref": "#/definitions/DetectedSource"
                },
                "type": "array"
              },
              "stored": {
                "type": "boolean"
              },
              "stored_hint": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "name",
              "sources",
              "stored"
            ],
            "type": "object"
          },
          "DetectedSource": {
            "properties": {
              "hint": {
                "description": "Masked value found there.",
                "type": "string"
              },
              "kind": {
                "$ref": "#/definitions/SourceKind"
              },
              "location": {
                "description": "The secrets worker's environment, the `.env` path, or the login shell path.",
                "type": "string"
              },
              "matches_stored": {
                "description": "The value equals the stored one (same fingerprint).",
                "type": "boolean"
              }
            },
            "required": [
              "hint",
              "kind",
              "location",
              "matches_stored"
            ],
            "type": "object"
          },
          "SourceKind": {
            "enum": [
              "process_env",
              "dotenv",
              "login_shell"
            ],
            "type": "string"
          }
        },
        "properties": {
          "results": {
            "items": {
              "$ref": "#/definitions/DetectResult"
            },
            "type": "array"
          }
        },
        "required": [
          "results"
        ],
        "title": "DetectResponse",
        "type": "object"
      }
    },
    {
      "description": "One secret's metadata (masked hint, fingerprint, consumers, timestamps; for store \"env\", where the variable is read from), or null. Never the value.",
      "metadata": {},
      "name": "secrets::get",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "StoreKind": {
            "description": "Where a secret's value lives.",
            "oneOf": [
              {
                "description": "Encrypted in `vault.json`; referenced as `secret://NAME`.",
                "enum": [
                  "vault"
                ],
                "type": "string"
              },
              {
                "description": "An environment variable: the project's `.env`, else this worker's environment; referenced as `env://NAME`. Only who may read it is recorded here.",
                "enum": [
                  "env"
                ],
                "type": "string"
              }
            ]
          }
        },
        "properties": {
          "name": {
            "type": "string"
          },
          "store": {
            "allOf": [
              {
                "$ref": "#/definitions/StoreKind"
              }
            ],
            "default": "vault",
            "description": "`vault` (default) or `env`."
          }
        },
        "required": [
          "name"
        ],
        "title": "NameRequest",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "anyOf": [
          {
            "$ref": "#/definitions/SecretMeta"
          },
          {
            "type": "null"
          }
        ],
        "definitions": {
          "SecretMeta": {
            "description": "Everything about a secret except its value.",
            "properties": {
              "consumers": {
                "description": "Worker names allowed to resolve the value. Empty: nobody.",
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "created_at": {
                "type": "string"
              },
              "description": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "fingerprint": {
                "description": "First 16 hex characters of HMAC-SHA256(master key, value). Changes on rotation. Vault only: an environment value can change outside this worker.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "hint": {
                "description": "Masked value, e.g. `sk-ant…9f2c`; `••••` under 12 characters. Empty for an environment variable that is not set.",
                "type": "string"
              },
              "last_resolved_at": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "last_resolved_by": {
                "description": "Worker name of the last successful resolver.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "location": {
                "description": "Env store: where the variable's value is read from now (the `.env` path, or this worker's environment); absent when it is not set.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "name": {
                "type": "string"
              },
              "ref": {
                "description": "`secret://NAME` or `env://NAME`, the string to put in versioned configuration.",
                "type": "string"
              },
              "store": {
                "$ref": "#/definitions/StoreKind"
              },
              "updated_at": {
                "type": "string"
              }
            },
            "required": [
              "consumers",
              "created_at",
              "hint",
              "name",
              "ref",
              "store",
              "updated_at"
            ],
            "type": "object"
          },
          "StoreKind": {
            "description": "Where a secret's value lives.",
            "oneOf": [
              {
                "description": "Encrypted in `vault.json`; referenced as `secret://NAME`.",
                "enum": [
                  "vault"
                ],
                "type": "string"
              },
              {
                "description": "An environment variable: the project's `.env`, else this worker's environment; referenced as `env://NAME`. Only who may read it is recorded here.",
                "enum": [
                  "env"
                ],
                "type": "string"
              }
            ]
          }
        },
        "title": "Nullable_SecretMeta"
      }
    },
    {
      "description": "Store a value found by secrets::detect: the worker re-reads it from the named source itself, so it never passes through the caller. With store \"env\", a value found in .env or this worker's environment is shared as it is, and one from the login shell is copied into .env.",
      "metadata": {},
      "name": "secrets::import",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "SourceKind": {
            "enum": [
              "process_env",
              "dotenv",
              "login_shell"
            ],
            "type": "string"
          },
          "StoreKind": {
            "description": "Where a secret's value lives.",
            "oneOf": [
              {
                "description": "Encrypted in `vault.json`; referenced as `secret://NAME`.",
                "enum": [
                  "vault"
                ],
                "type": "string"
              },
              {
                "description": "An environment variable: the project's `.env`, else this worker's environment; referenced as `env://NAME`. Only who may read it is recorded here.",
                "enum": [
                  "env"
                ],
                "type": "string"
              }
            ]
          }
        },
        "properties": {
          "consumers": {
            "default": null,
            "description": "Omit to keep the current list (`[]` for a new secret).",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "description": {
            "default": null,
            "description": "Omit to keep the current description; an empty string clears it.",
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "source": {
            "allOf": [
              {
                "$ref": "#/definitions/SourceKind"
              }
            ],
            "description": "Where the worker re-reads the value; it never travels through the caller."
          },
          "store": {
            "allOf": [
              {
                "$ref": "#/definitions/StoreKind"
              }
            ],
            "default": "vault",
            "description": "`vault` (default) or `env`: copied into the project's `.env` (a `dotenv` source is only shared, it is already there)."
          }
        },
        "required": [
          "name",
          "source"
        ],
        "title": "ImportRequest",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "StoreKind": {
            "description": "Where a secret's value lives.",
            "oneOf": [
              {
                "description": "Encrypted in `vault.json`; referenced as `secret://NAME`.",
                "enum": [
                  "vault"
                ],
                "type": "string"
              },
              {
                "description": "An environment variable: the project's `.env`, else this worker's environment; referenced as `env://NAME`. Only who may read it is recorded here.",
                "enum": [
                  "env"
                ],
                "type": "string"
              }
            ]
          }
        },
        "description": "Everything about a secret except its value.",
        "properties": {
          "consumers": {
            "description": "Worker names allowed to resolve the value. Empty: nobody.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "created_at": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "fingerprint": {
            "description": "First 16 hex characters of HMAC-SHA256(master key, value). Changes on rotation. Vault only: an environment value can change outside this worker.",
            "type": [
              "string",
              "null"
            ]
          },
          "hint": {
            "description": "Masked value, e.g. `sk-ant…9f2c`; `••••` under 12 characters. Empty for an environment variable that is not set.",
            "type": "string"
          },
          "last_resolved_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "last_resolved_by": {
            "description": "Worker name of the last successful resolver.",
            "type": [
              "string",
              "null"
            ]
          },
          "location": {
            "description": "Env store: where the variable's value is read from now (the `.env` path, or this worker's environment); absent when it is not set.",
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "ref": {
            "description": "`secret://NAME` or `env://NAME`, the string to put in versioned configuration.",
            "type": "string"
          },
          "store": {
            "$ref": "#/definitions/StoreKind"
          },
          "updated_at": {
            "type": "string"
          }
        },
        "required": [
          "consumers",
          "created_at",
          "hint",
          "name",
          "ref",
          "store",
          "updated_at"
        ],
        "title": "SecretMeta",
        "type": "object"
      }
    },
    {
      "description": "Every secret's metadata: vault secrets, then shared environment variables (masked hint, consumers, timestamps). Never a value.",
      "metadata": {},
      "name": "secrets::list",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "title": "EmptyRequest",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "SecretMeta": {
            "description": "Everything about a secret except its value.",
            "properties": {
              "consumers": {
                "description": "Worker names allowed to resolve the value. Empty: nobody.",
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "created_at": {
                "type": "string"
              },
              "description": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "fingerprint": {
                "description": "First 16 hex characters of HMAC-SHA256(master key, value). Changes on rotation. Vault only: an environment value can change outside this worker.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "hint": {
                "description": "Masked value, e.g. `sk-ant…9f2c`; `••••` under 12 characters. Empty for an environment variable that is not set.",
                "type": "string"
              },
              "last_resolved_at": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "last_resolved_by": {
                "description": "Worker name of the last successful resolver.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "location": {
                "description": "Env store: where the variable's value is read from now (the `.env` path, or this worker's environment); absent when it is not set.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "name": {
                "type": "string"
              },
              "ref": {
                "description": "`secret://NAME` or `env://NAME`, the string to put in versioned configuration.",
                "type": "string"
              },
              "store": {
                "$ref": "#/definitions/StoreKind"
              },
              "updated_at": {
                "type": "string"
              }
            },
            "required": [
              "consumers",
              "created_at",
              "hint",
              "name",
              "ref",
              "store",
              "updated_at"
            ],
            "type": "object"
          },
          "StoreKind": {
            "description": "Where a secret's value lives.",
            "oneOf": [
              {
                "description": "Encrypted in `vault.json`; referenced as `secret://NAME`.",
                "enum": [
                  "vault"
                ],
                "type": "string"
              },
              {
                "description": "An environment variable: the project's `.env`, else this worker's environment; referenced as `env://NAME`. Only who may read it is recorded here.",
                "enum": [
                  "env"
                ],
                "type": "string"
              }
            ]
          }
        },
        "properties": {
          "secrets": {
            "items": {
              "$ref": "#/definitions/SecretMeta"
            },
            "type": "array"
          }
        },
        "required": [
          "secrets"
        ],
        "title": "ListResponse",
        "type": "object"
      }
    },
    {
      "description": "Internal: re-read the secrets configuration after an operator change.",
      "metadata": {
        "internal": true
      },
      "name": "secrets::on-config-change",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Trigger payload for `<worker>::on-config-change`. Advisory only: handlers re-fetch the authoritative value and ignore it, so a direct call can never inject config.",
        "properties": {
          "id": {
            "default": null,
            "description": "Configuration id that changed.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "title": "OnConfigChangeEvent",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Ack returned by the internal `<worker>::on-config-change` handler.",
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "ok"
        ],
        "title": "OnConfigChangeResponse",
        "type": "object"
      }
    },
    {
      "description": "Return the value behind secret://NAME (the vault) or env://NAME (the project's .env, else this worker's environment) to a worker listed in its consumers; anyone else gets SECRET_FORBIDDEN. The caller is identified by the engine, not by the request.",
      "metadata": {},
      "name": "secrets::resolve",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "ref": {
            "description": "`secret://NAME`, `env://NAME`, or a bare `NAME` (the vault).",
            "type": "string"
          }
        },
        "required": [
          "ref"
        ],
        "title": "ResolveRequest",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "name": {
            "type": "string"
          },
          "value": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "value"
        ],
        "title": "ResolveResponse",
        "type": "object"
      }
    },
    {
      "description": "Store a credential under NAME (create, or rotate an existing one) and return its metadata. store \"vault\" (default) encrypts it, referenced as secret://NAME; store \"env\" writes NAME=value to the project's .env, referenced as env://NAME. The value is never returned by this or any metadata function. Omitted consumers keep the current allowlist ([] for a new secret).",
      "metadata": {},
      "name": "secrets::set",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "StoreKind": {
            "description": "Where a secret's value lives.",
            "oneOf": [
              {
                "description": "Encrypted in `vault.json`; referenced as `secret://NAME`.",
                "enum": [
                  "vault"
                ],
                "type": "string"
              },
              {
                "description": "An environment variable: the project's `.env`, else this worker's environment; referenced as `env://NAME`. Only who may read it is recorded here.",
                "enum": [
                  "env"
                ],
                "type": "string"
              }
            ]
          }
        },
        "properties": {
          "consumers": {
            "default": null,
            "description": "Worker names allowed to resolve. Omit to keep the current list (`[]` for a new secret).",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "description": {
            "default": null,
            "description": "Omit to keep the current description; an empty string clears it.",
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "description": "`^[A-Za-z_][A-Za-z0-9_.-]{0,127}$`; provider keys reuse their env var name.",
            "type": "string"
          },
          "store": {
            "allOf": [
              {
                "$ref": "#/definitions/StoreKind"
              }
            ],
            "default": "vault",
            "description": "`vault` (default) or `env`."
          },
          "value": {
            "description": "The credential. Encrypted in the vault, or written as `NAME=value` to the project's `.env`; never returned except by `secrets::resolve`.",
            "type": "string"
          }
        },
        "required": [
          "name",
          "value"
        ],
        "title": "SetRequest",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "StoreKind": {
            "description": "Where a secret's value lives.",
            "oneOf": [
              {
                "description": "Encrypted in `vault.json`; referenced as `secret://NAME`.",
                "enum": [
                  "vault"
                ],
                "type": "string"
              },
              {
                "description": "An environment variable: the project's `.env`, else this worker's environment; referenced as `env://NAME`. Only who may read it is recorded here.",
                "enum": [
                  "env"
                ],
                "type": "string"
              }
            ]
          }
        },
        "description": "Everything about a secret except its value.",
        "properties": {
          "consumers": {
            "description": "Worker names allowed to resolve the value. Empty: nobody.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "created_at": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "fingerprint": {
            "description": "First 16 hex characters of HMAC-SHA256(master key, value). Changes on rotation. Vault only: an environment value can change outside this worker.",
            "type": [
              "string",
              "null"
            ]
          },
          "hint": {
            "description": "Masked value, e.g. `sk-ant…9f2c`; `••••` under 12 characters. Empty for an environment variable that is not set.",
            "type": "string"
          },
          "last_resolved_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "last_resolved_by": {
            "description": "Worker name of the last successful resolver.",
            "type": [
              "string",
              "null"
            ]
          },
          "location": {
            "description": "Env store: where the variable's value is read from now (the `.env` path, or this worker's environment); absent when it is not set.",
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "ref": {
            "description": "`secret://NAME` or `env://NAME`, the string to put in versioned configuration.",
            "type": "string"
          },
          "store": {
            "$ref": "#/definitions/StoreKind"
          },
          "updated_at": {
            "type": "string"
          }
        },
        "required": [
          "consumers",
          "created_at",
          "hint",
          "name",
          "ref",
          "store",
          "updated_at"
        ],
        "title": "SecretMeta",
        "type": "object"
      }
    },
    {
      "description": "Where the vault lives, where the master key comes from (III_SECRETS_KEY or a key file outside the project), how many secrets are stored, and the .env the env store uses.",
      "metadata": {},
      "name": "secrets::status",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "title": "EmptyRequest",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "KeySourceKind": {
            "enum": [
              "env",
              "file"
            ],
            "type": "string"
          }
        },
        "properties": {
          "count": {
            "format": "uint",
            "minimum": 0,
            "type": "integer"
          },
          "env_count": {
            "description": "Environment variables shared with at least one worker.",
            "format": "uint",
            "minimum": 0,
            "type": "integer"
          },
          "env_file": {
            "description": "The `.env` the env store reads and writes, when the worker has one.",
            "type": [
              "string",
              "null"
            ]
          },
          "key_path": {
            "description": "The key file, when `key_source` is `file`.",
            "type": [
              "string",
              "null"
            ]
          },
          "key_source": {
            "allOf": [
              {
                "$ref": "#/definitions/KeySourceKind"
              }
            ],
            "description": "`env` when III_SECRETS_KEY supplies the master key, else `file`."
          },
          "vault_path": {
            "type": "string"
          },
          "version": {
            "description": "Vault file format version.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "count",
          "env_count",
          "key_source",
          "vault_path",
          "version"
        ],
        "title": "StatusResponse",
        "type": "object"
      }
    }
  ],
  "triggers": [
    {
      "description": "Fires after a secret is created, rotated, deleted or its consumers change. Carries name, ref, action, fingerprint and updated_at, never the value. Config: { names? } to narrow to some secrets.",
      "invocation_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "metadata": {
            "description": "Metadata attached to every invocation this binding receives."
          },
          "names": {
            "description": "Secret names to fire for: a bare `NAME` for both stores, or `secret://NAME` / `env://NAME` for one. Omit or leave empty for every secret.",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "title": "ChangedConfig",
        "type": "object"
      },
      "metadata": {},
      "name": "secrets::changed",
      "return_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "ChangeAction": {
            "enum": [
              "created",
              "rotated",
              "deleted",
              "access_changed"
            ],
            "type": "string"
          }
        },
        "description": "A `secrets::changed` delivery. Never carries a value.",
        "properties": {
          "action": {
            "$ref": "#/definitions/ChangeAction"
          },
          "fingerprint": {
            "description": "The current fingerprint; absent after a deletion and for the env store.",
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "ref": {
            "description": "`secret://NAME` or `env://NAME`.",
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          }
        },
        "required": [
          "action",
          "name",
          "ref",
          "updated_at"
        ],
        "title": "ChangedEvent",
        "type": "object"
      }
    }
  ]
}

Search the registry

Find workers, kits and executables, or jump to a page.