Skip to content

Add status list support for SD-JWT - #561

Merged
w-ensink merged 50 commits into
masterfrom
sd-jwt-status-lists
Jul 27, 2026
Merged

Add status list support for SD-JWT#561
w-ensink merged 50 commits into
masterfrom
sd-jwt-status-lists

Conversation

@w-ensink

@w-ensink w-ensink commented Jun 8, 2026

Copy link
Copy Markdown
Member

Implementing Token Status List (TSL) draft 15. We don't implement the latest version of the spec yet, because DIIP v5 is specifically talking about this draft.

Fixes privacybydesign/irmamobile#516

Base automatically changed from openid4vci to master June 15, 2026 12:17
@w-ensink
w-ensink marked this pull request as ready for review July 9, 2026 14:03
dobby-coder[bot]
dobby-coder Bot previously requested changes Jul 9, 2026

@dobby-coder dobby-coder Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for implementing Token Status List (draft-15) support — the package is well-structured and thoroughly tested. A few things to address before merge:

Blocking

  • statuslist/checker.go returns an error when the cache write fails, which contradicts its own comment and rejects otherwise-valid credentials on a transient cache failure (fail-closed path). See inline comment.

Non-blocking

  • openid4vci_statuslist_test.go is self-labeled "UNVERIFIED SCAFFOLDING" yet wired into the main session suite — please validate it against the stack or gate it behind a skip until then.
  • Status-list checks use context.Background() instead of a caller-supplied context, so they can't be cancelled by the surrounding session/request.

PR metadata (rule check)

  • The body's Fixes https://github.com/privacybydesign/irmamobile/issues/516 is a bare cross-repo URL, which does not auto-close on merge. To have the issue close automatically, use the fully-qualified form on its own line: Fixes privacybydesign/irmamobile#516. (Cross-repo auto-close is best-effort on GitHub; if it still doesn't fire, the issue will need to be closed manually.)

Note: the storage/db/services tests couldn't be exercised in the review sandbox (sqlcipher native dep unavailable — pre-existing infra limitation, not this PR); statuslist + sdjwtvc suites pass.

Comment thread eudi/credentials/statuslist/checker.go Outdated
Comment thread internal/sessiontest/openid4vci_statuslist_test.go Outdated
Comment thread eudi/credentials/sdjwtvc/verify.go
@w-ensink

Copy link
Copy Markdown
Member Author

/dobby please review again

@dobby-coder dobby-coder Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧦 Consolidated review — status list support for SD-JWT

Went through the diff plus a per-rule compliance pass (memory rules + irmago repo notes). No blocking correctness/security/rule issues found: concurrency is safe (singleflight + RWMutex cache), status checks are fail-closed with sane TTL bounds [60s, 24h], DB access is parameterized, and unit tests cover the new package. Nice work.

Verdict is a non-blocking COMMENT — three nits below, none merge-blocking.

CI note (non-blocking): integration-test-clientside is red on this run — TestClientIntegration/KeyshareSessions failed with UNEXPECTED_REQUEST (Session not yet started or already finished). That test doesn't touch the status-list code and master is currently green, so it reads as a flake / session-start timing race rather than a regression from this PR — but since master passes, please re-run the job and confirm it's not fallout from the docker-compose restructuring (shared veramo_postgres / new statuslist_agent startup ordering) before merge. The [no tests to run] line for the statuslist package in the same log is also worth a glance (build-tag/_test.go package mismatch?).

Comment thread CHANGELOG.md Outdated
Comment thread eudi/credentials/statuslist/checker.go
Comment thread docker-compose.yml Outdated
@w-ensink

Copy link
Copy Markdown
Member Author

/dobby review again

@dobby-coder dobby-coder Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧦 Dobby consolidated review — status list support for SD-JWT

Ran the per-rule compliance sweep (irmago repo rules + general PR/code rules) alongside the diff review. The PR is well-structured and thoroughly tested; unit tests pass for all changed packages (integration needs docker, skipped). CHANGELOG claims match the delivered code. One doc/behaviour inconsistency worth a look (inline).

Non-blocking heads-up (CodeQL): the new statuslist/fetcher.go error strings embed remote-server-controlled values (resp.Status, the Content-Type header) which then reach a logger via eudi.Logger.Warnf. irmago's CodeQL +security-and-quality suite has historically flagged log-injection/clear-text on changed log lines (see PR #597). If the CodeQL check goes red on this PR, that flow is the likely cause — sanitize the value before logging or drop it from the message.

Not blocking; posting as COMMENT.

Comment thread eudi/openid4vp/eudi_sdjwt_dcql/handler.go Outdated
@w-ensink

