Skip to content

ongoing Changes - #1592

Closed
lavkushry wants to merge 1 commit into
mainfrom
fix/mcp-unknown-tool-fail-closed
Closed

ongoing Changes#1592
lavkushry wants to merge 1 commit into
mainfrom
fix/mcp-unknown-tool-fail-closed

Conversation

@lavkushry

@lavkushry lavkushry commented Jun 26, 2026

Copy link
Copy Markdown
Owner

Summary

Closes #

Type of change

  • Bug fix
  • New feature
  • Refactor / cleanup
  • Docs
  • Security fix
  • Performance improvement
  • CI / build

Checklist

  • Tests added/updated; cargo test --workspace and python3 -m unittest discover -s sdk-python/tests pass.
  • cargo fmt -- --check and cargo clippy --workspace --all-targets -- -D warnings pass.
  • python3 -m black --check sdk-python/ examples/ passes.
  • No hardcoded secrets; secrets stay out of logs/receipts (hashes only).
  • Tenant-owned queries bind/filter tenant_id; parameterized SQL only.
  • PR title follows Conventional Commits (feat:, fix:, docs:, etc.).

Integrity invariants (do not weaken)

  • If canonicalization/hashing changed, the scheme version was bumped and the SDK ↔ gateway byte-equality corpora were updated together.
  • Fail-closed behavior preserved (unknown → deny; critical → deny; high-risk → approval; hash mismatch / expired / consumed approval → no execution).
  • Trust-provenance changes only let classifiers tighten a label, never loosen it.

Notes for reviewers

Summary by CodeRabbit

  • New Features

    • Added a high-priority policy that blocks tool-call actions when the tool is not recognized, causing unknown tools to be denied by default.
  • Bug Fixes

    • Improved how matched policy names are reported, so the policy shown to users and monitoring tools now uses a stable label instead of a positional name.
  • Chores

    • Applied a consistent identifier to the new policy for clearer reporting and tracking.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds a highest-priority Cedar deny rule for unknown MCP tool calls, tags that rule with mcp_unknown_tool, and updates authorization reporting to prefer Cedar rule ids when listing matched policies.

Changes

Unknown MCP tool authorization

Layer / File(s) Summary
Unknown tool deny rule
src/policies.cedar, helm/aegis-gateway/files/policies.cedar
Adds a highest-priority forbid rule that rejects tool_call actions when context.is_mcp_tool_known is false.
Stable matched policy ids
policies.cedar, lib/policy/src/cedar.rs
Adds the mcp_unknown_tool Cedar @id and changes authorize to report matched policies from the rule id when present, otherwise from policy_id.

🎯 3 (Moderate) | ⏱️ ~20 minutes

(_/)
(•ㅅ•) I hopped by the policy gate,
/ >🥕 and gave unknown tools a sealed fate.
Tiny ids now sparkle in the hay,
while matched rules keep their names on display.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is too vague and does not describe the actual change, which adds a fail-closed Cedar rule for unknown MCP tools. Use a specific title that names the main change, such as adding a fail-closed policy for unknown MCP tools.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/mcp-unknown-tool-fail-closed

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.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces a new forbid rule mcp-unknown-tool-forbid to deny unknown MCP tools by default across several Cedar policy files. It also updates the policy engine in lib/policy/src/cedar.rs to prefer using the policy's @id annotation as a stable identifier for matched policies instead of positional IDs. Feedback suggests optimizing the policy lookup in cedar.rs to avoid querying the policy set twice for the same ID.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread lib/policy/src/cedar.rs
Comment on lines +273 to 279
let matched_name = policy_set
.policy(policy_id)
.and_then(|p| p.annotation("id"))
.map(|a| a.trim_matches('"').to_string())
.unwrap_or_else(|| policy_id.to_string());
matched_policies.push(matched_name);
if let Some(policy) = policy_set.policy(policy_id) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The policy is looked up twice in policy_set for each matched policy ID: once to retrieve the @id annotation (lines 273-274) and once to perform decision escalation (line 279). We can optimize this by performing the lookup once and reusing the retrieved policy reference.

Suggested change
let matched_name = policy_set
.policy(policy_id)
.and_then(|p| p.annotation("id"))
.map(|a| a.trim_matches('"').to_string())
.unwrap_or_else(|| policy_id.to_string());
matched_policies.push(matched_name);
if let Some(policy) = policy_set.policy(policy_id) {
let policy = policy_set.policy(policy_id);
let matched_name = policy
.and_then(|p| p.annotation("id"))
.map(|a| a.trim_matches('"').to_string())
.unwrap_or_else(|| policy_id.to_string());
matched_policies.push(matched_name);
if let Some(policy) = policy {

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (1)
lib/policy/src/cedar.rs (1)

273-279: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Optional: fold the duplicate policy_set.policy(policy_id) lookup.

policy_set.policy(policy_id) is resolved at Line 274 for matched_name and again at Line 279 for the annotation-escalation block. Resolve it once and reuse the reference.

♻️ Resolve the policy once per matched id
 for policy_id in response.diagnostics().reason() {
+    let matched_policy = policy_set.policy(policy_id);
     // Prefer the policy's `@id` annotation as the matched-policy name so
     // callers and SOC detection rules see a stable identifier (e.g.
     // `mcp_unknown_tool`) rather than Cedar's positional `policyN`,
     // which shifts as rules are added/reordered. Falls back to the
     // Cedar policy id when no `@id` annotation is present.
-    let matched_name = policy_set
-        .policy(policy_id)
+    let matched_name = matched_policy
         .and_then(|p| p.annotation("id"))
         .map(|a| a.trim_matches('"').to_string())
         .unwrap_or_else(|| policy_id.to_string());
     matched_policies.push(matched_name);
-    if let Some(policy) = policy_set.policy(policy_id) {
+    if let Some(policy) = matched_policy {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/policy/src/cedar.rs` around lines 273 - 279, Resolve the duplicate policy
lookup in the matching flow by fetching policy_set.policy(policy_id) once and
reusing the same reference for both matched_name construction and the
annotation-escalation logic. Update the code around the matched_policies push
and the subsequent if let Some(policy) block in cedar.rs so the policy is bound
once, then use that binding for annotation("id") and the later annotation
checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@lib/policy/src/cedar.rs`:
- Around line 273-279: Resolve the duplicate policy lookup in the matching flow
by fetching policy_set.policy(policy_id) once and reusing the same reference for
both matched_name construction and the annotation-escalation logic. Update the
code around the matched_policies push and the subsequent if let Some(policy)
block in cedar.rs so the policy is bound once, then use that binding for
annotation("id") and the later annotation checks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 84ee4413-cbac-4bd7-b6d7-2dda1d0aca91

📥 Commits

Reviewing files that changed from the base of the PR and between 57cb5a0 and c68dcfd.

📒 Files selected for processing (6)
  • aegis.db-shm
  • aegis.db-wal
  • helm/aegis-gateway/files/policies.cedar
  • lib/policy/src/cedar.rs
  • policies.cedar
  • src/policies.cedar

lavkushry added a commit that referenced this pull request Jul 8, 2026
…y rule (#1789)

* ongoing Changes

* fix(policy): dedupe mcp_unknown_tool in matched_policies

The unknown-MCP-tool forbid rule already existed on main. Cherry-picking
#1592's one real commit onto a fresh branch surfaced that its @id-annotation
naming addition duplicated an existing lookup block, so matched_policies
contained "mcp_unknown_tool" twice whenever that rule fired. Remove the
redundant block and add a regression test asserting exactly one occurrence.
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