GitHub Integration Quick Start
This section describes how to configure SPIRL to provide SPIFFE identities to your GitHub actions and workflows.
In this guide we are going to use self-hosted Github Action Runners on a Kubernetes cluster.
Setup GH Actions Runner Controller on k8s
Follow Official GH documentation to setup the controller.
Installing Actions Runner Controller:
NAMESPACE="arc-systems"
helm install arc \
--namespace "${NAMESPACE}" \
--create-namespace \
oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set-controller
Configuring a runner scale set:
To auto mount SPIFFE Workload API socket to each runner instance we need to modify default template. Here is an example of the values.yaml
file with updated template:
githubConfigUrl: "https://github.com/spirl/gh-runner-k8s-spiffe"
githubConfigSecret:
github_token: ""
minRunners: 1
runnerScaleSetName: "arc-runner-set"
template:
metadata:
# This label is used by SPIRL to mount SPIFFE Workload API socket to the runner
labels:
k8s.spirl.com/spiffe-csi: enabled
spec:
containers:
- name: runner
image: ghcr.io/actions/actions-runner:latest
command: ["/home/runner/run.sh"]
SPIRL will then automatically mount the SPIFFE Workload API socket to the runner based on that label.
Then you can install the runner with the updated template:
GITHUB_PAT="YOUR_GITHUB_PAT"
NAMESPACE="arc-runners"
INSTALLATION_NAME="arc-runner-set"
helm install "${INSTALLATION_NAME}" \
--namespace "${NAMESPACE}" \
--create-namespace \
-f values.yaml \
--set githubConfigSecret.github_token="${GITHUB_PAT}" \
oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set
Add k8s cluster to SPIRL-managed trust domain
Add your k8s cluster to your SPIRL-managed trust domain. For example, using SPIRL CLI:
spirlctl ci-cd cluster add production --trust-domain example.com --platform k8s --profile github.com
Create a GH Action
Create a sample GH Action in your repo. Copy/paste the content below into .github/workflows/spirl-gh-demo.yml
.
name: SPIRL for GitHub Actions Demo
on:
workflow_dispatch:
jobs:
spiffecli-action-demo:
# Use the INSTALLATION_NAME (runner scale set)
runs-on: arc-runner-set
permissions:
id-token: write # This is required for requesting the JWT
contents: read # This is required for actions/checkout
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install OIDC Client from Core Package
run: npm install @actions/core@1.10.1 @actions/http-client
- name: Get Id Token
uses: actions/github-script@v7
id: idtoken
with:
script: |
const coredemo = require('@actions/core')
let audience = 'https://spirl.com';
let id_token = await coredemo.getIDToken(audience)
coredemo.setOutput('id_token', id_token)
- name: Install curl
run: sudo apt-get update && sudo apt-get install -y curl
- name: Download spiffecli to the runner at /tmp
run: |
ARCH=$(uname -m)
if [ "$ARCH" = "aarch64" ]; then
URL="https://github.com/elinesterov/gh-action-spiffecli/releases/download/v0.0.1/spiffecli-linux-arm64"
elif [ "$ARCH" = "x86_64" ]; then
URL="https://github.com/elinesterov/gh-action-spiffecli/releases/download/v0.0.1/spiffecli-linux-amd64"
else
echo "Unsupported architecture: $ARCH"
exit 1
fi
curl -LO $URL
chmod +x spiffecli-linux-* && mv spiffecli-linux-* /tmp/spiffecli
- name: Fetch JWT SVID
run: |
IDTOKEN=${{ steps.idtoken.outputs.id_token }}
AUDIENCE="https://your-audience.com"
cd /tmp
RESULT=$(./spiffecli get jwt-svid --audiences $AUDIENCE --identity-exchange-token $IDTOKEN)
echo "JWT_SVID=$RESULT" >> $GITHUB_ENV
- name: Use JWT SVID Result
run: |
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# THIS IS FOR DEMO PURPOSES ONLY
# NEVER EVER USE THIS IN PRODUCTION
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# Removing the first three characters from the JWT to prevent automatic masking
# You'll need to add 'eyJ' back to the output to decode the JWT
UNSAFE_JWT="${JWT_SVID:3}"
echo "The result of the JWT SVID fetch was: $UNSAFE_JWT"
The above action sets the SPIFFE JWT issued to your job into the JWT_SVID
environment variable such that it can be consumed by subsequent steps in your workflow. It will have a SPIFFE ID path based on the repo owner and repo name e.g. spiffe://example.com/github.com/github-k8s-runner-prod/mycompany/spiffe-gh-action-demo
. This JWT can then be used to access any internal or external infrastructure supporting either OIDC or SPIFFE authentication.