Commit fddea1a
* feat(adagents): add ads.txt MANAGERDOMAIN fallback discovery (#704)
Implements RFC 4175: when /.well-known/adagents.json returns 404 on a
publisher, consult /ads.txt for a MANAGERDOMAIN= directive and attempt
discovery one hop later on the manager. The fallback only kicks in for
the directive form — pure-comment lines like `# managerdomain=` are
rejected — and follows IAB last-wins resolution when a file declares
multiple MANAGERDOMAIN entries. Manager-domain 404 is a terminal
failure, not a silent pass.
`AdAgentsValidationResult` and the `DiscoveryMethod` literal are added
to the public API, exposing which path produced the data (direct,
authoritative_location, or ads_txt_managerdomain) plus the resolved
`manager_domain` for diagnostics. `fetch_adagents` transparently
benefits from the fallback while keeping its dict return shape; callers
who need provenance use the new `validate_adagents_domain`.
Refs: adcontextprotocol/adcp#4173, adcontextprotocol/adcp#4175
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(adagents): close SSRF + size + redirect-404 gaps on MANAGERDOMAIN fallback
Reviewer follow-ups on #705 / #704:
- SSRF: a publisher-controlled MANAGERDOMAIN=169.254.169.254 (or any
loopback / private / link-local literal) would have passed
`_validate_publisher_domain` and forced the SDK into a cross-origin
HTTPS GET against internal services. The fallback now routes every
manager domain through `_ensure_safe_manager_domain`, which composes
the existing `_validate_redirect_url` SSRF gate with the publisher
domain validator.
- ads.txt size: the body was passed to `_parse_managerdomains` with no
cap, so a hostile publisher could force the SDK to buffer arbitrary
data. Bodies over MAX_ADS_TXT_BYTES (1 MiB) are now discarded.
- Redirect-target 404: a 404 from a followed authoritative_location
target previously bubbled up as AdagentsNotFoundError and triggered
the ads.txt MANAGERDOMAIN fallback on the original publisher, which
conflates a broken pointer with a missing manifest. It now surfaces
as AdagentsValidationError so the fallback only fires on the
publisher's own direct 404.
Also documents the publisher-scope caveat on `validate_adagents_domain`
— callers wiring `ads_txt_managerdomain` results into authorization
decisions must verify the manager's adagents.json explicitly scopes
the source publisher (per the TS reference's `hasExplicitPublisherScope`
gate). Adding that gate as a default is tracked as a follow-up.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 2d1ae2f commit fddea1a
4 files changed
Lines changed: 806 additions & 57 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| 14 | + | |
14 | 15 | | |
| 16 | + | |
15 | 17 | | |
16 | 18 | | |
17 | 19 | | |
18 | 20 | | |
19 | 21 | | |
20 | 22 | | |
21 | 23 | | |
| 24 | + | |
22 | 25 | | |
23 | 26 | | |
24 | 27 | | |
| |||
805 | 808 | | |
806 | 809 | | |
807 | 810 | | |
| 811 | + | |
808 | 812 | | |
| 813 | + | |
809 | 814 | | |
810 | 815 | | |
| 816 | + | |
811 | 817 | | |
812 | 818 | | |
813 | 819 | | |
| |||
0 commit comments