Problem
Since 2026-10-07 our RFCs live in the RFCs product and every change to one goes through its API (RFC 0065). Most of that work is done by AI agents in coding sessions. They had two ways in, and neither fits:
- An operator's port-forward to the protocol with a hand-made admin identity
(
mise run rfcs:import). It goes around the gateway, carries the admin role and leaves every change looking like the operator's own. - A person's token. It would make every agent the owner, with every right the owner has, in every product.
The owner asked for a third: an identity that may write only to the Engineering account's RFC spaces, minted per session, and commands every agent uses the same way.
Proposal
A machine principal of its own
iohr-rfcs-agent is an OAuth2 client of the identity provider, with the client
credentials grant. Its tokens carry rfc:read and rfc:write and nothing else, so the
gateway admits them on the RFCs routes and on no other route, and never as a machine on the
staff hosts. They live 15 minutes and are minted per session. Its secret is made by a
task straight into the cluster's secret store and is never written to a file or shown.
The RFCs service makes it a member of one account and nothing more. A token is the agent only when it is a client-credentials token of a client the service's configuration names, with no role, account or key claim; anything else that looks like it is an ordinary caller and finds none of our spaces. The configuration names the account, which must be one of our own, and the spaces it may write in.
| The agent | |
|---|---|
| Reads | the Engineering account's documents up to team; never internal; no other account |
| Writes | documents, versions, statuses, comments, diagrams and review requests in Platform, LLM and EVM |
| Never | approves or asks for changes, changes settings or access levels, renames or deletes a space, imports, makes a space, names people on a document |
A document reaches decided only with the approvals its space asks for, and only a person
approves, so the agent can record a decision the owner made and never make one.
A diagram is drawn here in the RFCs product; this page does not show diagrams yet.
The commands
iohr rfc in the command line: list, show, create, save (a new version from a
file), status, comment, link-pr (a comment owner/repo#N "title": open, then
merged, then live) and review (ask the owner), each with --json. They call the API
through the SDK's rfcs operations, as any customer's program would. An agent runs
eval "$(mise run -q rfcs:token)" once per session and then iohr --profile rfcs rfc ....
Controls
- Least privilege. A member of one account, writing in three named spaces, refused every manager action, approval and change of people; tests prove each refusal and that lookalike tokens find nothing.
- Access control stays at the gateway and the service. The gateway admits the token by its scopes; the RFCs service decides membership. Nothing new checks a token.
- Secrets. The client secret lives in the cluster's secret store only; the token is printed only into a shell's environment, never to a terminal.
- Revocation. A revoke deletes the client and its secret; removing the agent from the service's configuration ends tokens already minted at the next roll.
- Audit and transparency. Every change is made as
iohr-rfcs-agent, so a reader sees which versions and comments an AI agent wrote, and the audit lines say so. All agent sessions share that one subject.
The compliance registry lists the new machine principal and its scope.
Alternatives considered
- An API key of the Engineering account. Keys are made by a person in the console, and a key holds every right of its account, managing included; the service would have to tell a key apart from its owner anyway.
- A membership row for the client. The same effect through the database, where a stray row could grant it; the configuration is reviewed in a pull request.
- One identity per session. Clearer audit lines, at the cost of a client per session at the identity provider. Worth it once agents act for other people.
Decision
Open.
Publication
docs/rfcs-api.md holds the commands; the command-line reference lists iohr rfc.
Status log
- 2026-10-07: opened. The agent principal, its tokens and the commands are built in inorbithr/core and inorbithr/sdk; the roll and the first live run follow.