Sandcastle v0.40.0
Security / How we protect your runs

Defense in depth. On by default.

Every request crosses independent security layers โ€” perimeter, auth, policy, execution, data. A failure in one is caught by the next. Your workflows run in ephemeral sandboxes that are destroyed after each step, and every run leaves a tamper-evident trail.

posture
modelzero trust
sandboxesephemeral
auditSHA-256 chain
residencyEU enforceable
The controls โ€” for the record

What's built in.

Every measure below ships with Sandcastle out of the box. No plugins, no paid tiers, no configuration required for the defaults.

01

Sandbox isolation

Sandboxing

AI agent code runs in ephemeral sandboxes that are destroyed after each execution. No shared state, no persistent access to host resources.

  • E2B โ€” cloud-hosted microVMs with SOC 2 Type II certification
  • Docker โ€” CapDrop: ALL, seccomp syscall allowlist, PID limits, CPU quotas, non-root user (UID 1000), bridge networking, auto-remove
  • Seccomp profiles โ€” block ptrace, mount, kexec_load, keyctl, reboot, swapon and other dangerous syscalls
  • Cloudflare Workers โ€” edge V8 isolates with per-request timeout
  • Local โ€” subprocess mode for development only (no isolation)
  • Runner file validation blocks path traversal (..) and absolute paths before execution
02

Hardened code steps

In-process sandbox

The in-process code step runs user expressions through a restricted evaluator, not Python's eval/exec. Policy expressions are evaluated with simpleeval, and file operations from runner code are validated before they touch disk.

  • Safe expression evaluation via simpleeval โ€” no raw Python eval/exec
  • Runner file validation blocks .. traversal and absolute paths
  • For untrusted code, the same step can be routed to an isolated sandbox backend (Docker / E2B / Workers)
03

Authentication

API keys / HMAC

API key authentication with HMAC-SHA256 hashing, key rotation with grace periods, expiry enforcement, and per-key IP allowlisting.

  • HMAC-SHA256 with configurable server-side pepper (API_KEY_PEPPER)
  • Keys accepted via X-API-Key, Authorization: Bearer, or query param (SSE)
  • Rotation โ€” POST /api/api-keys/{id}/rotate; old key enters a configurable grace period
  • Expiry โ€” expires_at enforced in middleware, returns 401 KEY_EXPIRED
  • IP allowlisting โ€” per-key CIDR allowlist (IPv4 + IPv6); empty list allows all
  • sc_ prefix, 32-byte URL-safe token, first 8 chars stored as key_prefix
  • last_used_at updated on every authenticated request; soft deletion via is_active preserves audit trail
04

Multi-tenant isolation

Tenant scoping

Each API key is scoped to a tenant. Tenant-scoped queries filter all data access to prevent cross-tenant leaks.

  • tenant_id set from the API key on every request via middleware
  • Admin keys (no tenant_id) can access all data
  • Tenant keys only see their own runs, workflows, and schedules
  • Per-key cost limits (max_cost_per_run_usd)
05

Policy engine

Redact / block / approve

Declarative policy rules evaluate step outputs in real time โ€” automatically redact PII, block secrets, and trigger approvals.

  • PII patterns โ€” email, phone, SSN, credit card regex detection
  • 30+ credential patterns โ€” Slack, GitHub, AWS, Stripe, OpenAI and more
  • Actions โ€” redact, block, inject_approval, alert, log
  • Severity levels โ€” critical, high, medium, low
  • Safe expression evaluation via simpleeval (no Python eval/exec)
  • Auto-generated credential policies when tools are used
  • Redacted output stored separately โ€” originals preserved for LLM context
06

Credential management

Secrets

Tool credentials are encrypted at rest with Fernet, resolved from environment variables or database-stored named connections. Never logged, never exposed in outputs.

  • Encryption at rest โ€” Fernet (AES-128-CBC + HMAC-SHA256) via CREDENTIAL_ENCRYPTION_KEY
  • Graceful fallback โ€” no key configured means plaintext passthrough (backwards compatible)
  • TOOL_* prefix convention for environment variables
  • Named connections (postgresql:analytics) stored in DB with unique constraint
  • Credential masking for UI โ€” shows first 4 + last 4 chars only
  • Injected into the sandbox env at runtime, not stored in workflow YAML
  • Export API (/workflows/{name}/export) sanitizes credentials from YAML
