Skip to content

TC-1500: fixed DID method allow-list for UCAN resolution - #392

Draft
samgbafa wants to merge 19 commits into
mainfrom
skgbafa/tc-1500-did-allow-list
Draft

samgbafa wants to merge 19 commits into
mainfrom
skgbafa/tc-1500-did-allow-list

Conversation

@samgbafa

@samgbafa samgbafa commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • UCAN DID resolution accepts one fixed method allow-list: did:key, did:pkh and did:jwk.
  • did:key must be an Ed25519 key with the exact Ed25519 identifier length. did:pkh must use the eip155 namespace, with an identifier of at most 70 characters. did:jwk must be an Ed25519 OKP JWK.
  • Any other method, namespace or key type is refused before any resolver lookup, at every UCAN verification and DID resolution site.
  • EIP-191 issuers are parsed as did:pkh:eip155 before signature recovery.
  • Signature primitives are pinned to a reviewed list of call sites by a source guard test.

Compatibility

  • did:web, did:tz, did:ethr, did:ion and unknown methods are refused on the UCAN path regardless of configuration, including network_methods = true.
  • did:jwk is admitted only as an Ed25519 OKP key. Other did:jwk key types are refused, matching the did:key rule.
  • did:key identifiers of any length other than the Ed25519 length, and did:pkh identifiers longer than 70 characters, are refused.
  • Stored delegator DIDs that do not match did:key:z6Mk%, did:pkh:eip155:% or did:jwk:% are affected. Query before deploying.
  • [global.did_resolution] network_methods and TINYCLOUD_DID_RESOLUTION__NETWORK_METHODS have no effect. Configuration files that set them parse, and a startup warning is logged when the key is present.
  • GET /info reports did_resolution.network_methods as a constant false.
  • Refusals use the did_method_disabled error code and method_disabled reason. Identity-string parsing in tinycloud-auth is outside this change.

Tests

  • tinycloud-core/tests/did_resolution_policy.rs: a table test over the resolution sites with a counting resolver. Refused DIDs produce zero lookups at every site; allowed DIDs reach the lookup exactly once.
  • tinycloud-node-server/tests/did_resolution_single_entry.rs: a source guard. It pins signature primitives to a reviewed list of call sites and fails on any new site outside that list. It does not cover generic .verify( calls.
  • tinycloud-node-server/tests/did_resolution_app_startup.rs: a real app started with the ignored environment key set does not enable any method outside the allow-list.
  • config.rs: the ignored key is detected for any value and is never written back (retired_did_resolution_network_methods_is_detected_for_any_value_and_never_written_back).
  • runtime.rs: the ignored key set through TINYCLOUD_DID_RESOLUTION__NETWORK_METHODS is detected in the configuration the node builds from its environment.

Verification

At this head, on SQLite: cargo fmt --all -- --check; cargo clippy --workspace --all-targets and cargo clippy -p tinycloud-core --features duckdb --all-targets, both with RUSTFLAGS=-Dwarnings; node scripts/gen-capabilities.mjs --check; and every test binary of tinycloud-core, tinycloud-node and tinycloud-auth pass, except the three startup_identity cases (the host has a dstack socket, so the node binary refuses to create an identity) and the three account_alias_tests, which time out when other jobs share the host and pass when the tinycloud-node lib tests run alone. did_resolution_policy (9) and did_resolution_single_entry (12) pass. PostgreSQL-backed tests run in CI.

Details: TC-1500

Naomi added 2 commits October 20, 2026 22:18
Replace the network_methods gate with a fixed allow-list: did:key, did:pkh and did:jwk. Refuse every other method, did:pkh outside the eip155 namespace, and did:key outside Ed25519, before any resolver lookup at each UCAN verification and DID resolution site. Remove the network_methods configuration logic. DidResolutionConfig stays as an empty section so existing configuration files still parse; the /info field is a constant false.

Tests: a table test over the resolution sites with a counting resolver proves refusal with zero lookups; an app-startup test checks that the retired environment variable does not enable any method.
Changelog, README, tinycloud.toml and the delegation-flow gate now describe the fixed allow-list and the retired network_methods setting.
@samgbafa

Copy link
Copy Markdown
Contributor Author

CHANGES REQUESTED: see TC-1500 (head 33a39cd)

@samgbafa

Copy link
Copy Markdown
Contributor Author

APPROVE: see TC-1500 (reviewed exact head 87de5f1)

@samgbafa

Copy link
Copy Markdown
Contributor Author

Guard check from TC-1452 (skgbafa/tc-1452-held-admission at cf100fc) merged with this branch's head (87de5f1, no conflicts). signature_primitives_are_pinned_to_reviewed_sites fails with two differences in SIGNATURE_PRIMITIVES:

  1. Missing from expected: held_email.rs :: recover_eip191_address :: recover_from_prehash. Add it.
  2. Stale in expected: policy_v3.rs :: verify_issuer_signature :: verify_bytes. The call site now uses verify_strict. Replace it with policy_v3.rs :: verify_issuer_signature :: verify_strict.

verify_strict is not in the list on this branch. Add it with the entry above.

Keep both policy_v3.rs :: ingest_status_checkpoint_unmounted :: verify_detached_ed25519 entries. There are two call sites.

The other 11 tests in did_resolution_single_entry pass with the merge. Nothing else on this branch was changed.

@samgbafa

Copy link
Copy Markdown
Contributor Author

APPROVE: see TC-1500 (reviewed exact head ce7f533)

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant