Security

Security you can actually audit

Isolation, encryption, redaction, and least-privilege access — the boring security work is done so you can focus on shipping.

Core posture

Six layers of protection

How Sandpods keeps your code, keys, and sessions safe.

Isolated environments

Every workspace runs in its own E2B sandbox, labeled and lifecycle-managed by the platform. Your code never shares a runtime with another user’s.

Encrypted at rest

Workspace env vars and global AI provider keys are encrypted with per-user AES-256-GCM keys derived via HKDF-SHA256. Values are never returned in their raw form to any API.

Two-way secret redaction

Sensitive values — API keys, tokens, JWTs, emails, IPs — are redacted from agent tool logs and restored before execution. Secrets stay out of transcripts.

Hashed API keys

REST API keys are SHA-256 hashed via Web Crypto before storage. Only the first 12 characters are ever shown, and the raw key is returned once at creation.

Least-privilege auth

GitHub OAuth requests repo, org, and webhook scopes — only what the workspace needs. Git and gh auth is scoped to your account inside the sandbox — no PATs to paste.

Privileged keys stay out

The platform’s own E2B key is never injected into sandboxes. Your BYOK provider keys and GitHub token are injected scoped; sandbox ids are never exposed to clients.

Hardening details

The fine print

The operational details that make the posture hold up in practice.

Signed webhooks

E2B webhooks are verified with a constant-time signature check against a shared secret — unsigned requests are rejected before any state change.

Stable, rotated SSH credentials

SSH access uses a stable per-workspace password persisted inside the sandbox. It only changes on explicit rotation or workspace recreation.

Safe config sync

MCP servers are managed via npx add-mcp and provider syncs (orbit) reconcile only the keys they own — human-authored sections of configs are left untouched, and unparseable files are never overwritten.

No raw secrets in the UI

Decrypted values are used for live injection, never rendered. The dashboard shows presence (hasKey) and masked prefixes instead.

Found something? Report it to our security contact and we’ll treat it as a first-class bug — disclose, fix, and credit.

Start on a secure foundation

Every sandbox is isolated from the start. Sign in with GitHub and try it.