07

SSRF prevention

Outbound guard

All webhook callback URLs are validated against private network ranges before any HTTP request is made.

  • Blocks loopback (127.0.0.0/8, ::1)
  • Blocks private networks (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
  • Blocks link-local (169.254.0.0/16) and IPv6 ULA (fc00::/7)
  • DNS resolved before the IP check โ€” prevents DNS rebinding via TOCTOU
  • Scheme validation โ€” only http:// and https://
08

Path traversal protection

Filesystem

All file operations are sandboxed within base directories. Resolved paths are validated to prevent escape.

  • Path.resolve() + is_relative_to() check on all storage operations
  • Raises ValueError on traversal attempts
  • Dashboard SPA fallback rejects paths containing ..
  • Runner file validation blocks .. and absolute paths
09

Rate limiting

Abuse control

Pluggable rate limiting with in-memory and distributed Redis backends. A sliding-window counter per tenant or IP prevents abuse of sandbox endpoints.

  • Default: 10 requests per 60 seconds on execution endpoints
  • Keyed by tenant:{id} when authenticated, ip:{addr} when anonymous
  • In-memory backend โ€” default, zero config, sliding window with stale-entry pruning
  • Redis backend โ€” distributed sorted-set pipeline, auto-selected when REDIS_URL is set
  • HTTP 429 with Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining headers
10

Security headers & CSP

Perimeter

Middleware injects hardened HTTP headers on every response. Content Security Policy is applied to dashboard routes, with a report-only mode for gradual rollout.

  • X-Content-Type-Options: nosniff โ€” prevents MIME sniffing
  • X-Frame-Options: DENY โ€” blocks clickjacking
  • Referrer-Policy: strict-origin-when-cross-origin
  • Permissions-Policy โ€” disables camera, microphone, geolocation, payment
  • CSP โ€” default-src 'self' with scoped overrides for styles, scripts, images, fonts
  • CSP applied to dashboard paths only (not /api) to avoid breaking JSON responses
  • CSP_REPORT_ONLY=true uses the report-only header for safe testing
11

Webhook signing

Outbound integrity

Outgoing webhooks are signed with HMAC-SHA256. Recipients can verify authenticity using the signature header.

  • HMAC-SHA256 signature over the JSON payload
  • Header: X-Sandcastle-Signature
  • Timing-safe comparison via hmac.compare_digest()
  • 10-second timeout on webhook delivery
12

Circuit breaker & failover

Resilience

A three-state circuit breaker protects against cascading backend failures and recovers automatically when the backend stabilizes. Provider failover keeps runs moving.

  • CLOSED โ€” normal operation, requests pass through
  • OPEN โ€” after 5 consecutive failures, reject immediately
  • HALF_OPEN โ€” after a 30s cooldown, allow one test request; success resets to CLOSED
  • Auto-failover triggers on HTTP 429, 5xx, and connection timeout
  • Per-provider cooldown (default 60s) prevents retry storms
  • Failover respects data-residency constraints; every event is logged
13

EU data residency

Data residency

Set DATA_RESIDENCY=eu and all AI processing routes through EU-based providers (Mistral) or stays local (Ollama). This is hard enforcement at the routing layer โ€” not a policy document.

  • The routing layer rejects non-EU providers when EU mode is active
  • Failover chain respects residency โ€” only EU/local providers in the chain
  • The provider audit trail logs the region for every AI call
  • Dashboard shows residency status per provider
  • Auto-generated GDPR privacy notice via GET /compliance/privacy-notice
14

Tamper-evident audit trail

Audit trail

A SHA-256 hash-chain audit trail. Every event links to the previous one via a cryptographic hash โ€” tamper-evident and independently verifiable.

  • Hash chain โ€” each AuditEvent stores entry_hash (SHA-256 of payload) and prev_hash
  • 7 executor hooks โ€” workflow/step started, completed, failed, and approval_requested
  • 9 admin hooks โ€” emergency_stop, emergency_reset, key created/rotated/revoked, credential stored/deleted, config & compliance changes
  • GET /audit/runs/{run_id} โ€” full event log for a run
  • GET /audit/verify/{run_id} โ€” verify chain integrity, returns broken links
  • GET /audit/admin โ€” paginated admin action log
  • Records PolicyViolation and ApprovalRequest entries with full context
15

Provider audit & SLO routing

Model routing

Every AI call logs which provider handled it, which model, which region, and whether it was a failover. SLO-aware routing matches the model to the task without manual config.

  • Provider, model, and region logged per advisor call
  • Failover events include the original provider and reason
  • Cost tracked per provider for billing transparency
  • Integrated with the SHA-256 hash-chain audit
  • Quality tiers: high (generation), medium (analysis), low (formatting)
  • Override with ADVISOR_QUALITY_MODE=always_best or always_cheapest
16

Telemetry anonymization

Privacy

Opt-in error reporting via Sentry with aggressive anonymization. Disabled by default. No user data, no secrets, no hostnames.

  • Opt-in only: TELEMETRY_ENABLED=true + SENTRY_DSN
  • send_default_pii=False, server_name=None, zero tracing
  • Before-send hook strips API keys, tokens, secrets, file paths, request & user data, stack-frame variables
  • 40+ sensitive env var names blocklisted from reporting
  • Local fallback: failed sends saved to data/error_reports/
17

EU AI Act toolkit

Audit-ready

Built for the EU AI Act era. Risk classification, transparency reports, technical-documentation stubs, and a global emergency stop โ€” configured in YAML, enforced at runtime.

  • Risk classification โ€” minimal / limited / high / unacceptable per Annex III; risk_level: high
  • Transparency reports โ€” per-run, GET /runs/{id}/transparency-report
  • Annex IV docs โ€” auto-generated stubs via GET /workflows/{name}/annex-iv
  • Global emergency stop โ€” POST /admin/emergency-stop halts running & queued workflows
  • Compliance mode โ€” COMPLIANCE_MODE=eu_ai_act blocks high-risk workflows without approval steps
Credential detection

The automatic secret scrubber.

The policy engine detects and redacts credentials from 30+ services in step outputs. Two-layer defense โ€” PEM key blocks first, then token regex. Idempotent and safe to run twice. Patterns are applied before data reaches storage, webhooks, or logs.

CategoryServices / patternsExamples
CommunicationSlack, Discord, Twilio, SendGrid, Resend, WhatsApp, Intercomxoxb-xoxp-SG.
AI providersOpenAI, Anthropic, ElevenLabs, Tavilysk-sk-ant-
Cloud & DevOpsAWS, Vercel, Datadog, PagerDuty, CloudflareAKIABearer
Version controlGitHub, Jira, Linearghp_gho_
Data & storageSupabase, Pinecone, Airtable, Snowflake, RediseyJ (JWT), UUID patterns
Payments & ERPStripe, Shopify, Plaid, QuickBooks, DocuSignsk_live_sk_test_
CRMHubSpot, Salesforce, Zendeskpat- Bearer tokens
PIIEmail, Phone, SSN, Credit CardRegex for common PII formats
Connection URLsPostgreSQL, Redis, MySQL, MongoDB stringspostgres://user:pass@host
PEM private keysRSA, EC, DSA, ENCRYPTED key blocks-----BEGIN RSA PRIVATE KEY-----
Cloud credentialsAzure Storage AccountKey, AWS compound keywordsAccountKey=โ€ฆaws_secret_access_key
JSON secretsJSON-quoted key/value pairs containing secrets"password": "โ€ฆ""secret": "โ€ฆ"
Privacy router ยท 7 PII patterns redacted before data leaves your infrastructure
user@company.com
[EMAIL]
+1 (555) 123-4567
[PHONE]
123-45-6789
[SSN]
4111 1111 1111 1111
[CREDIT_CARD]
192.168.1.1
[IP_ADDRESS]
DE89 3704 0044 0532
[IBAN]
15/03/1990
[DOB]
privacy.mode
redact

Coordinated disclosure

Report a vulnerability.

Found a security issue? Please report it responsibly. We respond within 24 hours and aim to fix critical issues within 72 hours. Please give us a chance to ship a fix before disclosing publicly.

Responsewithin 24h
Critical fixaim โ‰ค 72h
Public issuesGitHub โ†—