CLI app for developers prototyping atproto functionality
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Flag token_endpoint_auth_signing_alg = "none" as a direct SpecViolation

The atproto OAuth profile
(<https://atproto.com/specs/oauth#client-metadata>) states
explicitly: "`none` is never allowed here". Previously this condition
was only caught incidentally by the JWKS stage's
`has_key_for_signing_alg` (no JWK can match `alg="none"`), producing a
misleading diagnostic that cited the JWKS rather than the underlying
metadata-level rule.

Add a new metadata-stage check `token_endpoint_auth_signing_alg_valid`.
Semantics:
- Field absent → `Skipped` with reason
"`token_endpoint_auth_signing_alg` not declared" (the field is
OPTIONAL overall).
- Field equal to `"none"` → `SpecViolation` with a pointed
diagnostic.
- Any other declared value → `Pass` (whether that value is actually
usable against the JWKS remains the responsibility of the
JWKS-stage `has_key_for_signing_alg` check).

Regression coverage: new `signing_alg_none/` metadata fixture and
integration test. All 326 tests pass; all 16 real-world atproto
OAuth clients still pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

+232 -34
+1
docs/design-plans/2026-04-16-test-oauth-client.md
··· 83 83 - **test-oauth-client.AC2.4 Failure:** `dpop_bound_access_tokens` absent or `false` produces a `SpecViolation` with stable code `oauth_client::metadata::dpop_bound_required`. 84 84 - **test-oauth-client.AC2.5 Failure:** A confidential client without `jwks` or `jwks_uri` produces a `SpecViolation` with code `oauth_client::metadata::confidential_requires_jwks`. 85 85 - **test-oauth-client.AC2.6 Failure:** A public client whose `token_endpoint_auth_method` is anything other than `none` produces a `SpecViolation`. 86 + - **test-oauth-client.AC2.6b Failure:** A client metadata document declaring `token_endpoint_auth_signing_alg = "none"` produces a `SpecViolation` on `token_endpoint_auth_signing_alg_valid`. The atproto OAuth profile (<https://atproto.com/specs/oauth#client-metadata>) states: *"`none` is never allowed here."* When the field is absent entirely the check emits `Skipped` (the field itself is OPTIONAL overall); the companion `has_key_for_signing_alg` JWKS check handles whether any declared non-`none` value is actually matched by a key in the JWKS. 86 87 - **test-oauth-client.AC2.7 Failure:** A native client whose `redirect_uri` scheme does not match the reverse-domain of the `client_id` host produces a `SpecViolation`. 87 88 - **test-oauth-client.AC2.8 Failure:** A `scope` field that does not parse against the atproto permission grammar (<https://atproto.com/specs/permission#scope-string-syntax>) produces a `SpecViolation` with the offending token highlighted via miette source span. The grammar is `<resource>[:<positional>][?<query>]`; all three bracketed components are optional independently, so `repo` (bare), `repo:app.bsky.feed.post` (positional only), `repo?collection=foo` (query only), and `repo:app.bsky.feed.post?action=create` (both) are all valid. The resource name is **not** constrained to a fixed set — the spec states it will expand over time and defines `transition:generic`, `transition:chat.bsky`, and `transition:email` as migration-period resources, so the grammar check only flags genuinely syntactic failures (empty resource, malformed `key=value` query pairs, invalid percent-encoding). Unknown-but-well-formed resource names are accepted. 88 89 - **test-oauth-client.AC2.9 Skip:** Every metadata-document validation check on a loopback target emits `Skipped` with reason `"metadata is implicit for loopback clients"`.
+57
src/commands/test/oauth/client/pipeline/metadata.rs
··· 376 376 /// public / native clients. Any other value — including omitting 377 377 /// the field entirely — is a violation. 378 378 TokenEndpointAuthMethodValid, 379 + /// `token_endpoint_auth_signing_alg`, if present, is not `"none"`. 380 + /// The atproto OAuth profile 381 + /// (<https://atproto.com/specs/oauth#client-metadata>) says 382 + /// explicitly: *"`none` is never allowed here"*. The field is 383 + /// otherwise OPTIONAL overall (the Skipped path here when 384 + /// absent), but a declared value of `"none"` is a hard violation 385 + /// regardless of client kind — the related `HasKeyForSigningAlg` 386 + /// check in the JWKS stage is what decides whether a present 387 + /// non-`none` value is actually usable against the JWKS. 388 + TokenEndpointAuthSigningAlgValid, 379 389 /// A confidential client supplies exactly one of `jwks` or 380 390 /// `jwks_uri`. Confidential clients authenticate to the token 381 391 /// endpoint with `private_key_jwt`, so the AS needs their public ··· 428 438 Check::RedirectUrisShape => "oauth_client::metadata::redirect_uris_shape", 429 439 Check::TokenEndpointAuthMethodValid => { 430 440 "oauth_client::metadata::token_endpoint_auth_method_valid" 441 + } 442 + Check::TokenEndpointAuthSigningAlgValid => { 443 + "oauth_client::metadata::token_endpoint_auth_signing_alg_valid" 431 444 } 432 445 Check::ConfidentialRequiresJwks => "oauth_client::metadata::confidential_requires_jwks", 433 446 Check::PublicForbidsJwks => "oauth_client::metadata::public_forbids_jwks", ··· 456 469 Check::TokenEndpointAuthMethodValid => { 457 470 "`token_endpoint_auth_method` matches client kind" 458 471 } 472 + Check::TokenEndpointAuthSigningAlgValid => { 473 + "`token_endpoint_auth_signing_alg` is not `none`" 474 + } 459 475 Check::ConfidentialRequiresJwks => { 460 476 "Confidential client provides exactly one of `jwks`/`jwks_uri`" 461 477 } ··· 508 524 Check::RedirectUrisPresent, 509 525 Check::RedirectUrisShape, 510 526 Check::TokenEndpointAuthMethodValid, 527 + Check::TokenEndpointAuthSigningAlgValid, 511 528 Check::ConfidentialRequiresJwks, 512 529 Check::PublicForbidsJwks, 513 530 Check::ScopePresent, ··· 811 828 Check::ApplicationTypeKnown.id(), 812 829 )); 813 830 results.push(blocked_by( 831 + Check::TokenEndpointAuthSigningAlgValid.id(), 832 + Stage::OAUTH_CLIENT_METADATA, 833 + Check::TokenEndpointAuthSigningAlgValid.summary(), 834 + Check::ApplicationTypeKnown.id(), 835 + )); 836 + results.push(blocked_by( 814 837 Check::ConfidentialRequiresJwks.id(), 815 838 Stage::OAUTH_CLIENT_METADATA, 816 839 Check::ConfidentialRequiresJwks.summary(), ··· 918 941 Check::TokenEndpointAuthMethodValid 919 942 .spec_violation(Some(diagnostic)), 920 943 ); 944 + } 945 + 946 + // Emit TokenEndpointAuthSigningAlgValid. The 947 + // field is optional overall per the atproto 948 + // OAuth profile, so `None` => Skipped. Any 949 + // present value MUST NOT be the literal 950 + // `"none"` — the spec says "none is never 951 + // allowed here". 952 + match doc.token_endpoint_auth_signing_alg.as_deref() { 953 + None => { 954 + results.push(skipped_with_reason( 955 + Check::TokenEndpointAuthSigningAlgValid.id(), 956 + Stage::OAUTH_CLIENT_METADATA, 957 + Check::TokenEndpointAuthSigningAlgValid.summary(), 958 + "`token_endpoint_auth_signing_alg` not declared", 959 + )); 960 + } 961 + Some("none") => { 962 + let diagnostic: Box<dyn miette::Diagnostic + Send + Sync> = 963 + Box::new(MetadataViolationDiagnostic { 964 + message: 965 + "token_endpoint_auth_signing_alg = \"none\" is never \ 966 + allowed per the atproto OAuth profile" 967 + .to_string(), 968 + code: "oauth_client::metadata::token_endpoint_auth_signing_alg_valid", 969 + }); 970 + results.push( 971 + Check::TokenEndpointAuthSigningAlgValid 972 + .spec_violation(Some(diagnostic)), 973 + ); 974 + } 975 + Some(_) => { 976 + results.push(Check::TokenEndpointAuthSigningAlgValid.pass()); 977 + } 921 978 } 922 979 923 980 // Emit JWKS checks.
+24
tests/fixtures/oauth_client/metadata/signing_alg_none/metadata.json
··· 1 + { 2 + "client_id": "https://client.example.com/metadata.json", 3 + "application_type": "web", 4 + "response_types": ["code"], 5 + "grant_types": ["authorization_code"], 6 + "scope": "atproto", 7 + "redirect_uris": ["https://client.example.com/cb"], 8 + "dpop_bound_access_tokens": true, 9 + "token_endpoint_auth_method": "private_key_jwt", 10 + "token_endpoint_auth_signing_alg": "none", 11 + "jwks": { 12 + "keys": [ 13 + { 14 + "kty": "EC", 15 + "crv": "P-256", 16 + "alg": "ES256", 17 + "use": "sig", 18 + "kid": "k1", 19 + "x": "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU", 20 + "y": "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0" 21 + } 22 + ] 23 + } 24 + }
+2
tests/oauth_client_check_id_coverage.rs
··· 127 127 vec![ 128 128 // Discovery stage diagnostic codes. 129 129 "oauth_client::discovery::metadata_document_fetchable", 130 + "oauth_client::discovery::metadata_content_type_is_json", 130 131 "oauth_client::discovery::metadata_is_json", 131 132 // Metadata stage diagnostic codes. 132 133 "oauth_client::metadata::raw_document_deserializes", ··· 135 136 "oauth_client::metadata::confidential_requires_jwks", 136 137 "oauth_client::metadata::redirect_scheme_reverse_domain_mismatch", 137 138 "oauth_client::metadata::token_endpoint_auth_method_valid", 139 + "oauth_client::metadata::token_endpoint_auth_signing_alg_valid", 138 140 // JWKS stage diagnostic codes. 139 141 "oauth_client::jws::jwks_uri_unreachable", 140 142 "oauth_client::jws::jwks_is_json",
+36
tests/oauth_client_metadata.rs
··· 546 546 insta::assert_snapshot!(rendered); 547 547 } 548 548 549 + /// Per <https://atproto.com/specs/oauth#client-metadata>: 550 + /// "`token_endpoint_auth_signing_alg` … `none` is never allowed here." 551 + /// The metadata stage must flag this as a SpecViolation on 552 + /// `token_endpoint_auth_signing_alg_valid` regardless of what the 553 + /// JWKS looks like. 554 + #[tokio::test] 555 + async fn signing_alg_none_is_spec_violation() { 556 + let http = common::FakeHttpClient::new(); 557 + let metadata = include_bytes!("fixtures/oauth_client/metadata/signing_alg_none/metadata.json"); 558 + http.add_response( 559 + &Url::parse("https://client.example.com/metadata.json").unwrap(), 560 + 200, 561 + metadata.to_vec(), 562 + ); 563 + 564 + let target = target::parse("https://client.example.com/metadata.json").expect("parse failed"); 565 + let jwks_fetcher = common::FakeJwksFetcher::new(); 566 + let opts = OauthClientOptions { 567 + interactive: None, 568 + http: &http, 569 + jwks: &jwks_fetcher, 570 + verbose: false, 571 + clock: Arc::new(RealClock), 572 + }; 573 + 574 + let report = run_pipeline(target, opts).await; 575 + assert_eq!( 576 + report.exit_code(), 577 + 1, 578 + "token_endpoint_auth_signing_alg = `none` must be a SpecViolation" 579 + ); 580 + 581 + let rendered = render_report_to_string(&report); 582 + insta::assert_snapshot!(rendered); 583 + } 584 + 549 585 /// Per the atproto OAuth profile the client-metadata response must be 550 586 /// served with a JSON Content-Type. A `text/html` response — even one 551 587 /// whose body parses as JSON — fails
+2 -1
tests/snapshots/oauth_client_discovery__https_404_produces_network_error.snap
··· 24 24 [SKIP] `redirect_uris` is non-empty — blocked by oauth_client::discovery::metadata_document_fetchable 25 25 [SKIP] Every `redirect_uri` has the right shape for the client kind — blocked by oauth_client::discovery::metadata_document_fetchable 26 26 [SKIP] `token_endpoint_auth_method` matches client kind — blocked by oauth_client::discovery::metadata_document_fetchable 27 + [SKIP] `token_endpoint_auth_signing_alg` is not `none` — blocked by oauth_client::discovery::metadata_document_fetchable 27 28 [SKIP] Confidential client provides exactly one of `jwks`/`jwks_uri` — blocked by oauth_client::discovery::metadata_document_fetchable 28 29 [SKIP] Public/native client does not provide `jwks` or `jwks_uri` — blocked by oauth_client::discovery::metadata_document_fetchable 29 30 [SKIP] `scope` field is present — blocked by oauth_client::discovery::metadata_document_fetchable ··· 38 39 [SKIP] Keys use signing use — blocked by oauth_client::metadata::raw_document_deserializes 39 40 [SKIP] Algorithms are modern EC — blocked by oauth_client::metadata::raw_document_deserializes 40 41 41 - Summary: 1 passed, 0 failed (spec), 1 network errors, 0 advisories, 24 skipped. Exit code: 2 42 + Summary: 1 passed, 0 failed (spec), 1 network errors, 0 advisories, 25 skipped. Exit code: 2
+2 -1
tests/snapshots/oauth_client_discovery__https_confidential_happy_discovery.snap
··· 21 21 [OK] `redirect_uris` is non-empty 22 22 [OK] Every `redirect_uri` has the right shape for the client kind 23 23 [OK] `token_endpoint_auth_method` matches client kind 24 + [OK] `token_endpoint_auth_signing_alg` is not `none` 24 25 [OK] Confidential client provides exactly one of `jwks`/`jwks_uri` 25 26 [OK] `scope` field is present 26 27 [OK] `scope` includes the `atproto` token ··· 34 35 [OK] Keys use signing use 35 36 [OK] Algorithms are modern EC 36 37 37 - Summary: 24 passed, 0 failed (spec), 0 network errors, 0 advisories, 1 skipped. Exit code: 0 38 + Summary: 25 passed, 0 failed (spec), 0 network errors, 0 advisories, 1 skipped. Exit code: 0
+2 -1
tests/snapshots/oauth_client_discovery__https_not_json_produces_spec_violation.snap
··· 28 28 [SKIP] `redirect_uris` is non-empty — blocked by oauth_client::discovery::metadata_document_fetchable 29 29 [SKIP] Every `redirect_uri` has the right shape for the client kind — blocked by oauth_client::discovery::metadata_document_fetchable 30 30 [SKIP] `token_endpoint_auth_method` matches client kind — blocked by oauth_client::discovery::metadata_document_fetchable 31 + [SKIP] `token_endpoint_auth_signing_alg` is not `none` — blocked by oauth_client::discovery::metadata_document_fetchable 31 32 [SKIP] Confidential client provides exactly one of `jwks`/`jwks_uri` — blocked by oauth_client::discovery::metadata_document_fetchable 32 33 [SKIP] Public/native client does not provide `jwks` or `jwks_uri` — blocked by oauth_client::discovery::metadata_document_fetchable 33 34 [SKIP] `scope` field is present — blocked by oauth_client::discovery::metadata_document_fetchable ··· 42 43 [SKIP] Keys use signing use — blocked by oauth_client::metadata::raw_document_deserializes 43 44 [SKIP] Algorithms are modern EC — blocked by oauth_client::metadata::raw_document_deserializes 44 45 45 - Summary: 3 passed, 1 failed (spec), 0 network errors, 0 advisories, 22 skipped. Exit code: 1 46 + Summary: 3 passed, 1 failed (spec), 0 network errors, 0 advisories, 23 skipped. Exit code: 1
+2 -1
tests/snapshots/oauth_client_discovery__https_not_json_with_content_type_produces_spec_violation_with_ct.snap
··· 32 32 [SKIP] `redirect_uris` is non-empty — blocked by oauth_client::discovery::metadata_document_fetchable 33 33 [SKIP] Every `redirect_uri` has the right shape for the client kind — blocked by oauth_client::discovery::metadata_document_fetchable 34 34 [SKIP] `token_endpoint_auth_method` matches client kind — blocked by oauth_client::discovery::metadata_document_fetchable 35 + [SKIP] `token_endpoint_auth_signing_alg` is not `none` — blocked by oauth_client::discovery::metadata_document_fetchable 35 36 [SKIP] Confidential client provides exactly one of `jwks`/`jwks_uri` — blocked by oauth_client::discovery::metadata_document_fetchable 36 37 [SKIP] Public/native client does not provide `jwks` or `jwks_uri` — blocked by oauth_client::discovery::metadata_document_fetchable 37 38 [SKIP] `scope` field is present — blocked by oauth_client::discovery::metadata_document_fetchable ··· 46 47 [SKIP] Keys use signing use — blocked by oauth_client::metadata::raw_document_deserializes 47 48 [SKIP] Algorithms are modern EC — blocked by oauth_client::metadata::raw_document_deserializes 48 49 49 - Summary: 2 passed, 2 failed (spec), 0 network errors, 0 advisories, 22 skipped. Exit code: 1 50 + Summary: 2 passed, 2 failed (spec), 0 network errors, 0 advisories, 23 skipped. Exit code: 1
+2 -1
tests/snapshots/oauth_client_discovery__https_unreachable_produces_network_error.snap
··· 24 24 [SKIP] `redirect_uris` is non-empty — blocked by oauth_client::discovery::metadata_document_fetchable 25 25 [SKIP] Every `redirect_uri` has the right shape for the client kind — blocked by oauth_client::discovery::metadata_document_fetchable 26 26 [SKIP] `token_endpoint_auth_method` matches client kind — blocked by oauth_client::discovery::metadata_document_fetchable 27 + [SKIP] `token_endpoint_auth_signing_alg` is not `none` — blocked by oauth_client::discovery::metadata_document_fetchable 27 28 [SKIP] Confidential client provides exactly one of `jwks`/`jwks_uri` — blocked by oauth_client::discovery::metadata_document_fetchable 28 29 [SKIP] Public/native client does not provide `jwks` or `jwks_uri` — blocked by oauth_client::discovery::metadata_document_fetchable 29 30 [SKIP] `scope` field is present — blocked by oauth_client::discovery::metadata_document_fetchable ··· 38 39 [SKIP] Keys use signing use — blocked by oauth_client::metadata::raw_document_deserializes 39 40 [SKIP] Algorithms are modern EC — blocked by oauth_client::metadata::raw_document_deserializes 40 41 41 - Summary: 1 passed, 0 failed (spec), 1 network errors, 0 advisories, 24 skipped. Exit code: 2 42 + Summary: 1 passed, 0 failed (spec), 1 network errors, 0 advisories, 25 skipped. Exit code: 2
+2 -1
tests/snapshots/oauth_client_discovery__loopback_127_0_0_1.snap
··· 21 21 [SKIP] `redirect_uris` is non-empty — metadata is implicit for loopback clients 22 22 [SKIP] Every `redirect_uri` has the right shape for the client kind — metadata is implicit for loopback clients 23 23 [SKIP] `token_endpoint_auth_method` matches client kind — metadata is implicit for loopback clients 24 + [SKIP] `token_endpoint_auth_signing_alg` is not `none` — metadata is implicit for loopback clients 24 25 [SKIP] Confidential client provides exactly one of `jwks`/`jwks_uri` — metadata is implicit for loopback clients 25 26 [SKIP] Public/native client does not provide `jwks` or `jwks_uri` — metadata is implicit for loopback clients 26 27 [SKIP] `scope` field is present — metadata is implicit for loopback clients ··· 35 36 [SKIP] Keys use signing use — jwks not applicable to loopback clients 36 37 [SKIP] Algorithms are modern EC — jwks not applicable to loopback clients 37 38 38 - Summary: 1 passed, 0 failed (spec), 0 network errors, 0 advisories, 25 skipped. Exit code: 0 39 + Summary: 1 passed, 0 failed (spec), 0 network errors, 0 advisories, 26 skipped. Exit code: 0
+2 -1
tests/snapshots/oauth_client_discovery__loopback_root_produces_skip_rows.snap
··· 21 21 [SKIP] `redirect_uris` is non-empty — metadata is implicit for loopback clients 22 22 [SKIP] Every `redirect_uri` has the right shape for the client kind — metadata is implicit for loopback clients 23 23 [SKIP] `token_endpoint_auth_method` matches client kind — metadata is implicit for loopback clients 24 + [SKIP] `token_endpoint_auth_signing_alg` is not `none` — metadata is implicit for loopback clients 24 25 [SKIP] Confidential client provides exactly one of `jwks`/`jwks_uri` — metadata is implicit for loopback clients 25 26 [SKIP] Public/native client does not provide `jwks` or `jwks_uri` — metadata is implicit for loopback clients 26 27 [SKIP] `scope` field is present — metadata is implicit for loopback clients ··· 35 36 [SKIP] Keys use signing use — jwks not applicable to loopback clients 36 37 [SKIP] Algorithms are modern EC — jwks not applicable to loopback clients 37 38 38 - Summary: 1 passed, 0 failed (spec), 0 network errors, 0 advisories, 25 skipped. Exit code: 0 39 + Summary: 1 passed, 0 failed (spec), 0 network errors, 0 advisories, 26 skipped. Exit code: 0
+2 -1
tests/snapshots/oauth_client_discovery__loopback_with_port_produces_same_skip_rows.snap
··· 21 21 [SKIP] `redirect_uris` is non-empty — metadata is implicit for loopback clients 22 22 [SKIP] Every `redirect_uri` has the right shape for the client kind — metadata is implicit for loopback clients 23 23 [SKIP] `token_endpoint_auth_method` matches client kind — metadata is implicit for loopback clients 24 + [SKIP] `token_endpoint_auth_signing_alg` is not `none` — metadata is implicit for loopback clients 24 25 [SKIP] Confidential client provides exactly one of `jwks`/`jwks_uri` — metadata is implicit for loopback clients 25 26 [SKIP] Public/native client does not provide `jwks` or `jwks_uri` — metadata is implicit for loopback clients 26 27 [SKIP] `scope` field is present — metadata is implicit for loopback clients ··· 35 36 [SKIP] Keys use signing use — jwks not applicable to loopback clients 36 37 [SKIP] Algorithms are modern EC — jwks not applicable to loopback clients 37 38 38 - Summary: 1 passed, 0 failed (spec), 0 network errors, 0 advisories, 25 skipped. Exit code: 0 39 + Summary: 1 passed, 0 failed (spec), 0 network errors, 0 advisories, 26 skipped. Exit code: 0
+2 -1
tests/snapshots/oauth_client_endtoend__full_pipeline_all_pass.snap
··· 21 21 [OK] `redirect_uris` is non-empty 22 22 [OK] Every `redirect_uri` has the right shape for the client kind 23 23 [OK] `token_endpoint_auth_method` matches client kind 24 + [OK] `token_endpoint_auth_signing_alg` is not `none` 24 25 [OK] Confidential client provides exactly one of `jwks`/`jwks_uri` 25 26 [OK] `scope` field is present 26 27 [OK] `scope` includes the `atproto` token ··· 34 35 [OK] Keys use signing use 35 36 [OK] Algorithms are modern EC 36 37 37 - Summary: 24 passed, 0 failed (spec), 0 network errors, 0 advisories, 1 skipped. Exit code: 0 38 + Summary: 25 passed, 0 failed (spec), 0 network errors, 0 advisories, 1 skipped. Exit code: 0
+2 -1
tests/snapshots/oauth_client_jwks__discovery_failure_blocks_jwks.snap
··· 24 24 [SKIP] `redirect_uris` is non-empty — blocked by oauth_client::discovery::metadata_document_fetchable 25 25 [SKIP] Every `redirect_uri` has the right shape for the client kind — blocked by oauth_client::discovery::metadata_document_fetchable 26 26 [SKIP] `token_endpoint_auth_method` matches client kind — blocked by oauth_client::discovery::metadata_document_fetchable 27 + [SKIP] `token_endpoint_auth_signing_alg` is not `none` — blocked by oauth_client::discovery::metadata_document_fetchable 27 28 [SKIP] Confidential client provides exactly one of `jwks`/`jwks_uri` — blocked by oauth_client::discovery::metadata_document_fetchable 28 29 [SKIP] Public/native client does not provide `jwks` or `jwks_uri` — blocked by oauth_client::discovery::metadata_document_fetchable 29 30 [SKIP] `scope` field is present — blocked by oauth_client::discovery::metadata_document_fetchable ··· 38 39 [SKIP] Keys use signing use — blocked by oauth_client::metadata::raw_document_deserializes 39 40 [SKIP] Algorithms are modern EC — blocked by oauth_client::metadata::raw_document_deserializes 40 41 41 - Summary: 1 passed, 0 failed (spec), 1 network errors, 0 advisories, 24 skipped. Exit code: 2 42 + Summary: 1 passed, 0 failed (spec), 1 network errors, 0 advisories, 25 skipped. Exit code: 2
+2 -1
tests/snapshots/oauth_client_jwks__duplicate_kids_produces_spec_violation.snap
··· 21 21 [OK] `redirect_uris` is non-empty 22 22 [OK] Every `redirect_uri` has the right shape for the client kind 23 23 [OK] `token_endpoint_auth_method` matches client kind 24 + [OK] `token_endpoint_auth_signing_alg` is not `none` 24 25 [OK] Confidential client provides exactly one of `jwks`/`jwks_uri` 25 26 [OK] `scope` field is present 26 27 [OK] `scope` includes the `atproto` token ··· 43 44 [OK] Keys use signing use 44 45 [OK] Algorithms are modern EC 45 46 46 - Summary: 23 passed, 1 failed (spec), 0 network errors, 0 advisories, 1 skipped. Exit code: 1 47 + Summary: 24 passed, 1 failed (spec), 0 network errors, 0 advisories, 1 skipped. Exit code: 1
+2 -1
tests/snapshots/oauth_client_jwks__inline_es256_happy_jwks_passes.snap
··· 21 21 [OK] `redirect_uris` is non-empty 22 22 [OK] Every `redirect_uri` has the right shape for the client kind 23 23 [OK] `token_endpoint_auth_method` matches client kind 24 + [OK] `token_endpoint_auth_signing_alg` is not `none` 24 25 [OK] Confidential client provides exactly one of `jwks`/`jwks_uri` 25 26 [OK] `scope` field is present 26 27 [OK] `scope` includes the `atproto` token ··· 34 35 [OK] Keys use signing use 35 36 [OK] Algorithms are modern EC 36 37 37 - Summary: 24 passed, 0 failed (spec), 0 network errors, 0 advisories, 1 skipped. Exit code: 0 38 + Summary: 25 passed, 0 failed (spec), 0 network errors, 0 advisories, 1 skipped. Exit code: 0
+2 -1
tests/snapshots/oauth_client_jwks__loopback_skips_all_jwks.snap
··· 21 21 [SKIP] `redirect_uris` is non-empty — metadata is implicit for loopback clients 22 22 [SKIP] Every `redirect_uri` has the right shape for the client kind — metadata is implicit for loopback clients 23 23 [SKIP] `token_endpoint_auth_method` matches client kind — metadata is implicit for loopback clients 24 + [SKIP] `token_endpoint_auth_signing_alg` is not `none` — metadata is implicit for loopback clients 24 25 [SKIP] Confidential client provides exactly one of `jwks`/`jwks_uri` — metadata is implicit for loopback clients 25 26 [SKIP] Public/native client does not provide `jwks` or `jwks_uri` — metadata is implicit for loopback clients 26 27 [SKIP] `scope` field is present — metadata is implicit for loopback clients ··· 35 36 [SKIP] Keys use signing use — jwks not applicable to loopback clients 36 37 [SKIP] Algorithms are modern EC — jwks not applicable to loopback clients 37 38 38 - Summary: 1 passed, 0 failed (spec), 0 network errors, 0 advisories, 25 skipped. Exit code: 0 39 + Summary: 1 passed, 0 failed (spec), 0 network errors, 0 advisories, 26 skipped. Exit code: 0
+2 -1
tests/snapshots/oauth_client_jwks__public_client_skips_all_jwks.snap
··· 21 21 [OK] `redirect_uris` is non-empty 22 22 [OK] Every `redirect_uri` has the right shape for the client kind 23 23 [OK] `token_endpoint_auth_method` matches client kind 24 + [SKIP] `token_endpoint_auth_signing_alg` is not `none` — `token_endpoint_auth_signing_alg` not declared 24 25 [OK] Public/native client does not provide `jwks` or `jwks_uri` 25 26 [OK] `scope` field is present 26 27 [OK] `scope` includes the `atproto` token ··· 34 35 [SKIP] Keys use signing use — jwks not required for public clients 35 36 [SKIP] Algorithms are modern EC — jwks not required for public clients 36 37 37 - Summary: 18 passed, 0 failed (spec), 0 network errors, 0 advisories, 7 skipped. Exit code: 0 38 + Summary: 18 passed, 0 failed (spec), 0 network errors, 0 advisories, 8 skipped. Exit code: 0
+2 -1
tests/snapshots/oauth_client_jwks__signing_alg_has_no_compatible_key_produces_spec_violation.snap
··· 21 21 [OK] `redirect_uris` is non-empty 22 22 [OK] Every `redirect_uri` has the right shape for the client kind 23 23 [OK] `token_endpoint_auth_method` matches client kind 24 + [OK] `token_endpoint_auth_signing_alg` is not `none` 24 25 [OK] Confidential client provides exactly one of `jwks`/`jwks_uri` 25 26 [OK] `scope` field is present 26 27 [OK] `scope` includes the `atproto` token ··· 37 38 [OK] Keys use signing use 38 39 [OK] Algorithms are modern EC 39 40 40 - Summary: 23 passed, 1 failed (spec), 0 network errors, 0 advisories, 1 skipped. Exit code: 1 41 + Summary: 24 passed, 1 failed (spec), 0 network errors, 0 advisories, 1 skipped. Exit code: 1
+2 -1
tests/snapshots/oauth_client_jwks__uri_es256_happy_jwks_passes.snap
··· 21 21 [OK] `redirect_uris` is non-empty 22 22 [OK] Every `redirect_uri` has the right shape for the client kind 23 23 [OK] `token_endpoint_auth_method` matches client kind 24 + [OK] `token_endpoint_auth_signing_alg` is not `none` 24 25 [OK] Confidential client provides exactly one of `jwks`/`jwks_uri` 25 26 [OK] `scope` field is present 26 27 [OK] `scope` includes the `atproto` token ··· 34 35 [OK] Keys use signing use 35 36 [OK] Algorithms are modern EC 36 37 37 - Summary: 25 passed, 0 failed (spec), 0 network errors, 0 advisories, 0 skipped. Exit code: 0 38 + Summary: 26 passed, 0 failed (spec), 0 network errors, 0 advisories, 0 skipped. Exit code: 0
+2 -1
tests/snapshots/oauth_client_jwks__uri_invalid_json_produces_spec_violation.snap
··· 21 21 [OK] `redirect_uris` is non-empty 22 22 [OK] Every `redirect_uri` has the right shape for the client kind 23 23 [OK] `token_endpoint_auth_method` matches client kind 24 + [OK] `token_endpoint_auth_signing_alg` is not `none` 24 25 [OK] Confidential client provides exactly one of `jwks`/`jwks_uri` 25 26 [OK] `scope` field is present 26 27 [OK] `scope` includes the `atproto` token ··· 37 38 [SKIP] Keys use signing use — blocked by oauth_client::jws::jwks_is_json 38 39 [SKIP] Algorithms are modern EC — blocked by oauth_client::jws::jwks_is_json 39 40 40 - Summary: 20 passed, 1 failed (spec), 0 network errors, 0 advisories, 4 skipped. Exit code: 1 41 + Summary: 21 passed, 1 failed (spec), 0 network errors, 0 advisories, 4 skipped. Exit code: 1
+2 -1
tests/snapshots/oauth_client_jwks__uri_returns_404_produces_network_error.snap
··· 21 21 [OK] `redirect_uris` is non-empty 22 22 [OK] Every `redirect_uri` has the right shape for the client kind 23 23 [OK] `token_endpoint_auth_method` matches client kind 24 + [OK] `token_endpoint_auth_signing_alg` is not `none` 24 25 [OK] Confidential client provides exactly one of `jwks`/`jwks_uri` 25 26 [OK] `scope` field is present 26 27 [OK] `scope` includes the `atproto` token ··· 37 38 [SKIP] Keys use signing use — blocked by oauth_client::jws::jwks_uri_fetchable 38 39 [SKIP] Algorithms are modern EC — blocked by oauth_client::jws::jwks_uri_fetchable 39 40 40 - Summary: 19 passed, 0 failed (spec), 1 network errors, 0 advisories, 5 skipped. Exit code: 2 41 + Summary: 20 passed, 0 failed (spec), 1 network errors, 0 advisories, 5 skipped. Exit code: 2
+2 -1
tests/snapshots/oauth_client_jwks__uri_unreachable_produces_network_error.snap
··· 21 21 [OK] `redirect_uris` is non-empty 22 22 [OK] Every `redirect_uri` has the right shape for the client kind 23 23 [OK] `token_endpoint_auth_method` matches client kind 24 + [OK] `token_endpoint_auth_signing_alg` is not `none` 24 25 [OK] Confidential client provides exactly one of `jwks`/`jwks_uri` 25 26 [OK] `scope` field is present 26 27 [OK] `scope` includes the `atproto` token ··· 37 38 [SKIP] Keys use signing use — blocked by oauth_client::jws::jwks_uri_fetchable 38 39 [SKIP] Algorithms are modern EC — blocked by oauth_client::jws::jwks_uri_fetchable 39 40 40 - Summary: 19 passed, 0 failed (spec), 1 network errors, 0 advisories, 5 skipped. Exit code: 2 41 + Summary: 20 passed, 0 failed (spec), 1 network errors, 0 advisories, 5 skipped. Exit code: 2
+2 -1
tests/snapshots/oauth_client_jwks__weak_alg_rs1_produces_spec_violation.snap
··· 21 21 [OK] `redirect_uris` is non-empty 22 22 [OK] Every `redirect_uri` has the right shape for the client kind 23 23 [OK] `token_endpoint_auth_method` matches client kind 24 + [OK] `token_endpoint_auth_signing_alg` is not `none` 24 25 [OK] Confidential client provides exactly one of `jwks`/`jwks_uri` 25 26 [OK] `scope` field is present 26 27 [OK] `scope` includes the `atproto` token ··· 40 41 41 42 × One or more keys declare non-modern algorithms 42 43 43 - Summary: 22 passed, 2 failed (spec), 0 network errors, 0 advisories, 1 skipped. Exit code: 1 44 + Summary: 23 passed, 2 failed (spec), 0 network errors, 0 advisories, 1 skipped. Exit code: 1
+2 -1
tests/snapshots/oauth_client_jwks__wrong_use_produces_spec_violation.snap
··· 21 21 [OK] `redirect_uris` is non-empty 22 22 [OK] Every `redirect_uri` has the right shape for the client kind 23 23 [OK] `token_endpoint_auth_method` matches client kind 24 + [OK] `token_endpoint_auth_signing_alg` is not `none` 24 25 [OK] Confidential client provides exactly one of `jwks`/`jwks_uri` 25 26 [OK] `scope` field is present 26 27 [OK] `scope` includes the `atproto` token ··· 37 38 × One or more keys have `use` other than `sig` 38 39 [OK] Algorithms are modern EC 39 40 40 - Summary: 23 passed, 1 failed (spec), 0 network errors, 0 advisories, 1 skipped. Exit code: 1 41 + Summary: 24 passed, 1 failed (spec), 0 network errors, 0 advisories, 1 skipped. Exit code: 1
+2 -1
tests/snapshots/oauth_client_metadata__application_type_omitted_defaults_to_web.snap
··· 21 21 [OK] `redirect_uris` is non-empty 22 22 [OK] Every `redirect_uri` has the right shape for the client kind 23 23 [OK] `token_endpoint_auth_method` matches client kind 24 + [SKIP] `token_endpoint_auth_signing_alg` is not `none` — `token_endpoint_auth_signing_alg` not declared 24 25 [OK] Public/native client does not provide `jwks` or `jwks_uri` 25 26 [OK] `scope` field is present 26 27 [OK] `scope` includes the `atproto` token ··· 34 35 [SKIP] Keys use signing use — jwks not required for public clients 35 36 [SKIP] Algorithms are modern EC — jwks not required for public clients 36 37 37 - Summary: 17 passed, 0 failed (spec), 0 network errors, 0 advisories, 8 skipped. Exit code: 0 38 + Summary: 17 passed, 0 failed (spec), 0 network errors, 0 advisories, 9 skipped. Exit code: 0
+2 -1
tests/snapshots/oauth_client_metadata__confidential_happy.snap
··· 21 21 [OK] `redirect_uris` is non-empty 22 22 [OK] Every `redirect_uri` has the right shape for the client kind 23 23 [OK] `token_endpoint_auth_method` matches client kind 24 + [OK] `token_endpoint_auth_signing_alg` is not `none` 24 25 [OK] Confidential client provides exactly one of `jwks`/`jwks_uri` 25 26 [OK] `scope` field is present 26 27 [OK] `scope` includes the `atproto` token ··· 34 35 [OK] Keys use signing use 35 36 [OK] Algorithms are modern EC 36 37 37 - Summary: 24 passed, 0 failed (spec), 0 network errors, 0 advisories, 1 skipped. Exit code: 0 38 + Summary: 25 passed, 0 failed (spec), 0 network errors, 0 advisories, 1 skipped. Exit code: 0
+2 -1
tests/snapshots/oauth_client_metadata__confidential_missing_jwks.snap
··· 21 21 [OK] `redirect_uris` is non-empty 22 22 [OK] Every `redirect_uri` has the right shape for the client kind 23 23 [OK] `token_endpoint_auth_method` matches client kind 24 + [OK] `token_endpoint_auth_signing_alg` is not `none` 24 25 [FAIL] Confidential client provides exactly one of `jwks`/`jwks_uri` 25 26 oauth_client::metadata::confidential_requires_jwks 26 27 ··· 37 38 [SKIP] Keys use signing use — blocked by oauth_client::metadata::confidential_requires_jwks 38 39 [SKIP] Algorithms are modern EC — blocked by oauth_client::metadata::confidential_requires_jwks 39 40 40 - Summary: 17 passed, 1 failed (spec), 0 network errors, 0 advisories, 7 skipped. Exit code: 1 41 + Summary: 18 passed, 1 failed (spec), 0 network errors, 0 advisories, 7 skipped. Exit code: 1
+2 -1
tests/snapshots/oauth_client_metadata__discovery_failure_blocks_metadata.snap
··· 24 24 [SKIP] `redirect_uris` is non-empty — blocked by oauth_client::discovery::metadata_document_fetchable 25 25 [SKIP] Every `redirect_uri` has the right shape for the client kind — blocked by oauth_client::discovery::metadata_document_fetchable 26 26 [SKIP] `token_endpoint_auth_method` matches client kind — blocked by oauth_client::discovery::metadata_document_fetchable 27 + [SKIP] `token_endpoint_auth_signing_alg` is not `none` — blocked by oauth_client::discovery::metadata_document_fetchable 27 28 [SKIP] Confidential client provides exactly one of `jwks`/`jwks_uri` — blocked by oauth_client::discovery::metadata_document_fetchable 28 29 [SKIP] Public/native client does not provide `jwks` or `jwks_uri` — blocked by oauth_client::discovery::metadata_document_fetchable 29 30 [SKIP] `scope` field is present — blocked by oauth_client::discovery::metadata_document_fetchable ··· 38 39 [SKIP] Keys use signing use — blocked by oauth_client::metadata::raw_document_deserializes 39 40 [SKIP] Algorithms are modern EC — blocked by oauth_client::metadata::raw_document_deserializes 40 41 41 - Summary: 1 passed, 0 failed (spec), 1 network errors, 0 advisories, 24 skipped. Exit code: 2 42 + Summary: 1 passed, 0 failed (spec), 1 network errors, 0 advisories, 25 skipped. Exit code: 2
+2 -1
tests/snapshots/oauth_client_metadata__dpop_bound_false.snap
··· 24 24 [OK] `redirect_uris` is non-empty 25 25 [OK] Every `redirect_uri` has the right shape for the client kind 26 26 [OK] `token_endpoint_auth_method` matches client kind 27 + [OK] `token_endpoint_auth_signing_alg` is not `none` 27 28 [OK] Confidential client provides exactly one of `jwks`/`jwks_uri` 28 29 [OK] `scope` field is present 29 30 [OK] `scope` includes the `atproto` token ··· 37 38 [OK] Keys use signing use 38 39 [OK] Algorithms are modern EC 39 40 40 - Summary: 23 passed, 1 failed (spec), 0 network errors, 0 advisories, 1 skipped. Exit code: 1 41 + Summary: 24 passed, 1 failed (spec), 0 network errors, 0 advisories, 1 skipped. Exit code: 1
+2 -1
tests/snapshots/oauth_client_metadata__loopback_skips_all_metadata_checks.snap
··· 21 21 [SKIP] `redirect_uris` is non-empty — metadata is implicit for loopback clients 22 22 [SKIP] Every `redirect_uri` has the right shape for the client kind — metadata is implicit for loopback clients 23 23 [SKIP] `token_endpoint_auth_method` matches client kind — metadata is implicit for loopback clients 24 + [SKIP] `token_endpoint_auth_signing_alg` is not `none` — metadata is implicit for loopback clients 24 25 [SKIP] Confidential client provides exactly one of `jwks`/`jwks_uri` — metadata is implicit for loopback clients 25 26 [SKIP] Public/native client does not provide `jwks` or `jwks_uri` — metadata is implicit for loopback clients 26 27 [SKIP] `scope` field is present — metadata is implicit for loopback clients ··· 35 36 [SKIP] Keys use signing use — jwks not applicable to loopback clients 36 37 [SKIP] Algorithms are modern EC — jwks not applicable to loopback clients 37 38 38 - Summary: 1 passed, 0 failed (spec), 0 network errors, 0 advisories, 25 skipped. Exit code: 0 39 + Summary: 1 passed, 0 failed (spec), 0 network errors, 0 advisories, 26 skipped. Exit code: 0
+2 -1
tests/snapshots/oauth_client_metadata__metadata_non_200_2xx_is_spec_violation.snap
··· 25 25 [SKIP] `redirect_uris` is non-empty — blocked by oauth_client::discovery::metadata_document_fetchable 26 26 [SKIP] Every `redirect_uri` has the right shape for the client kind — blocked by oauth_client::discovery::metadata_document_fetchable 27 27 [SKIP] `token_endpoint_auth_method` matches client kind — blocked by oauth_client::discovery::metadata_document_fetchable 28 + [SKIP] `token_endpoint_auth_signing_alg` is not `none` — blocked by oauth_client::discovery::metadata_document_fetchable 28 29 [SKIP] Confidential client provides exactly one of `jwks`/`jwks_uri` — blocked by oauth_client::discovery::metadata_document_fetchable 29 30 [SKIP] Public/native client does not provide `jwks` or `jwks_uri` — blocked by oauth_client::discovery::metadata_document_fetchable 30 31 [SKIP] `scope` field is present — blocked by oauth_client::discovery::metadata_document_fetchable ··· 39 40 [SKIP] Keys use signing use — blocked by oauth_client::metadata::raw_document_deserializes 40 41 [SKIP] Algorithms are modern EC — blocked by oauth_client::metadata::raw_document_deserializes 41 42 42 - Summary: 1 passed, 1 failed (spec), 0 network errors, 0 advisories, 24 skipped. Exit code: 1 43 + Summary: 1 passed, 1 failed (spec), 0 network errors, 0 advisories, 25 skipped. Exit code: 1
+2 -1
tests/snapshots/oauth_client_metadata__metadata_non_json_content_type_is_spec_violation.snap
··· 25 25 [OK] `redirect_uris` is non-empty 26 26 [OK] Every `redirect_uri` has the right shape for the client kind 27 27 [OK] `token_endpoint_auth_method` matches client kind 28 + [OK] `token_endpoint_auth_signing_alg` is not `none` 28 29 [OK] Confidential client provides exactly one of `jwks`/`jwks_uri` 29 30 [OK] `scope` field is present 30 31 [OK] `scope` includes the `atproto` token ··· 38 39 [OK] Keys use signing use 39 40 [OK] Algorithms are modern EC 40 41 41 - Summary: 23 passed, 1 failed (spec), 0 network errors, 0 advisories, 1 skipped. Exit code: 1 42 + Summary: 24 passed, 1 failed (spec), 0 network errors, 0 advisories, 1 skipped. Exit code: 1
+2 -1
tests/snapshots/oauth_client_metadata__native_happy.snap
··· 21 21 [OK] `redirect_uris` is non-empty 22 22 [OK] Every `redirect_uri` has the right shape for the client kind 23 23 [OK] `token_endpoint_auth_method` matches client kind 24 + [SKIP] `token_endpoint_auth_signing_alg` is not `none` — `token_endpoint_auth_signing_alg` not declared 24 25 [OK] Public/native client does not provide `jwks` or `jwks_uri` 25 26 [OK] `scope` field is present 26 27 [OK] `scope` includes the `atproto` token ··· 34 35 [SKIP] Keys use signing use — jwks not required for native clients 35 36 [SKIP] Algorithms are modern EC — jwks not required for native clients 36 37 37 - Summary: 18 passed, 0 failed (spec), 0 network errors, 0 advisories, 7 skipped. Exit code: 0 38 + Summary: 18 passed, 0 failed (spec), 0 network errors, 0 advisories, 8 skipped. Exit code: 0
+2 -1
tests/snapshots/oauth_client_metadata__native_redirect_scheme_mismatch.snap
··· 24 24 25 25 × native redirect_uri scheme does not match reverse-domain of client_id host 26 26 [OK] `token_endpoint_auth_method` matches client kind 27 + [SKIP] `token_endpoint_auth_signing_alg` is not `none` — `token_endpoint_auth_signing_alg` not declared 27 28 [OK] Public/native client does not provide `jwks` or `jwks_uri` 28 29 [OK] `scope` field is present 29 30 [OK] `scope` includes the `atproto` token ··· 37 38 [SKIP] Keys use signing use — jwks not required for native clients 38 39 [SKIP] Algorithms are modern EC — jwks not required for native clients 39 40 40 - Summary: 17 passed, 1 failed (spec), 0 network errors, 0 advisories, 7 skipped. Exit code: 1 41 + Summary: 17 passed, 1 failed (spec), 0 network errors, 0 advisories, 8 skipped. Exit code: 1
+2 -1
tests/snapshots/oauth_client_metadata__public_happy.snap
··· 21 21 [OK] `redirect_uris` is non-empty 22 22 [OK] Every `redirect_uri` has the right shape for the client kind 23 23 [OK] `token_endpoint_auth_method` matches client kind 24 + [SKIP] `token_endpoint_auth_signing_alg` is not `none` — `token_endpoint_auth_signing_alg` not declared 24 25 [OK] Public/native client does not provide `jwks` or `jwks_uri` 25 26 [OK] `scope` field is present 26 27 [OK] `scope` includes the `atproto` token ··· 34 35 [SKIP] Keys use signing use — jwks not required for public clients 35 36 [SKIP] Algorithms are modern EC — jwks not required for public clients 36 37 37 - Summary: 18 passed, 0 failed (spec), 0 network errors, 0 advisories, 7 skipped. Exit code: 0 38 + Summary: 18 passed, 0 failed (spec), 0 network errors, 0 advisories, 8 skipped. Exit code: 0
+2 -1
tests/snapshots/oauth_client_metadata__public_with_token_endpoint_auth.snap
··· 24 24 oauth_client::metadata::token_endpoint_auth_method_valid 25 25 26 26 × token_endpoint_auth_method does not match client kind 27 + [SKIP] `token_endpoint_auth_signing_alg` is not `none` — `token_endpoint_auth_signing_alg` not declared 27 28 [OK] Public/native client does not provide `jwks` or `jwks_uri` 28 29 [OK] `scope` field is present 29 30 [OK] `scope` includes the `atproto` token ··· 37 38 [SKIP] Keys use signing use — jwks not required for public clients 38 39 [SKIP] Algorithms are modern EC — jwks not required for public clients 39 40 40 - Summary: 17 passed, 1 failed (spec), 0 network errors, 0 advisories, 7 skipped. Exit code: 1 41 + Summary: 17 passed, 1 failed (spec), 0 network errors, 0 advisories, 8 skipped. Exit code: 1
+2 -1
tests/snapshots/oauth_client_metadata__scope_grammar_invalid.snap
··· 21 21 [OK] `redirect_uris` is non-empty 22 22 [OK] Every `redirect_uri` has the right shape for the client kind 23 23 [OK] `token_endpoint_auth_method` matches client kind 24 + [OK] `token_endpoint_auth_signing_alg` is not `none` 24 25 [OK] Confidential client provides exactly one of `jwks`/`jwks_uri` 25 26 [OK] `scope` field is present 26 27 [SKIP] `scope` includes the `atproto` token — blocked by oauth_client::metadata::scope_grammar ··· 44 45 [OK] Keys use signing use 45 46 [OK] Algorithms are modern EC 46 47 47 - Summary: 22 passed, 1 failed (spec), 0 network errors, 0 advisories, 2 skipped. Exit code: 1 48 + Summary: 23 passed, 1 failed (spec), 0 network errors, 0 advisories, 2 skipped. Exit code: 1
+44
tests/snapshots/oauth_client_metadata__signing_alg_none_is_spec_violation.snap
··· 1 + --- 2 + source: tests/oauth_client_metadata.rs 3 + expression: rendered 4 + --- 5 + Target: https://client.example.com/metadata.json 6 + elapsed: XXms 7 + 8 + == Discovery == 9 + [OK] Client ID well-formed 10 + [OK] Metadata document fetchable 11 + [OK] Metadata Content-Type is JSON 12 + [OK] Metadata is valid JSON 13 + == Metadata == 14 + [OK] Metadata document deserializes 15 + [OK] Metadata `client_id` matches fetched URL 16 + [OK] `application_type` field is present 17 + [OK] `application_type` is `web` or `native` 18 + [OK] `response_types` includes `code` 19 + [OK] `grant_types` includes `authorization_code` 20 + [OK] `dpop_bound_access_tokens` is `true` 21 + [OK] `redirect_uris` is non-empty 22 + [OK] Every `redirect_uri` has the right shape for the client kind 23 + [OK] `token_endpoint_auth_method` matches client kind 24 + [FAIL] `token_endpoint_auth_signing_alg` is not `none` 25 + oauth_client::metadata::token_endpoint_auth_signing_alg_valid 26 + 27 + × token_endpoint_auth_signing_alg = "none" is never allowed per the atproto OAuth profile 28 + [OK] Confidential client provides exactly one of `jwks`/`jwks_uri` 29 + [OK] `scope` field is present 30 + [OK] `scope` includes the `atproto` token 31 + [OK] `scope` parses against the atproto permission grammar 32 + == JWKS == 33 + [OK] JWKS is present 34 + [SKIP] JWKS URI is fetchable — jwks is inline 35 + [OK] JWKS is valid JSON 36 + [OK] Keys have unique kid values 37 + [FAIL] JWKS contains a key compatible with `token_endpoint_auth_signing_alg` 38 + oauth_client::jws::has_key_for_signing_alg 39 + 40 + × no key in the JWKS is compatible with `token_endpoint_auth_signing_alg = none` 41 + [OK] Keys use signing use 42 + [OK] Algorithms are modern EC 43 + 44 + Summary: 23 passed, 2 failed (spec), 0 network errors, 0 advisories, 1 skipped. Exit code: 1