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_ENVto set environment variables for subsequent steps - Use
GITHUB_OUTPUTto 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 }}.