Secrets, Variables and Environments in GitHub Actions

A
Author
06 Aug, 2026 1 min read 464 views

Workflows need configuration (URLs, flags) and credentials (API keys, deploy tokens). GitHub provides separate tools for each, plus environments to control who and what can deploy where.

Secrets and variables

  • Secrets are encrypted, masked in logs and not readable after saving. Use them for credentials.
  • Variables are plain-text configuration. Use them for non-sensitive values like region names or feature flags.
  • Both can be defined at organisation, repository or environment level.
steps:
  - run: ./scripts/notify.sh
    env:
      SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
      APP_REGION: ${{ vars.APP_REGION }}

Pass secrets as environment variables, not inline in commands, so they don't end up in shell history or process listings.

Environments

jobs:
  deploy-production:
    runs-on: ubuntu-latest
    environment:
      name: production
      url: https://shop.example.com
    steps:
      - run: ./deploy.sh
        env:
          DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}   # the production environment's secret

In the repository settings, an environment can have:

  • Its own secrets and variables, available only to jobs that target it.
  • Required reviewers who must approve before the job runs.
  • A wait timer before deployment.
  • Deployment branch rules, for example only main can deploy to production.

Safety rules

  • Secrets aren't passed to workflows triggered by pull requests from forks.
  • Never echo a secret; masking catches exact values but not transformed ones (base64, substrings).
  • Prefer short-lived credentials via OIDC over long-lived cloud keys stored as secrets.
  • Rotate secrets regularly and immediately when someone leaves the team.
Was this article helpful?

Comments

No comments yet. Have a question or a tip? Be the first to share it.

Leave a comment

Comments are reviewed before they appear.