Skip to content

fix(destination): require fresh resolution on redirects - #92

Draft
seonghobae wants to merge 3 commits into
feat/resolution-freshness-authority-mainfrom
fix/redirect-resolution-freshness
Draft

fix(destination): require fresh resolution on redirects#92
seonghobae wants to merge 3 commits into
feat/resolution-freshness-authority-mainfrom
fix/redirect-resolution-freshness

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Buyer/security gap

Stacked follow-up to #47. The prerequisite introduces bounded FreshResolutionSnapshot authority, but its existing RedirectGuard::authorize_redirect still accepted the untimed ResolutionSnapshot. That left redirect hops as a first-party bypass: a target resolution could be origin-matched yet used after its freshness window expired.

Dependency

This Draft remains stacked on unchanged exact #47 head 6b5ed4dcea281b505f67db6180bb14c3bc95b392 and must remain Draft while #47 is active. No prerequisite check/review is transferred to this branch.

TDD / RCA sequence

  1. Exact test-only head 98bb8ee99ec685f19091d6b6094ac7861872292b added a realistic regression that gives a redirect target a two-second FreshResolutionSnapshot, attempts authorization exactly at the exclusive validity deadline, and requires the hop to fail without mutating redirect-chain state.
  2. CI run 31523936438, Rust contracts job 93887508525, passed repository contracts and canonical formatting, then reached the intended production boundary: cargo check --locked --workspace --all-targets failed because authorize_redirect still accepted &ResolutionSnapshot without trusted current time (E0061) and RedirectError::ResolutionFreshnessDenied did not exist (E0599). This is the valid RED.
  3. Production head 5516055bd70e687d6d76dc8660e90f003d3c0432 added the narrow freshness composition and migrated the existing redirect tests. CI run 31524429339 then stopped at one canonical rustfmt hunk in redirect_policy.rs; workspace/tests were skipped, so that head is not counted as GREEN.
  4. Formatting-only head b796564d059f7bcbd8177617b6fd46c6edc7dda1 applies exactly the reported rustfmt delta without changing behavior.
  5. Fresh exact-head CI run 31524574783 is now fully GREEN on b796564d059f7bcbd8177617b6fd46c6edc7dda1: Rust contracts job 93889674164 passed repository contracts, formatting, locked workspace/all-target check, full tests, strict Clippy and rustdoc; Production coverage job 93889674208 passed exact owned production function/line/region/branch enforcement. CodeRabbit exact-head commit status is success; GitHub reports the Draft mergeable, and no formal reviews or inline review threads are currently returned.

No cancelled/predecessor job, synthetic merge result, or prerequisite evidence is promoted as current proof.

Implemented boundary

RedirectGuard::authorize_redirect now:

  • requires the prerequisite FreshResolutionSnapshot rather than an untimed resolution snapshot;
  • requires caller-supplied trusted monotonic current_time from the same clock domain as resolution approval;
  • preserves exact readable-origin and resolution-origin binding checks;
  • fails closed before any redirect-chain state mutation when use occurs before approval or at/after the exclusive freshness deadline;
  • preserves existing HTTPS downgrade, redirect-cycle and hop-limit semantics; and
  • wraps the existing typed DestinationError::ResolutionUseBeforeApproval / ResolutionApprovalExpired outcomes as RedirectError::ResolutionFreshnessDenied, preserving the standard error source.

Focused regressions prove exact-boundary expiry, pre-approval use rejection, no chain advancement on freshness denial, stable credential-free error text/source, and migration of every existing redirect authorization path through fresh resolution authority.

Truth boundary

This is deterministic per-hop destination authority only. It performs no DNS lookup, socket I/O, HTTP redirect following, wall-clock read, proxy/PAC execution, TLS/browser/model operation, persistence, or runtime clock attestation. Constructing a FreshResolutionSnapshot does not prove the resolver or clock is trusted; the higher-layer resolver/network/browser adapter must supply independently validated resolution evidence and current time from the same trusted monotonic domain.

The active CHANGELOG.md path is currently touched by another OriginWeave writer lane, so this branch does not race that path. Canonical TM-002 already requires per-hop redirect authorization; no new trust domain or persistence owner is introduced by this bounded correction.

This PR is a partial hardening slice under #28/#47 and does not close either issue. Keep Draft while #47 remains active; any prerequisite or current-head movement requires fresh exact-head/live-base validation.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: dd4cc3a5-ba61-40c9-867e-4e7909135eff

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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