Skip to content

[P1] Gate pass markers are forgeable, so hard gates can self-approve #160

Description

@tg12

Severity: P1 critical

Problem

Hard gates trust writable files under .codearbiter/.markers/ as proof that a privileged review path already passed.

Source evidence:

  • plugins/ca/hooks/pre-bash.py:449-467 trusts .codearbiter/.markers/security-gate-passed when it is fresh and contains the digest of each sensitive added line.
  • plugins/ca/hooks/security-pass.py:75-90 writes that marker unconditionally for the current diff. The script itself does not verify that crypto-compliance or secret-handling actually ran.
  • plugins/ca/hooks/pre-bash.py:508-524 trusts .codearbiter/.markers/migration-gate-passed for migration commits.
  • plugins/ca/hooks/migration-pass.py:82-95 writes migration digests unconditionally for current migration files.
  • plugins/ca/skills/decision-lifecycle/SKILL.md:31-38 authorizes ADR writes by touching .codearbiter/.markers/adr-authoring-active.
  • plugins/ca/hooks/pre-write.py:36-42 and pre-edit.py:64-70 allow ADR writes whenever that marker exists and is fresh.

The Write/Edit guards do not protect .codearbiter/.markers/*, and pre-bash.py does not block direct execution of security-pass.py, migration-pass.py, or touch .codearbiter/.markers/adr-authoring-active.

Reproduction

In a throwaway enabled repo, stage a crypto change containing hashlib.md5(...).

Control case:

without marker exit 2
without marker stderr BLOCKED [H-09b]: This commit introduces crypto/TLS changes, but no security-gate pass is recorded ...

Then hand-write .codearbiter/.markers/security-gate-passed with the line_digest() of that added line, without running any security review.

Observed:

forged marker exit 0
forged marker stderr

The same class applies to migration-gate-passed by writing content_digest() values, and to ADR authoring by creating adr-authoring-active.

Impact

The marker files are the mechanism that turns a BLOCK into an allow. Because they are ordinary writable repo files and their producer scripts can be invoked directly, an agent can approve its own security, secret, migration, or ADR gate without the corresponding reviewer/skill ever running.

This collapses the hard-gate model to prose compliance.

Smallest credible fix

Do not treat a repo-writable marker as sufficient authority by itself.

Possible directions:

  • Block direct Write/Edit/Bash mutation of load-bearing marker files.
  • Block direct security-pass.py and migration-pass.py execution outside a sanctioned gate context.
  • Bind marker creation to a command-scoped nonce or signed receipt emitted by the reviewing gate, not just to diff content.
  • Add regression tests that direct marker writes and direct marker-script invocations cannot unblock H-09b/H-10b/H-14/H-11.

Duplicate check

Checked existing issues with:

gh issue list --repo arbiterForge/codeArbiter --state all --search "security-gate-passed OR migration-gate-passed OR adr-authoring-active OR marker forge OR forge marker OR marker bypass"

No matching marker-forgery issue was returned.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions