Skip to content

feat(cli): agent registry — list, pause, resume, revoke, and per-agent audit replay #607

Description

@plind-junior

What you're trying to do

there is no way to answer "which agents can write to this KB, and what did each
one actually do?" bearer tokens are matched in trust.py and hashed into an
auth_subject, but nothing enumerates them, nothing can suspend one, and
nothing maps a subject back to a readable name.

ditto ships this as a settings screen (heyditto.ai/docs/agent-accounts): every
agent row shows name, status (active / paused / revoked), a read-only badge,
claim date and last-used timestamp, with pause / resume / revoke controls.
notably their own docs stop short of per-action audit — "the documentation
doesn't explicitly detail comprehensive audit logs of specific agent actions."

vouch has an append-only audit log. this is the one place vouch can ship
strictly the better version of a ditto feature rather than catching up.

What you've tried

  • trust.pymatched_bearer_token, auth_subject_for_token. identity exists
    as a hash, with no registry behind it.
  • kb.audit → the events are all there, but keyed by actor string with no way
    to ask "everything agent X ever proposed."
  • removing a token from config → the only revocation available, and it takes
    every agent sharing that token down with it.

Suggested shape

a registry keyed by auth_subject, plus:

vouch agents list                  # name, status, scopes, claimed, last-used
vouch agents show <name>           # replay this agent's audit events
vouch agents pause <name>          # credential stops authenticating
vouch agents resume <name>
vouch agents revoke <name>         # terminal, irreversible
  • every transition writes an audit event, so the control plane's own history is
    as auditable as the KB's.
  • vouch agents show reads audit.log.jsonl filtered by proposer — the
    per-action attribution ditto doesn't claim.
  • paused/revoked checked in the same trust.py chokepoint that matches the
    token, so mcp, jsonl and http inherit it without three implementations.

Compatibility considerations

additive; the registry is new state. must be decided: does the registry live in
.vouch/ (committed, reviewable in PRs, consistent with the north star) or in
local config (secrets-adjacent)? proposal: the registry is committed —
names, scopes, status, claim date — while the credentials themselves stay in
local config, same split secrets.py already draws.

existing deployments with a plain bearer token keep working: an unregistered
token is treated as an unnamed active agent until someone registers it.

Alternatives

  • lean on scoping.py's VOUCH_AGENT viewer param — it already carries an
    agent name, but it is a view filter, not a credential, and an agent can set
    it to anything. it cannot be the basis for revocation.

part of the ditto-style track — see .superpowers/DITTO-STYLE-PLAN.md (T2.2).

Metadata

Metadata

Assignees

No one assigned

    Labels

    clicommand line interfaceenhancementNew feature or requeststoragekb storage, migrations, schemas, and proposals

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions