The breach that started with
a trusted tool.

On March 30, 2026, Cisco confirmed what security researchers had been warning about for weeks: attackers had used credentials harvested during the Trivy supply chain compromise to breach Cisco's internal development environment. More than 300 GitHub repositories were cloned. Source code for Cisco's AI Assistant and AI Defense products was stolen, along with code belonging to corporate customers at banks, business process outsourcing firms, and US government agencies.

The Cisco breach was not the result of a vulnerability in Cisco's own code. It was not a phishing attack. It was not an insider threat. It happened because Cisco trusted Trivy — a widely used open-source security scanner — and Trivy had already been turned into a weapon.

To understand how a company of Cisco's size and security sophistication ended up with its source code on an extortion site, you need to understand the full attack chain. It did not start on March 30. It started on March 1.

Full attack timeline — TeamPCP campaign CVE-2026-33634 · CVSS 9.4
Mar 1
TeamPCP

Initial credential theft via misconfigured GitHub Action

Attackers exploited a misconfigured pull_request_target workflow in Trivy's GitHub repository — present since October 2025 — to steal a Personal Access Token with write permissions. Aqua Security discovered the breach and rotated credentials, but the rotation was incomplete.

Mar 19
TeamPCP

Trivy v0.69.4 backdoored — 75 of 76 version tags poisoned

Using credentials that survived the incomplete rotation, TeamPCP force-pushed malicious code to 75 of 76 version tags in trivy-action and all seven tags in setup-trivy. The Trivy binary itself was backdoored across GitHub releases, Docker Hub, GitHub Container Registry, and Amazon ECR. CVE-2026-33634 assigned, CVSS 9.4.

Mar 19
Affected pipelines

Credential harvesting begins at scale across thousands of CI/CD pipelines

The malicious payload could read GitHub Actions Runner memory at /proc/<pid>/mem, bypassing log masking. Affected environments risked exposing cloud credentials, tokens, Kubernetes secrets, registry credentials, SSH keys, database passwords, and TLS material. Organizations that ran affected components should investigate and rotate credentials that were present.

Mar 23
TeamPCP

Checkmarx KICS and AST GitHub Actions compromised

Using credentials from the Trivy phase, TeamPCP moved to Checkmarx's KICS and AST repositories. The same credential harvesting payload was deployed. Malicious VSCode extensions were published simultaneously.

Mar 24
TeamPCP

LiteLLM PyPI compromised — 95 million monthly downloads affected

Malicious LiteLLM package versions 1.82.7 and 1.82.8 were published during the broader campaign. Environments that installed affected versions risked executing the credential-harvesting payload.

Mar 27
TeamPCP

Telnyx Python SDK compromised

The cascade continued with the Telnyx communications library on PyPI. The same infostealer payload. More credentials harvested from more developer environments.

Mar 30
TeamPCP using stolen Cisco credentials

Cisco development environment breached — 300+ repos cloned

Attackers used credentials harvested from Cisco's Trivy-enabled CI/CD pipeline to access Cisco's internal development environment. 300+ GitHub repositories were cloned including AI Assistant, AI Defense, and unreleased AI products. Source code belonging to banks, BPOs, and US government agencies was also stolen. Multiple AWS access keys were exfiltrated and used for unauthorized activities.

Mar 31
ShinyHunters

Extortion campaign launched — $13M demanded

ShinyHunters published an extortion post with an April 3 deadline claiming theft of 3+ million Salesforce records alongside the GitHub repositories and AWS assets. Cisco reportedly declined to pay. The group warned they would publish all data and contact every employee and client.

How the malware actually
read the credentials.

Most developers assume that GitHub Actions masks sensitive values in logs. If you add a secret to your repository's secrets store and use it in a workflow, GitHub replaces its value with asterisks in the log output. The assumption is that the secret is therefore safe even if logs are exposed.

The Trivy payload bypassed log-masking entirely.

