Mastering CodeQL Secret Scanning: Best Practices for Secure Secrets Handling in GitHub

Suthakar Paramathma
4 min readAug 8, 2023

--

It is dangerous and advised not to store secrets like tokens, keys, and passwords directly in GitHub repositories. The primary justification for this is that once the secrets are in the repository, they become vulnerable to leaks, and even if they are later removed, they remain in the git history.

The CodeQL Secret Scanning feature on GitHub is made to find secrets in open repositories and alert the service provider so they can revoke any credentials that have been exposed. Here are some best practices to follow if you want to store secrets securely or avoid false positives:

  1. Use Environment Variables: Instead of hardcoding secrets into your code, use environment variables to access them. By doing it this way, you can change the secret without changing the code and keep your code clean.
  2. Leverage Secret Management Systems:
    - AWS Secrets Manager
    or AWS Parameter Store if you’re on AWS
    - Azure Key Vault if you’re using Azure
    - Google Cloud’s Secret Manager if you’re on GCP
    - HashiCorp Vault is another popular standalone choice
  3. Use .gitignore: Add configuration files or other assets to your .gitignore file if they contain secrets and should never be committed to the repository.
  4. Encrypted Secrets: For configurations, consider encrypting the secrets. Tools like git-crypt or BlackBox can be helpful.
  5. GitHub Secrets: You can use GitHub Secrets to store confidential data for GitHub Actions and incorporate it into your workflows.
  6. Regularly Rotate Secrets: Rotate your secrets frequently to prevent leaks and minimize the damage they could cause.
  7. Audit and Monitoring: Ensure that you have surveillance in place to spot any unauthorized use of the secrets. Usually, the covert management system does this.
  8. Educate Your Team: Inform your group of the value of keeping information out of the repository. Reminders and training sessions on a regular basis can reduce errors.
  9. Scan the Past: If you believe that a secret has been unintentionally disclosed in the past, you can help to clean up the history by using programs like BFG Repo-Cleaner or ‘git filter-branch’.
  10. Limit Access to Repository: Place a cap on the number of users who can access the repository. The likelihood of an error or malicious intent decreases as the number of users with access increases.
  11. Enable Two-Factor Authentication: Ensure that all GitHub accounts belonging to project collaborators have two-factor authentication (2FA) enabled.

Use Environment Variables in GitHub & GitHub Action — Recommended Approach

It’s simple to use environment variables in GitHub Actions. You can use some of the predefined environment variables that GitHub Actions offer without any additional configuration and define your own. You can use environment variables in GitHub and GitHub Actions in the following ways:

1. GitHub Encrypted Secrets:

Before using environment variables in a GitHub Action, you must set up encrypted secrets in your GitHub repository if they contain sensitive data.

  • Go to your GitHub repository.
  • Click on the “Settings” tab.
  • In the left sidebar, click on “Secrets and variables” and select “Action”
  • Click the “New repository secret” button.
  • Provide a name (e.g., MY_SECRET) and its corresponding value.

This secret is now encrypted and stored in GitHub and can be used in GitHub Actions.

2. Using Encrypted Secrets in GitHub Actions

In your .github/workflows/<your-workflow>.yml file, you can reference this secret as an environment variable:

yamlCopy codejobs:
my_job:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Use secret as environment variable
run: echo "Doing something with the secret"
env:
MY_SECRET_ENV: ${{ secrets.MY_SECRET }}

In this example, the secret MY_SECRET is passed to the environment variable MY_SECRET_ENV and can be accessed in the steps of the job.

3. Using Predefined Environment Variables

GitHub Actions provides a set of default environment variables that can be used directly in your workflow. For instance:

yamlCopy codejobs:
print_env_variables:
runs-on: ubuntu-latest
steps:
- name: Print GitHub Repository
run: echo "This is running on $GITHUB_REPOSITORY"

4. Setting Your Own Environment Variables

You can set your own environment variables directly in the workflow file:

yamlCopy codejobs:
print_custom_env_variable:
runs-on: ubuntu-latest
steps:
- name: Print custom environment variable
run: echo "Custom variable is $CUSTOM_VAR"
env:
CUSTOM_VAR: "This is a custom variable"

5. Using Environment Variables in a Matrix Strategy

If you’re running jobs in a matrix strategy, environment variables can also be set based on the matrix context:

name: codejobs
jobs:
matrix_example:
runs-on: ubuntu-latest
strategy:
matrix:
node: [12, 14]
steps:
- name: Use Node.js ${{ matrix.node }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node }}

Summary

Using environment variables and encrypted secrets in GitHub Actions helps keep sensitive data safe and enables more dynamic and flexible workflows. Make sure never to hard-code sensitive data directly in workflow files, and always use GitHub’s encrypted secrets for any confidential information.

--

--