feat(core): bind extension grants to canonical origin - #177
Conversation
Keep an extension-to-Agent grant from surviving same-session navigation or a port change. RFC 6454 treats scheme, host, and port as the origin tuple, so evaluate_extension_access now requires the request origin to match the grant. Co-authored-by: Seongho Bae <[email protected]>
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
|
Warning Review limit reached
Next review available in: 53 minutes Limit details: You’ve used all 1 included review currently available under your plan. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (7)
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 |
There was a problem hiding this comment.
Verdict
SOUND for the claimed origin-binding slice on exact head afabb68c58b132f27f13ceb47bfbbd947f0fdedf.
This is the unique #27 origin/resource-scope landing. A grant for https://app.example cannot be reused after the same session/context navigates to https://other.example or https://app.example:8443. Comparison uses the existing canonical Origin type, so default-port https://app.example:443 remains the same origin. Chrome permissions still do not mint Agent capabilities. The PR does not install an extension, parse Chrome messages, bind expiry or task identity, or claim issue #27 closed.
Do not open a second origin-binding PR. Do not fold Chrome-permission isolation (#175), MV3 downloads (#43), HTTP (#37), or expiry/task onto this head.
Evidence checked
- Production:
ExtensionAgentGrant/ExtensionAccessRequestcarryOrigin;evaluate_extension_accessreturnsDenyOriginMismatchafter session/context match and before capability check. - Tests: host change and non-default port change; existing missing-grant, identity, session, context, and capability denials remain.
- Call sites: only
crates/originweave-core/tests/extension_authority.rs. - Docs: CHANGELOG, Proposed ADR 0013 follow-up, RFC 6454 APA 7th in
docs/doctoring.md, TRD active-PR note, traceability dossier. Honest about remaining expiry and task binding.
CodeRabbit GitHub is rate-limited on this PR (next window ~53 minutes from 16:46 UTC). CodeRabbit CLI 0.7.3 is installed here but coderabbit auth login --agent requires an interactive browser and did not authenticate. That is not a defect in this diff.
Pinned Chrome MV3 fixture already succeeded. Rust contracts, production coverage, SAST, and security checks were still in progress at review time. mergeable_state is blocked on those required checks. This automation has no merge tool and will not APPROVE as a substitute for exact-head CI.
Residuals (non-blocking)
ExtensionAccessDecision::Allowrustdoc still names only extension, session, context, and capability. Update it when the next grant-dimension slice touches that enum.- The section 4 authority chain still says
explicit extension/session/context grant. The new origin-binding section is accurate; the diagram can wait for protected-main land. - Same-origin default-port (
:443) is implied byOriginequality and is not a missing denial. Add an explicit allow case only if the next test edit is already in this file.
Next buyer-visible slice
ADR 0013 still requires exclusive expiry and task identity. After this head is on protected main, bind the grant to trusted-time exclusive expiry so a same-origin grant cannot be reused after the Agent Task window ends. Do not start that work on this branch.
Sent by Cursor Automation: Fix Issues
| if request.origin != grant.origin { | ||
| return ExtensionAccessDecision::DenyOriginMismatch; | ||
| } |
There was a problem hiding this comment.
Origin equality is the right check. Origin::parse already drops default HTTPS 443 / HTTP 80, so https://app.example and https://app.example:443 stay the same grant. Host change and :8443 are covered in the test. This is not a defect.
When the next grant-dimension slice touches this function, also update ExtensionAccessDecision::Allow rustdoc. It still says the grant is only extension, session, context, and capability.
|
|
||
| **Capability maturity:** `IMPLEMENTED_ON_ACTIVE_PR` | ||
|
|
||
| The current origin-binding slice requires `ExtensionAgentGrant` and `ExtensionAccessRequest` to carry the same canonical origin. A same-session, same-context request for `https://other.example` or `https://app.example:8443` against a grant for `https://app.example` is `DenyOriginMismatch`. This does not install an extension, parse Chrome messages, bind expiry or task identity, or mint Agent capabilities from Manifest V3 permissions. |
There was a problem hiding this comment.
This section correctly keeps the slice at IMPLEMENTED_ON_ACTIVE_PR and does not close #27.
Section 4 below still draws explicit extension/session/context grant without origin. Leave that diagram until this head is on protected main; do not widen this PR to a docs-only rewrite.
|
Superseded by #179 after fresh exact ancestry verification. Current #179 head |


Buyer-visible gap
Partial implementation of #27. Protected main already evaluates an explicit extension-to-Agent grant by extension identity, browser session, and browsing context. ADR 0013 also requires origin/resource scope. Without that match, a grant issued for
https://app.exampleremains usable after the same context navigates tohttps://other.exampleorhttps://app.example:8443.Current exact implemented boundary
Protected main is
0c376acf059be9ddddddfbde1d0189e4f39ef014. This branch:ExtensionAgentGrantandExtensionAccessRequestto carry the same canonical origin;DenyOriginMismatchfor a host change or a non-default port change;This PR does not implement HTTP/1.1 (#37), Chrome-permission isolation (#175), MV3 downloads (#43), or a Chromium adapter.
TDD
The first compile failed because
ExtensionAgentGrant::newandExtensionAccessRequest::newdid not accept an origin. After the fields existed, the production evaluator was updated to compare canonical origins. Local verification:originweave-coretests, Clippy-D warnings, rustdoc, and the product-documentation / destination / repository Python contracts passed.Standards
Barth, A. (2011). The web origin concept (RFC 6454). Internet Engineering Task Force. https://doi.org/10.17487/RFC6454
Partial implementation of #27.