# Infrastructure & Configuration Review (Cycle 5)

**Date**: 2026-05-12
**Mode**: Delta scan
**Scope**: Cycle-5 delta over the cycle-3 infrastructure review (`_docs/05_security/infrastructure_review.md`)

## Container Security

`Dockerfile` was not modified in cycle 5. Cycle-3 baseline holds: non-root user, distroless ASP.NET base, no secrets in build args, healthcheck present.

## CI/CD Security

Woodpecker CI configuration (`.woodpecker/`) was not modified. The cycle-4 dependency-scan workflow remains the supply-chain gate. AZ-504's `run-performance-tests.sh` fix is exercised by the existing perf-test job — no new step added.

## Environment Configuration

### `.env` / `.env.example`

Not modified in cycle 5. AZ-503 introduced no new env vars. The cycle-3 secrets posture (`GOOGLE_MAPS_API_KEY`, `JWT_SECRET`, `JWT_ISSUER`, `JWT_AUDIENCE` from env / gitignored `.env`; `.env.example` documents them with DEV-ONLY values) holds.

### Database extensions

Migration 014 issues `CREATE EXTENSION IF NOT EXISTS pgcrypto`. Posture:

- **Privilege**: Postgres `CREATE EXTENSION` requires the migration role to be a superuser OR to have explicit `CREATE` on the database. The satellite-provider connection string in `docker-compose.yml` connects as the `postgres` superuser. This is acceptable for the bundled Docker dev/test environment.
- **Production posture**: in a managed Postgres environment (e.g. AWS RDS, Google Cloud SQL), the deployment role typically does NOT have superuser. Operators MUST pre-install `pgcrypto` (it's in the `postgres-contrib` package on Debian/Ubuntu, and is allow-listed on RDS / Cloud SQL by default). The migration's `IF NOT EXISTS` clause makes pre-installation safe — the migration will succeed whether the extension is freshly created or already present.
- **Audit log**: extension creation IS visible in Postgres' standard CSV/JSON server logs (`log_statement = 'ddl'` setting). No additional surfaces.

**Finding**: F2-cy5 — Low (informational), Operational deployment note.
- Location: `_docs/05_security/infrastructure_review_cycle5.md` + `_docs/02_document/data_model.md` migration 014 entry
- Description: First production deployment of cycle-5 will issue `CREATE EXTENSION pgcrypto` if the extension is not already present. Some managed Postgres providers (e.g. RDS in strict-IAM mode) require an operator to allow-list the extension before the migration role can install it.
- Impact: Deployment may fail at the migration step with `must be owner of database` or `permission denied to create extension` if the deployment role lacks the privilege AND the extension is not pre-installed.
- Remediation: Pre-installation step. Two options:
  - (a) Add a one-line entry to the deployment runbook: "ensure `CREATE EXTENSION IF NOT EXISTS pgcrypto` has run as a superuser before the satellite-provider migration role runs migration 014."
  - (b) On RDS/Cloud SQL, add `pgcrypto` to the parameter group's `shared_preload_libraries` or use the provider's per-DB extension allow-list UI.
- Severity rationale: Low (informational) because (i) the Docker compose dev/test environment is unaffected (we connect as `postgres` superuser); (ii) the failure mode is loud (migration fails fast at startup, not at request time); (iii) the remediation is one-line operational, not a code change. Tracked as a deploy-runbook gap, not as a security defect.

## Network Security

- No new ports exposed (cycle 5 added no new listening services).
- No new outbound integrations (cycle 5 added no new HTTP clients).
- CORS / security headers: unchanged.

## Self-verification

- [x] Dockerfile / docker-compose diffs reviewed (none in cycle 5)
- [x] CI/CD config diffs reviewed (none in cycle 5)
- [x] Environment/config files reviewed (`.env`, `.env.example`, `appsettings*.json` — none modified)
- [x] New DB extensions documented (`pgcrypto`)

## Save action

Written to `_docs/05_security/infrastructure_review_cycle5.md`. The cycle-3 `infrastructure_review.md` remains authoritative for surfaces untouched by AZ-503.
