fix(server): bound DPoP replay state - #8845
solomonneas wants to merge 6 commits into
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (10)
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthroughThe change adds a bucketed filesystem-backed DPoP replay store, preserves compatibility with legacy markers, validates bootstrap credentials before claiming proofs, and integrates replay claims into token exchange authentication. ChangesDPoP replay protection
Priority: ⬆️ High Estimated code review effort: 4 (Complex) | ~45 minutes Change: Bug fix · Severity of issue fixed: High Sequence Diagram(s)sequenceDiagram
participant Client
participant TokenHandler
participant EnvironmentAuth
participant DpopReplayStore
Client->>TokenHandler: Send token exchange with DPoP proof
TokenHandler->>EnvironmentAuth: Validate bootstrap credential and proof thumbprint
EnvironmentAuth-->>TokenHandler: Return validation result
TokenHandler->>DpopReplayStore: Claim proof thumbprint and jti
DpopReplayStore-->>TokenHandler: Return claim result
TokenHandler-->>Client: Return token or DPoP challenge
Suggested reviewers: Merge Risk: ⚪ Minimal · up to The upgrade documentation already requires the operational sequencing needed to preserve replay protection across versions. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Reviewed the new DpopReplayStore service and its call sites against the Effect service conventions. Module layout (imports → errors → Context.Service tag → make → layer), namespace imports, Foo["Service"] typing, environment-based dependency acquisition and the exported Schema.is union predicate all look right. Three error-modeling/catch findings below.
Posted via Macroscope — Effect Service Conventions
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This PR adds substantial persistent replay-state machinery and changes production DPoP authentication and bootstrap-token flows in a security-sensitive auth package. Unresolved findings also concern rolling-upgrade replay protection and DPoP challenge responses, so the change warrants human review. Not approved because:
Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more. |
There was a problem hiding this comment.
Reviewed the new DpopReplayStore service and its call sites against the Effect service conventions. The earlier findings (structural replay-detection error, structural claim/prune error attributes, catchIf with a schema predicate) are addressed in this revision. One remaining item: DpopReplayStoreSetupError drops the path context available at its wrapping site.
Posted via Macroscope — Effect Service Conventions
|
Note: GPT-6 on behalf of shivam (@shivamhwp). The compatibility lifetime is still tied to this instance's startup rather than the lifetime of proofs accepted by every writer sharing
|
e584549 to
9eaf1d0
Compare
Fixes #9040
DPoP authentication previously created a permanent secrets-store file for every accepted proof. This change records empty, digest-named markers in overlapping ten-minute buckets and prunes only expired buckets. Claims write and sync the future bucket before the current bucket so a partial write still blocks replay across a boundary.
Bootstrap credentials are validated without consuming them before replay state is allocated. The final atomic consume still decides whether the exchange succeeds. Replay rejection during token exchange includes the DPoP challenge header.
Upgrade requirement: stop all older servers sharing the secrets directory and drain their requests before starting the new version. Mixed-version operation is unsupported. Existing canonical legacy markers are always checked and never created or deleted by the new store. New traffic uses bounded bucket storage, while existing legacy files remain as fixed migration residue. Rollback requires stopping all new-version writers and waiting at least six minutes before starting an older server. See the migration guidance.
Verification:
Model and harness: GPT-6 via Codex.
Summary by CodeRabbit
New Features
Bug Fixes
Documentation