Skip to content

fix(verify): enforce credential validity windows and hop timestamp ordering in cross_check_trace_dag (#306) - #308

Open
drk-ram wants to merge 1 commit into
agentrust-io:mainfrom
drk-ram:fix-lineage-hop-times
Open

drk-ram wants to merge 1 commit into
agentrust-io:mainfrom
drk-ram:fix-lineage-hop-times

Conversation

@drk-ram

@drk-ram drk-ram commented Nov 6, 2026

Copy link
Copy Markdown

What

Enforce delegation credential validity windows (iat, nbf, exp) and non-decreasing hop timestamps (iat) against parent hops inside cross_check_trace_dag (ca2a verify-lineage).

Why

cross_check_trace_dag checked hop signatures, subject/issuer continuity, and scope attenuation, but never compared a hop record's iat against the matched delegation credential's [nbf, exp] validity window or the parent hop's iat. As a result, hop records signed after credential expiry, before nbf/iat, or backdated before their parent hop were reported as authenticated_lineage.

Closes #306

Security impact

Prevents expired, premature, or backdated hop records from passing cross_check_trace_dag and ca2a verify-lineage as authenticated_lineage.

Test plan

  • pytest passes (pytest tests/unit/test_trace_binding.py tests/unit/test_lineage_cli.py — 71 passed)
  • ruff check passes (ruff check src tests — passed)
  • mypy passes (mypy src — passed)
  • Manual test performed (describe steps below if applicable)

DCO sign-off

  • My commits include Signed-off-by: (git commit -s)

Signed-off-by: Raghuvar Karthik Durga <177662415+drk-ram@users.noreply.github.com>
@drk-ram
drk-ram requested review from a team, carloshvp and zohebk8s as code owners November 6, 2026 16:30
@github-actions

github-actions Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

🔴 Contributor Check: HIGH

Check Result
Profile HIGH
Credential LOW
Overall HIGH

Automated check by AgenTrust Contributor Check.

@github-actions github-actions Bot added the needs-review:HIGH Contributor check flagged HIGH risk label Nov 6, 2026

@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 commit 622bc061b564419c451e397097992dd2ef0a7e1e.

The new checks bind each signed hop's iat to its credential's inclusive validity window and reject a hop that precedes its parent. Equal timestamps and inclusive endpoints remain accepted. The documentation correctly separates signer-asserted time from independent evidence of creation time and from verify_chain(at_time=...).

In a credential-free, network-disabled Python 3.12 environment installed from this head's hash lock, all 47 tests in test_trace_binding.py and test_lineage_cli.py pass. Full-source Ruff, mypy (47 files), and configured Bandit pass. Restoring only the base dag.py while retaining the new tests produces four failures, including the CLI falsely returning success; the reviewed source was then restored. DCO sign-off is present.

Security impact: the offline verifier now refuses the out-of-window and backward-ordered signed histories described in #306, while preserving signature and credential checks. This is one of the two maintainer approvals required for src/ca2a_verify/. Hosted CI remains action_required and has not supplied runtime-test evidence on this head; the full hosted matrix and remaining approval are still required before merge.

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

Reviewed 622bc06. The change checks each hop against its matched credential's inclusive not_before/not_after bounds and rejects decreasing hop times, preserving equal timestamps and optional bounds. I found no blocking defect in this bounded change. Signed iat remains a signer assertion, not independent evidence of creation time; verify_chain and verify_trace_dag remain prerequisites.

Independent local validation on Linux/Python 3.12.14, installed editable after the unchanged hash-required dev lock: 47 focused trace-binding/lineage CLI tests pass; full-source Ruff, mypy (47 files), Bandit and pip dependency installation complete. Ten additional signed-record boundary controls passed, covering absent/one-sided bounds and out-of-window records at each of three positions. Replacing only dag.py with its parent version produces four behavioral failures (including CLI false success), with 43 controls still passing; source restored exactly. Initial exploratory timestamps below the TRACE schema minimum were corrected before these boundary results.

Security impact: refuses signed out-of-window and backward-ordered histories at the credential/record reconciliation boundary. Current hosted CI/CodeQL remain action_required; this is a bounded code approval, not hosted-matrix completion, merge authorization, or a claim to satisfy the required two-maintainer gate. PR description says 71 focused tests; this exact head collects 47, so please align that count. Prepared 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:HIGH Contributor check flagged HIGH risk

Projects

None yet

3 participants