How to protect secrets when using GitHub Actions?

How to protect secrets when using GitHub Actions?

With the launch of GitHub Actions, GitHub has taken the DevOps world by storm. All the new buzzwords, such as Serverless, Functions as a Service (FaaS), and Platform as a Service (PaaS), have become much more accessible.

GitHub Actions are a new breed of FaaS. This new service allows anyone to write and execute code in the form of a script run by the GitHub platform. But one thing most developers and SREs miss when working with GitHub actions is to protecting the secrets leading to data leaks.

In this blog post, we will learn what GitHub Actions are and how you can protect your secrets when working with GitHub Actions.

What are GitHub Actions?

GitHub Actions are a powerful tool that allows you to automate your workflow. With Actions, you can trigger events based on certain conditions, such as when a new commit is pushed to your repository. This can save you a lot of time and effort, as you don't need to run your workflow every time something changes manually.

Teams can also use actions to run tests or deploy your code to a production server. There are many different ways to use Actions, and you can even create your own custom Actions.

Say NO to Plain Text Secrets

When building a GitHub action, you will probably want to use the secrets feature to store sensitive data, such as passwords or API keys, securely in your GitHub account. So why use a secret, and why not just use plain text for storing your secrets?

Direct hard-coding secrets such as database username and password in the .yml file lead to sensitive data exposure, which is a security concern. The problem with using plain text secrets directly in the GitHub actions is that these secrets are checked into your code. If someone gets a hold of your code, that person has access to your secrets.

With this in mind, using environment variables (GitHub Secrets) to store your secrets seems wiser. This way, you can use the same secrets in your CI server, local machine, and deployment scripts. But what exactly is a GitHub secret?

"Secret" is a data type in GitHub actions used to store sensitive data that you do not want to include in your GitHub action's source code. Secrets are encrypted using a libsodium sealed box to keep them secure.

Here's a sample vulnerable GitHub action that sends alerts to Slack whenever a new issue is created.

name: Notifications via Slack

on:
  issues:
    types: [opened]


jobs:
  send_slack_msg:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - uses: rtCamp/action-slack-notify@v2.0.0
    env:
        SLACK_WEBHOOK: xxxxxxxxx
        SLACK_USERNAME: theusername 
        SLACK_CHANNEL: git-alerts-repo

In the action mentioned above, all three env variables should not be added directly to the code. Let’s take a look at how we can GitHub secret and secure this vulnerable action.

How to Create & Use GitHub Secrets?

Before diving into how to create secrets, you must know that there are three types of secrets in GitHub: Repository, Environment & Organization.

Repository Secrets

Repository Secrets are visible to everyone with access to the repository and are used to store sensitive information like deployment keys.

To create a repository secret, navigate to the settings tab of your repository and click on Secrets < Actions < New repository secret. Enter the name & value of the secret and click on Add button.

Environment Secrets

Environment secrets are tied to repository-level secrets, but these are linked to specific examples such as dev, staging, or prod. These types of secrets are useful when you have multiple testing environments, each of which has different resources.

To create an environment secret, navigate to the settings tab of the repository and click on Environments < Choose Environment < Environment Secrets < Add Secret. Enter the name & value of the secret and click Add secret.

Organization Secrets

Organization Secrets are visible to members of the organization and are used to store sensitive information like API keys. You can also limit the repositories that can access those secrets.

To create an organization secret, navigate to the main page of the organization (for example, https://github.com/Mergifyio) and click on Settings < Secrets < Actions < New organization secret. Enter the secret details and click on Add secret button.

Note: You must have Admin level privileges to create an organization secret.

Updating the GitHub Action

Now that we have learned how to create a secret let’s fix the vulnerable GitHub action. First, let’s add 3 different repository secrets named SLACK_WEBHOOK, SLACK_USERNAME, and SLACK_CHANNEL with the respective values.

Once done, edit the workflow file to use these secrets. There’s a syntax we must use when adding secrets to your workflow.

${{ secrets.SECRET_NAME }}

Here’s what the updated workflow file looks like:

name: Notifications via Slack

on:
  issues:
    types: [opened]


jobs:
  send_slack_msg:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - uses: rtCamp/action-slack-notify@v2.0.0
    env:
        SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
        SLACK_USERNAME: ${{ secrets.SLACK_USERNAME }} 
        SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}

Conclusion

Secrets management and encryption are vital in a world where everything is moving so fast, and you must keep your secrets safe. In the case of GitHub, they were aware of the problem, too. That’s why they have provided us with GitHub secrets.

GitHub Secrets makes it easy to manage secrets and encrypt secrets in the same repository (or in the organization) where you are storing your code.

We hope you enjoyed our article about how to protect secrets when using GitHub Actions. With this knowledge, we know that you can safely store secrets during the build process of your GitHub Actions.

Thanks Keshav Malik for this article.

Ready to automate your GitHub workflow?
We save your time by prioritizing and automatically merging, commenting, rebasing, updating, labeling, backporting, closing, assigning, your pull requests.