Skip to content

Policy provider

A Policy provider is a translator.

It takes the Compiled Policy (same JSON for every agent in your org) and writes the config that one specific runtime target actually understands.

Without Policy providers, the Compiled Policy is just a file. With them, it becomes actual enforcement on a real target.

Note on naming. The earlier card simply called this "Provider", which conflated the translator concept with the LLM API client concept (gateway/anthropic.py, gateway/openai.py, …). The two are now split:

  • Policy provider (this card) — translates Compiled Policy → target-specific runtime config. Pure function.
  • LLM provider — HTTP client integration to one LLM API. Executes calls.

The Compiled Policy taxonomy below is unchanged — only the name is qualified.

Takesa Compiled Policy
Outputstarget-specific config (Claude Code's settings.json, OpenShell's YAML, Monty's host-function spec, …)
Invoked bythe host runtime (tappass-host) at Sandbox start + on every Compiled Policy update
Contractprovider(manifest, target_capabilities) → target_config — pure function, deterministic

Every Policy provider speaks one tool's local language:

ProviderKnows how to…
claude-codeWrite ~/.claude/settings.json with the right permissions.allow / permissions.deny / hooks from the Compiled Policy's tools and compliance_tags
cursorWrite Cursor's config + set its OpenAI-compat base URL
openshellWrite an OpenShell YAML profile with the network egress allowlist (from network.allow_domains), the Landlock rules (from filesystem.deny_paths), and credential hiding
nonoInvoke nono with the right --allow / --deny flags derived from the Compiled Policy
gvisorWrite a runsc policy + K8s pod-spec annotations
montyWrite a Monty host-function manifest from interpreter.host_functions, with the memory and CPU caps
anthropic-gateway (cross-cutting)Set ANTHROPIC_BASE_URL; configure per-call budget from budget.tokens_per_day
mcp-broker (cross-cutting)Configure per-tool ACLs and per-server allowlists

Each Policy provider is one well-scoped translator — typically a 2-week project.

Customers don't all use the same tools. A fintech CISO governs Macs running Claude Code, Linux servers running CI agents, and EKS pods running production agents — all from the same Policy. The substrate stays generic; Policy providers handle the local idioms.

Adding a new ecosystem (say, n8n) ≈ adding one Policy provider. The Runtime concept, the control plane, and the Compiled Policy itself are unchanged.

The Terraform analogy: Policy providers are to TapPass what aws / gcp / azure plug-ins are to Terraform's HCL. Pure functions. Composable. Same source-of-truth, many targets.

The contract: provider(manifest, target_capabilities) → target_config. Pure function. Deterministic. No side effects in compilation; only on apply.

The Policy-provider taxonomy is the unit of TapPass's expanding surface coverage.

The Policy-provider taxonomy (one per target across the three rings)

Section titled “The Policy-provider taxonomy (one per target across the three rings)”

Harness-ring providers (semantic, cooperative)

Section titled “Harness-ring providers (semantic, cooperative)”
Provider idTargetNative artifact
claude-codeClaude Code IDEmanaged settings.json
codexCodex CLI~/.codex/config.toml
cursorCursor IDEper-vendor config
clineClineper-vendor config
windsurfWindsurfper-vendor config
aiderAider OSS coding agent.aider.conf.yml
langgraph, crewai, autogenFramework agentstool catalogue API
librechatLibreChat self-hostedTapPass plugin
element-bot, slack-bot, discord-bot, teams-botBot frameworksbot-SDK wrapper
sdk-directCustom code via TapPass SDKnative; the canonical fallback

Kernel-ring providers (compulsory, coarse)

Section titled “Kernel-ring providers (compulsory, coarse)”
Provider idTargetBest forUpdate model
openshellOpenShell + L7 proxyservers, CI, K8shot-reload network; restart for FS/exec
nononono capability sandbox (Landlock / sandbox-exec)dev laptopsrestart-only
gvisorgVisor user-space kernelCloud Run, GKEper-pod restart
firecrackerFirecracker microVMAWS, Fly.io, multi-tenant edgeVM restart
bubblewrapLinux namespacesLinux dev / CIrestart-only
macos-sandbox-execmacOS native sandboxmacOS-specificrestart-only
windows-appcontainerWindows AppContainerWindowsrestart-only
k8s-netpol-gatekeeperK8s NetworkPolicy + OPA Gatekeepercluster-levellive admission + runtime
Provider idTargetLanguage
montyMonty (Rust-based, capability-only)Python subset
pyodidePyodide (WASM)Python full
v8-isolatesV8 isolates (Cloudflare Workers pattern)JavaScript / TypeScript
wasmtimeWasmtime + WASIpolyglot via WASM
restricted-duckdbDuckDB with restricted viewsSQL

Cross-cutting providers (gateway + MCP broker)

Section titled “Cross-cutting providers (gateway + MCP broker)”

These are not ring providers — they sit between processes rather than inside one. Treated as separate "providers" in code organization, but architecturally cross-cutting layers, not rings.

Provider idTargetWhat it does
llm-gateway-anthropicAnthropic Messages APIenv-var redirect; pipeline; budget
llm-gateway-openaiOpenAI-compat (chat completions)same
llm-gateway-vertexGoogle Vertex AI / Geminisame (planned)
llm-gateway-litellmLiteLLM 100+ providersalready shipped
mcp-brokerMCP proxy + registrybroker for every MCP connection

The cross-cutting gateway providers translate policy into gateway behavior (budget caps, base-URL redirection, redaction rules). They are distinct from the underlying LLM provider HTTP clients that actually execute the calls.

provider(manifest, target_capabilities) → target_config

A Policy provider:

  1. Consumes the canonical Compiled Policy (signed, versioned, JSON).
  2. Selects which Compiled Policy subsections apply to this target. (A harness-ring provider reads tools + compliance_tags; a kernel-ring provider reads network + filesystem + identity scoping.)
  3. Renders target-native config (a managed-settings.json for claude-code; a YAML profile for openshell; a CLI invocation for nono; a JSON manifest for monty).
  4. Reports what it cannot enforce (the target's surface doesn't support it) so the audit row records partial coverage with rationale.

The Policy provider is a pure function: deterministic, idempotent, side-effect-free. The control plane handles distribution; the host runtime supervisor handles application.

[design] Provider author maps the target's config surface to Compiled Policy fields
→ declares supported_layers + capabilities
[publish] Provider shipped as a versioned package (PyPI / built into tappass-host)
[register] Operator picks providers when authoring a Runtime
[compile] On manifest change: provider(compiled-policy) → target_config (in-process or on host)
[apply] Host runtime supervisor calls provider's apply path with appropriate update model
(hot-reload / restart / file rewrite)
[evolve] Target updates → provider version bump; operators pin
EngineWhat it doesStatus
Provider registryPer-org list of installed providers + versionsconcept
CompilerRoutes Compiled Policy through selected providers per Runtimeconcept (extends policy compiler)
Provider SDKStandard interface for new providers; published specconcept (v2 priority)
Provider marketplaceThird-party / community providersfuture (v2+)
PersonaSurfaceWhat you do
Operatortappass provider list / show <id>inspect installed providers + versions
Operatortappass runtime create --providers harness=claude-code,kernel=openshell,interpreter=montyauthor a Runtime by selecting providers per ring
Provider authorProvider SDK + spec docwrite a new Policy provider
Buyer / partnerProvider availability matrixanswer "can you cover my stack?"
  • inputCompiled Policy — the canonical IR
  • composes intoRuntime — recipes combining providers per ring
  • enforces atRing — harness / kernel / interpreter (rings) + cross-cutting LLM Gateway / MCP Broker
  • distinct fromLLM provider — HTTP client to an LLM API
  • Policy provider ≠ LLM provider. Policy provider = translator (Compiled Policy → target config). LLM provider = HTTP client (Anthropic / OpenAI / Bedrock API). The cross-cutting gateway Policy providers configure the LLM gateway behavior, but the LLM gateway uses LLM providers underneath to execute calls.
  • Policy provider ≠ Adapter. "Adapter per ecosystem" was an earlier, conflated framing. Policy providers are per target; Runtimes are per recipe. Same target reused across many runtimes.
  • Policy provider ≠ MCP server. An MCP server is a tool source (something the agent calls); a Policy provider is a runtime translator (how the target is configured).
  • Policy provider ≠ Ring. A ring is what kind of enforcement (harness, kernel, interpreter). A Policy provider is one implementation that fills that ring on one target.
  • Policy provider is a pure function. No side effects in compilation; side effects only on apply. This is what makes Policy providers composable, testable, and parallel-shippable.

The Policy-provider taxonomy is the unit of TapPass's expanding surface coverage. Adding a new ecosystem ≈ adding a small number of Policy providers (mostly one harness provider, sometimes also a kernel provider). Each is a 2-week project; the runtime / control plane / manifest are unchanged.

This is the substrate property that makes TapPass Terraform for agent runtimes: targets multiply, the substrate stays stable.