Sign in
Menu
Sign up
Docs
Govern your organization

Promotion and gates

This page is for the approver who puts a compliance posture into production, and for the auditor who wants to know how an exception reaches it. By the end you will have promoted an approved snapshot through the gate, and you will know how a waiver is frozen into what production serves and when it stops applying.

  • A binding points one project environment at one snapshot. That binding is what the registry serves.
  • Promotion moves a snapshot into an environment. Protected environments run it past a gate first.
  • Waivers are exceptions with a stated expiry. Approved, unexpired waivers are frozen into the binding at promotion time.
  • Rollback repoints an environment at the previous snapshot and leaves the frozen waivers as they were.
  • Separation of duties is off by default; enabling it is operator-assisted.

How it works

A compliance posture that can be edited in place has no defensible history. If an auditor asks what production enforced on a given date, "the current configuration" is not an answer: it changes every time someone edits it.

Compliance.tf separates authoring from what is live. You edit a draft freely; publishing freezes it into a snapshot that can never be modified (Configs and snapshots). An environment is bound to a specific snapshot, and production changes only when someone promotes a different snapshot to it. That act is recorded.

The objects

This page owns bindings and waivers. Configs, drafts and snapshots are defined on Configs and snapshots.

ObjectMutable?What it is
BindingYesThe pointer from one project environment to one snapshot, plus the waivers frozen at the moment of binding.
WaiverYesAn approved exception to one control or rule, scoped to one environment, carrying a stated expiry.

Protected environments

On a protected environment every bind runs the gate below; on an unprotected one a bind is direct. prod is protected, dev and staging are not. Protection is defined on Projects and environments.

From draft to a bound environment State diagram: a draft is edited and published into a published snapshot, approval makes it approved; an approved snapshot is bound to an unprotected environment or promoted to a protected one, and a protected environment can roll back to the previous snapshot. edit publish approve bind promote rollback Drafteditable Snapshot: publishedimmutable Snapshot: approvedgate passed Unprotected envdev · staging Protected envprod Previous snapshotrestored binding LegendMutable / bindingImmutable snapshotGated promotionRollback outcome

A protected environment needs an approved snapshot, not just a published one. Why publishing and approving are separate acts is on Configs and snapshots.

The gate

A promotion names a snapshot and a target environment. On a protected environment the gate evaluates the request and returns a list of blockers. Each blocker has a severity: a block refuses the promotion, a warn records a concern and lets it through.

A successful promotion changes what the registry serves from the next request. The served module version does not change with the posture, so a workspace that already has the module installed keeps its copy on a plain terraform init; run terraform init -upgrade, or init in a fresh working directory, to download it again. See how a module request resolves.

You do not have to attempt a promotion to find out how the gate will judge it. The preview endpoint runs the same gate without changing anything, and returns the blockers alongside a diff of what would change and which waivers would carry over. It reports the gate's verdict on the state at the moment you ask, and reserves nothing: anything that changes afterwards is evaluated afresh when you promote.

Promote a snapshot

  1. Get the snapshot approved. A protected environment refuses a snapshot that is only published.
  2. Preview the promotion to the target environment. Read the whole blocker list, the diff, and the waivers that would carry over. Capture any warn blocker now: the promotion record will not carry it.
  3. Clear every block. An unapproved snapshot, a self-approval when separation of duties is on, or uncovered coverage when the organization blocks on it.
  4. Promote. If someone promoted in between, the call is refused with 409; re-read and decide again.
  5. Refresh workspaces. The served module version does not change with a posture, so run terraform init -upgrade where the module is already cached. See How a module request resolves.

To undo, roll back. The environment returns to its previous snapshot. The frozen waiver set stays as the last promotion built it.

Waivers

A waiver records a decision to accept a specific gap for a limited time. It names the control or rule, an expiry, and a justification. Waivers are proposed and approved as separate acts.

On a project environment, an exception is made in one of two reviewed ways: a time-limited waiver, or a permanent change to the config (the control in its forbidden list) published and promoted as a new snapshot. A module source there cannot carry ?disable=: the organization's host refuses it with a 400, so no parameter in a source string can subtract from the environment's posture. Pointing a source at a different host or environment is a code change, which your review and CI checks on module sources have to catch. On a framework endpoint such as soc2.compliance.tf, a control is turned off with ?disable= in the module source itself, where code review sees it; see Turn controls on and off.

The important property is when a waiver takes effect on an environment, and the matching question of when its expiry takes effect.

A waiver sitting on an environment is only a proposal until a promotion happens. At promotion time, waivers that are both approved and unexpired are copied into the binding and frozen there.

The expiry is checked twice. At the freeze, an expired waiver is not copied into the binding. After that, the registry checks each frozen waiver's expiry every time it resolves the environment's posture: once the expiry has passed, the waiver stops relaxing what the registry serves, with no promotion needed. A frozen waiver whose expiry cannot be read is treated as expired.

Revocation works differently. To clear a revoked waiver from an environment, promote a different snapshot to it: a bind or promote that actually writes a new binding is what rebuilds the frozen set. Two things that look like they would work do not: re-promoting the snapshot already bound is a no-change write, and a rollback repoints the snapshot without rebuilding the frozen set.

Consequences worth understanding:

  • Approving a waiver does not change what production serves. The next promotion does.
  • Revoking a waiver does not change what production serves either. The frozen copy stays in effect until a bind or promote writes a new binding and drops it.
  • A waiver that expires stops applying when its expiry passes: it is not carried into new bindings, and its frozen copy no longer relaxes what the registry serves.

This is what makes a binding reproducible. What the registry serves for an environment is determined by the binding and the expiry dates frozen into it, not by the current state of an editable waiver list.

What it does not do

  • It does not enforce separation of duties by default. The setting is off unless enabled for your organization with our help; there is no self-service switch. To check whether it is on, see Access control.
  • It does not withdraw a revoked waiver from a binding. Only a bind or promote that writes a new binding does. An expired waiver stops applying on its own.
  • Rollback does not rebuild the waiver set. It moves the snapshot only.
  • There is no unbind. A binding can be re-pointed, never removed.
  • A warn is not recorded. It appears in the preview only.

Who may do what

ActionWho
Preview a promotion, view environment statusAny member
Publish a snapshot; bind to an unprotected environmentAdmin or owner
Approve a snapshot; propose, approve or revoke a waiverAdmin with the approver capability, or owner
Bind or promote to a protected environment; roll backAdmin with the approver capability, or owner

The permission for a bind is chosen from the target environment's protection state, not from the endpoint's name, so the ability to publish never reaches production by itself. The full table is on Access control.

What gets recorded

Every bind, promotion, rollback and waiver decision is recorded in the audit trail, written in the same atomic operation as the change. Reading it needs the audit:read permission.

Operating details

The rest of this page is the operator's half: every gate blocker and what raises it, and the guarantees that hold under concurrent promotions and partial failure.

On this page

Ask AI about this

Help improve this page