Skip to content

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

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.

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/Dublin
freeze_periods:
- name: Year-end freeze
from: 2026-12-18T00:00:00Z
to: 2027-01-04T00:00:00Z
reason: Holiday change freeze

Outside 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.

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) | warn

Each 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.

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.

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.

Terminal window
slipway deployment get dep_01H... # shows gates and their detail

ApprovalService.EvaluateGates returns the pass/fail result and reasons for each gate so a failing policy is debuggable.