GitHub Actions Community Plugin
Overview
GitHub Actions enables you to automate workflows for your GitHub-hosted repositories.
With this community plugin, you can fetch secrets directly from the Akeyless Platform into your workflows.
This guide will demonstrate the uses of OAuth 2.0 / JWT and AWS IAM Authentication Methods to fetch both Static and Dynamic secrets from Akeyless.
Prerequisites
- Job permissions requirement: (Relevant for OAuth 2.0 / JWT Authentication only)
The default usage relies on using the GitHub JWT (JSON Web Token) to authenticate to Akeyless. To make this available, you must configure it inside your job workflow.
jobs:
my_job:
#---------Required---------#
permissions:
id-token: write
contents: read
#--------------------------#
- For Dynamic Secrets, jq must be installed on the runner host.
Authentication
The following Authentication Methods can be used for authentication:
OAuth 2.0 / JWT
Create a new OAuth 2.0 / JWT Authentication Method using the CLI:
akeyless create-auth-method-oauth2 --name /Dev/GitHubAuth \
--jwks-uri https://token.actions.githubusercontent.com/.well-known/jwks \
--unique-identifier repository \
--force-sub-claims
Where:
-
--jwks-uri
- The URL to theJWKS
that contains the public keys that would be used for JWT verification. -
--unique identifier
, A unique ID, usually a value such asemail
,username
orupn
for example. Whenever a user logs in with a token, these authentication types issue Sub-Claims that contains details uniquely identifying that user. This sub-claim includes a key containing the ID value you configured and is used to distinguish between users from within the same organization. -
--force-sub-claims
- Enforce role association to include sub-claims.
Create an Access Role:
akeyless create-role --name /Dev/GitHubRole
Warning
It is required to add appropriate Sub-Claims based on the claims available in the JWT to prevent access by unauthorized users.
Sub-Claim configuration allows Akeyless to grant access to specific workflows, based on the claims that GitHub provides in the JWT.
Attach your OAuth 2.0 / JWT
Authentication Method to the Access Role that was created and add an appropriate Sub-Claim, for example: repository=octo-org/octo-repo
where octo-org = {GitHub Account}
and octo-repo = {GitHub Repository}
.
akeyless assoc-role-am --role-name /Dev/GitHubRole \
--am-name /Dev/GitHubAuth \
--sub-claims repository=<octo-org/octo-repo>
Set Read
permissions for Items for the Access Role:
akeyless set-role-rule --role-name /Dev/GitHubRole \
--path /Path/To/your/secret/'*' \
--capability read
AWS IAM
Create an AWS IAM Authentication Method using the CLI:
akeyless create-auth-method-aws-iam \
--name /Dev/AWSAuth \
--bound-aws-account-id <AWS Account ID>
Create an Access Role :
akeyless create-role --name /Dev/AWSRole
Attach the AWS IAM Authentication Method to the Access Role :
akeyless assoc-role-am --role-name /Dev/AWSRole \
--am-name /Dev/AWSAuth
Set Read
permissions for Items for the Access Role:
akeyless set-role-rule --role-name /Dev/AWSRole \
--path /Path/To/your/secret/'*' \
--capability read
Runner Configuration
Configure a self-hosted-runner:
- In GitHub - navigate to the main page of the repository and select Settings > Actions > Runners > New self-hosted runner.
- Select the operating system and architecture of your self-hosted-runner machine.
- Follow the instructions in the Download section to prepare a directory for the GitHub runner, and then download the runner.
- Follow the instructions in the Configure section to configure the runner to connect to GitHub with a token GitHub generates for the runner.
GitHub Repository Secret
You can store the AccessID
as a GitHub secret inside the repository to use in your workflow.
In the following examples, instead of explicitly specifying the AccessID
of the Authentication Method inside the workflow, we store it as a secret in the repository as a variable called ACCESS_ID
.
- On GitHub, navigate to the main page of the repository, and select Settings > Secrets and variables > Actions > New repository secret.
- Enter the name for the secret (for example,
ACCESS_ID
) and set the secret value to your Auth Method Access ID. - Select Add secret.
Usage
The following examples will demonstrate how to fetch Static and Dynamic secrets from Akeyless.
Fetching Static Secrets
Create a static secret using the following command:
akeyless create-secret --name /GitHub/MyGitSecret --value <Secret value>
Example of fetching a static secret using OAuth 2.0 / JWT and AWS_IAM Authentication Methods :
name: 'Static-Secret'
on: push
jobs:
fetch_secrets:
runs-on: 'ubuntu-latest'
permissions: # IMPORTANT - both of these are required
id-token: write
contents: read
name: Fetch some static secrets
steps:
- name: Fetch secrets from AKeyless
id: fetch-secrets
uses: LanceMcCarthy/akeyless-action@v3
with:
access-id: ${{ secrets.ACCESS_ID}}
static-secrets: '{"/GitHub/MyGitSecret":"MY_SECRET"}'
- name: Use Outputs
run: |
echo "Step Outputs"
echo "MY_SECRET: ${{ steps.fetch-secrets.outputs.MY_SECRET }}"
echo "Environment Variables"
echo "MY_SECRET: ${{ env.MY_SECRET }}"
name: 'Static-Secret'
on: push
jobs:
fetch_secrets:
runs-on: 'self-hosted'
name: Fetch some static secrets
steps:
- name: Fetch secrets from AKeyless
id: fetch-secrets
uses: LanceMcCarthy/[email protected]
with:
access-id: ${{ secrets.ACCESS_ID}}
access-type: 'aws_iam'
static-secrets: '{"GitHub/MyGitSecret":"MY_SECRET"}'
- name: Use Outputs
run: |
echo "Step Outputs"
echo "MY_SECRET: ${{ steps.fetch-secrets.outputs.MY_SECRET }}"
echo "Environment Variables"
echo "MY_SECRET: ${{ env.MY_SECRET }}"
Fetching Dynamic Secrets
The key difference with dynamic secrets is that the output value is typically a JSON object. There are two ways you can handle this: default output or parsed output.
Example of fetching AWS Dynamic Secret using OAuth 2.0 / JWT Authentication Method:
name: 'MyDynamicSecret'
on: push
jobs:
fetch_dynamic_secrets:
runs-on: 'ubuntu-latest'
name: Fetch dynamic secrets
permissions:
id-token: write
contents: read
steps:
- name: Fetch dynamic secrets from Akeyless
id: fetch-dynamic-secrets
uses: LanceMcCarthy/akeyless-action@v3
with:
access-id: ${{ secrets.ACCESS_ID }}
dynamic-secrets: '{"/GitHub/MyGitSecret":"MY_SECRET"}'
- name: Export Secrets to Environment Vars
run: |
echo '${{ steps.fetch-dynamic-secrets.outputs.MY_SECRET }}' | jq -r 'to_entries|map("JWT_\(.key)=\(.value|tostring)")|.[]' >> $GITHUB_ENV
# You can now access each secret separately as environment variables
- name: Verify Vars
run: |
echo "access_key_id: ${{ env.JWT_access_key_id }}"
echo "id: ${{ env.JWT_id }}"
echo "secret_access_key: ${{ env.JWT_secret_access_key }}"
echo "type: ${{ env.JWT_type }}"
name: 'MyDynamicSecret'
on: push
jobs:
fetch_dynamic_secrets:
runs-on: 'ubuntu-latest'
name: Fetch dynamic secrets
permissions:
id-token: write
contents: read
steps:
- name: Fetch dynamic secrets from Akeyless
id: fetch-dynamic-secrets
uses: LanceMcCarthy/[email protected]
with:
access-id: ${{ secrets.ACCESS_ID }}
dynamic-secrets: '{"/GitHub/MyGitSecret":"MY_SECRET"}'
parse-dynamic-secrets: true
- name: Verify Job Outputs
run: |
echo "access_key_id: ${{ steps.fetch-dynamic-secrets.outputs.access_key_id }}"
echo "id: ${{ steps.fetch-dynamic-secrets.outputs.id }}"
echo "secret_access_key: ${{ steps.fetch-dynamic-secrets.outputs.secret_access_key }}"
echo "type: ${{ steps.fetch-dynamic-secrets.outputs.type }}"
- name: Verify Environment Variables
run: |
echo "access_key_id: ${{ env.access_key_id }}"
echo "id: ${{ env.id }}"
echo "secret_access_key: ${{ env.secret_access_key }}"
echo "type: ${{ env.type }}"
For additional information use this link.
Tutorial
Check out our tutorial video on Managing Secrets in Github Pipelines.
Updated 3 months ago