Skip to content
Go to console
Go to console

A tick asks, an environment decides, and the check says which one decides

Decision record 0093

Amends 0020 (what the docs say an environment with required reviewers is for) and 0061 (the check names the environment of each job that deploys). Built as slice 5.28.

A tick rule narrows within write access and never widens it (0018). So on its own, the ceiling on who may deploy is who may edit the dashboard issue. For a team with separation of duties that is the wrong set: the people allowed to deploy to production are usually fewer, decided somewhere other than a file in the repo, and audited (issue 212, from a hard look at how the product would be attacked). GitHub already has the gate for that, an Environment with required reviewers, and 0020 already made Sluiceway wait for it. But the docs read it as an extra for people who want a second pair of eyes, not as the answer to “who may deploy”. Nothing in the code had to change for a team to be safe. The risk was that nobody told them how, in the words an auditor reads.

Decision

  • The docs say it plainly: a tick decides who may ask, and an environment with required reviewers on the job that deploys decides who may deploy. Without such an environment the tick rule decides both. docs/security.md has a section of its own, “A tick asks, an environment decides”, under “Who can tick”, and tickers and stacks[].environment in the configuration, the environment sections of the workflow and the split workflow, and the README’s paragraph on sluiceway.yaml each say it in a sentence or two and link there.
  • The shape is shown with the tick rule left at its default: a stack with environment: production and no tickers, the split workflow’s apply job naming ${{ matrix.environment }} with deployment: false, and the environment with the people who may deploy as its reviewers, the default branch alone as its deployment branch and the credentials that change production as its secrets. It needs the split workflow, as 0020 and 0077 already say, because in one job every scan would wait for a reviewer.
  • What each one can and cannot do is a table. A tick rule is Sluiceway’s own, lives in sluiceway.yaml and changes by a commit, names people with write access, and is recorded as the ticker on the deployment record, on the trail and in a refusal comment. It cannot go beyond write access, name a team, or stop someone who uses the credentials without the dashboard. An environment is GitHub’s, lives in the repo’s settings, can name teams, records who approved on the run, and the deploy shows in the repo’s deployment history under it. It cannot show the reviewer the diff, and it is not on every plan.
  • The gap in between is said as it is. The tick is judged first, and resolve opens the deployment record, with the ticker and the diff hash, before the apply job waits for a reviewer. For as long as the approval takes, a record is open for a deploy that has not happened, and the deployment history shows it. A rejected or expired job is ended by settle with a failure line. An approved one previews again and deploys only on the same diff hash, so what goes out is still only what the ticked row showed, however long the wait.
  • GitHub’s rule against approving your own run is not a rule against approving your own tick, and the docs say so. The run that deploys is started by whoever edited the dashboard last, or by Sluiceway after a deploy that others wait for, and that is not always the ticker.
  • The check says, for each job that deploys, which of the two decides, from what the file shows and nothing more. A job that deploys is one whose modes include apply: the apply job of the split workflow, or the one job of the one-step workflow when its triggers start a deploy. With no environment: on the job, the line says the tick rule alone decides who may deploy. That is certain: a GitHub Environment on the job is the only thing GitHub puts between a tick and the deploy. With an environment, the line names it as written, says the tick rule decides who may ask and its required reviewers, if it has them, decide who may deploy, and says that whether it has them is a setting of the repo the check cannot read. The line goes in the Workflows part of the job log and the summary. It is never a warning: neither answer is a mistake.

Why the check does not say more

The check cannot know whether an environment has required reviewers. That is a setting of the repo, answered only by the GitHub API, and the check’s promise is files only, no credential and no GitHub call, so it is safe on a pull request from a fork (0042). Asking the API would break the promise, and would still not be enough: a workflow that names an environment the repo does not have gets one made by GitHub at the first run, with no rules at all, and an expression such as ${{ matrix.environment }} is only known in a run. So the check says the half it knows for certain and names the other half as a condition, rather than guess. A reader is never told the deploy is gated when it may not be, and is told for certain when it is not.

Considered

  • Leaving the check alone. The owner’s brief allowed it where the check cannot know reliably. Rejected, because the half it does know is the one that matters most: a team that believes a reviewer guards production while the deploy job names no environment is exactly the reader who is wrong today, and the check can tell them for certain.
  • A warning for a job that deploys without an environment. Rejected. Setup 1 of 0020 is a real gate and the right one for a single owner or a small team, and a warning on a correct workflow teaches people to ignore the check (the reason 0061 gives).
  • Resolving ${{ matrix.environment }} to the stacks’ environment values from the config. Left out: the text as written is what GitHub evaluates, and none of those names would say anything more about reviewers.
  • Saying it on the dashboard too, once, where the tick rule is explained, as issue 212 suggested. Left out: the dashboard has no place that explains the tick rule, and the scan that writes it cannot read an environment’s rules either (docs/later.md).
  • Changing a default, a tick rule, or what resolve or apply do. Out of scope. Nothing about who may tick or what deploys changes.

Consequences

  • Record 0020 is amended: an environment with required reviewers is the answer to who may deploy for a team with separation of duties, and the docs present it so, with the shape and the gap.
  • Record 0061 is amended: the check’s list of Sluiceway jobs carries the environment a job names, and each job that deploys gets one line on who decides who may deploy.
  • CONTEXT.md: the tick rule decides who may ask, the reviewers of an environment decide who may deploy.
  • docs/later.md gains the line about saying it on the dashboard.