[DEEP RESEARCH] TeamPCP’s CI/CD Trust Inversion: When “Pinned” Actions Become Initial Access
A lot of teams “secured” Actions by pinning to tags. Great plan, right up until the trusted scanner becomes initial access. CI trust is now flimsy in ways most incident playbooks still ignore.


TL;DR
Key Points
- TeamPCP compromises high‑trust OSS Actions/packages and abuses tags, releases, and GitHub tokens so normal CI runs execute their stealer.
- Their core primitive is mutable references: force‑pushed tags and “imposter commits” (commits reachable by SHA but not on protected branches).
- Payloads are CI‑tuned: runner memory scraping, credential‑path sweeps, then encrypted exfil to attacker infra or via victim GitHub repos.
- After theft, they validate secrets, pivot into cloud discovery, push malicious PR workflows, perform mass cloning, and delete workflow logs.
- Defenders should focus on three pillars: break Action/tag trust, shrink CI secret blast radius, and treat CI exposure as an incident.
The story in 60 seconds
TeamPCP targets CI/CD as initial access, not just dependencies. They compromise security‑adjacent OSS (Trivy, KICS Actions; LiteLLM, Telnyx on PyPI). Then they use Git tags, releases, and tokens so pipelines that “pin to tags” quietly run attacker code.
They rely on tag poisoning (force‑pushing many historical tags) and imposter commits to keep workflows looking pinned and routine. Inside CI, their payloads read /proc/<pid>/mem to pull secrets from runner memory, sweep common credential paths on disk (SSH keys, cloud creds, kube configs, TLS keys, shell history), then encrypt and exfiltrate.
Stolen secrets are validated quickly (e.g., TruffleHog, sts:GetCallerIdentity), followed by discovery in core cloud services and GitHub‑native abuse: malicious PR workflows, mass git clone, repo staging (docs-tpcp/tpcp-docs), and workflow log deletion to reduce evidence. The tradecraft is repeatable and likely to spread.
High Impact, Quick Wins
-
1) Break Action/tag trust: commit‑SHA pinning + tag protection
- Removes TeamPCP’s main lever—silent tag hijack across historical versions.
- Metric: % of third‑party Actions pinned by SHA; # of unauthorized tag movements/month.
-
2) Shrink CI secret blast radius (how much a single compromise can reach)
- Limits what a poisoned Action can see and what stolen tokens can do.
- Metric: # of long‑lived CI secrets; % of CI→cloud auth via OIDC; % workflows with read‑only vs write‑scope
GITHUB_TOKEN.
-
3) Operationalize “CI exposure = incident”
- Matches TeamPCP’s fast move from theft to cloud discovery.
- Metric: time from exposure identification to credential invalidation; # of workflows covered by CI‑incident runbooks.
AlphaHunt
Stop doomscrolling, start decisioning. We chewed through the muck so your team doesn’t have to. → Subscribe!
Like this? Forward this to a friend!
(Have feedback? Did something resonate with you? Did something annoy you? Just hit reply! :))
Why it matters
SOC
- Source control / CI signals:
- Alert on tag anomalies: bursts of tag updates/movements or deletions, especially on popular Actions.
- Alert on workflow/log integrity: new or modified
.github/workflows/*by unusual actors and any workflow log deletions.
- Runner behavior:
- On self‑hosted runners, flag
/proc/*/memor/proc/*/mapsaccess by build or Action processes.
- On self‑hosted runners, flag
- Network:
- Monitor CI egress for a small, curated set of campaign domains; treat any hit as high‑severity and pivot to the initiating workflow.
IR
- Escalation:
- If a compromised Action/package executed in your CI, assume CI‑accessible secrets are compromised and trigger the runbook.
- Rotation and evidence:
- Rotate GitHub tokens, cloud keys, registry and deploy creds used in affected workflows.
- Preserve GitHub audit logs, workflow run metadata, runner logs, and cloud control‑plane logs before retention or deletion.
- Post‑compromise hunting:
- Look for secret validation (TruffleHog‑like behavior,
sts:GetCallerIdentity), discovery in core AWS services, and GitHub abuse (mass cloning,docs-tpcp/tpcp-docsrepos, malicious PR workflows, workflow log deletion).
- Look for secret validation (TruffleHog‑like behavior,
SecOps
- Policies and controls:
- Enforce commit‑SHA pinning for third‑party Actions that access secrets; protect tags and releases with restricted owners.
- Require CODEOWNERS for
.github/workflows/*changes; block direct workflow edits outside PRs.
- Identity and secrets:
- Default
GITHUB_TOKENto read‑only; grant write only to specific jobs. - Scope secrets to the smallest necessary job/environment; prevent PR‑originated workflows from accessing high‑value secrets.
- Default
- CI infrastructure:
- Segment runners (PR/test vs release/prod); log DNS/HTTP from runner networks and apply egress allow/alert lists focused on build registries, code hosts, and artifact stores.
Strategic
- Risk framing:
- Treat third‑party Actions and CI tooling as primary attack surface; most orgs already depend on them heavily without the controls above.
- Investment:
- Fund platform work on secure workflow templates, centralized checks for SHA pinning and tag governance, and durable audit log export/retention for GitHub/CI.
- Governance:
- Pre‑approve authority for rapid credential rotation and release freezes when CI‑focused tripwires (tag hijack, workflow log deletion, campaign domain hits) are triggered.
AlphaHunt Converge - Plug in your Flight Crew
Get intelligence where it counts. No dashboards. No detours. AlphaHunt Converge teases out your intent, reviews the results and delivers actionable intel right inside Slack. We turn noise into signal and analysts into force multipliers.
Anticipate, Don’t Chase.
See it in your telemetry
Network
- CI runner egress:
- DNS/HTTP(S) to known TeamPCP exfil domains from runner IP ranges.
- Short bursts of outbound connections immediately after third‑party Action steps start.
- Cloud logs:
- Clusters of
sts:GetCallerIdentityand broadList*/Describe*calls across core AWS services (e.g., IAM, EC2, S3, Secrets Manager) shortly after suspect CI runs.
- Clusters of
Endpoint
- On self‑hosted runners / build agents:
- Any non‑debug process opening
/proc/*/memor/proc/*/maps, especially child processes of CI agents or Actions. - Processes reading common credential paths (SSH keys, cloud credential files, kube configs/tokens, Docker configs, TLS keys, shell history) and then making outbound HTTP(S) connections.
- Map suspicious processes back to specific workflows and third‑party Actions in the workspace.
- Any non‑debug process opening
Source Control / CI (control plane)
- Git/GitHub:
- Tag integrity: mass tag changes, deletions, or popular tags suddenly pointing to new SHAs; tags whose commits are not on protected branches.
- Workflow integrity: new or edited
.github/workflows/*outside normal PR paths or without CODEOWNERS approval. - Evidence/staging behavior: workflow log deletions, org‑wide
git clonespikes, and creation of repos with names consistent with attacker staging patterns.
DEEP RESEARCH: TeamPCP- Supply-Chain “Trust Inversion” Attacks Against Source Control and CI/CD
TL;DR
- TeamPCP operationalizes source control trust (Git tags, GitHub Actions, PATs) as an initial access vector, not just a development risk.
- Their most repeatable win condition is mutable references: force-pushed tags and “imposter commits” that make compromised Actions look routine.
- The payloads are purpose-built for CI: steal secrets from runner memory (
/proc/<pid>/mem) and from common credential paths, then exfiltrate. - Post-compromise behavior includes workflow abuse (malicious PR workflows), repo cloning at scale, and log deletion to reduce evidence.
- Treat exposure as an incident: rotate secrets, audit GitHub org activity, and implement branch/tag protections + OIDC + least-privilege tokens.
What TeamPCP is (and what matters to defenders)
This actor is best understood as a campaign identity attached to a set of tradecraft optimized for CI/CD compromise at scale.
-
Operational focus (as observed publicly in Mar 2026):
- Compromise “security-adjacent” OSS that already runs with high privilege in CI (scanners, IaC tools, AI gateways).
- Abuse source control mechanics (tags, release automation, tokens) to convert normal pipeline activity into credential theft.
-
Why this is different from “normal” dependency compromise:
- It targets the delivery mechanism (Actions, release pipelines, registries) and the execution environment (runners with secrets).
- It leverages “expected behavior” (a scan action runs, returns normal output) while running the stealer first.
Campaign timeline (source control + CI/CD oriented)
| Date (UTC) | Target / Ecosystem | What happened (defender-relevant) | Source |
|---|---|---|---|
| 2026-03-19 | Trivy GitHub Actions + releases | Compromised credentials used to publish malicious artifacts and force-push tags for aquasecurity/trivy-action and setup-trivy |
Aqua GitHub discussion; Aqua blog; Wiz |
| 2026-03-19 to 2026-03-20 | Downstream CI users | Runners executing affected tags ran a credential-stealing payload, including memory scraping of GitHub runner processes | Aqua blog; Wiz; StepSecurity |
| 2026-03-23 | Checkmarx KICS GitHub Action | All 35 tags hijacked in kics-github-action; exfil domain shifted to checkmarx[.]zone; fallback uses victim GitHub token to create docs-tpcp repo |
Wiz |
| 2026-03-24 | LiteLLM (PyPI) | Malicious litellm==1.82.7 / 1.82.8 briefly available; 1.82.8 used .pth execution for code-at-interpreter-startup; exfil to models[.]litellm[.]cloud |
LiteLLM; Unit 42; RL |
| 2026-03-27 | Telnyx (PyPI) | Malicious telnyx==4.87.1 / 4.87.2 reported; described as stealer with staging (including WAV steganography in some reporting) |
Unit 42; RL |
| 2026-03-30 | Post-compromise | Wiz reports real-world follow-on: secret validation with TruffleHog, AWS discovery, malicious GitHub workflows via PRs, workflow log deletion, mass git.clone |
Wiz (post-compromise) |
| 2026-03-31 | Consolidated threat brief | Unit 42 publishes multi-wave write-up with IOCs, malware evolution, and guidance | Unit 42 |
Core intrusion mechanics in source control (how the compromises actually worked)
1) Tag poisoning (force-push) is the “blast radius multiplier”
This is the single most important pattern to internalize because it breaks a common security assumption: “we pin to a version tag, so we’re safe.”
-
Observed in the Trivy action compromise:
- Attackers force-pushed 76 of 77 tags in
aquasecurity/trivy-actionand all tags insetup-trivy, redirecting popular historical tags to malicious commits. - Downstream workflows that referenced
uses: aquasecurity/trivy-action@v0.x.ysilently started running the attacker’s code. - Aqua’s own write-up highlights why this is effective: workflows continue to succeed while secrets are stolen first.
- Source: Aqua incident disclosure and updates, plus related analysis from Wiz and StepSecurity.
- Attackers force-pushed 76 of 77 tags in
-
Observed in KICS:
- Wiz reports all 35 tags of the KICS GitHub Action were updated to point at malicious payload commits within a specific window (2026-03-23).
- Source: Wiz KICS post.
Defender takeaway (source control policy):
- A Git tag is not inherently immutable.
- “Immutable” UI indicators are not a substitute for governance; you need tag protection / rulesets, signed commits, and ideally pinned SHAs for third-party Actions.
2) “Imposter commits” (reachable-by-SHA but not on a branch)
This technique exploits how Git objects can be fetched by SHA even when they are not on an expected branch tip.
-
StepSecurity describes this technique explicitly:
- A commit can resolve by SHA but not exist on any branch of the source repo, which is highly suspicious for Actions usage.
-
Aqua’s update describes attacker behavior consistent with this pattern (crafted commits and metadata cloning across tags).
Defender takeaway (hunting + policy):
- If your org allows Actions by tag, you need detection for:
- Actions resolving to commits not on a protected branch.
- Unexpected tag movement events.
3) Payload design: built for CI runners, not endpoints
Across write-ups, the payload themes are consistent:
-
Memory scraping on GitHub-hosted runners
- Aqua and StepSecurity describe the approach: identify runner processes and read process memory (
/proc/<pid>/mem) to extract plaintext secrets, including bypass of masking. - Wiz similarly describes carving JSON patterns from runner memory.
- Aqua and StepSecurity describe the approach: identify runner processes and read process memory (
-
File system credential sweeping (especially self-hosted runners)
- Aqua’s write-up includes a long list of targeted file paths:
- SSH keys, Git credential stores, cloud provider credentials, Kubernetes configs/tokens, Docker configs, CI config files, database configs, TLS private keys, VPN configs, shell history, and more.
- Aqua’s write-up includes a long list of targeted file paths:
-
Encryption + exfil
- Consistently: collect → encrypt → exfil.
- Fallback exfil channels can involve abusing the victim’s own GitHub tokens to create repos/releases for staging (e.g.,
tpcp-docs/docs-tpcppatterns are repeatedly referenced across reporting).
What to prioritize for defense in “source control, etc.”
A. GitHub (or equivalent) audit log signals to baseline + alert on
This is the highest ROI for your stated environment focus.
-
Tag & release integrity
- Alert on:
- Tag creation / deletion bursts.
- Tag updates / force-push events (where visible).
- Release asset modifications outside normal release automation windows.
- Investigate:
- Tag movement where the referenced commit is unsigned, not on mainline, or authored by unexpected identities.
- Alert on:
-
Actions workflow abuse
- Alert on:
- New or modified workflow files (
.github/workflows/*) outside normal PR patterns. - Workflow runs triggered by unusual PR authors or from newly created branches.
- Workflow log deletion events (explicitly called out in Wiz post-compromise observations).
- New or modified workflow files (
- Alert on:
-
Token misuse patterns
- Alert on:
- PAT usage from new ASNs / VPN exit nodes.
- Unusual spikes in:
git.cloneoperations at org scale (Wiz observed this as a data collection method).- Repo creation within org (especially names resembling
tpcp-docs/docs-tpcp).
- Alert on:
B. CI/CD hardening controls that directly break TeamPCP’s playbook
These controls align to the observed attack chain.
-
Pin Actions by commit SHA (not tags)
- This is the most direct mitigation against tag force-push compromise.
- If you can’t do it universally, do it for:
- Security scanners.
- Release/publish actions.
- Any action that can access secrets.
-
Restrict
GITHUB_TOKENpermissions- Ensure default permissions are read-only wherever possible.
- Explicitly grant write permissions only to jobs that need them, and isolate those jobs with approvals/environments.
-
Use OIDC to cloud providers; eliminate long-lived cloud keys in CI
- TeamPCP’s payloads are designed to steal static credentials and tokens.
- OIDC reduces the value window of stolen material.
-
Harden self-hosted runners
- Treat them as production assets:
- Separate networks.
- Egress allowlisting for build jobs.
- No direct access to org-wide secrets by default.
- Treat them as production assets:
-
Egress controls for runners
- Several write-ups highlight the exfil domains being distinctive.
- Implement allowlisting where feasible:
- Your build/test registries.
- Code hosts.
- Artifact stores.
- Anything else should alert or block.
C. Incident response decision rule: when to escalate
Based on observed post-compromise behavior (Wiz):
-
Escalate to incident handling if any of the following are true:
- A compromised Action/package ran in your org during the exposure window.
- You see evidence of:
- workflow log deletion,
- mass cloning,
- secret validation tooling activity,
- abnormal enumeration bursts in cloud control planes.
-
Treat as “secrets compromised,” not “dependency risk.”
Detection & hunting: practical pivots you can operationalize
1) Source-control-focused hunting questions (fast triage)
Use these to rapidly bound your exposure.
-
Did we run the affected Actions by tag during the exposure window?
- Trivy: hunt for
uses: aquasecurity/trivy-action@anduses: aquasecurity/setup-trivy@in workflows, then correlate with run times around 2026-03-19 to 2026-03-20.
- Trivy: hunt for
-
Did any job attempt to access runner memory or
/proc/*/mem?- This is a high-signal behavior in CI contexts.
-
Did any repo named
tpcp-docsordocs-tpcpappear?- Both Aqua and Wiz describe repo-creation fallback mechanisms.
-
Did we see workflow runs created via suspicious PRs and then deleted logs?
- Wiz explicitly observed this post-compromise technique.
2) High-signal network pivots (defanged)
If you are doing retrospective DNS/HTTP review from runner networks, prioritize known campaign infrastructure.
scan[.]aquasecurtiy[.]org(Trivy wave)checkmarx[.]zone(KICS wave and also referenced in other stages)models[.]litellm[.]cloud(LiteLLM PyPI wave)tdtqy-oyaaa-aaaae-af2dq-cai[.]raw[.]icp0[.]io(fallback C2 referenced in multiple write-ups)
3) “Post-exposure” hunting: what TeamPCP does after secrets are stolen
From Wiz’s post-compromise observations:
-
Secret validation
- Look for TruffleHog usage patterns or API calls like
sts:GetCallerIdentityshortly after suspected execution windows.
- Look for TruffleHog usage patterns or API calls like
-
GitHub abuse
- Mass
git.clone. - Malicious workflow PRs.
- Workflow log deletions.
- Mass
-
Cloud discovery
- Broad AWS enumeration patterns (IAM/EC2/Lambda/RDS/Route53/S3/ECS/Secrets Manager).
MITRE ATT&CK mapping (defender-oriented, source control centric)
This mapping is anchored in the behaviors described in the cited write-ups, with emphasis on source control + CI.
-
Initial Access
- Supply Chain Compromise (CI/CD, Actions, package registries)
-
Execution
- Command and Scripting Interpreter (shell, Python used in payload stages)
-
Credential Access
- Credentials from Password Stores / Files (SSH keys, cloud configs, kube tokens)
- OS Credential Dumping–like behavior adapted to CI: process memory reads (
/proc/<pid>/mem) to extract secrets
-
Discovery
- Cloud service discovery and enumeration (observed in post-compromise)
-
Exfiltration
- Exfiltration over web services (HTTPS POST to attacker infrastructure)
- Exfiltration to cloud accounts / repos using victim tokens (fallback repo/release asset technique)
-
Defense Evasion
- Delete/modify logs (workflow log deletion mentioned by Wiz)
Practical hardening blueprint (minimum viable controls)
If you want an actionable baseline for a source-control-heavy org, implement these as a “one sprint” package:
-
Enforce Action pinning policy
- Require full commit SHA pinning for third-party actions.
- Exceptions require security review.
-
Protect tags & releases
- Tag protection/rulesets that restrict who can create/move tags.
- Require signed commits and verified identities for release-related workflows.
-
Reduce CI secret exposure
- Move cloud auth to OIDC.
- Reduce secret scope to environment-level, repo-level, and job-level minimums.
-
Runner segmentation
- Separate self-hosted runners by trust zone and project sensitivity.
- Implement egress allowlisting for runner networks.
-
Audit logging
- Ensure GitHub audit logs are retained and include IP logging.
- Alert on workflow log deletion and unusual cloning spikes.
Recommendations, Detections, Actions, Suggested Pivots, Forecasts, Next Steps and References..
(Specially baked, for Paid Subscribers..)
