Skip to main content

Managing Secrets and Variables

1. Creating Repository Secrets

Field Description Example
name The name of the secret API_KEY
value The encrypted value of the secret abc123xyz

Example: Creating a Repository Secret via GitHub UI

Settings > Secrets and variables > Actions > New repository secret
Note: Secrets are encrypted using AES-256 encryption and stored securely by GitHub.
Warning: Never commit secrets to your repository's code or configuration files.

2. Creating Organization Secrets

Field Description Values
name Name of the secret SECRET_NAME
value Value of the secret (encrypted) secret_value
visibility Who can access the secret all, selected
selected_repositories Repositories that can access the secret (when visibility is selected) [repo1, repo2]

Example: Creating an Organization Secret via API

curl -X POST \
  -H "Accept: application/vnd.github+json" \
  -H "Authorization: Bearer <token>" \
  https://api.github.com/organizations/<org_name>/actions/secrets \
  -d '{
    "name": "DEPLOY_KEY",
    "key_id": "123456789",
    "visibility": "selected",
    "selected_repositories": ["repo1", "repo2"]
  }'
Note: The key_id is required for encryption and must be obtained from the organization's public keys.
Warning: Secrets are stored encrypted and are only accessible in workflows. Never expose secrets in logs or outputs.

3. Creating Environment Secrets

Property Description Values
name Name of the environment secret SECRET_NAME
value Value of the secret (encrypted) secret-value
environment Environment to which the secret belongs production, staging

Example: Creating an Environment Secret via GitHub UI

Settings > Environments > [Environment Name] > Secrets and variables > New secret

Example: Creating an Environment Secret via API

const secret = {
  name: "API_KEY",
  value: "secret-value",
  environment: "production"
};

4. Using Secrets in Workflows

Property Description Usage
secrets.<secret-name> Reference to a secret defined in the repository or organization env: or with: in a step

Example: Using a secret in a job

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to server
        env:
          API_KEY: ${{ secrets.API_KEY }}
        run: |
          echo "Deploying with key: $API_KEY"
Note: Secrets are injected at runtime and are not visible in the logs or UI.
Warning: Never hardcode secrets in workflow files. Always use ${{ secrets.SECRET_NAME }}.

5. Creating Variables

Example: Setting a Repository Variable

name: Set Repository Variable
on:
  push:
    branches:
      - main
jobs:
  set-variable:
    runs-on: ubuntu-latest
    steps:
      - name: Set Variable
        run: |
          echo "MY_VAR=hello-world" >> $GITHUB_ENV
Property Description Usage
GITHUB_ENV File to write environment variables to Used in workflow steps to set environment variables
GITHUB_OUTPUT File to write outputs to Used in workflow steps to set job outputs
Note: Variables set in a job are only available to subsequent steps in that job.
Warning: Environment variables set in a workflow are not encrypted and should not contain sensitive data.

Key Points

  • Use GITHUB_ENV to set environment variables for subsequent steps
  • Use GITHUB_OUTPUT to set job outputs for use in other jobs
  • Variables are scoped to the job and not shared across workflows

6. Using Environment Variables

Variable Value Description
GITHUB_ENV path/to/env/file File to write environment variables to
GITHUB_OUTPUT path/to/output/file File to write outputs to
GITHUB_STATE path/to/state/file File to write state variables to

Example: Setting an environment variable in a job

jobs:
  build:
    steps:
      - name: Set environment variable
        run: echo "MY_VAR=value" >> $GITHUB_ENV

Example: Using environment variable in a step

jobs:
  build:
    steps:
      - name: Use environment variable
        run: echo "Value is $MY_VAR"

7. Setting Default Environment Variables

Variable Value Description
GITHUB_ACTOR string The username of the person or app that initiated the workflow
GITHUB_REPOSITORY string The owner and repository name, e.g., octocat/Hello-World
GITHUB_WORKFLOW string The name of the workflow
GITHUB_RUN_ID string A unique number for each workflow run within a repository
GITHUB_RUN_NUMBER string A unique number for each run of a particular workflow
GITHUB_SHA string The commit SHA that triggered the workflow
GITHUB_REF string The branch or tag ref that triggered the workflow
GITHUB_EVENT_NAME string The name of the event that triggered the workflow

