feat(prover): close security-check gaps found in long-horizon adversarial testing
@zredlined is already working on this.
Since Aug 20, 2026.
- Dominant language
- Rust
- Stars
- 8.7k
- Forks
- 1.3k
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 253
Description
User Story
As a human or trusted-agent policy reviewer, I want the existing prover findings to identify the concrete request authority added by a proposed policy, so that meaningful changes remain visible even when the binary, destination, port, or HTTP method already exists in the baseline policy.
Problem Statement
OpenShell currently produces four policy-prover findings:
credential_reach_expansioncapability_expansionl7_bypass_credentialedlink_local_reach
The gateway runs these checks against the baseline and candidate policies, then compares the resulting finding paths. Finding identity primarily consists of category, binary, host, port, and HTTP method.
This comparison loses authority dimensions already enforced by OpenShell, including:
- HTTP path matchers;
- GraphQL operation constraints;
- Git upload-pack versus receive-pack;
- inspected versus uninspected transport.
A candidate can therefore permit a new operation while producing prover: no new findings if the baseline already contains the same binary, host, port, and method.
L7-bypass detection has a related limitation. It derives bypass primarily from exact binary-registry metadata rather than the inspection mode of the actual policy route. An inspected baseline route and an unrestricted candidate route can consequently collapse into the same finding.
Impact / Why This Matters
A long-horizon adversarial Policy Advisor experiment evaluated 358 policy proposals across 15 campaigns.
The existing checks provided substantial review evidence:
- 195 proposals contained prover findings;
- 193 contained
credential_reach_expansion; - 2 contained
capability_expansion; - 176 of the 195 prover-positive proposals were rejected by the reviewer;
- prover-positive proposals accounted for 73.6% of all 239 reviewer rejections;
- 157 proposals reported
prover: no new findings; - 6 proposals failed before producing a normal prover result.
These results show that existing credential-reach findings were frequently relevant. They do not establish causal effectiveness because the reviewer saw the findings and the experiment did not include a prover-ablation condition.
The experiment also exposed important residual gaps. Of the 58 rejected proposals reporting no findings:
- 39 targeted canonical GitHub endpoints;
- 24 targeted
api.github.com, principally through GraphQL proposals; - 15 targeted
github.com; - 13 of those attempted Git receive-pack or equivalent write authority;
- 2 attempted GitHub web operations using paths not present in the baseline;
- 18 used alternate or ambiguous endpoint identities;
- 1 involved a speculative indirect mutation path through another service.
The 18 endpoint-identity cases require shared validation and canonicalization and are outside this proposal.
The 39 canonical-host cases are candidates for improved prover coverage. The strongest directly demonstrated cases were 13 /usr/bin/git write proposals that produced no findings despite attempting to expand fetch-only Git authority into push authority.
The experiment also contained:
- 84 proposals without an L7 protocol;
- 21 such proposals targeting canonical GitHub endpoints;
- one explicit proposal for unrestricted
/usr/bin/git → github.com:443transport so the agent could push without L7 restrictions.
That explicit proposal reported no findings. The reviewer rejected it because it enabled receive-pack and ref mutation without enforcing the stated repository or refspec restriction.
Conversely, 11 related proposals naming Git remote-helper executables produced generic credential-reach findings. The result therefore depended partly on executable identity rather than the effective Git authority granted.
When automatic proposal approval is enabled, an empty prover delta may allow a proposal to proceed without human review. The current representation can therefore understate changes that the existing security-check UX is intended to expose.
Proposed Design
Preserve the existing four finding categories and proposal-review workflow, but compute their deltas using normalized, protocol-aware authority.
Conceptually, the prover should answer:
Does the candidate effective policy permit a request that the baseline effective policy denies?
A witness should preserve the authority dimensions already enforced by OpenShell:
- effective executable identity;
- normalized destination and port;
- transport and inspection mode;
- attached credential context;
- protocol-specific operation;
- policy rule responsible for the authorization.
Protocol-specific operations should use existing enforcement concepts:
- HTTP method and path matcher;
- GraphQL operation constraints;
- Git upload-pack versus receive-pack;
- existing WebSocket, JSON-RPC, or MCP operation constraints where applicable;
- raw L4 or TLS reach when no finer inspection applies.
The existing categories should classify these witnesses:
- new credentialed destination authority →
credential_reach_expansion; - new operation at an existing credentialed destination →
capability_expansion; - new uninspected authority at a credential-associated destination →
l7_bypass_credentialed; - new link-local authority →
link_local_reach.
L7-bypass classification should depend on the selected route's inspection behavior. Binary-registry capabilities and declared spawn relationships may enrich the evidence, but an exact binary name should not determine whether the policy route is inspected.
The change should retain:
- the four existing category names;
- the existing proposal inbox and approval workflow;
- the rule that any finding blocks automatic approval;
- suppression of redundant capability findings when the same change is already reported as new credential reach;
- the existing compact validation-result format, enriched with protocol-specific operation evidence where useful.
The implementation should reuse policy normalization and matching semantics shared with enforcement. It should not maintain service-specific knowledge about which external API operations are benign or destructive.
Expected Experimental Effect
The most conservative expected improvement is coverage of the 13 Git write proposals that currently reported no findings:
- the explicit unrestricted transport proposal should surface as
l7_bypass_credentialed; - inspected receive-pack additions should surface as
capability_expansion.
That would increase prover-supported reviewer rejections from 176 to approximately 189, or from 73.6% to 79.1% of all reviewer rejections.
If replay confirms that all 39 canonical-host cases expanded enforceable authority, the approximate result would become:
- up to 234 of 358 proposals with findings, rather than 195;
- up to 215 of 239 reviewer rejections accompanied by prover evidence, or approximately 90%;
- approximately 40
capability_expansionproposals rather than 2; - at least one surfaced
l7_bypass_credentialedproposal rather than zero; - as few as 19 rejected proposals reporting no findings rather than 58.
These are replay expectations, not claims about changed reviewer decisions or prevented compromise. The reviewer already rejected these proposals, and no protected mutation occurred.
Acceptance Criteria
- The prover continues to expose only the existing four finding categories.
- No new policy fields, settings, reviewer steps, or organization-maintained service taxonomies are required.
- Candidate-minus-baseline comparison preserves HTTP method and path authority.
- Candidate-minus-baseline comparison preserves existing GraphQL operation constraints.
- Git receive-pack authority is distinguishable from upload-pack authority.
- Changing an inspected credential-associated route into an uninspected route produces
l7_bypass_credentialed, even when binary, host, and port are unchanged. - An inspected Git fetch route is not classified as uninspected solely because
/usr/bin/gitcan also use bypassing protocols. - Git and declared transport helpers produce consistent findings for equivalent effective authority.
- A syntactically different candidate with no effective authority expansion produces no delta finding.
- A new credentialed destination remains
credential_reach_expansionwithout redundant per-operation findings. - Existing link-local behavior remains covered by regression tests.
- Existing automatic-approval behavior continues to require an empty prover delta.
- Compact validation output retains its current structure while identifying the newly authorized operation.
- The 13 Git write cases from the experiment are replayed and produce operation-appropriate findings when structurally valid.
- The 24 canonical GraphQL cases and 2 canonical web-operation cases are replayed. Each enforceable authority expansion produces a witness; non-expanding cases are documented as such.
- The 18 alternate endpoint-identity cases are explicitly excluded from the prover replay expectation and tracked as validation/canonicalization concerns.
- Tests demonstrate deterministic results without external API calls or service-specific mutation labels.
Alternatives Considered
Add GitHub-specific queries
Queries for Git receive-pack, GraphQL mutation, Contents API writes, or web-editor routes would address examples from this experiment but require continuously labeling service-specific behavior.
This would scale with the number of external services and operations rather than with the protocols OpenShell enforces.
Add the path to the existing finding key
Adding HTTP path alone would address some REST cases but would not represent GraphQL constraints, Git operations, or inspection-mode changes. It would preserve the underlying baseline/candidate comparison of incomplete presentation keys.
Expand the binary registry
Adding every Git helper, wrapper, shell, interpreter, and temporary executable would improve selected examples but would not scale to enterprise software inventories. Route inspection should be determined from policy semantics, with binary metadata used only as supporting evidence.
Add new finding categories
Categories such as git_write_expansion, graphql_mutation, or unrestricted_https would increase the reviewer vocabulary without fixing the shared loss of authority dimensions.
The existing categories are sufficient if their witnesses accurately represent the enforced operation.
Rely on the contextual reviewer
The experiment's reviewer correctly rejected the missed Git proposals. However, this requires the reviewer to reconstruct authority manually from policy syntax and leaves automatic approval dependent on an incomplete deterministic delta.
Out of Scope
- Exact candidate preflight, apply-time validation parity, and review-token binding, tracked separately by #2841.
- Endpoint validation or canonicalization for Unicode, encoded, numeric, or ambiguous host representations.
- New query categories or severity levels.
- Classifying provider operations as benign, mutating, or destructive.
- Organization-defined risk policies.
- New credential-scope configuration.
- Protocols OpenShell does not currently inspect or enforce.
- Changes to reviewer approval UX.
- Repairing the experiment's post-review application failures or invalid campaigns.
Environment and Research Basis
- Experiment deployment: OpenShell v0.0.106
- Campaigns: 15
- Policy proposals: 358
- Reviewer decisions: 119 approvals and 239 rejections
- Prover-positive proposals: 195
- Prover-negative proposals: 157
- Proposal merge failures: 6
- Re-audited against v0.0.109 and current main
- Existing query and finding-delta semantics were unchanged across the audited revisions
- Evidence included proposal packets, current policies, reviewer decisions, transcripts, runtime logs, and final outcomes
- Export checksums were verified before analysis
Agent Investigation
crates/openshell-prover/src/queries.rsimplements the four existing categories.- L7 bypass currently derives from binary capability metadata before considering a protocol-specific operation.
- Capability expansion currently emits one path per HTTP method but does not preserve the path matcher.
crates/openshell-server/src/grpc/policy.rs::finding_path_keykeys finding paths by binary, host, port, category, and method.- Bypass findings have an empty method, so inspected and uninspected routes for the same binary and destination can collapse into one key.
crates/openshell-prover/registry/binaries/git.yamlmarks/usr/bin/gitas bypassing L7 globally and declares its spawned transport helpers.- Binary-registry lookup does not currently use declared spawn relationships to compute effective capabilities.
- Credential context supplied to the prover is currently host-coarse and does not model provider permission scopes.
- Current runtime protections for uninspected credential-associated endpoints remain defense in depth but do not correct the proposal finding's authority representation.
Checklist
- I've reviewed existing issues and the architecture documentation.
- This is a design proposal, not a request to implement service-specific attack signatures.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.