Docs · reference

install reference
platform-team evaluator

Install reference — the platform-team evaluator checklist, before sign-off.

Three prerequisites (Node runtime · Postgres · object storage for SBOM artifacts), the env-var surface grouped into data-handling toggles, signing-key mount, and audit-log sink, a worked local-dev Docker compose path a platform engineer runs on a laptop, and a three-step evaluator-scoped upgrade / rollback path that links back to /architecture for the pipeline vocabulary. The full seven-set lives on /docs/self-host.

Prerequisites

Three rows the platform team holds

Node runtime (≥ 20.18.1, pinned in package.json › engines.node) · Postgres 16+ · object storage for SBOM artifacts — three rows the install page covers, the full seven-set lives on /docs/self-host › prerequisites.

Env-var surface

Three groupings, every key grounded

Data-handling toggles (NODE_ENV · SEO_INDEXABLE) · signing-key mount (BETTER_AUTH_SECRET + DRIFTLOCK_KMS_KEY_ALIAS) · audit-log sink (DATABASE_URL · REKOR_URL) — every key cross-referenced against .env.example + the runtime schema in env.ts.

Worked local-dev

One compose the platform team drops in

Four-service docker-compose snippet a platform engineer runs on a laptop before evaluation. Rolls the watcher + sandbox-runner + sbom-emitter + db up with the same KMS-resident posture the cluster install demands — minus the chart-managed secret mounts the on-cluster install adds.

node ≥ 20.18.1 · postgres 16+ · object storage · data-handling toggles · KMS-resident · audit-log sink · docker compose · upgrade / rollback

Prerequisites

What the platform team holds before docker compose up runs end to end.

Three rows the install evaluator confirms before the platform team can sign off. Each row names the requirement, the verification command the platform team runs to greenlight install, and the compliance control the prerequisite maps to. Reviewers read this table alongside the seven-row prerequisites table on /docs/self-host › prerequisites — same vocabulary, trimmed to the three a platform engineer stands up on a laptop.

Prerequisite · anchor

Requirement · verification

Node runtime

anchor · FedRAMP SI-7 · SOC 2 CC6.7

Node.js >= 20.18.1 (pinned in `package.json` › `engines.node`). Local-dev laptop installs run on the same major + minor the deployed chart pins — a sub-20.18.1 toolchain fails the post-install audit-trail signature path on the first signed run.

Verification
Run `node --version` and confirm `v20.18.1` or later; run `corepack enable` so the pnpm / yarn the chart pins is the version the lockfile expects.

Postgres target

anchor · SOC 2 CC7.2 · FedRAMP AU-2

PostgreSQL 16+ on a managed target (RDS · Cloud SQL · Azure Database) or a local-dev `postgres:16-alpine` container. 8 vCPU · 32 GiB · gp3 storage · automated base backup + PITR for the production target. The chart-managed install job bootstraps before any workload rolls.

Verification
Run `psql "${DATABASE_URL}" -c "SELECT version();"` and confirm version ≥ 16; for local-dev laptop installs confirm `docker compose up -d db && docker compose exec db pg_isready` exits 0 within 30 seconds.

Object storage for SBOM artifacts

anchor · SOC 2 CC6.7 · FedRAMP SI-7

S3 · GCS · Azure Blob, or an OCI-compatible container registry — content-addressed by `<org>/<repo>/spdx/<sbom_sha256>.spdx.json`. The sbom-emitter writes every emission; the audit-trail row cross-references the same path. The byte-stable replay path the runbook pins lives on this target, so a misconfigured bucket fails the install at first run.

Verification
Run `cosign verify --certificate-identity-regexp ".*" registry.internal/<org>/<repo>/spdx/<sha256>.spdx.json` against the registry (or `aws s3 ls s3://<bucket>/spdx/`) and confirm the platform team can write + read the SBOM at the content-addressed path.

node runtime · postgres 16+ · object storage

Env-var surface

Three functional groupings — every key cross-referenced against .env.example + env.ts.