Example: Using Default Environment Variables in a Job

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Echo Environment Variables
        run: |
          echo "Actor: $GITHUB_ACTOR"
          echo "Repository: $GITHUB_REPOSITORY"
          echo "Workflow: $GITHUB_WORKFLOW"

8. Masking Secret Values

When working with secrets in GitHub Actions, it's important to mask sensitive values to prevent them from being exposed in logs or outputs. GitHub Actions automatically masks secrets that are set using the secrets context.

Secret Value Masking Status Notes
GITHUB_TOKEN DEPRECATED Use secrets.GITHUB_TOKEN instead for better security practices.
CUSTOM_SECRET Automatically masked Any value set in secrets context is automatically masked in logs.

Example: Setting a Secret

jobs:
  build:
    steps:
      - name: Use Secret
        run: echo ${{ secrets.CUSTOM_SECRET }}
Note: The GITHUB_TOKEN is automatically masked in logs and outputs, but it's recommended to use secrets.GITHUB_TOKEN explicitly for clarity and consistency.
Warning: Never output secret values directly in logs or use them in echo commands. Even if masked, they may still be visible in logs or cached outputs.

9. Using Encrypted Secrets

Secret Name Value Usage Notes
GH_TOKEN ghp_xxx... Used for authentication with GitHub API Generated automatically for workflows
API_KEY sk-xxx... Used for external API access Must be stored as encrypted secret

Example: Using Encrypted Secrets in Workflow

name: Secure Workflow
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Code
        uses: actions/checkout@v4
      - name: Use Secret
        run: echo ${{ secrets.GH_TOKEN }}
Note: Secrets are encrypted at rest and only decrypted during job execution.
Warning: Never log or print secret values to console.
Secret Type Description Access Scope Security Level
Repository Secret Available to all workflows in a repository All branches High
Environment Secret Available to workflows in a specific environment Specific environments High
Organization Secret Available to workflows in any repo within an organization All repos in org Very High

10. Accessing Secrets in Actions

Secret Access Method Description
GITHUB_TOKEN secrets.GITHUB_TOKEN Automatically provided token with limited scopes for workflow access
CUSTOM_SECRET secrets.CUSTOM_SECRET User-defined secret stored in repository settings

Example: Using a Secret in a Job

jobs:
  build:
    steps:
      - name: Use Secret
        run: echo ${{ secrets.CUSTOM_SECRET }}
Note: GITHUB_TOKEN is automatically available and does not need to be explicitly set as a secret.

11. Managing Secret Scope

Scope Description Access Level Usage Example
Repository Secrets available to all workflows in the repository Read-only for workflows secrets.MY_SECRET
Environment Secrets specific to a named environment Read-only for workflows secrets.MY_SECRET
Organization Secrets available across repositories in the organization Read-only for workflows secrets.MY_SECRET
Enterprise Secrets available across all repositories in the enterprise Read-only for workflows secrets.MY_SECRET
Note: Repository-level secrets are the most commonly used and default scope for most workflows.

Example: Using Repository Secret in Workflow

jobs:
  build:
    steps:
      - name: Use Secret
        run: echo ${{ secrets.API_KEY }}

12. Rotating Secrets

Secret Rotation Status Notes
GH_TOKEN NEW Used for authenticating with GitHub API. Rotate every 90 days.
AWS_ACCESS_KEY_ID DEPRECATED Legacy key. Migrate to AWS Secrets Manager or GitHub Secrets.
DATABASE_PASSWORD Active Rotate every 30 days or upon security incident.

Example: Rotating a Secret in GitHub Actions

name: Rotate Secret
on:
  schedule:
    - cron: '0 0 * * 1' # Weekly rotation
jobs:
  rotate-secret:
    runs-on: ubuntu-latest
    steps:
      - name: Rotate Secret
        run: |
          # Generate new secret value
          NEW_SECRET=$(openssl rand -base64 32)
          # Update GitHub Secret via API
          curl -X PATCH \
            -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
            -H "Accept: application/vnd.github.v3+json" \
            https://api.github.com/repos/OWNER/REPO/actions/secrets/SECRET_NAME \
            -d '{"value":"'"$NEW_SECRET"'"}'
Note: Ensure that the GITHUB_TOKEN has sufficient permissions to update repository secrets.
Warning: Do not hardcode secret values in workflows. Always use ${{ secrets.SECRET_NAME }}.

Was this article helpful?