Skip to content

feat(core): bind extension grants to canonical origin - #177

Closed
seonghobae wants to merge 1 commit into
mainfrom
cursor/bc-20dfb9b2-e814-4a5a-bb50-57f334099788-8698
Closed

feat(core): bind extension grants to canonical origin#177
seonghobae wants to merge 1 commit into
mainfrom
cursor/bc-20dfb9b2-e814-4a5a-bb50-57f334099788-8698

Conversation

@seonghobae

Copy link
Copy Markdown
Contributor

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.example remains usable after the same context navigates to https://other.example or https://app.example:8443.

Current exact implemented boundary

Protected main is 0c376acf059be9ddddddfbde1d0189e4f39ef014. This branch:

  • requires ExtensionAgentGrant and ExtensionAccessRequest to carry the same canonical origin;
  • returns DenyOriginMismatch for a host change or a non-default port change;
  • still refuses missing grants, wrong extension/session/context, and ungated capabilities;
  • does not install an extension, parse Chrome messages, bind expiry or task identity, or mint Agent capabilities from Manifest V3 permissions.

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::new and ExtensionAccessRequest::new did not accept an origin. After the fields existed, the production evaluator was updated to compare canonical origins. Local verification: originweave-core tests, 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.

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]>
@cursor

cursor Bot commented Aug 16, 2026

Copy link
Copy Markdown

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.

@coderabbitai

coderabbitai Bot commented Aug 16, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@seonghobae, you've reached your PR review limit, so we couldn't start this review.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: fda3be33-ce7d-44df-8818-e33928430c6a

📥 Commits

Reviewing files that changed from the base of the PR and between 0c376ac and afabb68.

📒 Files selected for processing (7)
  • CHANGELOG.md
  • crates/originweave-core/src/lib.rs
  • crates/originweave-core/tests/extension_authority.rs
  • docs/TRD.md
  • docs/adr/0013-manifest-v3-extension-authority.md
  • docs/doctoring.md
  • docs/traceability/extension-authority-security.md

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.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 / ExtensionAccessRequest carry Origin; evaluate_extension_access returns DenyOriginMismatch after 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)

  1. ExtensionAccessDecision::Allow rustdoc still names only extension, session, context, and capability. Update it when the next grant-dimension slice touches that enum.
  2. 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.
  3. Same-origin default-port (:443) is implied by Origin equality 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.

Open in Web View Automation 

Sent by Cursor Automation: Fix Issues

Comment on lines +1069 to +1071
if request.origin != grant.origin {
return ExtensionAccessDecision::DenyOriginMismatch;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Contributor Author

Superseded by #179 after fresh exact ancestry verification. Current #179 head 16a872cddd0e336adfe0a686a75d057c05d8c74a is a direct child of this exact head afabb68c58b132f27f13ceb47bfbbd947f0fdedf (merge base equals #177 head; ahead 1 / behind 0), so the complete origin-binding delta is preserved unchanged and #179 adds the dependent exclusive-expiry authority. Keeping both main-targeting PRs open would duplicate the same integration lineage. This closure does not promote #179 checks/reviews or authorize merge; #179 must satisfy its own exact-head required workflows, review-thread resolution, counted independent/latest-push approval, and protected-main policy.

@seonghobae seonghobae closed this Aug 16, 2026
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.

2 participants