The env-var surface the runtime schema parses, grouped by what the platform team sets the key for. Every key on this page exists in either .env.example(the build's source of truth) or env.ts (the runtime schema); secrets are hedged as KMS-injected or chart-injected so a reviewer never follows a fabricated key back to an actual schema. The full seventeen-row table lives on /docs/self-host › environment variables.

Env-var group

Data-handling toggles

anchor · SOC 2 CC6.6 · FedRAMP AC-4

Four toggles on the runtime schema the platform team sets before `helm install` — the chart never defaults these for you. `NODE_ENV` controls the audit-trail verbosity, `SEO_INDEXABLE` controls whether the deployed surface lands in search-engine indexes, and `POLSIA_IMAGE_REMOTE_HOSTS` controls whether the SBOM registry the sbom-emitter writes to is reachable from the rendering layer.

name · type

R / O

source

default

NODE_ENV

type · string

R

source

env.ts schema

development

POLSIA_IMAGE_REMOTE_HOSTS

type · string

O

source

.env.example

(unset → no remote hosts)

NEXT_PUBLIC_APP_URL

type · url

R

source

env.ts schema

http://localhost:3000

SEO_INDEXABLE

type · boolean

O

source

.env.example

(unset → robots Disallow: /)

Env-var group

Signing-key mount

anchor · SOC 2 CC6.1 · FedRAMP SC-12

Two KMS-resident surfaces the platform team wires before the signing-controller rolls. `BETTER_AUTH_SECRET` is the session-cookie HMAC key for the in-VPC auth surface; the KMS-backed alias `DRIFTLOCK_KMS_KEY_ALIAS` is the chart-injected pointer the cosign ECDSA P-256 commit signer reads from. KMS-resident by default — the platform team never commits a real value.

name · type

R / O

source

default

BETTER_AUTH_SECRET

type · string

R

source

env.ts schema

(none — KMS / chart-injected)

DRIFTLOCK_KMS_KEY_ALIAS

type · string

R

source

chart values

driftlock/commit-signer

Env-var group

Audit-log sink

anchor · SOC 2 CC7.2 · FedRAMP AU-2

The seven-column audit-trail record the runbook walks. The ingest layer emits one row per merged PR; the chart-injected KMS pointer signs the row, the registry-aligned SBOM path (mirroring `POLSIA_IMAGE_REMOTE_HOSTS`) hosts the artifact, and retention defaults to 7 years hot / 10 years cold with an indefinite Rekor-logged pin on the signature + SBOM rows.

name · type

R / O

source

default

DATABASE_URL

type · url

R

source

env.ts schema

(none — KMS / chart-injected)

POLSIA_EMAIL_PROXY_URL

type · url

R

source

env.ts schema

(none — platform-injected)

DRIFTLOCK_REKOR_URL

type · url

O

source

chart values

https://rekor.driftlock.dev

NODE_ENV · POLSIA_IMAGE_REMOTE_HOSTS · SEO_INDEXABLE · BETTER_AUTH_SECRET · DRIFTLOCK_KMS_KEY_ALIAS · DATABASE_URL · POLSIA_EMAIL_PROXY_URL · DRIFTLOCK_REKOR_URL

Docker-compose local-dev install

Stand the stack up on a laptop — the platform team's eval-day compose file.

One snippet the platform team drops into a scratch dir, runs docker compose up against, and tears down at the end of evaluation. The four services — db + watcher + sandbox-runner + sbom-emitter — are the laptop-shaped trim of the seven-service graph the cluster install demands. Every image pins by tag, no KMS target, an internal: true network.

Worked local-dev install: docker-compose.yml a platform team runs on a laptop

The snippet below is the laptop-shaped install the platform team drops into a scratch dir, runs docker compose upagainst, and tears down at end of evaluation. The full seven-service graph + the KMS-resident secret-management wiring the cluster install demands lives on /docs/self-host › Docker-compose, and is the version a security reviewer reads end to end.

# docker-compose.yml — local-dev install a platform team
# runs end to end on a laptop before evaluation. The full seven-service
# graph + the KMS-resident secret-management bindings the cluster
# install demands live on /docs/self-host#docker-compose — this file is
# the laptop-shaped trim that stands up the stack without a KMS target.
#
# Pin every image by tag, not :latest, so the hermetic-build hash stays
# byte-stable across reruns.

services:
  db:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: driftlock
      POSTGRES_USER: driftlock
      POSTGRES_PASSWORD: driftlock
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
      interval: 10s
      timeout: 5s
      retries: 5

  watcher:
    image: registry.internal/driftlock/watcher:vX.Y.Z
    restart: unless-stopped
    environment:
      DATABASE_URL: postgres://driftlock:driftlock@db:5432/driftlock
      BETTER_AUTH_URL: http://localhost:3000
      DRIFTLOCK_KMS_KEY_ALIAS: driftlock/commit-signer
    depends_on:
      db: { condition: service_healthy }

  sandbox-runner:
    image: registry.internal/driftlock/sandbox-runner:vX.Y.Z
    restart: unless-stopped
    environment:
      DATABASE_URL: postgres://driftlock:driftlock@db:5432/driftlock
      DRIFTLOCK_HERMETIC: "1"
      DRIFTLOCK_EGRESS_ALLOWED: 127.0.0.1/32
    depends_on:
      db: { condition: service_healthy }

  sbom-emitter:
    image: registry.internal/driftlock/sbom-emitter:vX.Y.Z
    restart: unless-stopped
    environment:
      DATABASE_URL: postgres://driftlock:driftlock@db:5432/driftlock
      DRIFTLOCK_SBOM_KEY_ALIAS: driftlock/sbom-signer
      DRIFTLOCK_REKOR_URL: https://rekor.driftlock.dev
    volumes:
      - sbom-out:/var/lib/driftlock/sbom
    depends_on:
      sandbox-runner: { condition: service_healthy }

volumes:
  pgdata:
  sbom-out:

four services · postgres:16-alpine · watcher · sandbox-runner · sbom-emitter · local-dev install

Four verification commands a platform engineer runs

  • db readydocker compose exec db pg_isready -U driftlock -d driftlock
  • watcher livecurl -fsS http://localhost:8080/healthz
  • sandbox replay okdocker compose logs sandbox-runner | grep REPLAYED_OK
  • sbom emittedls -la /var/lib/driftlock/sbom/spdx/*.spdx.json | head -1

A platform engineer walks these four commands top-to-bottom — the db healthcheck confirms the schema target loads, the watcher healthcheck confirms the ingest surface mounts, the sandbox runner's REPLAYED_OK line confirms a hermetic step replay succeeded, and the SBOM emission confirms the content-addressed artifact path the audit-trail row cross-references is reachable.

postgres:16-alpine · watcher · sandbox-runner · sbom-emitter · KMS-resident · laptop install

Upgrade / rollback path

Three steps — pre-flight, apply (rolling or blue/green), rollback.

The trimmed upgrade / rollback loop the eval-window platform team prints and pins. The full seven-step runbook (including backup-verify, image-tag strategy, db compat, and post-record) lives on /docs/self-host › upgrade runbook. These three cover the chart-diff → apply → rollback loop a security reviewer asks about first.

install upgrade runbook · install-up-pre-flight

Action
Run `helm template driftlock driftlock/driftlock --version vX.Y.Z+1 -f values.yaml` and diff against the previous rendered release. The chart pre-flight returns zero unowned changes — only `image.tag` differs and any `sandbox.*` / `egress.*` keys the platform team intended to bump. A spurious change to `networkPolicy.enabled`, `tls.pinningRequired`, or `dns.policy` blocks the upgrade before it lands.
Verification
Diff returns the deltas the runbook records — no unowned diff surfaces. The chart-injected `BETTER_AUTH_SECRET` and `DRIFTLOCK_KMS_KEY_ALIAS` aliases remain unchanged across the diff (a re-issued alias is a key-rotation event the runbook records separately).
Rollback
Stop before `helm upgrade` — the runbook has not started, no service disruption.

install upgrade runbook · install-up-apply

Action
Default path: rolling (`helm upgrade --atomic`, one workload at a time, pre-flight green per workload before the next). Blue/green when the diff touches `sandbox.timeoutSec` upward, when a major version change to the signing-controller lands, or when the diff mounts a new KMS alias. Blue/green ships the new chart to `driftlock-canary` first; smoke runs there; the live namespace atomically swaps if smoke is green.
Verification
Rolling: every workload reports `Ready` within the chart timeout (default 5m) before the next one lands. Blue/green: `driftlock-canary` round-trips a smoke PR before live flips. `cosign verify` against the registry confirms the pull-side signature is valid for the new image tag.
Rollback
Rolling: `helm rollback driftlock <REVISION>` revives the previous revision; signing-controller + sbom-emitter resume single-writer in seconds. Blue/green: live keeps running on the previous revision while the canary is debugged.

install upgrade runbook · install-up-rollback

Action
Run `helm rollback driftlock <REVISION> --namespace driftlock --wait --cleanup-on-fail` against the last green revision the chart shipped. The runbook records the failing revision + the smoke target the chart failed against; the next pre-flight gates on the recorded failures before moving forward.
Verification
`kubectl rollout status` reports the previous revision as `Ready` within the chart timeout (default 5m). The audit-trail row from the failed upgrade carries the failing `image.tag` + the rollback revision id; the next runbook cycle cites the same row id.
Rollback
If the rollback itself fails (a roll-roll-forward runbook the platform team owns), freeze the install and escalate — the runbook does not auto-retry past a single rollback without a recorded hand-off.

pre-flight · apply · rollback · rolling · blue/green · audit-linked · reversible

Back to the runbook

The parent /docs page covers the overview — this page is the install evaluator-checklist a platform engineer reads in front of a sign-off.

The three subsections on /docs name the prerequisites + install + upgrade path the runbook owns. This deep- dive expands each step into the three rows the platform team confirms on a laptop install: Node runtime + Postgres + object storage, an env-var surface grouped by what the key is for (data-handling toggles · signing-key mount · audit-log sink), a four-service docker-compose the platform engineer drops into a scratch dir, and a three-step upgrade / rollback path that links to /architecture.

prereq-nodeenv-signing-keydocker-compose

Request the install reference walkthrough

We'll reply with a calendar link and the env-var surface + KMS-resident key-handling runbook relevant to your scope — and a copy of the docker-compose starter we ship behind SSO once your team's SSO is on file.