Code of the Day
AdvancedCI/CD for Automation

Secrets and environments

GitHub Secrets are encrypted and masked in logs — understand how they differ from plain environment variables, and how deployment environments add approval gates for production runs.

WorkflowAdvanced6 min read
By the end of this lesson you will be able to:
  • Distinguish GitHub Secrets (encrypted, masked) from plain environment variables
  • Reference a secret in a workflow file and understand when it is exposed
  • Explain deployment environments and required-reviewer protection rules

Every automation pipeline eventually needs credentials: an API key, a database password, a webhook URL. Putting these in code or in a plain .env file committed to the repository is the single most common cause of credential leaks. GitHub Secrets provide an encrypted, audit-logged alternative.

What GitHub Secrets are

GitHub Secrets are key/value pairs stored encrypted at rest. They are:

  • Masked in logs. If a secret value appears anywhere in a workflow log output, GitHub replaces it with ***. This catches accidental echo $API_KEY calls.
  • Never readable after creation. You can update or delete a secret, but you cannot view its value through the API or UI once it is set.
  • Scoped. Repository secrets are available to all workflows in the repo. Environment secrets are only available to jobs targeting that environment. Organisation secrets can be shared across multiple repositories.

Set them in Settings → Secrets and variables → Actions → New repository secret.

Referencing secrets in workflows

Use the ${{ secrets.SECRET_NAME }} expression syntax:

steps:
  - name: Run pipeline
    run: python pipeline.py
    env:
      API_KEY: ${{ secrets.API_KEY }}
      DB_PASSWORD: ${{ secrets.DB_PASSWORD }}

The secret is injected as an environment variable for that step only — it is not available as a shell variable in other steps unless you set it there explicitly.

Never pass secrets as command-line arguments (e.g., python script.py --key $SECRET). Command-line arguments appear in the process list and in runner logs before masking is applied. Always use environment variables.

Plain environment variables vs Secrets

Environment variablesGitHub Secrets
StoredIn YAML file (version-controlled)Encrypted in GitHub
Visible in logsYes, unless masked manuallyAlways masked
Readable after setYesNo
Appropriate forNon-sensitive config (e.g., ENV=staging)Credentials, tokens, keys

A common pattern is to store non-sensitive config as workflow-level env: or repository variables (Settings → Variables), and credentials as Secrets.

Deployment environments

A deployment environment is a named gate in the workflow. Jobs can target an environment:

jobs:
  deploy-production:
    environment: production
    runs-on: ubuntu-latest
    steps:
      - name: Deploy
        run: python deploy.py
        env:
          API_KEY: ${{ secrets.PROD_API_KEY }}

With an environment configured to require a reviewer (Settings → Environments → Protection rules → Required reviewers), the job pauses before it runs and waits for an approved team member to click "Approve and deploy". This is a hard gate for production deployments.

Environment secrets are scoped: secrets.PROD_API_KEY is only available to jobs targeting the production environment, even if other jobs in the same workflow run with higher permissions.

Use environments for anything that touches production data or infrastructure. Required reviewers ensure that no scheduled or automated trigger can reach production without a human in the loop — a crucial control for compliance.

Rotating secrets

When a credential is rotated (a good security practice), update it in GitHub Secrets without touching any code or workflow files. The next workflow run picks up the new value automatically.

Automate reminders to rotate credentials by scheduling a workflow that posts a Slack message on the first of each month — a lightweight secret-rotation checklist that requires no external tooling.

Where to go next

Next: lab — deploy workflow — write a GitHub Actions workflow that runs the containerised pipeline on a daily schedule, references a Secret for the API key, and uploads the report as a downloadable artifact.

Finished reading? Mark it complete to track your progress.

On this page