Instead of reading from environment variables or workflow outputs, the malicious GitHub Action read directly from the GitHub Actions Runner process memory — specifically from /proc/<pid>/mem on Linux runners. This file provides direct access to a process's virtual memory space. The runner process holds all environment variables, including secrets, in memory. The masking in logs does not affect what lives in the process's memory space.

The attack mechanism

The runner process holds your secrets in memory whether or not they appear masked in logs. Any code with access to the runner's process memory — including a compromised GitHub Action — can read them directly. Log masking is a display feature. It is not a security boundary.

Once collected, the harvested credentials were encrypted with AES-256-CBC and wrapped with RSA-4096, making network-layer inspection ineffective. The payload then exfiltrated the encrypted bundle to TeamPCP's C2 infrastructure. The encryption was not to protect the data in transit — it was to prevent security tools from detecting the stolen credential patterns in network traffic.

What the payload targeted in affected pipelines

Cloud credentials

  • AWS access keys and secret keys
  • GCP service account credentials
  • Azure service principal credentials
  • AWS STS session tokens

Infrastructure secrets

  • SSH private keys
  • Kubernetes service account tokens
  • Docker registry credentials
  • TLS private keys and certificates

Developer credentials

  • GitHub Personal Access Tokens
  • npm authentication tokens
  • PyPI API tokens
  • Database connection strings

Application secrets

  • API keys for third-party services
  • Webhook secrets
  • Signing keys
  • OAuth client secrets

For Cisco specifically, the stolen AWS keys were confirmed to have been used for unauthorized activities across a small number of Cisco AWS accounts. The breach impacted dozens of developer and lab workstations. The company's CSIRT, Unified Intelligence Center, and Emergency Operations Center teams were all engaged in the response.

Cisco expects continued fallout. The same Trivy credentials that opened Cisco's environment were also used to compromise LiteLLM and Checkmarx. Each wave of the campaign used credentials stolen in the previous phase to reach further into the ecosystem.

Why secret retrieval created
a runtime gap.

Encryption at rest is only one part of the credential lifecycle. A CI/CD job may still retrieve a secret into an environment variable or process memory so a build tool can use it. Code running with the same access can potentially read that plaintext value.

Many common secret-retrieval workflows follow that pattern: encrypt the secret at rest, retrieve it when the pipeline needs it, then expose it to the process performing the work. The risk comes from the runtime access granted after retrieval, not from a failure of encryption at rest.

Step three is the blind spot. The moment the secret is retrieved and placed into the runner's environment, it exists as a plaintext string in process memory. That is exactly where the Trivy malware looked. Not in the vault. Not in the encrypted storage. In the memory of the running process that had just retrieved the secret to use it.

One common CI/CD retrieval pattern VULNERABLE
# Simplified GitHub Actions retrieval pattern
# Step 1: Vault or GitHub Secrets retrieves the key (encrypted)
# Step 2: Key is decrypted and injected as environment variable
# Step 3: Runner process holds it in memory

env:
  AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
  AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
  OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}

steps:
  - name: Run security scan
    uses: aquasecurity/trivy-action@v0.28.0  # ← reads /proc/<pid>/mem
    # Secrets are now in runner memory. Malicious action reads them.
    # Log masking is irrelevant. Memory access bypasses it entirely.
    # Stolen. Encrypted. Exfiltrated. Done.
"The Cisco breach did not happen because of a flaw in Cisco's own security practices in isolation. It happened because a widely trusted open-source security tool was turned into a weapon."

This is not unique to Cisco. Any organization that ran Trivy between March 19 and March 24, 2026, with secrets present in the runner environment is a potential victim of this credential harvest. The tooling that was supposed to protect the pipeline became the attack vector into the pipeline.

What could have reduced
the credential exposure.

Clear distinction before this section: VaultProof does not prevent supply chain attacks. The Trivy compromise would still have happened. TeamPCP would still have injected malware into the GitHub Action. The malicious code would still have run in affected pipelines.

