Repository navigation
feat(domain-linkage): read and edit configuration entries unverified - #127
daniel-mader merged 2 commits into
Conversation
The controller of an origin maintains the DID configuration it publishes: it renews credentials before they expire and unlinks an origin by dropping its credentials. Both need each entry's DID, origin and expiry, read back from credentials it signed itself. `DomainLinkageConfiguration::entries` reads each JWT entry without verifying it, as an `UnverifiedLinkage` (DID, normalized origin, issuer, `nbf`, `exp`) or the reason it does not read. `earliest_expiry` says when renewal is due, and `remove_origin` drops the entries of an origin, compared normalized, keeping entries that do not read. `UnverifiedLinkage::from_jwt` reads one credential. The subject DID and origin are read by the same helpers `DomainLinkageValidator` uses, so both agree on what an entry says. Closes #123. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PB1rHNJ3YpjogEUJQYccc2
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 26 minutes. View limit details
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Unverified JWT linkage view src/domain_linkage/mod.rs, tests/domain_linkage.rs |
Adds UnverifiedLinkage::from_jwt to decode the subject DID, normalized origin, issuer, issuance date, and optional expiration without verification. Shared helpers now parse the subject DID and origin in check_format. Tests cover invalid subjects and origins. |
Configuration inspection and removal src/domain_linkage/mod.rs, src/prelude.rs, tests/domain_linkage.rs, docs/DESIGN.md, docs/FEATURES.md |
Adds entries, earliest_expiry, and remove_origin. The prelude exports UnverifiedLinkage. Tests cover entry parsing, expiry lookup, and origin removal. The design and feature documentation describe these operations. |
Priority:
Estimated code review effort: 3 (Moderate) | ~20 minutes
Change: Feature
Sequence Diagram(s)
sequenceDiagram
participant Controller
participant DomainLinkageConfiguration
participant UnverifiedLinkage
participant decode_credential
Controller->>DomainLinkageConfiguration: Call entries
DomainLinkageConfiguration->>UnverifiedLinkage: Parse each JWT with from_jwt
UnverifiedLinkage->>decode_credential: Decode credential JWT
decode_credential-->>UnverifiedLinkage: Return decoded credential or error
UnverifiedLinkage-->>DomainLinkageConfiguration: Return linkage value or error
DomainLinkageConfiguration-->>Controller: Return indexed entry results
Controller->>DomainLinkageConfiguration: Call remove_origin
DomainLinkageConfiguration-->>Controller: Return number of removed entries
Possibly related PRs
- impierce/identity-kit#118: Changes validation errors that
entries()andUnverifiedLinkage::from_jwtcan return. - impierce/identity-kit#85: Changes which credential JWTs
decode_credentialaccepts, affecting the entries these APIs can read.
Merge Risk: 
Minimal · previous review 5435e
-
The configuration-maintenance APIs appear ready to merge after normal checks.
Pre-merge checks: 
4 · 
1
-
Failed checks: 1 warning Passed checks: 4 passed-
Full details: Linked Issues check
-
Explanation
Issue
#123is open and directly linked. The PR addsDomainLinkageConfiguration::entries()with indexed success orDomainLinkageErrorresults,earliest_expiry(), and normalizedremove_origin().UnverifiedLinkage::from_jwt()reads the subject DID, origin, issuer,nbf, andexpwithout verification. The shared parsing helpers keep validator and unverified parsing consistent. The PR documents the controller maintenance use case and keeps validation as the security decision. Tests cover the specification example, malformed entries, earliest expiry, normalized removal, retained unreadable entries, order preservation, and empty configurations.FEATURES.mdcontains the requested issue row.
Full details: Out of Scope Changes check
-
Explanation
The changes stay within issue
#123. The source changes implement unverified entry reading, expiry inspection, origin removal, shared parsing, and the requested public re-export. The tests verify those APIs and error cases. The module, design, and feature documentation describe the same maintenance behavior. No unrelated product behavior is identified.
-
Full details: Docstring Coverage
-
Explanation
Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 14 functions across 3 files. (2 skipped: 2 unsupported.)
Resolution
Write docstrings for the functions missing them to satisfy the coverage threshold.
-
Finishing Touches: 💡 1
-
📝 Generate docstrings: 💡
-
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
-
- Commit to this branch
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! 🚀 New features to boost your workflow:
|
|
@coderabbitai review Generated by Claude Code |
✅ Action performed
|
…imedes-echxvg-did-configuration-entries
Closes #123.
The controller of an origin maintains the DID configuration it publishes. It renews credentials before they expire, and it unlinks an origin by dropping that origin's credentials. Both need each entry's DID, origin and expiry, read from credentials it signed itself, so verifying them again adds nothing. UniCore does this by hand today:
credential_claims,credential_originandneeds_renewalinagent_identity/src/service/aggregate.rsbase64-decode the payload and dig throughvc.credentialSubject.API
On
DomainLinkageConfiguration:entries(): each JWT entry with its position, read without verifying it as anUnverifiedLinkage, or theDomainLinkageErrorsaying why it does not read. Entries that don't decode are reported, not skipped. Linked Data Proof entries aren't JWTs and aren't among them, as withjwts().earliest_expiry(): the earliestexpamong the entries that read, orNone; when renewal is due at the latest.remove_origin(&Url): drops the JWT entries linking that origin, compared normalized (scheme, host, non-default port; a path or trailing slash is ignored), and returns how many it dropped. Entries that don't read, and Linked Data Proof entries, are kept.linked_didsstays a publicVec, soretaincovers any other predicate without new API.UnverifiedLinkage::from_jwt(&Jwt)reads one credential:didcredentialSubject.id, which must be a DIDorigincredentialSubject.origin, normalizedissuerdidnot_beforenbf, orissuanceDatewithout oneexpiresexp, orexpirationDatewithout oneThe type's docs, and the new "Maintaining a configuration" section of the module docs, say it's for the origin's controller, never for deciding whether a DID and an origin are linked; that stays
DomainLinkageValidator's job.Shared reading
check_formatread the subject DID and origin inline. Those are now two private helpers,subject_didandsubject_origin, used by both the validator andUnverifiedLinkage, so the two agree on what an entry says. The validator's checks and their order are unchanged. The#[expect(clippy::similar_names)]oncheck_formatwent with the inline code.Tests
In
tests/domain_linkage.rs:did:key:z6MkoTHsg…, with the originhttps://identity.foundation(the example JWT writes it without a scheme),nbf1607112739 andexp1764879139. Thatexpis the earliest expiry, andfrom_jwtgives the same result.example.com(30 days) andexample.org:8443(365 days), and a JWT that isn't a credential between them.entriesreads the two credentials and reports the third asValidation.earliest_expiryis day 30.remove_origin("https://example.com/")removes exactly one, and keeps the unreadable entry and the order; removing it again removes none.InvalidOrigin.example.org:8443.InvalidOriginProperty;InvalidOrigin;SubjectNotDid;Docs
DESIGN.md: thedomain_linkageparagraph.FEATURES.md: a row for Read and edit the entries of your own DID configuration without verifying them #123.UnverifiedLinkageis inprelude::credentials.Checks
All with rustc/clippy 1.99.1:
--all-features --all-targets -D warnings;cargo hack clippy --each-feature -D warnings;-D warnings;cargo test --all-features;--no-default-features --features did-key,softwarebuild;cargo publish --dry-run;cargo semver-checks("no semver update required")..cargo/mutants.tomlpins no lines indomain_linkage, so the moved code doesn't affect it.Generated by Claude Code
Summary by CodeRabbit