Background
AAuth's per-instance agent identity (aauth:local@domain) gives each runtime its own identifier and signing key — great for per-instance authorization, revocation, and audit. But there's no first-class way to group instances of the same product.
A user installing Planner today has to consent to each Planner instance separately. A new install or container restart triggers re-consent. There's no way to say "I trust any Planner instance from vendor.example."
Proposal
Add an OPTIONAL class claim to the agent token.
{
"iss": "https://vendor.example",
"sub": "aauth:planner.7f3c@vendor.example",
"cnf": { "jwk": ... },
"class": "planner"
}
Semantics:
class is an opaque string defined by the AP.
- A class is identified by the tuple
(iss, class). Verifiers MUST scope all class comparisons to that tuple.
- Comparison is exact string equality.
Where it lives:
- Only in the agent token. NOT copied to auth tokens.
Who enforces it:
- The PS only. PS uses class for grant matching. When a user consents at class granularity, the PS records
(user, iss, class) → {scopes, ...}. Future instances of the same class match the existing grant without re-consent.
Storage is implementation choice. PSes can synthesize an internal key like https://vendor.example/planner for indexing, or use any other scheme. The wire format stays minimal.
No hierarchy. Class strings are flat. APs may use any internal naming convention but the protocol does exact equality only.
Rationale
Why class at all
Per-instance identity without a category concept means per-instance consent — too fine-grained for users in practice. Every major AI agent identity system has converged on having a class-like concept:
- Microsoft Foundry / Entra Agent ID: agent identity blueprints "establish the category of agent through type classification" (e.g., "Contoso Sales Agent"). Each agent identity is an instance of a blueprint.
InheritDelegatedPermissions lets instances inherit permissions from the blueprint to "reduce consent complexity for multi-instance scenarios."
- Google OAuth (cross-client identity): project-wide consent — "when a user has granted access to a particular scope to any client ID in a project, the grant indicates the user's trust in the whole application."
- Karl McGuinness's
client_instance_assertion draft: separates client_id (logical class) from sub (instance).
- Auth0, Okta, Ping: all building agent identity products with class-like categorization.
AAuth's class claim is the same pattern in our terminology: AP labels what kind of agent an instance is.
Why flat (no hierarchy)
Three reasons:
-
No production system uses hierarchical class. Microsoft blueprints are flat. Google projects are flat. Karl's client_id is flat. A hierarchical AAuth class would put us in a club of one.
-
Hierarchy use cases are covered by other primitives. "User consents to /planner; should cover sub-agents" — sub-agents get authorization via parent delegation, not class match. "Reject sub-agents for sensitive scope" — handled by the act != ∅ check, not class depth. "Resource policy by class subtree" — class is PS-only; resources don't see it.
-
Implementation cost vs. benefit is poor. Hierarchy requires prefix-matching DB queries, normalization rules, depth concept, "most specific match wins" semantics. Flat equality is one query.
Why PS-only
The PS is the consent/grant authority. Class exists for consent grouping. Pushing class into auth tokens is propagating an input that's already been consumed by the only party that uses it.
Open questions
- Does anyone have a real cross-deployment use case for hierarchical class that the flat model can't express?
- When
class is omitted, the PS treats the agent purely by agent identifier (today's behavior). Good?
References
Background
AAuth's per-instance agent identity (
aauth:local@domain) gives each runtime its own identifier and signing key — great for per-instance authorization, revocation, and audit. But there's no first-class way to group instances of the same product.A user installing Planner today has to consent to each Planner instance separately. A new install or container restart triggers re-consent. There's no way to say "I trust any Planner instance from vendor.example."
Proposal
Add an OPTIONAL
classclaim to the agent token.{ "iss": "https://vendor.example", "sub": "aauth:planner.7f3c@vendor.example", "cnf": { "jwk": ... }, "class": "planner" }Semantics:
classis an opaque string defined by the AP.(iss, class). Verifiers MUST scope all class comparisons to that tuple.Where it lives:
Who enforces it:
(user, iss, class) → {scopes, ...}. Future instances of the same class match the existing grant without re-consent.Storage is implementation choice. PSes can synthesize an internal key like
https://vendor.example/plannerfor indexing, or use any other scheme. The wire format stays minimal.No hierarchy. Class strings are flat. APs may use any internal naming convention but the protocol does exact equality only.
Rationale
Why class at all
Per-instance identity without a category concept means per-instance consent — too fine-grained for users in practice. Every major AI agent identity system has converged on having a class-like concept:
InheritDelegatedPermissionslets instances inherit permissions from the blueprint to "reduce consent complexity for multi-instance scenarios."client_instance_assertiondraft: separatesclient_id(logical class) fromsub(instance).AAuth's
classclaim is the same pattern in our terminology: AP labels what kind of agent an instance is.Why flat (no hierarchy)
Three reasons:
No production system uses hierarchical class. Microsoft blueprints are flat. Google projects are flat. Karl's
client_idis flat. A hierarchical AAuth class would put us in a club of one.Hierarchy use cases are covered by other primitives. "User consents to /planner; should cover sub-agents" — sub-agents get authorization via parent delegation, not class match. "Reject sub-agents for sensitive scope" — handled by the
act != ∅check, not class depth. "Resource policy by class subtree" — class is PS-only; resources don't see it.Implementation cost vs. benefit is poor. Hierarchy requires prefix-matching DB queries, normalization rules, depth concept, "most specific match wins" semantics. Flat equality is one query.
Why PS-only
The PS is the consent/grant authority. Class exists for consent grouping. Pushing class into auth tokens is propagating an input that's already been consumed by the only party that uses it.
Open questions
classis omitted, the PS treats the agent purely by agent identifier (today's behavior). Good?References