All posts
Engineering

The gates: what has to pass before AzureProof ships

Every deploy runs typecheck, 72 frontend and 689 engine tests, Trivy vulnerability scans, and a database security gate that rebuilds the schema from zero — then rolls back automatically if the health check fails.

A
AzureProof Engineering
8/5/20267 min read
Engineering

Compliance software that cannot prove its own release process is not convincing. So we made the pipeline boring: a fixed sequence of gates that must pass, in order, before an image reaches production — and a rollback that fires on its own if the new build does not come up healthy.

The pipeline, step by step

CI/CD runs on GitHub Actions and is split into two workflows — one for the engine and one for the frontend — so a change to one does not rebuild and redeploy the other. Both follow the same shape:

  1. Typecheck — TypeScript compiles with no errors.
  2. Tests — 72 frontend tests and 689 engine tests, all mocked so they are safe to run in CI.
  3. Build — the production bundle is assembled.
  4. Vulnerability scan — Trivy scans the built image and fails the run on any Critical or High finding. A small ignore file documents the unpatchable base-image findings.
  5. Database security gate — a throwaway Postgres is created, all migrations are applied from zero, and 16 security assertions must pass.
  6. Push & deploy — the image is tagged with the commit SHA and rolled out.
  7. Health check — the service must report healthy after deploy.
  8. Rollback — if the health check fails, the previous image is restored automatically.

The database gate is the one we care most about

A web app can hide buttons, but hiding UI is not authorization. So before anything ships, a script builds the entire database schema from scratch on a clean Postgres and runs 16 security assertions as the real application roles. It checks that:

  • a user cannot self-insert as the owner of someone else’s organization,
  • a user cannot self-provision a paid plan,
  • evidence tables cannot be written by the browser,
  • the enforcement function cannot be called by anything but the service role,
  • invitations cannot be enumerated anonymously.

Because the hosting platform can re-apply broad grants on reload, the test goes further: it re-grants the privileges first and proves the triggers still block the bad write, while a legitimate rename still succeeds. That is the difference between a check that passes today and a check that keeps passing after the next platform change.

Security before it ever reaches the pipeline

Before launch we ran a full security audit of the code and the database. It found 7 critical and 17 high findings — every one was remediated and re-verified against the live database. That audit is why the RLS policies, the secret encryption, the signed webhook verification, and the security headers all exist. We would rather ship a little later than ship a compliance product with a compliance problem.

Rollbacks are automatic, not a runbook

Deploys tag the current image as :previous before pulling the new one. If the health check does not pass, the rollback job restores :previous and brings the service back up without a human on call. A failed deploy should mean "one minute of the old version", not "pages a dev and a coffee".

The whole point of this machinery is unglamorous: nothing reaches production by accident, and nothing stays broken for long.

Get new posts in your inbox

One thoughtful email per month on Azure compliance. No spam.

See it in your own tenant

Connect a read-only service principal and run your first evidence collection the same day.

Start free trial