Deploy Gates
Turn PreFlight evidence into a hard release control that blocks unsafe CI and Vercel deploys.
Guides
Deploy Gates
Deploy Gates turn PreFlight evidence into a hard release control. Instead of hoping someone ran checks before promoting, CI or Vercel asks PreFlight one question — is this project safe to deploy right now? — and blocks the release when the answer is no.
Gates evaluate stored check runs, Sentinel samples, revenue snapshots, schema sync, and provider probes against a per-project policy. The result is a single allow/deny signal with actionable blockers and dashboard deep links.
How it works
Your CI job or Vercel deploy hook calls the gate endpoint. PreFlight evaluates current evidence and returns:
- HTTP 200 with
allowed: truewhen the release is safe. - HTTP 409 with
allowed: falseand a blocker list when it is not.
/api/v1/projects/:projectId/deploy-gateEvaluate release readiness. Optional query: ?mode=strict or ?mode=relaxed.
curl -sS -H "Authorization: Bearer pf_live_..." \
"https://getpreflight.dev/api/v1/projects/<project-id>/deploy-gate?mode=strict"
Example blocked response:
{
"allowed": false,
"mode": "strict",
"project_name": "vibecoder-saas",
"blockers": [
{
"key": "checks_not_clean",
"severity": "failed",
"source": "checks",
"message": "2 failed, 1 warnings.",
"dashboard_url": "https://getpreflight.dev/dashboard/projects/.../checks"
}
],
"warnings": [],
"summary": "1 blocker."
}
Fail your CI job on HTTP 409. Each blocker includes a dashboard_url linking straight to the failing surface.
Strict vs relaxed mode
| Mode | Behavior | Best for |
|---|---|---|
strict | Warnings and failures block the deploy | Production releases |
relaxed | Only hard failures block; warnings are reported but allowed | Staging, preview branches, fast internal iterations |
Set the default mode in the gate policy on /dashboard/deploy-gates. Override per request with ?mode=strict or ?mode=relaxed.
In strict mode, allowed requires zero blockers and zero warnings. In relaxed mode, warnings do not prevent allowed: true.
Default policy
When no custom policy exists, PreFlight applies these defaults:
| Setting | Default |
|---|---|
| Enabled | true |
| Mode | strict |
| Require Sentinel | true |
| Require Revenue Watch | true |
| Block on schema drift | true |
| Max check age | 24 hours |
| Min pass percentage | unset (disabled) |
What a gate can require
Each requirement maps to a blocker source. The policy controls whether that source blocks, warns, or is ignored.
| Requirement | Source | What it enforces |
|---|---|---|
| Clean checks | checks | Latest standard check run is success; in strict mode, no warnings |
| Max check age | checks | Latest check is newer than max_check_age_hours — stale evidence blocks |
| Sentinel active | sentinel | Sentinel enabled, not paused, last sample clean |
| Revenue Watch | revenue | Recent Revenue Ledger snapshot with no unresolved drift |
| Schema drift | schema | Supabase schema sync is clean |
| Provider health | provider | No recent failed or warning probe within the check-age window |
| Pass-percentage floor | checks | Recent pass rate stays at or above min_pass_percentage |
Tuning the policy
Real pipelines need escape hatches that do not gut the gate:
| Control | Purpose |
|---|---|
warn_only_sources | Downgrade a whole source (e.g. revenue) from blocking to warning while stabilizing |
ignored_probe_keys | Exclude specific noisy probes from gate evaluation |
min_pass_percentage | Allow a known-flaky suite when overall pass rate stays above a floor |
enabled: false | Open gate — returns allowed: true with a "policy is disabled" summary |
Disabled policy = open gate
A disabled gate provides no protection. Keep the policy enabled for production projects. Use warn_only_sources or relaxed mode when you need temporary flexibility without turning the gate off entirely.
Wiring into CI
Create an API key. In Settings → API keys, generate a workspace-owner key. The raw
pf_live_…value is shown once.Configure the gate policy. Open Deploy Gates, select the project, and set requirements for production vs staging.
Add a gate step before deploy. Call
GET /deploy-gateand fail the job on HTTP 409.Choose a mode. Use
strictfor production andrelaxedfor preview branches.Read the blockers. Each entry includes
dashboard_url,source, andmessagefor fast triage.
GitHub Actions example
- name: PreFlight deploy gate
run: |
code=$(curl -sS -o gate.json -w "%{http_code}" \
-H "Authorization: Bearer ${{ secrets.PREFLIGHT_API_KEY }}" \
"https://getpreflight.dev/api/v1/projects/${{ vars.PREFLIGHT_PROJECT_ID }}/deploy-gate?mode=strict")
cat gate.json
if [ "$code" != "200" ]; then
echo "Deploy gate blocked the release."
exit 1
fi
Vercel integration
Add the gate call as a step before vercel deploy --prod, or use a GitHub Action that runs on deployment_status. Pair with Vercel Watch so deployment drift is caught between gate checks.
Fresh evidence matters
Trigger a check with POST /projects/:id/checks and an Idempotency-Key before calling the gate when your pipeline just deployed. The gate reads stored rows — it does not run probes itself.
