© The Author(s), under exclusive license to APress Media, LLC, part of Springer Nature 2021
C. Chandrasekara, P. HerathHands-on GitHub Actionshttps://doi.org/10.1007/978-1-4842-6464-5_4

4. Secrets and Tokens

Chaminda Chandrasekara1   and Pushpa Herath2
(1)
Dedigamuwa, Sri Lanka
(2)
Hanguranketha, Sri Lanka
 

The ability to keep secret values is an essential feature in any CI/CD pipeline implementation tool because some parameters/variables are sensitive information that cannot be stored openly. Further, programmatically allowing access to third parties may be necessary. Authentication should be provided using tokens.

This chapter explores the options for keeping secrets in GitHub Actions and generating tokens to provide programmatic access to GitHub.

Defining and Using Secrets

Secrets are important in any CI/CD pipeline implementation tool. They protect sensitive information, such as connection strings and passwords, and keep passwords or other secrets applied in application configuration settings.

Repo-Level Secrets

GitHub repos allow you to create secrets in the Settings section. Select the Secrets tab to define a secret (see Figure 4-1).
../images/502534_1_En_4_Chapter/502534_1_En_4_Fig1_HTML.jpg
Figure 4-1

Secrets

Clicking the “New secret” button lets you set up a secret in your GitHub repository (see Figure 4-2). To use a secret in the workflow, you need collaborator permission. The secrets you create in a GitHub repo are not available in the repo’s forks, which essentially protects sensitive information.
../images/502534_1_En_4_Chapter/502534_1_En_4_Fig2_HTML.jpg
Figure 4-2

New secret

Once a secret is created, the value cannot be seen again, but it can be utilized in the workflows. If required, you can either remove or update the secret to a new value.

Organization-Level Secrets

You can also create organization-level secrets in GitHub. If your organization is set up in GitHub, you can set up a secret in Settings (see Figure 4-3).
../images/502534_1_En_4_Chapter/502534_1_En_4_Fig3_HTML.jpg
Figure 4-3

Secrets in GitHub organizations

Organization secrets are available to private repositories with the paid plans. Organization secrets are available in public repos through workflows.

Naming Secrets

The following describes considerations for naming secrets.
  • Characters: Alphanumeric characters are used in secret names; however, secrets cannot start with a number. Only an underscore can separate parts of a secret name. Spaces and other special characters are not allowed in secret names.

  • Unique: Secret names must be unique at the repo or organization level, and names are case sensitive. If you define a secret name at the organization level and use the same secret name in the organization’s repo, precedence is given to the repo-level secret.

  • GITHUB_ Prefix: You cannot use GITHUB_ in secret names; it results in an error.

Using Secrets in Workflows

You can use the following syntax to access a secret from a workflow.
${{ secrets.secret_name }}
For example, an AppCenterAPIToken secret created in a repo can be accessed as follows.
${{ secrets.AppCenterAPIToken }}
For more clarity, a usage example in a job and an action is shown next.
  AppCenterDistibute:
    runs-on: ubuntu-latest
    needs: Android
    steps:
    - uses: actions/download-artifact@v2
      with:
        name: my-artifact
    - name: App Center
      uses: wzieba/AppCenter-Github-Action@v1.0.0
      with:
        # App name followed by username
        appName: Ch-DemoOrg/SLDevOpsDemoTrail
        # Upload token - you can get one from appcenter.ms/settings
        token: ${{ secrets.AppCenterAPIToken }}
        # Distribution group
        group: alphatesters
        # Artifact to upload (.apk or .ipa)
        file: AwesomeApp/AwesomeApp.Android/bin/Debug/com.companyname.AwesomeApp.apk
        # Release notes visible on release page
        releaseNotes: "demo test"

Note that GitHub always redacts the secrets printed in workflow logs; however, you should take care to not accidentally print the secrets to logs.

Limitations with Secrets

Using secrets in a GitHub Actions workflow has some limitations.
  • Only up to 100 secrets per workflow is supported.

  • The size of a secret is limited to 64 KB. If the secret is larger than 64 KB, storing an encrypted secret in the GitHub repo and keeping a decrypted password is recommended.

