Safeguard
Security Guides•

A deploy starter workflow: add environments and required reviewers

Deployment templates often run on any push. Put the deploy job behind a GitHub environment with required reviewers so a person approves first.

Safeguard Security Team
3 min read

Put the deploy job in a named environment, store deployment secrets as environment secrets, and require a reviewer. GitHub says a job cannot access environment secrets until a reviewer approves. That one change turns a deploy template from automatic on every push into approved by a person each time.

What the public templates assume

GitHub's collection of starter workflows includes a deployment category next to continuous integration and others. Those files are a starting point for getting code to a platform. They cannot know your approval process, which accounts are production, or who may release.

So the first edit is not the cloud settings. It is the control around the deploy job.

Step 1: create an environment

In the repository settings, create environments such as staging and production. GitHub's documentation lets you attach protection rules, including required reviewers.

Step 2: move secrets into it

Repository secrets are readable by any workflow in the repository. GitHub's guidance suggests protecting environment secrets with required reviewers, so a job cannot read them until approval is granted. Move deploy credentials out of the repository level and into the matching environment.

Step 3: name the environment in the job

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production
    permissions:
      contents: read
    steps:
      - run: echo "deploy step goes here"

The job waits for approval, then receives the environment's secrets.

Step 4: prefer short lived credentials

If your cloud provider supports it, replace stored keys with OpenID Connect. GitHub describes it as a way to authenticate without storing long lived cloud credentials as secrets. The deploy job can then request a short lived token for the run. See GitHub Actions OIDC for cloud access.

Step 5: separate build from deploy

Run build and tests in one job with minimal permissions and no deploy secrets. Run deploy in a second job that depends on the first and sits behind the environment. If a test step is compromised, it never sees the deployment credentials.

What reviewers should check

At approval timeQuestion
What is being deployedIs it the commit I expect?
Who triggered itIs this a normal release or something unusual?
Where it goesRight environment, right account?
What changed in the workflowDid the YAML change since the last approved run?

The last question matters. Code owners on the workflows directory mean the deploy logic itself had a review, not just the app code.

A caveat on reusable workflows

GitHub's reuse documentation says that to use an environment secret in a reusable workflow, you set the environment on the job inside the reusable workflow, and the caller must still pass the secret. It also warns that if the caller does not pass an environment secret, it resolves to an empty string with no error, unless you mark the secret required. Test the path end to end.

Quick check

Does a required reviewer stop all bad deploys?

No. It adds a person at a key moment. Reviewers still need to look at what is being released, and workflow files need their own review.

Should staging also need approval?

Not necessarily. Many teams let staging deploy automatically and require approval for production.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.