Secrets and capabilities
Every other boundary in meclaw is a property of the tree a reviewer reads off files. This one is configured: a secret has to be put in, and somebody has to say who may spend it. Two cells do that, and neither of them hands a credential to the agent that asks.
The vault
vault is a secret store with no operation that returns a secret. put and rotate come
from the user channel, use signs on the broker’s behalf so the secret does the work and
stays home, and deliver answers with a ciphertext sealed to a key the requester minted for
that one call. get is refused the way an unknown op is.
A secret goes in over the CLI, read from stdin, with no message and no log row:
meclaw --vault /main/access/vault --vault-add telegram_token
The vault mints its half of the sealing key per answer and drops it, so no key material
anywhere opens yesterday’s box. templates/vault.
The vault is the only road for a secret a cell spends. Since GH #1235 a secret param takes no
${VAR}: an api_key, a chat token, a webhook secret, the credential of a meclaw peer proxy or the bearer of an
mcp cell written as an environment token is refused at boot and at the mutation door, because every cell
the colony process spawns can read its environment. .env carries non-secrets only, such as model
names, addresses and the app id (config.md, § params).
Handles instead of secrets
access is the capability broker. An agent asks for a capability, and what comes back is a
grant handle with a summary of what it covers, never the chat id, the endpoint or the
credential.
{"capability": "chat.send", "subject": "member:example",
"resource": {"channel": "example-chat"}, "purpose": "answer the incoming message"}
Policy is rows in a store, changed with an insert or an update while the colony runs:
requester, capability, subject, scope_match, verdict, max_ttl_ms, constraints, and a
cred_ref that names a credential and never carries one. Seven rows ship, five of them
disabled; the two enabled ones are the pair a fresh colony cannot start without.
Two rules make the broker an authority rather than a lookup table. The requester is read from
context.requester, which an edge sets and the colony wrote, never from the body, and an
absent one is a denial. The address of an invocation is built from the grant, and every
address key in the payload is removed before the message reaches the connector.
templates/access, wired to a consumer in
examples/vault-pilot.