feat: the offline_access mandate

The standing authority the autonomous runs act under: an offline refresh token
issued by a new classic-models-mandate client for the user who authorised the
agent, stored in Vault, redeemed at trigger time.

The mandate client holds no domain audience. It cannot reach data; it can only
say who authorised whom. Direct access grants on it is a lab shortcut, noted as
such — mandating an agent is a decision a person takes, and a password grant
records no consent where the authorization code flow would.

Verified end to end: refresh gives sub=pm-user azp=classic-models-mandate with
the agent in the audience, the agent exchanges it to azp=itself and
aud=mcp-catalog, and the MCP call answers 200. sub stays the person who
mandated, azp says which agent acted.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Stéphane Tailland
2026-08-29 17:42:33 +02:00
parent 06c102fb72
commit 8f1f0245da
3 changed files with 32 additions and 0 deletions
+1
View File
@@ -37,6 +37,7 @@ spec:
# The agents' Keycloak client secrets, so a workflow can exchange tokens
# as the agent it represents. Created by agent-secrets.yaml beside this.
EXTRA_ENV_SECRET: n8n-agent-secrets
EXTRA_ENV_SECRET_2: n8n-mandate-secrets
EXTRA_CA_CONFIGMAP: sttlab-ca
# "false" so a workflow can read $env.<AGENT>_CLIENT_SECRET. It means any
# workflow on this instance can read any variable in the pod — acceptable