Skip to content
Latchkey

How to Enforce Separation of Duties in CI/CD

GitHub already blocks self-approval; the deploy side needs an environment gate so the person who merged cannot also release unreviewed.

Separation of duties (often "four eyes") means one person cannot both create and release a change. GitHub disallows approving your own pull request, and you add a protected environment with required reviewers to enforce it on the deploy side. This is educational guidance, not a legal control mapping.

Steps

  • Require at least one approval and enable Code Owner review on the default branch.
  • Create a protected environment (for example production) with required reviewers.
  • Set the reviewer list to a group that excludes typical change authors where possible.
  • Optionally add a job-level guard that fails if the actor equals the PR author.

Deploy job gated by environment

.github/workflows/deploy.yml
jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production   # required reviewers approve the release
    steps:
      - uses: actions/checkout@v4
      - run: ./deploy.sh

Optional actor guard

.github/workflows/deploy.yml
- name: Block self-release
  run: |
    if [ "${{ github.actor }}" = "${{ github.event.pull_request.user.login }}" ]; then
      echo "Author cannot approve their own release"; exit 1
    fi

Notes

  • The environment approval is recorded and exportable as evidence of the second signer.
  • GitHub refuses self-approval on the PR, so the merge side is already covered.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →