Commit 249c284
fix(signing): authorized_operators[] is top-level on brand.json, re-export new types
Addresses PR #770 reviewer feedback (aao-ipr-bot, two reviews on commit
d3536c2).
**Blocking — authorized_operators[] location.** Per the canonical
brand.json schema (House Portfolio variant in schemas/cache/3.0/brand.json),
``authorized_operators`` is a TOP-LEVEL property of the document —
sibling of ``house`` / ``brands`` / ``contact`` / ``trademarks`` — and
ADCP #3690 security.mdx step 3 reads it unqualified at the document
root.
I had misread the schema indentation and was reading from
``data["house"]["authorized_operators"]``. As written, the SDK would
have silently failed closed against every conforming brand.json the
TS/Go reference impls accept, AND would have created an
operator-delegation bypass via cross-verifier disagreement once Stage 5
wires it into the verifier path. Fix reads from the document root and
adds a defensive test asserting that operators misplaced under
``house`` are IGNORED (the wrong-location reading must fail closed).
**Non-blocking — re-export new public symbols.** Reviewer noted the
PR description says adopters can use the resolver today, but the new
types live in submodules and aren't exported from ``adcp.signing``.
The sibling ``BrandJsonJwksResolver`` IS exported via that surface,
so the new types should follow the same pattern. Adds to ``__init__``
and ``__all__``:
- BrandAuthorizationResolver / BrandJsonAuthorizationResolver
- BrandAuthorizationResult / BrandAuthorizationReason
- build_brand_json_resolvers
- host_from / registrable_domain / same_registrable_domain
**Not addressed in this commit** (deferring to Stage 4 PR or
follow-ups; reviewer flagged as non-blocking):
- BrandAuthorizationReason taxonomy overlap with spec codes — the
taxonomy is intentionally finer than the spec's framework-boundary
codes (e.g. ``agent_type_mismatch`` vs spec's
``agent_not_in_brand_json``); Stage 5 maps reasons to spec codes at
the dispatch boundary. Confirmed with reviewer reading.
- Protocol returns ``bool`` not ``BrandAuthorizationResult`` — Stage 5
consumers use ``check()`` on the concrete impl. Widening the
Protocol can come with Stage 5 when the framework wire-up exposes
the real ergonomic shape.
- IDNA-2008 A-label canonicalization in ``host_from`` — existing
codebase uses stdlib ``host.encode("idna")`` (IDNA 2003) consistently
(jwks.py, ip_pinned_transport.py, revocation_fetcher.py). Migrating
all of them to IDNA 2008 is a separate concern, deserves its own
spec-conformance pass.
- shared-fetcher test should exercise the JWKS resolver too — agreed,
trivial follow-up.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent d3536c2 commit 249c284
3 files changed
Lines changed: 82 additions & 19 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
101 | 101 | | |
102 | 102 | | |
103 | 103 | | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
104 | 111 | | |
105 | 112 | | |
106 | 113 | | |
| |||
175 | 182 | | |
176 | 183 | | |
177 | 184 | | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
178 | 190 | | |
179 | 191 | | |
180 | 192 | | |
| |||
293 | 305 | | |
294 | 306 | | |
295 | 307 | | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
296 | 312 | | |
297 | 313 | | |
298 | 314 | | |
| |||
373 | 389 | | |
374 | 390 | | |
375 | 391 | | |
| 392 | + | |
376 | 393 | | |
377 | 394 | | |
378 | 395 | | |
| |||
388 | 405 | | |
389 | 406 | | |
390 | 407 | | |
| 408 | + | |
391 | 409 | | |
392 | 410 | | |
393 | 411 | | |
394 | 412 | | |
395 | 413 | | |
396 | 414 | | |
397 | 415 | | |
| 416 | + | |
398 | 417 | | |
399 | 418 | | |
| 419 | + | |
400 | 420 | | |
401 | 421 | | |
402 | 422 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
498 | 498 | | |
499 | 499 | | |
500 | 500 | | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
501 | 511 | | |
502 | | - | |
503 | | - | |
504 | | - | |
505 | | - | |
| 512 | + | |
506 | 513 | | |
507 | 514 | | |
508 | 515 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
243 | 243 | | |
244 | 244 | | |
245 | 245 | | |
246 | | - | |
247 | | - | |
248 | | - | |
249 | 246 | | |
250 | 247 | | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
251 | 251 | | |
252 | 252 | | |
253 | 253 | | |
| |||
273 | 273 | | |
274 | 274 | | |
275 | 275 | | |
276 | | - | |
277 | | - | |
278 | | - | |
279 | 276 | | |
280 | 277 | | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
281 | 281 | | |
282 | 282 | | |
283 | 283 | | |
| |||
304 | 304 | | |
305 | 305 | | |
306 | 306 | | |
307 | | - | |
308 | | - | |
309 | | - | |
310 | 307 | | |
311 | 308 | | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
312 | 312 | | |
313 | 313 | | |
314 | 314 | | |
| |||
337 | 337 | | |
338 | 338 | | |
339 | 339 | | |
340 | | - | |
341 | | - | |
342 | | - | |
343 | 340 | | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
344 | 344 | | |
345 | 345 | | |
346 | 346 | | |
| |||
368 | 368 | | |
369 | 369 | | |
370 | 370 | | |
371 | | - | |
372 | | - | |
373 | | - | |
374 | 371 | | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
375 | 375 | | |
376 | 376 | | |
377 | 377 | | |
| |||
388 | 388 | | |
389 | 389 | | |
390 | 390 | | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
391 | 427 | | |
392 | 428 | | |
393 | 429 | | |
| |||
0 commit comments