Skip to content

test(security): execute permission gate corpus - #601

Open
rakeshutekar wants to merge 1 commit into
andrewyng:mainfrom
rakeshutekar:test/permission-gate-corpus-runner
Open

test(security): execute permission gate corpus#601
rakeshutekar wants to merge 1 commit into
andrewyng:mainfrom
rakeshutekar:test/permission-gate-corpus-runner

Conversation

@rakeshutekar

Copy link
Copy Markdown
Contributor

Summary

The layered permission-gate corpus documents 120 deterministic security scenarios, but those scenarios were not executed against the production PermissionEngine.

This meant permission behavior could drift from expected_current without CI detecting the regression.

This change adds an offline corpus runner that executes every permission-gate row through the real engine. Current-policy mismatches fail the run, while differences from the recommended expected_secure policy are reported separately as remediation work.

Behavior

The runner classifies each production decision as:

  • allow_without_reviewer
  • reviewer_eligible
  • human_only
  • hard_deny

A run fails when the actual decision differs from expected_current.

Differences from expected_secure remain visible in the report but do not fail the run when current behavior still matches the documented implementation. This prevents acknowledged security gaps from being silently blessed while keeping regression detection deterministic.

The runner evaluates policy only. It does not execute tools, invoke the reviewer, call a model, or make network requests.

Implementation

  • Replay all 120 permission_gate.jsonl scenarios through PermissionEngine.evaluate
  • Construct engine state from the row's mode, roots, metadata, and declarative setup.permission_engine configuration
  • Encode command allowlists, domain allowlists, standing rules, and risk overrides directly in their fixtures
  • Reject unknown or incorrectly typed setup fields instead of silently ignoring fixture state
  • Report current-policy mismatches and secure-policy differences separately
  • Return a non-zero CLI exit status only for validation errors or current-policy regressions
  • Add pytest coverage proving every corpus row reaches the real permission engine

The MCP override fixture now supplies an actual risk override instead of relying on metadata that already produced the expected result.

Compatibility

This PR does not change production permission behavior or public runtime APIs.

setup.permission_engine is an optional additive corpus field. Existing rows without engine-specific state continue to use the default production configuration.

The runner is independent of the model-backed reviewer evaluation harness.

Verification

  • python scripts/build_layered_corpora.py
    • 302 total layered scenarios generated
  • python scripts/validate_layered_corpora.py
    • all layered corpora valid
  • python scripts/eval_permission_gate.py
    • 120 permission rows executed
    • 0 current-policy mismatches
    • 36 secure-policy differences reported
  • affected and adjacent security suites
    • 155 passed
  • python -m compileall -q scripts/eval_permission_gate.py tests/test_permission_gate_corpus.py
  • git diff --check

Coverage includes all permission modes, write scoping, deferred-execution files, shell actions, egress, persistent authority, command and domain allowlists, standing rules, unknown tools, MCP overrides, browser actions, and connector operations.

Coordination

This PR is independent of #587.

#598 also changes the layered corpus generator and permission-gate fixtures. If it merges first, this branch should be rebased and the generated corpus refreshed before merging.

Out of scope

This PR does not implement the 36 recommended secure-policy changes. It reports them as explicit remediation gaps.

It also does not add evaluators for reviewer_actions.jsonl or action_sequences.jsonl; those require separate model-backed and sequence-aware harnesses.

Replay every deterministic permission scenario through the real PermissionEngine and fail on current-policy regressions while reporting secure-target gaps separately. Encode allowlist, standing-rule, and risk-override state directly in corpus fixtures so runs are self-contained.
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