fix(server): send PushNotificationConfig.authentication as an Authorization header - #1271
Merged
JakubWorek merged 2 commits intoSep 29, 2026
Conversation
🧪 Code Coverage (vs
|
| Base | PR | Delta | |
|---|---|---|---|
| src/a2a/server/tasks/base_push_notification_sender.py | 95.12% | 94.34% | 🔴 -0.78% |
| Total | 93.12% | 93.12% | ⚪️ -0.00% |
Generated by coverage-comment.yml
JakubWorek
added this pull request to stack #1275
September 23, 2026 12:55
JakubWorek
force-pushed
the
jakubworek/acts-push-auth-header
branch
from
September 23, 2026 13:11
675e513 to
337c1e8
Compare
JakubWorek
marked this pull request as ready for review
September 23, 2026 13:26
mykytanetipa
requested changes
Sep 27, 2026
JakubWorek
force-pushed
the
jakubworek/acts-push-auth-header
branch
from
September 28, 2026 08:30
337c1e8 to
8ffc371
Compare
JakubWorek
force-pushed
the
jakubworek/acts-push-auth-header
branch
from
September 28, 2026 08:47
8ffc371 to
2957666
Compare
JakubWorek
force-pushed
the
jakubworek/acts-push-auth-header
branch
from
September 28, 2026 08:54
2957666 to
c431444
Compare
…zation header
Spec 4.3.3 gives the webhook request an
'Authorization: {scheme} {credentials}' header built from
PushNotificationConfig.authentication, but the sender only ever read the
sibling token field, so a receiver had no credential to check and could
not tell a genuine push from a forged one.
Sent only when both scheme and credentials are set: a half-filled
AuthenticationInfo would otherwise put 'Bearer ' with nothing after it
on the wire.
JakubWorek
force-pushed
the
jakubworek/acts-push-auth-header
branch
from
September 28, 2026 10:14
533fa53 to
faf467a
Compare
mykytanetipa
approved these changes
Sep 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Spec 4.3.3 gives the webhook request an
Authorization: {authentication_scheme} {credentials}header, built fromPushNotificationConfig.authentication.BasePushNotificationSendernever read that field - the only header it has ever sent isX-A2A-Notification-Token, from the siblingtoken. A receiver therefore had no credential to check and no way to tell a genuine push from a forged one, which is the whole point of registeringauthenticationin the first place.Nothing suggests this was left to the application. The constructor docstring explicitly justifies delegating URL screening, on the grounds that the spec makes it a SHOULD, and says nothing about auth, which the spec makes a MUST. The code already reads the field next to it. This reads as an omission.
Only when both halves are present
AuthenticationInfois a message, so a config can setschemewithoutcredentials. Sending on that would putBearerwith nothing after it on the wire - a header that looks like a credential and is not. Both must be non-empty.Note the singular
scheme. Only the v0.3 compat type has repeatedschemes, andconversions.py:252-261collapses it toschemes[0]on the way in, so the sender only ever deals with one.Heads-up on the ACTS side
SEC-PUSH-001,SEC-PUSH-002andPUSH-DELIV-001currently pass in nightly CI for every SDK, so this may look like a fix to something that was not broken. It is not: the assertion that inspects the delivered request is new, added in a2aproject/A2A@82c277f. The corpus CI runs predates it, and the older tests only checked that the config API accepted the config - which, as that commit's own note puts it, "a server that stores it and pushes anonymously, or never pushes, satisfies".A consequence worth stating: no other SDK has been measured against the real assertion yet, so unlike the rest of this stack there is no cross-SDK corroboration here. The code is the evidence -
push_info.authenticationappears nowhere undersrc/a2a/server/before this change.Result
Clears
SEC-PUSH-001,SEC-PUSH-002(must) andPUSH-DELIV-001(may) on all three bindings, and with them the last failing MUST:The three PRs after this one are SHOULD-level and change the verdict for nobody; they take the remaining non-MUST failures to zero.
Closes #585