Organizational

Sandbox Environments

Pattern for isolated, developer-owned sandbox environments for local development and testing.

Production

Definition

A sandbox is an isolated, non-production environment designed for:

  • Local development
  • Experimentation
  • Testing
  • Debugging

Sandboxes are developer-owned and MUST NOT affect production systems, data, or resources.

Core Principles

Isolation

Sandboxes MUST be completely isolated from production:

  • No access to production databases
  • No access to production APIs (unless explicitly read-only and safe)
  • No ability to trigger production events or side effects
  • No shared state with production systems

Developer Ownership

Each developer MUST be able to:

  • Start their own sandbox independently
  • Tear down their sandbox without coordination
  • Modify sandbox configuration without affecting others
  • Run multiple sandboxes simultaneously if needed

Reproducibility

Sandboxes MUST be:

  • Quickly recreatable from scratch
  • Consistent across different developer machines
  • Documented in the repository's operational instructions

Sandbox Architectures

Sandboxes may take different forms depending on the repository:

Local-Only Sandbox

All components run on the developer's machine:

  • Databases: Docker Compose or local instances
  • Services: Running natively or in containers
  • External dependencies: Mocked or stubbed

When to use: Simple services with minimal external dependencies

For services running on AWS Lambda, AWS services (DynamoDB, S3, SSM, API Gateway, etc.) can be emulated locally using LocalStack. This keeps the sandbox fully local while preserving the Lambda execution model. See Local AWS Sandbox.

Hybrid Sandbox

Mix of local and remote resources:

  • Frontend: Running locally for fast iteration
  • Backend: Running locally or against a shared dev environment
  • Databases: Local or remote development instances
  • External APIs: Mocked locally or pointing to dev endpoints

When to use: Complex systems with heavy infrastructure requirements

Remote Sandbox

Ephemeral cloud resources:

  • Infrastructure: Deployed to a dedicated sandbox namespace
  • Databases: Isolated sandbox instances
  • Services: Deployed to sandbox environment
  • Cleanup: Automated teardown after session

When to use: Services requiring production-like infrastructure

Requirements

Task Exposure

If a repository CAN reasonably run in sandbox mode, it MUST provide Taskfile tasks:

  • sandbox:start — Start the sandbox environment
  • sandbox:stop — Stop and clean up the sandbox
  • sandbox:restart — Restart the sandbox environment
  • sandbox:seed — Seed the sandbox environment with sample data
  • sandbox:reset — Reset sandbox to clean state (optional)

If a repository CANNOT run in sandbox mode (e.g., infrastructure-only repos), this MUST be documented in AGENTS.md.

No Production Leakage

Sandboxes MUST implement safeguards:

  • Environment variables clearly distinguish sandbox from production
  • Configuration defaults to sandbox mode
  • Accidental production access is prevented by design

Example environment variable naming:

# Clear distinction
SANDBOX_MODE=true
ENVIRONMENT=sandbox

# Avoid ambiguous naming
ENV=dev  # Unclear if this is sandbox or shared dev

Easy Teardown

Developers MUST be able to:

  • Tear down sandboxes without manual cleanup
  • Remove all sandbox resources with a single command
  • Avoid orphaned resources (containers, volumes, cloud resources)

Sandbox vs. Other Environments

EnvironmentPurposeIsolationLongevityData
SandboxDev/experimentationCompleteEphemeralDisposable
DevelopmentIntegration testingSharedPersistentRealistic but not real
StagingPre-production validationProduction-likePersistentProduction snapshot
ProductionReal usersCompletePermanentReal data

Anti-Patterns

❌ Shared "Dev" Databases

Multiple developers sharing a single development database:

  • Causes state conflicts between developers
  • Makes debugging harder
  • Slows down development

Instead: Each developer runs their own isolated database in their sandbox.

❌ Manual Setup Steps

Requiring developers to manually provision resources:

  • Increases friction and setup time
  • Leads to inconsistent environments
  • Makes onboarding painful

Instead: Automate sandbox startup with sandbox:start.

❌ Stateful Sandboxes

Sandboxes that accumulate state over time:

  • Become unreproducible
  • Drift from clean state
  • Hide bugs that only appear in fresh environments

Instead: Design sandboxes to be easily reset to a known good state.

❌ Production Credentials in Sandbox

Using production API keys or credentials in sandbox:

  • Risks accidental production modifications
  • Violates least privilege principle
  • Creates security exposure

Instead: Use sandbox-specific credentials or mocks.

Examples

Simple Sandbox (Local Docker)

# Taskfile.yaml
sandbox:start:
  desc: Start local sandbox environment
  cmds:
    - docker compose -f docker-compose.sandbox.yml up -d
    - task: dev:migrate
    - echo "Sandbox running at http://localhost:8080"

sandbox:stop:
  desc: Stop and clean up sandbox
  cmds:
    - docker compose -f docker-compose.sandbox.yml down -v

Hybrid Sandbox (Local Frontend + Remote Backend)

# Taskfile.yaml
sandbox:start:
  desc: Start hybrid sandbox (local frontend + dev backend)
  cmds:
    - echo "Starting frontend locally..."
    - npm run dev &
    - echo "Frontend: http://localhost:3000"
    - echo "Backend: https://api-dev.ontopix.internal"

sandbox:stop:
  desc: Stop local frontend
  cmds:
    - pkill -f "npm run dev"

Remote Sandbox (Ephemeral Cloud)

# Taskfile.yaml
sandbox:start:
  desc: Deploy ephemeral sandbox to cloud
  vars:
    SANDBOX_ID:
      sh: echo "sandbox-$(whoami)-$(date +%s)"
  cmds:
    - terraform -chdir=.infra/sandbox apply -var="sandbox_id={{.SANDBOX_ID}}"
    - echo "Sandbox deployed: {{.SANDBOX_ID}}"

sandbox:stop:
  desc: Destroy ephemeral sandbox
  cmds:
    - terraform -chdir=.infra/sandbox destroy -auto-approve

Sandbox-Specific Configuration

Configuration SHOULD default to sandbox mode:

# config.py
import os

ENVIRONMENT = os.getenv("ENVIRONMENT", "sandbox")  # Default to sandbox
DATABASE_URL = os.getenv(
    "DATABASE_URL",
    "postgresql://localhost:5432/myapp_sandbox"  # Sandbox default
)

if ENVIRONMENT == "production":
    # Production overrides
    DATABASE_URL = os.getenv("PROD_DATABASE_URL")  # No default for production

Documentation Requirements

Every repository with sandbox capability MUST document in AGENTS.md:

  • How to start the sandbox
  • What the sandbox includes (databases, services, etc.)
  • How to verify the sandbox is working
  • How to tear down the sandbox
  • Any prerequisites (Docker, cloud CLI, etc.)

Example:

## Sandbox Mode

This repository supports local sandbox mode using Docker Compose.

**Start sandbox:**

task sandbox:start


**Sandbox includes:**
- PostgreSQL database (port 5432)
- Redis cache (port 6379)
- API service (port 8080)

**Verify sandbox:**

curl http://localhost:8080/health


**Stop sandbox:**

task sandbox:stop


**Prerequisites:**
- Docker and Docker Compose installed
- Ports 5432, 6379, 8080 available

Rationale

Sandboxes exist to:

  • Enable fearless experimentation
  • Reduce developer setup time
  • Prevent accidental production impact
  • Make development environments reproducible

Isolated, developer-owned sandboxes are a prerequisite for productive development at Ontopix.