GitHub Actions Certification
GitHub Actions Core Concepts
Working with Repository Level Secrets
Securely managing sensitive data in GitHub Actions is essential for robust CI/CD pipelines. In this guide, you’ll learn how to store credentials at the repository level and reference them in your workflows without exposing plain-text values.
Table of Contents
- Why Use Secrets and Variables?
- Scopes of Secrets and Variables
- Adding a Repository-Level Secret
- Adding a Repository-Level Variable
- Referencing Secrets and Variables
- Inspecting Workflow Logs
- Further Reading
Why Use Secrets and Variables?
Embedding credentials in workflow YAML blocks risks accidental leaks via PRs, clones, or shared logs. GitHub Actions provides a secure mechanism to inject encrypted values at runtime:
- Secrets for sensitive data (passwords, tokens).
- Variables for non-sensitive settings (usernames, tags).
Scopes of Secrets and Variables
You can define secrets and variables at three different levels:
Scope | Use Case | Visibility |
---|---|---|
Organization | Shared across multiple repositories | Only Org Admins |
Repository | Shared by all workflows in a single repo | Write access to Settings |
Environment | Limited to specific deployment environments | Environment admins and selected roles |
Adding a Repository-Level Secret
- Navigate to Settings > Secrets and variables > Actions.
- Click New repository secret, set the Name (e.g.,
DOCKER_PASSWORD
), and paste your secret. - Click Add secret to save.
Note
Repository secrets are encrypted and cannot be viewed once saved. If you lose the value, you must recreate the secret.
Adding a Repository-Level Variable
- Still under Settings > Secrets and variables > Actions, select New repository variable.
- Enter Name (e.g.,
DOCKER_USERNAME
) and Value. - Click Add variable to confirm.
Note
Repository variables are visible in Settings but cannot expose sensitive information.
Use variables for configuration values that are not confidential.
Referencing Secrets and Variables
Below is an insecure example with a plain-text password:
name: Exploring Variables and Secrets
on: [push]
env:
CONTAINER_REGISTRY: docker.io
DOCKER_USERNAME: siddharth1
IMAGE_NAME: github-actions-nginx
jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Docker Build
run: echo docker build
- name: Docker Login
env:
DOCKER_PASSWORD: s3cUrePasSw0rd
run: echo docker login --username=$DOCKER_USERNAME --password=$DOCKER_PASSWORD
- name: Docker Publish
run: echo docker push $CONTAINER_REGISTRY/$DOCKER_USERNAME/$IMAGE_NAME:latest
Secure Workflow with Repository-Level Secrets and Variables
name: Exploring Variables and Secrets
on: [push]
env:
CONTAINER_REGISTRY: docker.io
IMAGE_NAME: github-actions-nginx
jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Docker Build
run: |
echo docker build \
-t ${{ env.CONTAINER_REGISTRY }}/${{ vars.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest
- name: Docker Login
run: |
echo docker login \
--username=${{ vars.DOCKER_USERNAME }} \
--password=${{ secrets.DOCKER_PASSWORD }}
- name: Docker Publish
run: |
echo docker push \
${{ env.CONTAINER_REGISTRY }}/${{ vars.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest
deploy:
needs: docker
runs-on: ubuntu-latest
steps:
- name: Docker Run
run: |
echo docker run -d -p 8080:80 \
${{ env.CONTAINER_REGISTRY }}/${{ vars.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest
Warning
Your editor might flag unresolved ${{ vars.* }}
or ${{ secrets.* }}
references. These work at runtime and can be safely ignored.
Inspecting Workflow Logs
After committing and pushing your workflow, visit the Actions tab to observe the run:
Expand the Docker Login step to verify masking:
echo docker login \
--username=${{ vars.DOCKER_USERNAME }} \
--password=${{ secrets.DOCKER_PASSWORD }}
shell: /usr/bin/bash -e {0}
env:
CONTAINER_REGISTRY: docker.io
IMAGE_NAME: github-actions-nginx
docker login --username=siddharth1 --***
Secrets remain hidden (***
) and variables load correctly at runtime.
Further Reading
Watch Video
Watch video content
Practice Lab
Practice lab