Skip to content

fix(verify,runtime): reject private JWK members, non-canonical base64url, lone surrogates, and duplicate JSON keys (#267) - #270

Open
drk-ram wants to merge 1 commit into
agentrust-io:mainfrom
drk-ram:drk-ram-fix-verify-runtime-hardening-267
Open

drk-ram wants to merge 1 commit into
agentrust-io:mainfrom
drk-ram:drk-ram-fix-verify-runtime-hardening-267

Conversation

@drk-ram

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

Copy link
Copy Markdown

What

Reject RFC 7517/7518/8037 private JWK members and non-canonical base64url keys in ca2a_verify.dag and ca2a_runtime.agent_manifest, reject lone UTF-16 surrogates in ca2a_runtime.canonical, and reject duplicate JSON object keys in ca2a_verify.verify.

Why

Closes items 1-3 of #267 (item 4 is covered by #269).

Security impact

Prevents private key material (d, p, q, dp, dq, qi, oth, k) and malleable base64url public keys from being accepted in TRACE DAG verification and Agent Manifest trust anchors, prevents lone UTF-16 surrogates from leaking UnicodeEncodeError during RFC 8785 canonicalization, and blocks duplicate-key JSON smuggling in chain and revocation files.

Test plan

  • pytest passes (pytest tests/unit/test_agent_manifest_cose.py tests/unit/test_canonical.py tests/unit/test_trace_binding.py tests/unit/test_verify.py -q: 105 passed)
  • ruff check and ruff format --check pass (All checks passed!)
  • mypy passes (mypy --strict src/ca2a_runtime/canonical.py src/ca2a_verify/verify.py: Success)
  • Manual test performed (verified private JWK, non-canonical base64url, lone surrogate, and duplicate-key rejection cases)

DCO sign-off

@drk-ram
drk-ram requested review from a team, carloshvp and zohebk8s as code owners October 23, 2026 15:10
@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 365bed8. Independently ran the four test modules named in the description against fetched, pinned repository source on Linux/Python 3.12: 105 passed, not 176. Ruff passes for all four changed source modules. Please reconcile the description's count or provide the additional selection/revision behind 176.

The inspected changes preserve InvalidCredential/InvalidRevocation translation for duplicate JSON members, reject private JWK parameters before decoding, enforce canonical 32-byte DAG keys, and give an exact ValueError for surrogate input. Existing accepting cases and the added refusal cases pass. No additional blocker found in this bounded review; #269 remains a separate freshness change.

This was not a hash-locked full-suite run (dependencies included agent-manifest 0.15.0, agentrust-trace 0.11.0 and trace-tests 0.6.2). Source import paths were checked. Hosted full CI, types/security checks and the two-maintainer requirement for ca2a_verify remain separate; I am not claiming merge readiness or hardware acceptance. Reviewed with OpenAI Codex.

dinakarjs added a commit to dinakarjs/ca2a that referenced this pull request Oct 23, 2026
Format four changed test files without altering their Python ASTs.

Signed-off-by: Srinivasa Dinakar Jainti <dinakarjs@gmail.com>

@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 exact-head validation: 879 unit/conformance tests passed, 11 skipped, 90.53% coverage; Ruff lint, mypy (47 files), and Bandit passed in a hash-locked editable-install environment. The required Ruff formatting gate fails in four changed test files: test_agent_manifest_cose.py, test_canonical.py, test_trace_binding.py, and test_verify.py. I prepared commit c3a9dd3 on dinakarjs/ca2a branch fix/270-format-gate for adoption. The four ASTs are unchanged and the formatting gate then passes across all 107 files. The existing implementation still needs its hosted checks and independent maintainer approval.

…url, lone surrogates, and duplicate JSON keys (agentrust-io#267)

- Reject RFC 7517/7518/8037 private JWK parameters and non-canonical base64url encodings in ca2a_verify.dag and ca2a_runtime.agent_manifest.
- Reject lone UTF-16 surrogates (U+D800..U+DFFF) in ca2a_runtime.canonical keys and string values per RFC 8785 / I-JSON.
- Reject duplicate JSON object keys in ca2a_verify.verify (verify_chain_file and load_revocation_snapshot).

Refs agentrust-io#267

Signed-off-by: Raghuvar Durga <177662415+drk-ram@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@drk-ram
drk-ram force-pushed the drk-ram-fix-verify-runtime-hardening-267 branch from 365bed8 to b4bb370 Compare October 23, 2026 23:12
@drk-ram

drk-ram commented Oct 23, 2026

Copy link
Copy Markdown
Author

Thank you @dinakarjs! Applied
uff format across the four test files (
uff format --check src tests passes across all 107 files) and updated the PR description to state the exact 4-file count (105 passed).

@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 b4bb370703e176920d0aaa4cebcb5f8915ac6db7 in an isolated checkout.

Reviewed public-only Ed25519 JWKs, canonical encodings and key lengths, controlled lone-surrogate rejection and duplicate-member rejection in credential/revocation file loading. The updated formatting and expanded malformed-input cases are present. Valid signed-chain and COSE controls remain passing; no blocking source finding in this scope.

Fresh hash-locked Python 3.12.10 validation: 821 unit tests passed, 16 skipped; pip check, Ruff, mypy, Bandit and diff whitespace checks passed. Every PR commit has a sign-off. Hosted CI and the required maintainer/security approval inventory remain separate from this source approval.

Reviewed with OpenAI Codex.

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.

3 participants