Copy link
Copy Markdown
Member Author

/dobby i changed the architecture a bit, please review it one more time

@dobby-coder

dobby-coder Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Got it — I'll take another pass over PR #561 now that the architecture's changed and post a fresh review shortly.

@dobby-coder dobby-coder Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One note from re-review, non-blocking. The architecture change reads cleanly: the x5c-or-kid+DID dispatch is now shared via eudi/jwt.JwtKeyProvider, status checks are wired at issuance / post-verification / background sweep, and the batch invariant checks in validateStatusReferences look correct (Reference is a value struct of uint64+string, so the != / map-key comparisons are safe). One stale line in the CHANGELOG — see inline.

Comment thread CHANGELOG.md Outdated
@dobby-coder

dobby-coder Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Re-reviewed the updated architecture and posted a review — non-blocking.

It reads cleanly overall: the shared x5c-or-kid+DID dispatch via eudi/jwt.JwtKeyProvider is good de-duplication, status checks are wired at every lifecycle site (issuance, post-verification, background sweep), and the validateStatusReferences batch invariants check out.

One thing to fix: the CHANGELOG still mentions the RequireStatusListIssuerMatch flag, but that was removed in this refactor — a delegated Status Issuer is now accepted as long as the signature is trusted and sub matches the referenced uri. Left an inline comment on CHANGELOG.md — worth dropping that clause (or re-adding the flag if you meant to keep it).

@w-ensink

Copy link
Copy Markdown
Member Author

/dobby fix the changelog

@dobby-coder

dobby-coder Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Got it — I'm on it. I'll take a look at the changelog in this PR and push a fix.

dobby-coder Bot and others added 2 commits July 21, 2026 11:01
The flag was removed in the status-list simplification refactor and no
longer exists in the tree; a delegated Status Issuer is accepted as long
as the signature is trusted and sub matches the referenced uri.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The method's doc claimed the result is joined with its batch's IssuerURL,
but CredentialStatusInstance has no such field and the query selects/joins
none. Drop the misleading clause.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
dobby-coder[bot]
dobby-coder Bot previously approved these changes Jul 21, 2026

@dobby-coder dobby-coder Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧦 Dobby consolidated review — Token Status List support for SD-JWT.

Changelog fix (your request): done. The stale RequireStatusListIssuerMatch clause was dropped in 42281d2f, and I verified the rest of the Unreleased status-list entry now matches the tree — RefreshStatuses exists, and StatusRefreshService / RefreshAll / status_refresh_service.go are gone from both code and changelog. The TTL wording (prefers the token's own ttl/exp, falls back to HTTP max-age, clamped [60s, 24h]) matches the code — no leftover min(...) claim.

Review + rule sweep: the only finding this cycle was one doc nit — ListInstancesWithStatusReference's comment claimed the result was "joined with its batch's IssuerURL", but CredentialStatusInstance has no such field and the query selects/joins none. I fixed it directly in 0afaf71d (doc-only, builds green). No bug- or rule-level issues remain; PR-metadata (fully-qualified Fixes privacybydesign/irmamobile#516) is correct.

Approving. Nice, well-tested feature.

@dobby-coder

dobby-coder Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

🧦 Done — the changelog is fixed and PR #561 is now approved.

I dropped the stale RequireStatusListIssuerMatch clause and re-checked the whole Unreleased status-list entry against the code — RefreshStatuses exists, the removed StatusRefreshService/RefreshAll are gone from both code and changelog, and the TTL wording matches what's actually implemented. While sweeping the rest of the PR I also fixed a doc nit (a comment claiming a non-existent IssuerURL join), doc-only change, builds green.

Submitted a formal APPROVE review — nothing left blocking on my side, merge whenever you're ready.

Comment thread client/client.go
Comment thread client/client.go Outdated
Comment thread eudi/credentials/statuslist/context.go Outdated
Comment thread eudi/credentials/statuslist/doc.go Outdated
Comment thread eudi/credentials/statuslist/reference.go
Comment thread eudi/jwt/key_providers.go
Comment thread eudi/openid4vp/eudi_sdjwt_dcql/handler.go
Comment thread eudi/openid4vp/eudi_sdjwt_dcql/handler.go
Comment thread eudi/services/credential_service.go
Comment thread CHANGELOG.md Outdated
@rubenhensen
rubenhensen self-requested a review July 24, 2026 13:48
@w-ensink
w-ensink merged commit 332d1f6 into master Jul 27, 2026
33 of 34 checks passed
@w-ensink
w-ensink deleted the sd-jwt-status-lists branch July 27, 2026 07:09
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.

OID4VCI - DIIPv5: Add support for IETF Token Status List

4 participants