~bigbes/sr-ht-spec

ref: 3a56ee617a14a82d7d2d430173c84474444bc111 sr-ht-spec/web/tokens.go -rw-r--r-- 2.1 KiB
a4d8cc52 — Eugene Blikh 10 days ago
authn: remove the local agent-token plane

The agent_token table and everything that minted, verified, listed or revoked
it. Agent credentials are tokens.sr.ht working tokens now: signed, expiring,
owned by a meta.sr.ht account and carrying grants, verified locally by
sr-ht-ecore's bearer package. One door, and nothing behind it — a credential the
instance plane refuses is refused, where it used to be offered to a second store
that might say yes.

DEPLOY GATE: do not deploy this until every agent configured with the shared
secret holds a tokens.sr.ht token with spec:propose (spec:read to read).
Migration 0005 drops the table, migrate-on-upgrade runs it on deploy, and
deploying early locks out every agent at once — including the SSH push path.

hooks/ no longer reads agent_token directly. The push path goes through the same
authn.Resolver the HTTP surfaces use and demands spec:propose, because a push by
an agent is a proposal by another transport. The refs rule and the provenance
requirement are untouched on both counts: a universal grant is still only an
agent to the receive path, and X-Agent / X-Agent-Session are still mandatory on
every agent write.

bearer.ErrNotOurs is now a permanent refusal. A meta.sr.ht PAT used to fall
through to the local store and miss there; with no store to fall through to it
earns a 401 rather than the 503 an unclassified error would.

[tokens.sr.ht] origin becomes a required config key: with no issuer there is no
credential to check, so the daemon fails startup instead of serving reads and
refusing every agent write one request at a time.

/tokens redirects to the daemon that issues (tokens SPEC ch. 7).
8219ede1 — Eugene Blikh 13 days ago
feat(web,service): the owner mints and revokes agent tokens in a browser

Issuing a credential required SSH to the host, which made the remote
agent write plane unusable from anywhere else: to hand an agent a token
the owner had to be at the machine. /tokens is that page — list, mint,
revoke — behind the same owner-only gate and same-origin guard as
approve/reject.

The mint is owner-only, and that rule is what revocation depends on: an
agent allowed to mint would survive having its own credential revoked by
issuing itself another, and "revoke the token" is the entire incident
response this design has. An agent asking for the page gets 403 rather
than the read plane's login redirect — it is authenticated already, so
bouncing it to meta would answer a question it did not ask.

The plaintext is rendered in the response to the POST rather than after a
redirect. A redirect would either drop the secret or carry it in a URL,
where it lands in history and in every proxy log on the way; the cost is
that a reload re-submits and mints a second token, which is one click to
revoke on that same page, whereas a lost token is not recoverable.

service.IssueAgentToken/ListAgentTokens/RevokeAgentToken hold the ACL and
the mint, and `specsrht token` now goes through them too, so the CLI and
the page cannot drift into two ideas of what issuing a token is.

spec-ejq.3