This section discussed creating and using secrets with GitHub workflows, including limitations and naming considerations.

GITHUB_TOKEN

In your workflow, you might need to push changes to your repo or add a label. Or you might want to create an issue in the GitHub repo while the workflow is executing. To do these activities, the workflow requires authentication.

GITHUB_TOKEN is the default token to authenticate GitHub Actions to the repo. GITHUB_TOKEN is an automatically created secret available in your workflow. A GITHUB_TOKEN’s permissions are limited to the repo in which the workflow exists (see Table 4-1).
Table 4-1

GITHUB_TOKEN Permissions

Permission

Access for Repo

Access for Forked Repos

Actions

read/write

Read

Checks

read/write

Read

Contents

read/write

Read

Deployments

read/write

Read

Issues

read/write

Read

metadata

read

Read

packages

read/write

Read

pull requests

read/write

Read

repository projects

read/write

read

statuses

read/write

read

Except for metadata, all other repo-related areas have read/write permissions in a workflow with GITHUB_TOKEN.

For example, you can use GITHUB_TOKEN and create an issue from a workflow. Creating an issue for a failed build job is a good use case. Let’s try to understand this with an example.

The following workflow is triggered on a push, which executes a job step that passes, then another step is made to fail purposefully by returning exit code 1.
on: [push]
jobs:
  FailJobIssueDemo:
    runs-on: ubuntu-latest
    steps:
      - name: Step is going to pass
        run: echo Passing step
      - name: Step is going to fail
        run: exit 1
Another step can then be added to run on a previous step’s failure to create an issue in the GitHub repository. If: ${{ failure() }} is making the step execute only when a previous step in the job fails. You can see the header is passed with GITHUB_TOKEN (--header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}) so that authentication can enable issue creation.
- name: Step To run on failure
        if: ${{ failure() }}
        run: |
          curl --request POST \
          --url https://api.github.com/repos/${{ github.repository }}/issues \
          --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \
          --header 'content-type: application/json' \
          --data '{
            "title": "Issue created due to workflow fialure: ${{ github.run_id }}",
            "body": "This issue was automatically created by the GitHub Action workflow **${{ github.workflow }}**. \n\n due to failure in run: _${{ github.run_id }}_."
            }'
The entire workflow is as follows.
on: [push]
jobs:
  FailJobIssueDemo:
    runs-on: ubuntu-latest
    steps:
      - name: Step is going to pass
        run: echo Passing step
      - name: Step is going to fail
        run: exit 1
      - name: Step To run on failure
        if: ${{ failure() }}
        run: |
          curl --request POST \
          --url https://api.github.com/repos/${{ github.repository }}/issues \
          --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \
          --header 'content-type: application/json' \
          --data '{
            "title": "Issue created due to workflow fialure: ${{ github.run_id }}",
            "body": "This issue was automatically created by the GitHub Action workflow **${{ github.workflow }}**. \n\n due to failure in run: _${{ github.run_id }}_."
            }'
Once executed, the step intentionally fails; however, the next step still executes, creating an issue in the GitHub repo (see Figure 4-4).
../images/502534_1_En_4_Chapter/502534_1_En_4_Fig4_HTML.jpg
Figure 4-4

Generate issue on failure

An issue is created in the repo, as shown in Figure 4-5.
../images/502534_1_En_4_Chapter/502534_1_En_4_Fig5_HTML.jpg
Figure 4-5

GitHub issue created by a workflow

If the permissions of GITHUB_TOKEN is not sufficient to perform the activity you need, you may create a personal access token (PAT) in GitHub and store it as a secret. Then utilize it in the workflows for authentication purposes.

This section discussed GITHUB_TOKEN with workflows and looked at an example scenario of creating an issue from a workflow job failure, in which a token is useful.

Summary

This chapter explored the capability to use secrets and considerations when using secrets. It looked at the GITHUB_TOKEN, which lets you authenticate and perform several actions with GitHub repos and the REST API.

The next chapter explores artifacts and cashing workflow dependencies.