VaultProof addresses one consequence for supported provider API keys: raw provider credentials do not need to enter the application or CI/CD runner environment.

If a supported provider API key is used through VaultProof's proxy flow, a compromised runner does not receive that original provider key. This reduces one credential-harvesting path; it does not protect every credential type or replace CI/CD hardening.

VaultProof splits a supported provider API key before upload and stores both shares as separate authenticated ciphertexts. The application or runner uses a scoped VaultProof project value and provider-compatible base URL. The proxy reconstructs the provider key only for the upstream request, then clears the reconstructed buffer.

With VaultProof — what the malicious Trivy action would have found PROTECTED
# Pipeline environment with VaultProof
# The runner holds a scoped project value, not the provider key

env:
  VAULTPROOF_PROJECT_ID: vp-proj-abc123  # non-secret identifier
  # The original supported provider API key is not in this environment.
  # Encrypted shares remain inside the VaultProof service boundary.

steps:
  - name: Run security scan
    uses: aquasecurity/trivy-action@v0.28.0  # runs malicious payload
    # Payload reads /proc/<pid>/mem
    # Finds: scoped project value, not the original provider key
    # Other runner credentials still require separate controls
    # Original provider-key exposure path: reduced

  - name: Make API calls via VaultProof proxy
    # SDK sends request to proxy
    # Proxy decrypts shares and reconstructs the key for the request
    # API call made. Key zeroed from proxy memory.
    # The complete credential never existed in the runner.
The principle

A compromised runner cannot read an original provider key that never entered its environment. That narrows the exposed credential surface, but teams still need dependency pinning, least privilege, runner isolation, short-lived cloud identity, monitoring, and rotation.

What about the AWS keys specifically?

Reporting on the Cisco incident linked stolen AWS credentials to unauthorized activity in a limited number of accounts. Static cloud credentials in CI/CD pipelines are high-value targets and should be replaced with workload identity where the platform supports it.

AWS supports OIDC authentication for GitHub Actions — a mechanism that issues short-lived tokens rather than static keys. If Cisco had used OIDC for AWS authentication, the stolen credentials would have been ephemeral tokens with limited validity windows, significantly reducing the blast radius.

VaultProof does not replace cloud workload identity. Use OIDC or the cloud provider's equivalent for AWS, GCP, and Azure access. VaultProof's provider-proxy flow addresses supported third-party HTTP API keys; database credentials, signing secrets, and other runtime values require controls appropriate to their own execution path.

If you ran Trivy between
March 19 and 24, do this.

The safe versions of Trivy are v0.69.3 or earlier, trivy-action@v0.35.0, and setup-trivy@v0.2.6. If your pipelines ran any other version during the window, treat all pipeline credentials as compromised.

Immediate triage checklist:

If you ran affected Trivy versions

Rotate all AWS access keys immediately. Rotate all GitHub Personal Access Tokens. Rotate all Kubernetes service account tokens. Rotate all Docker registry credentials. Check your GitHub organization for any repositories named tpcp-docs — this indicates successful exfiltration. Block scan.aquasecurtiy[.]org and 45.148.10.212 at network level. Check developer machines for sysmon.py or pgmon systemd services. Treat all secrets that were present in affected pipeline environment variables as fully compromised.

Going forward: pin all GitHub Actions to full commit SHA hashes, not version tags. Version tags like @v0.28.0 are mutable pointers. The commit hash they point to can be silently changed by anyone with repository access. A SHA hash cannot be moved. This single change would have prevented the tag-poisoning phase of this attack from affecting pinned pipelines.

The broader lesson from the Cisco breach is not that organizations need better secret rotation policies, though they do. It is that the entire paradigm of secrets-as-environment-variables in CI/CD pipelines is structurally vulnerable to the supply chain attack class. As long as the complete credential must exist as a plaintext string somewhere in the runner's memory, a sufficiently motivated attacker with code execution in that environment will find it.