Skip to content

🧪 Beta — Available today; the interface contract may still change.

Audit and accountability chain

When something goes wrong you need to answer three questions within ten minutes: who authorized it, on whose behalf it was done, and what exactly was done.

Traditional logs cannot answer them. Because the agent uses a shared credential, the log holds one line — "service account X called endpoint Y" — and the authorizing person, along with who was being represented, is nowhere in the record.

GenAuth's answer is to give every authorization an identifier, and hang everything that follows off it.

Why agents need it

Human actions have a natural accountability path: the account is the person. Agents break that path — one agent may act for a hundred different people under a hundred different grants. The log must capture two subjects (the delegator and the executor) plus one basis for the authority (which grant allowed this). Miss any one of them and the chain breaks.

This is not only an operations need. Compliance audits, security post-mortems and customer enquiries all ask the same thing: trace this access back to the person who made the decision.

Three mandatory questions, three fields

QuestionAnswer comes fromNotes
Who authorized it?sub (the subject in both the delegate token and the access token)Always a person. An agent cannot authorize itself
On whose behalf did it act?sub + act (access token)sub is the person represented; act names the executing agent (field structure: Token and claim reference)
What was done?The event sequence linked by audit_id + grant_idThe full lifecycle of one authorization

How the two IDs divide the work:

  • grant_id — the ID of one grant record. It answers "which authorization is this": scope, lifetime and approver all hang off it.
  • audit_id — the audit chain ID. It answers "what happened after this authorization": issuance, exchange, access and recall, each appended to it.

How it works

  1. The user completes consent; GenAuth generates grant_id and audit_id and writes the first audit event (grant approved: who approved, what scope, for how long).
  2. GenAuth issues the delegate token with grant_id and audit_id embedded in its claims — from here on the two IDs travel with the token and do not depend on the caller passing them along.
  3. The agent exchanges for an access token; the exchange event joins the chain under the same audit_id and gets its own exchange_id.
  4. Your resource service validates the access token and handles the request. Record the token's sub / act / audit_id into your own business logs — this is the seam that extends the chain from GenAuth into your side (how: Protect your APIs).
  5. When authority is recalled (revoked or expired), the terminal event joins the same chain — recall is itself an audit subject: who withdrew what, and when.

What a chain looks like

Using the employee data assistant scenario (illustrative values):

text
audit_id: aud_demo_7f3c9a
├─ [10:02:11] grant approved      approver usr_demo_0001 · agent report-agent
│                                 scope [webagent.web_search:run, webagent.web_search:read] · lifetime 7200s
│                                 grant_id: grant_demo_51ab
├─ [10:02:12] delegate token issued  jti: jti_demo_9c02 · expires 12:02:12
├─ [10:02:15] token exchanged     resource: webagent · exchange_id: exc_demo_2d17
│                                 scope [webagent.web_search:run]
├─ [10:02:16] resource access     sub usr_demo_0001 · act report-agent · your business log seam
├─ [10:41:53] key disabled        operator admin_demo_02 · reason security response · further issuance stopped
└─ [12:02:12] token expired

Any line on this chain answers all three questions. And in reverse: from one audit_id in a business log you can trace back to the original authorization.

Design point: the audit chain is generated server-side, never declared by the caller

audit_id and grant_id are generated by GenAuth and embedded in the token; a caller cannot forge or substitute them. That is what keeps the chain intact — even an attacker holding a token cannot record their actions under someone else's authorization.

Two things you need to do

  1. Log the seam fields on your side: in the logs where you handle agent requests, record at least sub, act.agent_id and audit_id. Without those three, GenAuth's chain stops at your API boundary.
  2. Retention and access control: configure retention and query permissions for audit data according to your own compliance requirements. How to query and export: Audit and compliance reporting.

Standards and protocols

  • The dual-subject expression of sub / act inside a token follows the delegation semantics of RFC 8693 (GenAuth extends act; parsing notes in Token and claim reference).
  • Audit events themselves are not an external protocol; the API response is authoritative for their fields.

Next steps