Skip to content

feat: cryptographic agent identity binding for sandbox policy #682

@aeoess

Description

@aeoess

Problem Statement

OpenShell enforces policy at the binary/destination/method/path level — strong containment. But sandboxes have no cryptographic agent identity. The sandbox knows what process is running, not who authorized it or what scope they were granted.

This matters in three scenarios:

  1. Multi-tenant gateways — when multiple agents share infrastructure, there's no way to verify that the agent requesting sandbox creation was authorized by a specific principal with a specific scope. A compromised orchestrator can spin up sandboxes for any agent.

  2. Cross-sandbox delegation — Agent A in Sandbox 1 delegates a subtask to Agent B in Sandbox 2. OpenShell can enforce that B's sandbox has a restrictive policy, but cannot verify that B's authority derives from A's delegation, or that A had the scope to delegate in the first place.

  3. Audit attribution — OpenShell logs allow/deny decisions, but the audit trail attributes actions to sandbox IDs, not to cryptographic identities. An agent that rotates through sandboxes loses its audit history.

Proposed Design

Add a identity_policy section to the sandbox policy schema that binds sandboxes to cryptographically verified agent identities. The identity layer sits above the existing four policy domains (filesystem, network, process, inference) and gates sandbox creation.

1. Policy schema extension:

version: 1

# New: cryptographic identity binding
identity_policy:
  require_passport: true
  trusted_issuers:
    - name: aeoess
      public_key: "e11f46f5831432d17852189d5df10ed21d5774797ae9ee52dbab8c650fec16ae"
      verify_url: "https://aeoess.com/.well-known/aeoess-issuer.json"
  delegation_scope_mapping:
    "filesystem:read": { filesystem_policy: "read_only" }
    "filesystem:write": { filesystem_policy: "read_write" }
    "network:*": { network_policies: "allow" }
    "inference:local": { inference_routing: "local_only" }
  max_delegation_depth: 3

# Existing sections unchanged
filesystem_policy: ...
network_policies: ...
process: ...

2. Sandbox creation flow change:

Current:  openshell sandbox create -- claude
Proposed: openshell sandbox create --passport ./agent-passport.json -- claude

At creation, the gateway:

  • Verifies the agent's self-signature (Ed25519)
  • Verifies the issuer countersignature against trusted_issuers
  • Extracts delegation scope from the passport's delegation chain
  • Maps delegation scopes to policy domains via delegation_scope_mapping
  • Generates a sandbox policy that is the intersection of the YAML policy and the delegation scope
  • Stores the passport public key as the sandbox identity for audit attribution

3. Runtime identity binding:

The sandbox metadata (already stored in the gateway's SQLite/Postgres) gains an agent_public_key field. Audit logs include this key, creating a continuous identity across sandbox restarts. The OPA engine gains a new input field agent.public_key available in Rego rules for identity-aware policy decisions.

4. Cross-sandbox verification:

When Sandbox A needs to delegate to Sandbox B, the delegation chain is verified: A's passport must include scope for the delegated action, and B's scope must be a subset of A's (monotonic narrowing). The gateway enforces this at sandbox creation — B cannot be created with broader scope than A granted.

Alternatives Considered

Process identity only (current approach): Sufficient for single-sandbox isolation but breaks down in multi-agent, multi-tenant deployments where knowing which agent matters, not just which process.

API key per sandbox: Simpler but doesn't support delegation chains, scope narrowing, or cascade revocation. An API key is all-or-nothing.

OAuth/JWT tokens: Standard identity but no delegation chain semantics, no monotonic narrowing, no cryptographic scarring on misbehavior.

Agent Investigation

The Agent Passport System (Apache 2.0, npm install agent-passport-system) already implements the identity primitives this design requires:

  • countersignPassport() / verifyIssuerSignature() — CA model, issuer countersigns passports, verifiers check published public key
  • createDelegation() / verifyDelegation() — scoped delegation chains with monotonic narrowing
  • cascadeRevoke() — revoke one delegation, all downstream die
  • resolveTierAuthority() — Bayesian reputation gates effective permissions

SDK: v1.29.0, 1852 tests, 94 modules. MCP server: 122 tools.
Issuer public key: https://aeoess.com/.well-known/aeoess-issuer.json
Paper: https://doi.org/10.5281/zenodo.19260073 (Faceted Authority Attenuation)
GitHub: https://github.com/aeoess/agent-passport-system

The proposed delegation_scope_mapping is a thin adapter layer — APS scopes are strings, OpenShell policy domains are YAML sections. The mapping is deterministic and can be evaluated at sandbox creation without runtime overhead.

Checklist

  • I've reviewed existing issues and the architecture docs
  • This is a design proposal, not a "please build this" request

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