fix: complete revocation — TS HTTP verifier wired, README corrected, tests added#40
Merged
fix: complete revocation — TS HTTP verifier wired, README corrected, tests added#40
Conversation
…tests added The other LLM that audited the repo was correct: two things were incomplete on main after PRs #38 and #39. 1. ts/verifier/main.ts — TS HTTP verifier service still had the stub. The SDK verifier (ts/sdk/src/verifier.ts) was fully implemented, but the HTTP service has its own independent verification loop. It was never updated. Fixed: Cascade import added. revocationURL field added to TrustAnchor. revocCache: Map<string, CachedRevocation> added. checkRevocation() and parseRevArtifact() added — mirrors Go HTTP verifier implementation with full signature verification, algorithm binding, staleness check (32 entries), fail-closed behavior. 2. README.md — line 225 explicitly said 'Revocation not implemented.' This is what the other LLM read. Updated to accurately describe the current state: all four SDK verifiers are wired, cascade is cross-verified against locked test vectors, revocation_url is in trust config. Mode 0 fail-open behavior documented as the intentional design for offline deployments. RevocationTest.java — six behavioral tests added to Java SDK test suite: notRevokedEntryVerifies, revokedEntryIsRejected, revocationDoesNotAffectOtherEntries, multipleRevocations, revokeZeroThrows, revokeUnissuedThrows. All 6 pass. Java total: 39/39. interop_test.py — two cross-implementation revocation tests added: 'Revoke: Go issuer → TS verifier rejects' (issuer port 8091, verifier 3012) 'Revoke: TS issuer → Go verifier rejects' (issuer port 3011, verifier 8092) Dedicated fresh service instances used to avoid cache contamination from the positive matrix runs. Cold-cache verify: revocation happens before the first verify call so the verifier fetches the updated artifact directly. Both pass. Interop total: 17/17.
rmhrisk
pushed a commit
that referenced
this pull request
Mar 17, 2026
…guages
Addresses eight gaps identified in a cross-language audit:
1. Rust claims type (HashMap<String,String> → HashMap<String,serde_json::Value>)
Non-string claim values (integers, booleans, nulls, arrays) were silently
dropped at decode time. Added cbor_to_json() helper preserving all CBOR types.
2. Rust Issuer revocation (revoke(), revocation_artifact())
Rust Issuer had the cascade but no public revocation API. Added revoke(),
revocation_artifact(), build_revocation_artifact(), entry_expiry_time(),
revoked_indices HashSet, latest_rev_artifact Option<String> in State, and
revocation_url emission from trust_config_json(). Wired into publish_checkpoint.
3. TS SDK Issuer revocation (revoke(), revocationArtifact())
SDK Issuer had internal state but no public API. Added public revoke(bigint),
revocationArtifact() methods, buildRevocationArtifact() private method,
entryExpiryTime() helper, Cascade and decodeTbs imports, and revocation_url
in trustConfigJson(). Wired into publishCheckpoint.
4. TS SDK Verifier RevocationProvider
Added RevocationProvider type and 3rd constructor parameter, symmetric with
Java. Wired into fetchRevArtifact for test injection. Updated all.test.ts to
pass revocationProvider so smoke tests no longer fail-closed on localhost:0.
5. Rust Verifier RevocationProvider
Added RevocationProvider type and with_revocation_provider() constructor,
symmetric with Java and TS SDK. Wired into fetch_revocation_artifact.
6. Mode 0 rejection — TS SDK and Rust verifiers now reject mode=0 payloads
explicitly before any network work, with a clear 'not implemented' message.
Go already did this correctly; Java falls through (mode=0 fails at proof
verification, not at an explicit check — Java gap noted but not fixed here).
7. Behavioral revocation tests:
- Go: IsRevoked() accessor added; TestRevokeAndArtifact, TestRevokeIndexZeroRejected,
TestRevokeUnissuedRejected, TestMultipleRevocations (4 tests, log_test.go)
- TS SDK: revocation.test.ts — 6 behavioral tests + 1 mode=0 rejection test (7 total)
- Rust: revocation_tests module — un_revoked_entry_verifies, revoked_entry_is_rejected,
revoke_zero_rejected, revoke_unissued_rejected, mode_zero_rejected (5 tests)
- Java: unchanged — RevocationTest.java already has 6 behavioral tests from PR #40
8. Documentation:
- SPEC.md §Deferred Items: 'not yet implemented' → 'specified and implemented'
- ARCHITECTURE.md: Revocation section (cascade algorithm, wire format, issuer/verifier
implementation summary, cache semantics). Multi-anchor vs single-anchor design
decision documented (HTTP services are multi-anchor; SDK libraries are single-anchor).
- IMPLEMENTERS_GUIDE.md: Three stale 'revocation is stubbed' references fixed.
Test totals after this PR:
Go: 42 tests (was 38) — 4 new revocation behavioral tests
TS SDK: 47 tests (was 40) — 7 new revocation + mode0 tests
Rust: 28 unit + 2 doctests = 30 (was 23+2=25) — 5 new revocation tests
Java: 39 tests (unchanged — already had RevocationTest from PR #40)
Interop: 17/17 (unchanged)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Addresses the gaps that caused an external audit to conclude revocation was not implemented.
Root cause 1 —
ts/verifier/main.ts: The TS HTTP verifier service had an independent verification loop that still contained the stub. The SDK verifier (ts/sdk/src/verifier.ts) was fully wired, but the HTTP service was not. Fixed:checkRevocation()andparseRevArtifact()added,revocationURLfield added toTrustAnchor,revocCacheadded.Root cause 2 —
README.md: Line 225 explicitly said "Revocation not implemented." Updated to accurately describe what's done and document the intentional Mode 0 fail-open behavior.RevocationTest.java: Six behavioral tests covering the full issue → revoke → verify path:notRevokedEntryVerifies,revokedEntryIsRejected,revocationDoesNotAffectOtherEntries,multipleRevocations,revokeZeroThrows,revokeUnissuedThrows. Java total: 39/39.interop_test.py: Two cross-implementation revocation tests using dedicated fresh service instances (ports 8091/3011 issuers, 8092/3012 verifiers). Cold-cache verify pattern — revoke before first verify so the verifier fetches the updated artifact directly. Interop total: 17/17.