Skip to main content

Command Palette

Search for a command to run...

Two Ways to Control Who Can Deploy to Production in GitHub Actions

Updated
3 min readView as Markdown
Two Ways to Control Who Can Deploy to Production in GitHub Actions
M
I'm a software engineer with over 15 years of experience. While my background is primarily in backend engineering, my work today spans cloud infrastructure, AI integrations, and the systems that support modern software applications. I started this blog to share what I’ve learned in a simplified, approachable way — and to add value for fellow developers. Though I’m an introvert, I’ve chosen to put myself out there to encourage more women to explore and thrive in tech. I believe that by sharing what we know, we learn twice as much — that’s precisely why I’m here.

Two Ways to Control Who Can Deploy to Production in GitHub Actions

Say you have a GitHub Actions workflow that someone can manually trigger to deploy something to an environment. It could be production, staging, preproduction, or any other environment where you want to control who can perform the deployment.

For this example, we'll use production.

You want to make sure that only certain people can deploy to it.

There are two ways you might approach this.

Option 1: Check the actor in the workflow

One simple solution is to keep a list of allowed users directly in the workflow and check who triggered it:

env:
  ALLOWED_ACTORS: "alice bob"

jobs:
  check-actor:
    runs-on: ubuntu-latest
    steps:
      - name: Verify actor
        env:
          ACTOR: ${{ github.actor }}
        run: |
          for a in $ALLOWED_ACTORS; do
            if [[ "$ACTOR" == "$a" ]]; then
              exit 0
            fi
          done
          echo "::error::Actor '$ACTOR' is not allowed."
          exit 1

  deploy:
    needs: check-actor
    steps: [...]

This is simple and it works. If the person who triggered the workflow is on the list, the deployment continues. Otherwise, it fails.

But there are some downsides.

First, the list of allowed users is hardcoded. If someone else needs permission to deploy, you have to modify the workflow file and merge that change.

More importantly, the protection itself lives inside the workflow. Anyone with permission to modify that file could potentially add themselves to the list, change the check, or remove it entirely.

For a sensitive operation like deploying to production, that's an important limitation.

Option 2: Use GitHub environments

GitHub provides a built-in way to protect deployments through environments.

Instead of implementing the access check yourself, your deployment job can target a configured environment:

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production
    steps: [...]

The production environment is configured in the repository settings.

To configure it:

  1. Go to your repository on GitHub.

  2. Open Settings → Environments.

  3. Create or select the production environment.

  4. Under Deployment protection rules, enable Required reviewers.

  5. Add the users or teams authorized to approve deployments.

  6. Optionally, enable Prevent self-review if you want to require someone other than the person who triggered the workflow to approve the deployment.

Screenshot 2026-07-11 at 3.52.10 PM

Once configured, when the workflow reaches a job that targets the production environment, GitHub pauses the job and waits for approval from an authorized reviewer before continuing.

The same approach can be used for other environments. For example, you could have separate staging, preproduction, and production environments, each with its own protection rules and authorized reviewers.

This keeps the list of authorized reviewers out of the workflow and gives you built-in deployment history and traceability without having to build your own auditing mechanism.

Where to see your deployment history

Once you start using GitHub environments, GitHub keeps a record of your deployments.

You can find this history from your repository's main page, under Deployments. From there, you can see deployments to each environment and inspect details such as who triggered the deployment, which branch or commit was deployed, when it happened, whether it succeeded or failed, and who approved it when approval was required.

This gives you a built-in audit trail without having to create or maintain one yourself.

GitHub provides more details on how to view deployment history.

Conclusion

Both approaches can restrict who is allowed to deploy, but for sensitive environments like production, GitHub environments provide better protection and built-in traceability without requiring custom logic in your workflow.