Gates
A gate is a condition checked before or during a deployment. Each has a kind, a status and recorded evaluation detail, so you can see exactly why a deployment is waiting.
| Kind | Passes when | Plan |
|---|---|---|
manual |
A human approves | Free |
window |
The time is inside a deployment window and outside freeze periods | Free |
policy |
A CEL expression is true (external OPA decisions are planned) | Free (3 policies), then unlimited |
change_ticket |
A linked change request is approved | Business |
metric |
A metric query is within bounds | Team |
Manual gates
Section titled “Manual gates”A manual gate is an approval step at any point in a strategy, not just at the start. Example: pause a blue/green deployment after the green side passes smoke tests and before traffic switches. See Approvals.
Scheduled gates: windows and freezes
Section titled “Scheduled gates: windows and freezes”A window has one of three shapes: daily (days, start, end, timezone), cron (cron plus duration) or absolute (from and to).
deployment_windows: - name: Business hours days: [mon, tue, wed, thu] start: "09:00" end: "16:00" timezone: Europe/Dublinfreeze_periods: - name: Year-end freeze from: 2026-12-18T00:00:00Z to: 2027-01-04T00:00:00Z reason: Holiday change freezeOutside a window, or inside a freeze, the deployment is waiting_window. The freeze calendar (EnvironmentService.GetFreezeCalendar) shows every freeze and window across environments. An authorised user can override a freeze with a recorded reason, if the freeze allows overrides.
Policy gates (CEL)
Section titled “Policy gates (CEL)”Policies are CEL expressions that must evaluate to true for the deployment to proceed. They are part of the environment’s protection rules:
policies: - name: only-main expression: provenance.branch == "main" message: Production deploys must come from main - name: verified-provenance expression: provenance.verified - name: no-self-deploy expression: actor.id != release.created_by severity: warn # deny (default) | warnEach expression sees these variables:
| Variable | Fields |
|---|---|
release |
id, version, channel, service_id, created_by, created_at, age_hours, artifacts (name to kind, ref, version, digest), commit_sha, notes |
environment |
id, name, slug, kind, order, url |
service |
id, name, slug, kind |
actor |
id, kind, name |
deployment |
strategy, triggered_by, tenant, force, comment |
provenance |
run_id, pipeline_id, branch, tag, sha, repo, commit_at, builder, verified, attestations (list of type, verified, signer), author, message |
time |
The evaluation time |
The standard CEL string, list and set extensions are available, plus semver.gt, semver.lt, semver.satisfies and glob. Evaluation cost is bounded so a faulty expression cannot stall the engine. Use has() before reading optional fields.
Free allows 3 policies per org; Team and above are unlimited. Two related protection rules need no CEL: allowed_branches and require_verified_provenance.
Change-ticket gates
Section titled “Change-ticket gates”Business and above. The environment requires a linked change request in ServiceNow or Jira Change Management to be in an approved state. Slipway can create the change from the deployment, wait for approval, and close it on completion. Set change_ticket_required: true on the environment and configure the integration.
Metric gates
Section titled “Metric gates”A metric gate holds or fails a deployment based on a query against a metric provider, for example “no firing alerts for this service”. It is the same mechanism canary verification uses, applied at an arbitrary point.
Evaluating without deploying
Section titled “Evaluating without deploying”slipway deployment get dep_01H... # shows gates and their detailApprovalService.EvaluateGates returns the pass/fail result and reasons for each gate so a failing policy is debuggable.