refactor: an autonomous run is a machine identity, not a mandate

Withdrawn: the offline_access mandate built an hour ago. An agent running on its
own account acts for itself. Nobody asked for the 06:00 run, so naming a person
as its principal was a fiction — and choosing which person was arbitrary, as the
first implementation showed by picking whichever test user was to hand.

It also cost more than it was worth. An offline token has no exp, dies only
after 30 days unused, is not rotated on use, and is revocable only by killing
that user's offline session: a permanent bearer credential standing in for a
consent nobody gave.

Now client_credentials, with the service account carrying read_only — the least
privilege the job needs. That is not a convention the workflow observes: the MCP
server maps the role to a consumer group at discovery, so tools/list under this
identity returns get-product and list-products and nothing else. create-product
is invisible rather than merely unused.

Nothing downstream changes. azp still names the agent, audiences are still
per-server, and policy still reads roles — a service account has roles like
anyone else.

The mandate client stays in the realm, unused, for the case where a person's own
authority genuinely is in play: Recouvrement's dunning, which is human-validated
already.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Stéphane Tailland
2026-08-29 17:51:18 +02:00
parent 8f1f0245da
commit 2bb6faa121
6 changed files with 61 additions and 154 deletions
+15 -10
View File
@@ -106,18 +106,23 @@ scanned 110 of 110, complete
escalate: true
```
### It stops without a mandate, and that is the point
### It acts under its own machine identity
No user session exists at 06:00, so authority has to be pre-established. The
design calls for an `offline_access` mandate — the authorising user's refresh
token, stored encrypted, exchanged at trigger time, so `sub` stays the person
who mandated and `azp` says which agent acted.
`client_credentials`, not a mandate. An agent running on its own account acts
for itself — nobody asked for the 06:00 run, so naming a person as its principal
is a fiction and choosing which person is arbitrary.
**That does not exist yet.** The first node looks for
`APPROVISIONNEMENT_MANDATE_TOKEN` and, finding none, halts before any exchange
and before reading anything. Verified: the run completes, `Exchange token` never
executes, nothing is read. An agent without an identity does nothing rather than
inventing an authority.
The service account carries **`read_only`**, and the MCP server maps that to a
consumer group at discovery, so `create-product` is not merely unused — it is
invisible to this identity:
```
tools/list under the machine identity → get-product, list-products
```
Least privilege enforced by the realm and the gateway rather than by this
workflow behaving itself. An earlier revision used an `offline_access` mandate;
see CLAUDE.md for why it was withdrawn.
### The proposal has nowhere to go