Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
5387eab
docs(spec): track AAuth Events draft in update workflow
nedruk Jul 14, 2026
436f6ac
Vendor AAuth protocol draft 09
nedruk Jul 14, 2026
14ced95
docs(events): add research and implementation plan
nedruk Jul 15, 2026
07bdde0
Address AAuth Events plan review
nedruk Jul 15, 2026
a5c74c5
Initialize AAuth Events implementation
nedruk Jul 15, 2026
6855f45
Add AAuth Events token foundation
nedruk Jul 15, 2026
f7b78d8
Harden Events token validation
nedruk Jul 15, 2026
dc2f762
Merge AAuth Events token foundation
nedruk Jul 15, 2026
cc6629c
Complete AAuth Events foundation integration
nedruk Jul 15, 2026
1a6a121
Add AAuth Events HTTP security layer
nedruk Jul 15, 2026
d2da27b
Harden Events HTTP verification
nedruk Jul 15, 2026
2e834f1
Merge AAuth Events HTTP security layer
nedruk Jul 15, 2026
a493edd
Complete AAuth Events HTTP integration
nedruk Jul 15, 2026
bbd1053
Add AAuth Events discovery support
nedruk Jul 15, 2026
50f14e5
Add AAuth Events Agent Provider role
nedruk Jul 15, 2026
47c2c15
Add AAuth Events agent verification
nedruk Jul 15, 2026
f8d59dd
Add AAuth Events subscription registration
nedruk Jul 15, 2026
8597e6f
Test Events metadata issuer binding
nedruk Jul 15, 2026
af4c180
Fix AAuth Events agent DI and failures
nedruk Jul 15, 2026
0b4fe70
Harden Events subscription endpoints
nedruk Jul 15, 2026
5f1b54a
Harden AAuth Events Agent Provider role
nedruk Jul 15, 2026
4b980f6
Reject unresolved AsyncAPI channel references
nedruk Jul 15, 2026
3d36a3a
Merge AAuth Events discovery role
nedruk Jul 15, 2026
4c47819
Merge AAuth Events registration role
nedruk Jul 15, 2026
63a3ecd
Merge AAuth Events Agent Provider role
nedruk Jul 15, 2026
1e74256
Merge AAuth Events agent verification role
nedruk Jul 15, 2026
f7a25e6
Record AAuth Events role implementations
nedruk Jul 15, 2026
183dbe7
Add AAuth Events resource delivery
nedruk Jul 15, 2026
1e8f80d
Harden AAuth Events resource delivery
nedruk Jul 15, 2026
cd944c2
Merge AAuth Events resource delivery
nedruk Jul 15, 2026
bd4ef81
Record AAuth Events delivery implementation
nedruk Jul 15, 2026
3c6dd7f
Add subscribe token conformance matrix
nedruk Jul 15, 2026
d79a5d3
Add registration conformance matrix
nedruk Jul 15, 2026
5517579
Add agent verification conformance matrix
nedruk Jul 15, 2026
5604464
Add event delivery conformance matrix
nedruk Jul 15, 2026
c7c84eb
Merge subscribe token conformance matrix
nedruk Jul 15, 2026
ee91bdb
Merge registration conformance matrix
nedruk Jul 15, 2026
6e4a657
Merge event delivery conformance matrix
nedruk Jul 15, 2026
e6a9747
Merge agent verification conformance matrix
nedruk Jul 15, 2026
f2eb6dc
Correct AAuth Events delivery conformance
nedruk Jul 15, 2026
ff1ad7e
Add cross-role AAuth Events conformance
nedruk Jul 15, 2026
0730f75
Harden cross-role Events conformance
nedruk Jul 15, 2026
adea898
Merge cross-role AAuth Events conformance
nedruk Jul 15, 2026
8d7b1c0
Freeze AAuth Events public APIs
nedruk Jul 15, 2026
8f83a4a
Add Bookings AAuth Events waitlist sample
nedruk Jul 15, 2026
cdb4e88
Add MockAgentProvider Events inbox sample
nedruk Jul 15, 2026
3eb3240
Add AAuth EventAgent console sample
nedruk Jul 15, 2026
0158af2
Preserve revoked Events subscriptions
nedruk Jul 15, 2026
6f10423
Harden Bookings Events trigger
nedruk Jul 15, 2026
0447148
Harden EventAgent payload processing
nedruk Jul 15, 2026
0f4ce99
Merge Bookings AAuth Events sample
nedruk Jul 15, 2026
d2a90b5
Merge MockAgentProvider Events inbox sample
nedruk Jul 15, 2026
33f9a72
Merge AAuth EventAgent sample
nedruk Jul 15, 2026
3d53a95
Integrate the AAuth Events sample stack
nedruk Jul 15, 2026
007189c
Record runnable AAuth Events sample
nedruk Jul 15, 2026
ad769e3
Pack AAuth Events in the release workflow
nedruk Jul 15, 2026
9d46fd9
Document AAuth Events workflow and package
nedruk Jul 15, 2026
526edbf
Fix protected subscription documentation
nedruk Jul 15, 2026
cad3409
Merge AAuth Events documentation
nedruk Jul 15, 2026
b9801ec
Merge AAuth Events release wiring
nedruk Jul 15, 2026
e3c0e31
Complete AAuth Events documentation and release gate
nedruk Jul 15, 2026
1bbebce
Fix internal AAuth Events review findings
nedruk Jul 15, 2026
4d83551
Bound AAuth Events client responses
nedruk Jul 15, 2026
a76ead2
Complete AAuth Events internal review
nedruk Jul 15, 2026
86bd831
fix(events): require resource audience binding
nedruk Jul 16, 2026
3c2c92c
fix(events): separate token and subscription lifetimes
nedruk Jul 16, 2026
085681d
fix(samples): retain accepted event receipts
nedruk Jul 16, 2026
b2ac115
docs(events): record post-review resolutions
nedruk Jul 16, 2026
1ac8fa0
docs(events): fix workflow sequence diagram
nedruk Jul 16, 2026
6b27429
docs(events): add specification review
nedruk Jul 17, 2026
39512e9
fix(docs): correct AAuth spec document dates to published Internet-Dr…
dasiths Jul 29, 2026
ac5e351
fix(instructions): source spec document date from the published Inter…
dasiths Jul 29, 2026
dd543a7
docs: add draft-09 SDK conformance migration research
dasiths Jul 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
564 changes: 564 additions & 0 deletions .agent/plans/2026-07-14-aauth-events/implementation-log.md

