# Staging environment exists with infrastructure and dependencies matching production

- **Pattern:** `ab-000974` (`deployment-readiness.ci-cd-pipeline.staging-environment`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000974
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000974)

## Why it matters

Deploying directly to production without a staging environment means every untested configuration change, database migration, or third-party integration issue hits live users first. NIST CM-4 requires evaluating the security impact of changes before production; that evaluation requires a representative environment. A staging environment that uses SQLite while production uses PostgreSQL is not representative — subtle query behavior differences and migration incompatibilities only surface at the worst time.

## Severity rationale

High because skipping a production-equivalent staging environment means integration failures, migration errors, and environment-specific bugs are discovered by users rather than by the team.

## Remediation

Configure a staging environment with matching infrastructure. For Docker Compose projects, use profiles to separate staging and production:

```yaml
# docker-compose.yml
services:
  app-staging:
    build: .
    environment:
      DATABASE_URL: postgres://staging-db:5432/app
    profiles: [staging]

  app-prod:
    build: .
    environment:
      DATABASE_URL: postgres://prod-db:5432/app
    profiles: [prod]
```

Add a CI/CD step that deploys to staging after tests pass and before the production promotion step. For Vercel users, Preview Deployments already provide this gate — ensure the preview environment variables match production (same DB engine, same third-party service URLs, same feature flags).

## Detection

- **ID:** `staging-environment`
- **Severity:** `high`
- **What to look for:** Enumerate every relevant item. Look for staging environment configuration in deployment files (vercel.json preview env, netlify.toml preview context, separate staging database, staging DNS, docker-compose staging profile). Check CI/CD workflow for pre-production deployment step. Look for environment variable files (.env.staging, .env.production) or deployment configs that show distinct staging and production targets.
- **Pass criteria:** At least 1 of the following conditions is met. A staging environment exists with the same infrastructure, dependencies, and service configuration as production. Deployments to staging are part of the CI/CD pipeline before production.
- **Fail criteria:** No staging environment exists, or staging is configured differently from production (e.g., staging uses SQLite while production uses PostgreSQL, or staging omits external services).
- **Skip (N/A) when:** The project is not planned for production, or the platform manages staging automatically (e.g., Vercel preview deployments).
- **Cross-reference:** For user-facing accessibility and compliance, the Accessibility Basics audit covers foundational requirements.
- **Detail on fail:** `"No staging environment found. Deployments go directly to production."` or `"Staging environment exists but uses SQLite database while production uses PostgreSQL — infrastructure mismatch."`
- **Remediation:** Set up a staging environment that mirrors production. For a Docker project:

  ```yaml
  # docker-compose.yml with staging profile
  services:
    app-staging:
      build: .
      environment:
        DATABASE_URL: postgres://staging-db:5432/app
      profiles: [staging]

    app-prod:
      build: .
      environment:
        DATABASE_URL: postgres://prod-db:5432/app
      profiles: [prod]
  ```

  Then add a CI/CD step to deploy to staging after tests pass:

  ```yaml
  - run: docker compose --profile staging up -d
  ```

## External references

- iso-25010 reliability.maturity
- nist CM-4

Taxons: operational-readiness

HTML version: https://auditbuffet.com/patterns/ab-000974
