Introduction
I would like to go through some thoughts on how you can better maintain and make use of secrets with your GitHub Actions workflows. Once I had read through the GitHub documentation, I did a simple breakdown of the core activities before giving a number of recommendations:
Overview of Secrets:
In GitHub, these are called secrets, which are stored-sensitive data at the organization, repository, or environment level. Secrets might be used within workflows but would remain accessible only when they have explicitly been mentioned in a workflow file to protect API tokens, credentials, and other sensitive data.
Examples of Secrets:
Here are some robust pragmatic ways to apply secrets within a GitHub Actions workflow:
Example 1: Using Secrets as Environment Variables
The following example uses a secret as an environment variable in a step in a workflow:
name: Use secret as environment variable
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run a command with a secret
env:
API_KEY: ${{ secrets.API_KEY }} # Use your secret here
run: echo "Using secret in a command"
In this example, environment variable API_KEY
secret was used in the job. The secret is securely passed to the worflow and can be set in the script without showing sensitive data.
Example 2: Using Secrets as Workflow Inputs
This is how you can perform it in case you want to pass a secret as an input for an action:
name: Use secret as input
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Use secret in an action
uses: some-action/with-secrets@v1
with:
api_key: ${{ secrets.API_KEY }} # Set secret as input
For this action, api_key
is a required input; hence, we safely pass the API_KEY
secret to satisfy this requirement.
Monitoring GitHub Actions Workflows
CICube is a GitHub Actions monitoring tool that provides you with detailed insights into your workflows to further optimize your CI/CD pipeline. With CICube, you will be able to track your workflow runs, understand where the bottlenecks are, and tease out the best from your build times. Go to cicube.io now and create a free account to better optimize your GitHub Actions workflows!
Example 3: Decrypting Large Secrets
Another alternative, especially for large secrets bigger than 48KB, is the encryption of a file and its storage in a repository, then using a passphrase stored as a secret from GitHub to decrypt that particular file during workflow execution.
- encrypt the secret file:
gpg --symmetric --cipher-algo AES256 my_secret.json
This command will create the encrypted file called my_secret.json.gpg
.
- Store the passphrase as secret in GitHub. For example,
LARGE_SECRET_PASSPHRASE
. - Add a workflow step to decrypt the file:
name: Decrypt large secret
on: push
jobs:
decrypt-job:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Decrypt large secret
// higliht-next-line
run: ./decrypt_secret.sh
env:
LARGE_SECRET_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }}
This step uses that passphrase as stored in the secret LARGE_SECRET_PASSPHRASE
to decrypt the my_secret.json.gpg
file.
#!/bin/sh
gpg --quiet --batch --yes --decrypt --passphrase="$LARGE_SECRET_PASSPHRASE"
--output $HOME/secrets/my_secret.json my_secret.json.gpg
Example 4: Base64 Encoding a Binary Blob
We can store binary blobs, such as certificates, as Base64-encoded strings. Here is how it’s done :
- Encode your file to Base64:
base64 -i cert.der -o cert.base64
This command takes the cert.der binary file and transforms it into a base64-encoded string, placing the output into cert.base64:.
-
Store the Base64 string as a secret in GitHub.
-
Decode a Base64 secret in a workflow:
name: Retrieve Base64 secret
on: push
jobs:
decode-secret:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Decode Base64 secret
env:
CERTIFICATE_BASE64: ${{ secrets.CERTIFICATE_BASE64 }}
run: |
echo $CERTIFICATE_BASE64 | base64 --decode > cert.der
In this example, a Base64-encoded certificate is stored as a secret and decoded back to its original binary form inside the workflow.
Example 5: Conditional Step with Secrets
Secrets cannot be used directly within conditional if statements. However, we can make a secret a job-level environment variable and then use that value for conditional logic:
name: Conditional secret usage
on: push
jobs:
build:
runs-on: ubuntu-latest
env:
SECRET_FLAG: ${{ secrets.FLAG_SECRET }}
steps:
- name: Conditional step
if: env.SECRET_FLAG == 'enabled'
run: echo "The secret flag is enabled!"
Besides the above example here the secret FLAG_SECRET
is assigned to an environment variable SECRET_FLAG
controlling via its existence whether or not a conditional step will be executed:
Conclusion
Secret usage within GitHub Actions workflows offers a layer of protection to sensitive data while efficiently automating. Setting these secrets across higher levels of granularity-organization, repository, and environment-will give you the flexibility of access control. Be it API keys, credentials, or encrypted files, this should give one a good basis for security and reliability within the workflow.
Source link
lol