GitHub API Access
This guide shows how to store a GitHub Personal Access Token in a Kubernetes Secret and have Riptides inject it transparently into outbound requests to api.github.com — including calls made by the gh CLI — with no token management in the workload.
Overview
Section titled “Overview”Accessing the GitHub API or running gh CLI commands from a workload traditionally requires embedding a token in environment variables, mounted files, or application configuration. With Riptides, you can instead:
- Store your GitHub PAT in a Kubernetes Secret.
- Create a WorkloadIdentity that assigns a SPIFFE identity to the workload and enables TLS intercept for outbound connections.
- Create a CredentialSource that references the Secret.
- Create a CredentialBinding that tells the kernel to inject
Authorization: Bearer <token>into outbound connections toapi.github.com.
Your application code and gh CLI invocations make plain, unauthenticated requests. The Riptides kernel module intercepts each outbound connection to api.github.com, terminates TLS, injects the credential, and re-originates the connection to GitHub.
Prerequisites
Section titled “Prerequisites”- A running Riptides control plane with minimum one daemon deployed
kubectlaccess to theriptides-systemnamespace- The
oidc-loginkubectl plugin (kubelogin) for control plane authentication. See Install theoidc-loginPlugin. - A GitHub Personal Access Token with the scopes your workload requires (e.g.,
repo,read:org) ghthe GitHub CLI
Step 1: Create a Kubernetes Secret
Section titled “Step 1: Create a Kubernetes Secret”Store your GitHub PAT in a Kubernetes Secret in the riptides-system namespace.
kubectl create secret generic github-pat \ --from-literal=token='<your-github-pat>' \ -n riptides-systemSecurity note: The Secret lives in the
riptides-systemnamespace. Access is mediated through CredentialSource and CredentialBinding resources — the workload never directly accesses the Secret.
Step 2: Create a WorkloadIdentity
Section titled “Step 2: Create a WorkloadIdentity”The WorkloadIdentity must exist before other resources that reference its workloadID. It assigns a SPIFFE identity to the workload and enables TLS intercept for outbound connections so the kernel can inject credentials.
First, find the daemon running on the host:
riptides-cli ctl get daemonsRetrieve its ID:
riptides-cli ctl get daemon <daemon-name> -o jsonpath='{.spec.workloadID}'Use that value in the scope.daemon.id field below:
riptides-cli ctl apply -f - <<EOFapiVersion: core.riptides.io/v1alpha1kind: WorkloadIdentitymetadata: name: gh-cli namespace: riptides-systemspec: connection: tls: mode: PERMISSIVE intercept: true scope: daemon: id: "<daemon-id>" selectors: - process:name: gh workloadID: "gh-cli"EOFKey field:
connection.tls.intercept: true: The kernel intercepts outbound TLS connections and handles credential injection. Required for theinjectionpropagation mode to work.
Step 3: Create a CredentialSource
Section titled “Step 3: Create a CredentialSource”The CredentialSource tells Riptides where to find the credential and how to treat it.
riptides-cli ctl apply -f - <<EOFapiVersion: core.riptides.io/v1alpha1kind: CredentialSourcemetadata: name: github-token-source namespace: riptides-systemspec: kubernetes: secretRef: name: github-pat key: token type: BearerTokenEOFVerify:
riptides-cli ctl get credentialsource github-token-source# STATE should show AVAILABLEStep 4: Create a Service for the GitHub API
Section titled “Step 4: Create a Service for the GitHub API”Define a Riptides Service for api.github.com. This tells Riptides which outbound destinations should receive the credential.
riptides-cli ctl apply -f - <<EOFapiVersion: core.riptides.io/v1alpha1kind: Servicemetadata: name: github-api-svc namespace: riptides-systemspec: addresses: - address: api.github.com port: 443 external: true labels: api: githubEOFStep 5: Create a CredentialBinding
Section titled “Step 5: Create a CredentialBinding”The CredentialBinding connects the CredentialSource to your workload and configures how the credential is delivered.
riptides-cli ctl apply -f - <<EOFapiVersion: core.riptides.io/v1alpha1kind: CredentialBindingmetadata: name: github-token-binding namespace: riptides-systemspec: credentialSource: github-token-source propagation: injection: selectors: - api: github workloadID: "gh-cli"EOFVerify:
riptides-cli ctl describe credentialbinding github-token-binding# STATE should show OKWhen the workload makes an outbound HTTPS request to api.github.com, the kernel intercepts the connection and injects Authorization: Bearer <token>. The workload does not set any authentication headers.
Step 6: Configure the Riptides CA Bundle
Section titled “Step 6: Configure the Riptides CA Bundle”Because tls.intercept: true causes the kernel to terminate and re-originate TLS, processes need to trust the Riptides CA. The daemon automatically merges the intercept CA into the OS trust store, so on most hosts no extra configuration is needed.
In containers or environments where the OS trust store is not updated by the daemon, you will need to point your runtime at the Riptides CA file. gh is written in Go and uses the OS trust store — in containers, SSL_CERT_FILE covers it alongside other Go-based tools.
See Trusting the Riptides CA for the full list of runtime-specific environment variables.
Step 7: Use the Credential
Section titled “Step 7: Use the Credential”Your workload makes plain, unauthenticated requests — no token handling in the application or script. The kernel intercepts each connection to api.github.com and injects the credential automatically.
gh CLI
Section titled “gh CLI”gh requires GH_TOKEN to be set to a non-empty value before it will make API requests. Export a placeholder so gh proceeds — Riptides replaces it on the wire:
export GH_TOKEN=.Then make API calls as normal:
gh api gistsThe kernel intercepts gh’s outbound connection to api.github.com, strips the placeholder, injects the real PAT, and re-originates the TLS session to GitHub. The gh process never sees the token.
HTTP libraries and curl
Section titled “HTTP libraries and curl”import requests
# No Authorization header — the Riptides kernel module injects itresponse = requests.get("https://api.github.com/user/repos")print(response.json())# No -H flags neededcurl https://api.github.com/user