Skip to content

fix(runtime): enforce canonical base64url in agent_manifest and reject duplicate JSON keys across server, catalog, and inspection (#798) - #800

Open
drk-ram wants to merge 1 commit into
agentrust-io:mainfrom
drk-ram:drk-ram-fix-runtime-canonical-base64url-json-key
Open

drk-ram wants to merge 1 commit into
agentrust-io:mainfrom
drk-ram:drk-ram-fix-runtime-canonical-base64url-json-key

Conversation

@drk-ram

@drk-ram drk-ram commented Oct 23, 2026 •

Copy link
Copy Markdown

Summary

  • src/cmcp_runtime/agent_manifest.py: Enforce canonical unpadded base64url (len(value) % 4 != 1 and exact round-trip encoding), reject RFC 7517/7518/8037 private or symmetric JWK parameters (d, p, q, dp, dq, qi, oth, k), and reject duplicate JSON object keys and NaN/Infinity constants when loading Agent Manifest documents, trust policies, and revocation lists.
  • src/cmcp_runtime/catalog/loader.py: Reject duplicate JSON object keys, NaN/Infinity constants, and private JWK parameters in publisher_jwk when loading catalogs and entry schemas.
  • src/cmcp_runtime/inspection/pipeline.py & src/cmcp_runtime/mcp/server.py: Reject duplicate JSON object keys in MCP JSON-RPC envelopes, admin endpoints, pattern files, Stage 2 schema validation, and sensitivity classification.
  • src/cmcp_runtime/mcp/proxy.py: Enforce IEEE-754 / RFC 8785 safe-integer bounds (abs(v) <= 2**53 - 1) and reject non-finite floats in _cedar_safe and trace_action, failing closed as PolicyDeny / trace:refused.

Closes #798

Validation

  • python -m pytest tests/unit/test_agent_manifest.py tests/unit/test_catalog.py tests/unit/test_mcp_proxy.py tests/unit/test_stage2_schema.py tests/unit/test_trace_gate_hook.py -q (213 passed in the 5 focused modules; 2,586 passed, 6 skipped across tests/unit)
  • python -m ruff check src/cmcp_runtime/agent_manifest.py src/cmcp_runtime/catalog/loader.py src/cmcp_runtime/inspection/pipeline.py src/cmcp_runtime/mcp/proxy.py src/cmcp_runtime/mcp/server.py (All checks passed!)

@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

🟡 Contributor Check: MEDIUM

Check Result
Profile MEDIUM
Credential LOW
Overall MEDIUM

Automated check by AgenTrust Contributor Check.

@github-actions github-actions Bot added the needs-review:MEDIUM Contributor check flagged MEDIUM risk label Oct 23, 2026

@dinakarjs dinakarjs left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Bounded review at 043be57. I fetched the source and the five named test modules at this SHA and independently ran them on Linux/Python 3.12: 213 passed (one Starlette deprecation warning), not the 300 stated in the description. The documented Ruff selection passes. Please reconcile the count or identify the additional executable selection and revision behind 300.

The inspected paths reject duplicate members recursively, retain JSON/COSE loader distinction, reject noncanonical key/signature encodings, and retain sensitivity scanning when schema parsing denies a response. The new proxy numeric checks and gated refusal tests pass in this selection. No additional blocker found in this bounded source/test review.

This run used the pinned repository source with agent-manifest 0.15.0 and published dependencies; it was not a hash-locked full-suite run. Current-head checks exposed here contain contributor/approval gates but do not establish the full runtime CI matrix. Full pytest, mypy, Bandit and required independent maintainer approvals remain necessary before merge. No hardware or production validation claimed. Reviewed with OpenAI Codex.

@dinakarjs dinakarjs left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Expanded validation at 043be57: all 722 tracked source blobs matched the pinned GitHub tree. In a hash-locked development environment with the package installed editable, tests/unit completed with 2,586 passed and 6 skipped. Ruff (src/tests), mypy (76 source files), and Bandit passed locally. This supplements my earlier 213-test focused run; it does not establish the PR body's separate 300-test command/count. Hosted CI and independent maintainer approval remain separate gates.

@drk-ram

drk-ram commented Oct 23, 2026

Copy link
Copy Markdown
Author

Thank you @dinakarjs! Updated the PR description to state 213 passed for the 5 focused test modules (2,586 passed, 6 skipped across ests/unit).

@carloshvp carloshvp left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reviewed exact head 043be57a3eee9b0bd9f5d755c5bd0291031eeab1 in an isolated checkout.

The changed runtime boundaries reject ambiguous JSON, non-canonical Agent Manifest encodings and private public-key material, while retaining PII classification on denied responses and controlled TRACE finalization for invalid numbers. I found no blocking defect in the changed paths. The two duplicate-key/schema/PII regressions pass here and both fail with the actual merge-base pipeline restored in process.

In a fresh hash-locked Python 3.12.10 environment with the local package installed, the full unit suite passed: 2,572 passed, 20 skipped. pip check, Ruff, mypy and configured Bandit passed. The commit sign-offs are present. git diff --check reports only new blank lines at test-file EOFs; please trim those as cleanup. This is a source-review approval; the hosted approval/policy checks and applicable CI still need to complete.

Reviewed with OpenAI Codex.

@carloshvp

Copy link
Copy Markdown
Member

Hosted CI follow-up at head 043be57a3eee9b0bd9f5d755c5bd0291031eeab1: I approved the held validation runs after the local source review. The first test job stops at its security-audit step, before the unit suite, because this branch still locks certifi 2026.7.22, filelock 3.32.5 and setuptools 84.0.0. The current log reports five known vulnerabilities across those three packages: https://github.com/agentrust-io/cmcp/actions/runs/39976045429/job/120848329344. Please refresh the dependency baseline and generated locks coherently; another test rerun of this unchanged head will reproduce the audit failure.

The older approval gate is also inconsistent with the current review API: rerun job 120848778091 reports zero independent approvals, while REST review 5637901229 is APPROVED by carloshvp at this exact head. I re-evaluated the checked-in filter using the current base-policy file and live reviews and obtained one qualifying approval. I have not established why that job sees zero, and repeated reruns are not evidence of a source defect. The local source approval stands; hosted audit and gate completion remain separate.

@carloshvp

Copy link
Copy Markdown
Member

Maintainer-policy readback for current head 043be57a3eee9b0bd9f5d755c5bd0291031eeab1: rerunning the existing gate still fails with "Awaiting 1 independent maintainer approval(s) ... found 0" (attempt 3).

GitHub's raw review API currently returns my approval 5637901229 as APPROVED, type User, on that exact commit. Both the PR-base and head maintainer rosters include carloshvp. The ordinary eligibility calculation therefore finds one approval, while the executed gate finds none.

This is an unresolved policy/check-state discrepancy. The required gate should remain blocking until a legitimate current policy run succeeds; no code change or approval bypass was made for this retry. The existing technical approval remains attached to its reviewed commit.

Prepared with OpenAI Codex.

…t duplicate JSON keys across server, catalog, and inspection

- Reject len % 4 == 1 and non-canonical trailing bits in cmcp_runtime.agent_manifest._b64url_decode and verify v0.1 signature_value canonical encoding
- Reject private JWK key parameters in Agent Manifest trust anchors and catalog publisher_jwk entries
- Reject duplicate JSON object member names and non-finite constants across mcp/server.py, catalog/loader.py, agent_manifest.py, and inspection/pipeline.py
- Reject non-finite floats and integers outside the RFC 8785 safe-integer range in mcp/proxy.py (_cedar_safe, trace_action, _trace_begin, and _call_tool_impl)

Closes agentrust-io#798

Signed-off-by: Raghuvar Karthik Durga <177662415+drk-ram@users.noreply.github.com>
Signed-off-by: Raghuvar Karthik Durga <177662415+drk-ram@users.noreply.github.com>
@drk-ram

drk-ram commented Oct 29, 2026

Copy link
Copy Markdown
Author

@carloshvp @dinakarjs Rebased onto origin/main (6cf01bb, including #795 and #832 dependency-audit updates) in 31fdb56 (213 passed across the 5 focused unit test modules).

@drk-ram
drk-ram force-pushed the drk-ram-fix-runtime-canonical-base64url-json-key branch from 043be57 to 31fdb56 Compare October 29, 2026 15:28

@dinakarjs dinakarjs left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Follow-up at exact head 31fdb56, isolated checkout on Linux/Python 3.12.14.

Verified the rebased head incorporates the merged dependency-audit baseline and preserves the JSON/canonical-encoding and schema/PII follow-up paths inspected here. Full unit selection passes 2,595 tests with 6 skips after removing this environment's inherited SOCKS proxy variables; the first run's nine failures were missing SOCKS transport support in the environment. Ruff, mypy over 63 source files, configured Bandit and installed dependency consistency pass. This closes my requested rebase/test follow-up as a technical COMMENT; it does not resolve or bypass the previously reported maintainer-gate discrepancy, grant approval for an unreviewed commit, or establish hardware validation. Independent current-head maintainer review and a legitimate successful policy run remain required.

Reviewed with OpenAI Codex.

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 90.07634% with 13 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/cmcp_runtime/inspection/pipeline.py 87.87% 4 Missing ⚠️
src/cmcp_runtime/mcp/proxy.py 89.74% 4 Missing ⚠️
src/cmcp_runtime/catalog/loader.py 88.23% 2 Missing ⚠️
src/cmcp_runtime/mcp/server.py 85.71% 2 Missing ⚠️
src/cmcp_runtime/agent_manifest.py 96.42% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-review:MEDIUM Contributor check flagged MEDIUM risk

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(runtime): enforce canonical base64url in agent_manifest and reject duplicate JSON keys across server, catalog, and inspection

5 participants