Large diffs are not rendered by default.

639 changes: 639 additions & 0 deletions .agent/plans/2026-07-14-aauth-events/implementation-plan.md

Large diffs are not rendered by default.

422 changes: 422 additions & 0 deletions .agent/plans/2026-07-14-aauth-events/research.md

Large diffs are not rendered by default.

254 changes: 254 additions & 0 deletions .agent/plans/2026-07-14-aauth-events/spec-review.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
# AAuth Events Specification Review

**Spec:** `draft-hardt-aauth-events-00`, 2026-06-24.

**Method:** Compiled from [research.md](research.md),
[implementation-plan.md](implementation-plan.md), and
[implementation-log.md](implementation-log.md), then checked against the
vendored draft, `src/AAuth.Events`, and its conformance tests. These are
upstream specification issues, not unresolved SDK defects.

## 1. `eid` cannot be both a subscription ID and an event idempotency key

- **Nature:** Internal contradiction. `eid` identifies a subscription, which
may accept unlimited events, but agent verification deduplicates every event
by `{iss, eid}` ([Terminology](../../../aauth-spec/v09/draft-hardt-aauth-events.md#terminology),
L138; [Subscribe Token](../../../aauth-spec/v09/draft-hardt-aauth-events.md#subscribe-token),
L229; [Agent Verification](../../../aauth-spec/v09/draft-hardt-aauth-events.md#ap-to-agent),
L445).
- **Concern:** All events in one subscription share the same key.
- **If unchanged:** An agent following the draft processes the first event and
discards every later event in an ongoing subscription.
- **SDK assumption/trade-off:** Deduplicate the exact compact token hash, not
`{iss, eid}`, and rely on a fresh `jti` to distinguish later events
([EventTokenVerifier.cs](../../../src/AAuth.Events/Agent/EventTokenVerifier.cs#L155-L211),
[EventTokenBuilder.cs](../../../src/AAuth.Events/Tokens/EventTokenBuilder.cs#L30-L87)).
This deliberately deviates from the draft; a newly signed token is a new
event even if its business payload is equivalent.

## 2. Event tokens do not explicitly forbid `alg: none`

- **Nature:** Missing security requirement. Subscribe tokens say
implementations `MUST NOT` accept `none`; the equivalent event-token rule is
absent ([Subscribe Token](../../../aauth-spec/v09/draft-hardt-aauth-events.md#subscribe-token),
L212; [Event Token](../../../aauth-spec/v09/draft-hardt-aauth-events.md#event-token),
L348).
- **Concern:** The asymmetry permits an event-only implementation to interpret
unsigned JWTs as allowed.
- **If unchanged:** A permissive verifier can accept forged events without a
resource private key.
- **SDK assumption/trade-off:** Apply one strict algorithm allowlist to both
token types: EdDSA or ES256 only
([EventsJwtKeyResolver.cs](../../../src/AAuth.Events/Http/EventsJwtKeyResolver.cs#L122-L124)).
This closes the gap but requires an SDK update before any future algorithm
can interoperate.

## 3. The minimum resource record cannot populate event `aud`

- **Nature:** Internal contradiction. The stated minimum resource state is
`{eid, iss}`, while event issuance and AP validation require the agent
identifier in `aud`
([Subscription Verification](../../../aauth-spec/v09/draft-hardt-aauth-events.md#subscribe-token),
L279; [Event Token](../../../aauth-spec/v09/draft-hardt-aauth-events.md#event-token),
L356; [AP Validation](../../../aauth-spec/v09/draft-hardt-aauth-events.md#event-delivery),
L413).
- **Concern:** Neither `eid` nor the AP issuer identifies the subscribed agent.
- **If unchanged:** A resource storing only the documented minimum cannot issue
an acceptable event token; delivery fails the AP audience check.
- **SDK assumption/trade-off:** Persist subscribe-token `sub` as
`AgentSubject`, in addition to the stated minimum, and use it as event `aud`
([ResourceSubscription.cs](../../../src/AAuth.Events/Resource/ResourceSubscription.cs#L45-L63),
[EventDeliveryClient.cs](../../../src/AAuth.Events/Resource/EventDeliveryClient.cs#L190-L203)).
This adds required durable state without changing the wire format.

## 4. Event payload integrity ends at the AP

- **Nature:** End-to-end integrity gap. The event token excludes event data;
`Content-Digest` protects the resource-to-AP hop, but the agent may use the
forwarded payload directly
([Event Token](../../../aauth-spec/v09/draft-hardt-aauth-events.md#event-token),
L361; [Event Delivery](../../../aauth-spec/v09/draft-hardt-aauth-events.md#event-delivery),
L387; [Agent Verification](../../../aauth-spec/v09/draft-hardt-aauth-events.md#ap-to-agent),
L447).
- **Concern:** The agent has no resource-signed digest with which to authenticate
payload bytes supplied by the AP.
- **If unchanged:** A compromised or malicious AP can substitute actionable
payload content while the event token still verifies.
- **SDK assumption/trade-off:** Expose payload bytes only as
`UnauthenticatedEventPayload`; consequential details must be re-fetched from
the verified resource
([UnauthenticatedEventPayload.cs](../../../src/AAuth.Events/Agent/UnauthenticatedEventPayload.cs#L9-L46)).
This avoids a private wire extension but adds application work and another
authenticated request.

## 5. Registration JSON is not integrity-bound

- **Nature:** Signature-profile gap. Registration signs `content-type` but not
`content-digest`, unlike event delivery
([Registration Presentation](../../../aauth-spec/v09/draft-hardt-aauth-events.md#subscribe-token),
L251-L266; [Event Delivery](../../../aauth-spec/v09/draft-hardt-aauth-events.md#event-delivery),
L382-L399).
- **Concern:** The HTTP signature authenticates the agent and path, not the
registration body bytes.
- **If unchanged:** A TLS-terminating intermediary or compromised hop can alter
requested event types or other body preferences without invalidating the
HTTP signature.
- **SDK assumption/trade-off:** Retain the draft profile for interoperability,
label the body `SignatureUnboundRegistrationBody`, and prohibit body
preferences from widening authorization
([SignatureUnboundRegistrationBody.cs](../../../src/AAuth.Events/Resource/SignatureUnboundRegistrationBody.cs#L9-L35)).
This contains the authorization impact but does not provide body integrity.

## 6. Event payload wire shape and media type conflict

- **Nature:** Conflicting wire definitions. The HTTP example sends a direct
JSON body, discovery prose calls it a `payload` field, and the AsyncAPI
example declares `application/jwt`
([Event Delivery](../../../aauth-spec/v09/draft-hardt-aauth-events.md#event-delivery),
L380-L395; [AsyncAPI Document](../../../aauth-spec/v09/draft-hardt-aauth-events.md#event-discovery),
L479; [Example AsyncAPI Document](../../../aauth-spec/v09/draft-hardt-aauth-events.md#event-discovery),
L551).
- **Concern:** The alternatives describe different HTTP bodies and parsers.
- **If unchanged:** Implementations may send a JSON object, a wrapper object, or
a JWT and fail to interoperate.
- **SDK assumption/trade-off:** Follow the concrete delivery example: preserve
the direct payload bytes and require `application/json`, with no wrapper
([PreparedEventDelivery.cs](../../../src/AAuth.Events/Resource/PreparedEventDelivery.cs#L28-L49)).
Peers choosing either other interpretation are incompatible.

## 7. Required signed components exist only in examples

- **Nature:** Normative omission. Examples cover `content-type` for
registration and `content-type` plus `content-digest` for event delivery, but
the verification algorithms do not require those components
([Registration Verification](../../../aauth-spec/v09/draft-hardt-aauth-events.md#subscribe-token),
L265-L279; [AP Validation](../../../aauth-spec/v09/draft-hardt-aauth-events.md#event-delivery),
L404-L413).
- **Concern:** Examples and normative steps define different signature
profiles.
- **If unchanged:** Strict implementations can reject each other, while lenient
implementations may leave event bodies unprotected.
- **SDK assumption/trade-off:** Treat the examples as normative and require the
exact component sequence: base components only when bodyless,
`content-type` for registration JSON, and `content-type` plus
`content-digest` for event JSON
([AAuthEventsConstants.cs](../../../src/AAuth.Events/AAuthEventsConstants.cs#L63-L75),
[EventsHttpMessageVerifier.cs](../../../src/AAuth.Events/Http/EventsHttpMessageVerifier.cs#L42-L93)).
This is secure and deterministic but may reject a peer following only the
prose.

## 8. `max_uses` is incremented before audience validation

- **Nature:** Invalid validation order. AP step 7 mutates use state before step
8 checks the event audience
([AP Validation](../../../aauth-spec/v09/draft-hardt-aauth-events.md#event-delivery),
L412-L413).
- **Concern:** A request can fail authorization after consuming a finite use.
- **If unchanged:** Wrong-audience deliveries can exhaust a subscription
without delivering any event.
- **SDK assumption/trade-off:** Require one durable store transaction to check
subscription, resource, audience, expiry, replay, and limits before committing
use count and inbox state
([IAAuthAgentProviderEventStore.cs](../../../src/AAuth.Events/AgentProvider/IAAuthAgentProviderEventStore.cs#L5-L29),
[EventEndpointExtensions.cs](../../../src/AAuth.Events/AgentProvider/EventEndpointExtensions.cs#L129-L132)).
Correctness depends on the application-provided store honoring this contract.

## 9. The protocol has no per-event identity or AP retry rule

- **Nature:** Missing replay/idempotency model. Event claims omit `jti`, and AP
validation has no exact-retry check
([Event Token](../../../aauth-spec/v09/draft-hardt-aauth-events.md#event-token),
L351-L359; [AP Validation](../../../aauth-spec/v09/draft-hardt-aauth-events.md#event-delivery),
L404-L413).
- **Concern:** A retry is indistinguishable from another use; token-hash
deduplication alone also collides when two same-second events serialize
identically.
- **If unchanged:** Network retries can double-deliver and double-count
`max_uses`; attempts to add local deduplication can suppress legitimate
same-second events.
- **SDK assumption/trade-off:** Add a required, fresh 128-bit `jti`; use the
compact-token SHA-256 hash as the AP and agent idempotency key; return the
prior `202` result for an exact retry without another use
([EventTokenBuilder.cs](../../../src/AAuth.Events/Tokens/EventTokenBuilder.cs#L30-L87),
[IncomingEvent.cs](../../../src/AAuth.Events/AgentProvider/IncomingEvent.cs#L24-L42),
[EventAcceptanceResult.cs](../../../src/AAuth.Events/AgentProvider/EventAcceptanceResult.cs#L3-L38)).
This is a deliberate wire extension: otherwise spec-conforming event tokens
that omit `jti` are rejected.

## 10. Subscription expiry has no wire representation

- **Nature:** Missing lifecycle contract. The AP can return `404` for an expired
subscription, but subscribe-token `exp` is explicitly only the registration
window
([AP Validation](../../../aauth-spec/v09/draft-hardt-aauth-events.md#event-delivery),
L409-L428; [Design Rationale](../../../aauth-spec/v09/draft-hardt-aauth-events.md#design-rationale),
L681-L687).
- **Concern:** No field communicates or negotiates subscription lifetime
between AP and resource.
- **If unchanged:** Implementations apply unrelated local expiry policies and
can disagree about whether a subscription is active.
- **SDK assumption/trade-off:** Keep `TokenLifetime` and AP-side
`SubscriptionLifetime` separate, and require resource applications to supply
their own stored `ExpiresAt`
([SubscribeTokenIssuer.cs](../../../src/AAuth.Events/AgentProvider/SubscribeTokenIssuer.cs#L22-L24),
[ResourceSubscription.cs](../../../src/AAuth.Events/Resource/ResourceSubscription.cs#L74-L92)).
No non-standard claim is added, so cross-party lifetime synchronization
remains unsolved.

## 11. Required event `iat` is never listed as validated

- **Nature:** Missing validation requirement. `iat` is required, but neither
the AP nor agent validation sequence says to reject a future value
([Event Token](../../../aauth-spec/v09/draft-hardt-aauth-events.md#event-token),
L358; [AP Validation](../../../aauth-spec/v09/draft-hardt-aauth-events.md#event-delivery),
L404-L413; [Agent Verification](../../../aauth-spec/v09/draft-hardt-aauth-events.md#ap-to-agent),
L438-L445).
- **Concern:** Requiring a claim without defining its validation gives it no
consistent security meaning.
- **If unchanged:** Future-issued events may be accepted by some
implementations and rejected by others.
- **SDK assumption/trade-off:** Require `iat`, require `exp > iat`, and reject
future issuance using configured clock skew
([EventTokenClaims.cs](../../../src/AAuth.Events/Tokens/EventTokenClaims.cs#L30-L42),
[TokenVerifier.cs](../../../src/AAuth/Tokens/TokenVerifier.cs#L107-L130)).
This is stricter than the event-specific validation lists.

## 12. Failure status codes are incomplete

- **Nature:** Interoperability omission. Registration defines no failure map;
AP delivery omits outcomes for an expired event token and wrong event
audience
([Protocol Overview](../../../aauth-spec/v09/draft-hardt-aauth-events.md#protocol-overview),
L163; [AP Validation](../../../aauth-spec/v09/draft-hardt-aauth-events.md#event-delivery),
L404-L428).
- **Concern:** Callers cannot implement deterministic retry, re-registration,
or terminal-failure policy.
- **If unchanged:** Servers return different statuses for the same failure and
clients handle them inconsistently.
- **SDK assumption/trade-off:** Registration maps to
`200/400/401/403/404/409`; expired or invalid event tokens map to `401`; wrong
event audience maps to `403`
([SubscriptionRegistrationResult.cs](../../../src/AAuth.Events/Resource/SubscriptionRegistrationResult.cs#L3-L11),
[SubscriptionEndpointExtensions.cs](../../../src/AAuth.Events/Resource/SubscriptionEndpointExtensions.cs#L183-L190),
[EventEndpointExtensions.cs](../../../src/AAuth.Events/AgentProvider/EventEndpointExtensions.cs#L157-L191)).
These are opinionated defaults, not guaranteed peer behavior.

## 13. AsyncAPI operation direction is reversed or perspective-dependent

- **Nature:** Vocabulary ambiguity. A resource-owned document uses
`action: receive` for messages emitted by the resource, while the rationale
frames the document for an agent reader
([AsyncAPI Document](../../../aauth-spec/v09/draft-hardt-aauth-events.md#event-discovery),
L478; [Example AsyncAPI Document](../../../aauth-spec/v09/draft-hardt-aauth-events.md#event-discovery),
L537 and L544; [Design Rationale](../../../aauth-spec/v09/draft-hardt-aauth-events.md#design-rationale),
L721).
- **Concern:** AsyncAPI normally describes `send`/`receive` from the document
owner's perspective; the draft mixes resource ownership with agent
perspective.
- **If unchanged:** Generic tooling can model the resource as a consumer and
generate the wrong integration shape.
- **SDK assumption/trade-off:** Do not validate operation direction; validate
only AAuth-specific declarations
([AsyncApiAAuthValidator.cs](../../../src/AAuth.Events/Discovery/AsyncApiAAuthValidator.cs#L53-L103),
[DiscoveryTests.cs](../../../tests/AAuth.Events.Tests/Discovery/DiscoveryTests.cs#L118-L136)).
This accepts both interpretations but cannot diagnose a direction error.
Loading
Loading