Security model
How Parity isolates tenants and sandboxes, controls egress, handles secrets and records what people and agents did.
Isolation
- Tenants. Each account runs on its own nodes. Nothing of one tenant is visible to another: names, IDs and sandboxes are scoped to the account.
- Environments. Each sandbox, staging and production is its own Kubernetes namespace with a default-deny network policy. Sandboxes and long-lived environments run on separate nodes.
- Workloads. Containers run as non-root under the
restrictedPod Security Standard: no privileged containers, no host access, no added capabilities, no service account tokens. Thekubernetesescape hatch enforces the same rules. - Built-ins. Every sandbox gets its own Postgres, Redis, buckets, inbox, OIDC issuer and certificate authority with generated credentials. Two sandboxes never trust each other's certificates.
Egress
Outbound traffic from a sandbox goes through its own egress proxy and DNS resolver. Only hosts listed in externals resolve and connect, matched on DNS name and TLS SNI, on ports 443 and 80. Everything else is blocked and reported in the sandbox's egress report with the service, host and count.
The allowlist comes from the project's promoted manifest: the default branch's parity.yaml after each merge (unless it is invalid or production is frozen), or a manifest a person promotes with parity promote. A branch or an agent that adds a host does not get it: the host stays blocked and is listed as not approved until the manifest that adds it is promoted, and parity up with a sandbox token that adds one is refused with egress_not_approved. Builds have their own narrower allowlist: package registries, base-image registries, and the hosts a build lists in build.externals.
Secrets
- Staging and production read credentials from the secret store (OpenBao), synced into each environment. Staging and production hold separate values under the same keys.
- Sandboxes never read staging or production secrets. Their credentials are generated per sandbox and deleted with it.
- Developers set and rotate secrets but cannot read them. Only Admins can reveal a value, and each reveal is recorded. Agents can add secrets and never read them.
- In a sandbox, generated values of 8 characters or longer are masked in what Parity returns (logs, exec output, job logs, recorded calls), including their base64 and URL-encoded forms. Masking is best effort: a command that transforms a value can still print it.
Audit logging
- Every API call, from the CLI, MCP, the console or an integration, is recorded with the token, the person, the agent if any, the endpoint and the result.
- The activity history shows each change to a project (promotes, rollbacks, freezes, secret changes, member changes) with who made it and for whom.
- Deletes of staging, production, their databases and their buckets are soft for 7 days.
Proof bundles
An agent can export a proof bundle for a sandbox: its attached evidence, every call made against the sandbox, and the person and agent behind them. Parity signs the bundle, and parity proof verify checks it against the public keys at GET /v0/keys, so a reviewer can confirm nothing was edited after export.
Transport
All public endpoints use TLS certificates from Let's Encrypt, issued over ACME DNS-01. Sandbox hostnames live under env.parity.ninja; customer domains for production are separate from Parity's own.