Skip to content

bug(policy): auto-approval leaves unmergeable proposals pending without an actionable reason #2821

Description

@krishicks

User Story

As a sandbox developer using automatic policy proposals, I want safe proposals to either merge automatically or explain why they could not, so that I can iterate on a workload without repeatedly diagnosing opaque 403 failures.

Problem Statement

When a host and port already exist as an inspected endpoint for one binary, a denial from another binary can produce a mechanistic proposal for a separate generic L4 endpoint. The proposed endpoint conflicts with the existing endpoint metadata for the same host and port.

The prover can report no new findings while auto-approval subsequently fails during merge or policy validation. The proposal remains pending, but openshell rule get only shows the successful prover result. It does not expose the auto-approval failure. Repeated attempts continue failing and incrementing the proposal hit count.

Impact / Why This Matters

Auto mode appears enabled and the proposal appears safe, but the workload does not progress. Users must inspect gateway logs, infer an endpoint-ambiguity conflict, and manually author a compatible rule. This defeats the quicker deny-propose-approve-retry workflow and is especially costly for dependency resolvers that repeatedly retry the same request.

The current presentation is also misleading: prover: no new findings is shown beside a pending proposal without the separate merge-validation failure that explains why it was not approved.

Acceptance Criteria

  • A mechanistic proposal for a new binary on an existing host and port preserves compatible endpoint metadata or otherwise proposes a mergeable binary expansion without weakening L7 enforcement.
  • With proposal_approval_mode=auto, a mergeable proposal with an empty prover delta and no security notes is approved, persisted as a new base-policy revision, and hot-reloaded.
  • If auto-approval cannot merge or validate a proposal, the failure reason is persisted with the chunk and displayed by openshell rule get.
  • The displayed status distinguishes prover success from merge or policy-validation failure.
  • Repeated observations deduplicate against the existing chunk without hiding the failure reason or creating an indefinite unexplained retry loop.
  • If a later policy revision already covers the pending proposal, the proposal is reconciled into an appropriate terminal or superseded state.
  • Existing L7 endpoint behavior is not silently downgraded to L4 passthrough.

Reproduction Steps

  1. Create repro-policy.yaml with a REST endpoint for one binary:

    version: 1
    
    network_policies:
      cargo_registry:
        name: cargo-registry
        endpoints:
          - host: index.crates.io
            port: 443
            protocol: rest
            enforcement: enforce
            access: read-only
        binaries:
          - path: /usr/bin/cargo
  2. Create a sandbox with the policy and auto approval:

    openshell sandbox create \
      --policy repro-policy.yaml \
      --approval-mode auto \
      auto-approval-repro \
      -- sleep infinity
    
    openshell settings set auto-approval-repro \
      --key agent_policy_proposals_enabled \
      --value true
  3. From a different binary, request the same host and port:

    openshell sandbox exec auto-approval-repro -- \
      /usr/bin/curl https://index.crates.io/config.json
  4. Wait for policy analysis to flush, then inspect pending rules:

    sleep 15
    openshell rule get auto-approval-repro --status pending
  5. Observe a pending L4 proposal for /usr/bin/curl on index.crates.io:443 with prover: no new findings. The request remains denied. Gateway logs contain an auto-approval failure, but the chunk output does not contain its reason.

Environment

  • OpenShell CLI: 0.0.83
  • Host OS: macOS Darwin 25.5.0, ARM64
  • Compute runtime: Podman
  • Policy advisor: enabled at sandbox scope
  • Proposal approval mode: auto at sandbox scope
  • Providers v2: enabled globally

Logs

Status: pending
Rule: allow_index_crates_io_443
Binary: /usr/bin/curl
Validation: prover: no new findings
Endpoints: index.crates.io:443 [L4]

[gateway] WARN auto-approval failed; chunk remains pending for human review

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