Technical Observation: The LiteLLM Dependency Trap
While auditing a LiteLLM deployment for a Mumbai-based fintech startup, we identified a critical oversight in their CI/CD pipeline. The team was using LiteLLM to aggregate responses from local providers like Sarvam AI and Krutrim. However, their requirements.txt lacked cryptographic hashes for transitive dependencies. We observed that a simple pip install litellm pulled in over 40 sub-dependencies, any of which could be swapped via a dependency confusion attack on the public PyPI registry.
The Vulnerability of Unpinned AI Stacks
LiteLLM sits at the heart of the modern AI proxy layer. It handles API keys, sensitive prompts, and PII. If an attacker successfully executes a dependency confusion attack—registering a private internal module name on the public PyPI—they gain execution context within the pipeline. I’ve seen this happen where an internal utility named llm-auth-utils was shadowed by a malicious package, leading to the exfiltration of OpenAI and Anthropic keys during the build phase. We explore these supply chain risks in depth within our cybersecurity training courses.
Why Scanners Aren't Always Enough
We often rely on tools like Trivy to save us, but scanners themselves have attack surfaces. For instance, CVE-2023-46642 showed that Trivy could be tricked into processing malicious configuration files. If your pipeline automatically scans any repository it finds, a malicious actor could submit a Pull Request with a poisoned .trivyignore or a malformed config that triggers an information disclosure vulnerability in the scanner itself.
Defining Software Supply Chain Security
In our research, we define the software supply chain as everything that touches the code from the developer's IDE to the production environment. This includes the source code, the build tools (compilers, interpreters), the third-party libraries, and the CI/CD runners. In the context of LiteLLM, the supply chain is particularly complex because it bridges the gap between traditional Python environments and dynamic LLM provider APIs.
The Graph of Trust
We no longer just trust the code we write. We trust the maintainers of every library in our pip freeze output. In a typical LiteLLM setup, this trust graph extends to:
- The Python Package Index (PyPI) infrastructure.
- The maintainers of
openai,anthropic, andinstructorlibraries. - The GitHub Actions or Jenkins plugins used for deployment.
- The container base images (e.g.,
python:3.11-slim).
The Evolution of CI/CD Attack Surfaces
Traditional attacks targeted the production server. Modern attacks target the build process. By poisoning a build artifact, an attacker ensures their backdoor is signed, verified, and deployed by the legitimate system. I observed that many Indian organizations are moving toward "Internal Developer Platforms" (IDPs), which centralize CI/CD but also create a single point of failure for the entire supply chain.
Common Vulnerabilities in the CI/CD Pipeline
The most frequent entry point we see is insecure third-party dependencies. In the Python ecosystem, this often manifests as "Dependency Confusion." Attackers look for internal package names mentioned in public pyproject.toml or requirements.txt files on GitHub. They then upload a higher version number of that package to PyPI.
Secrets Exposure in Pipeline Logs
During a red-team engagement, we found that LiteLLM debug logs were being captured by the CI/CD runner's stdout. These logs contained raw API keys for Indian LLM gateways. If your pipeline configuration doesn't explicitly mask these secrets or use short-lived OIDC tokens, they are stored in plain text within your CI provider's database, making a SIEM for log monitoring essential for detection.
Poisoned Build Artifacts and Image Tag Mutability
We often see teams using litellm/olama:latest as their base image. This is a security anti-pattern. The latest tag is mutable. An attacker who gains access to the container registry can overwrite the latest tag with a backdoored version of the image. Without digest pinning (using the SHA256 hash), the CI/CD pipeline will blindly pull the malicious image.
The wrong way: Mutable tags
docker pull litellm/olama:latest
The right way: Immutable digests
docker pull litellm/olama@sha256:45b3830331a39d643a3fca533f0a7935a9d8fd30154339a968e47019b9364001
Core Components of a Secure CI/CD Supply Chain
To secure LiteLLM and Trivy deployments, we must implement a Software Bill of Materials (SBOM). An SBOM is a formal record containing the details and supply chain relationships of various components used in building software. We use syft to generate these because of its accuracy in detecting nested Python dependencies.
Gaining Visibility with Syft
We run syft against the LiteLLM image to identify every layer and library. This allows us to compare the build-time state against the runtime state. If the SBOM changes unexpectedly between the staging and production builds, we halt the pipeline.
Generating a CycloneDX SBOM for LiteLLM
syft scan litellm/olama:latest -o cyclonedx-json > sbom.json
Artifact Signing and Attestation with Sigstore
Once the image is built and scanned, we sign it using cosign. This ensures that the image running in your Kubernetes cluster is the exact same one that passed the CI security checks. In the Indian context, where compliance with the DPDP Act 2023 is becoming mandatory, proving the integrity of the data-processing software (like LiteLLM) is a key requirement for technical audits.
Signing the image after a successful scan
cosign sign --key cosign.key /litellm-custom:latest
Hardening the Build Infrastructure
We recommend using ephemeral runners. Persistent Jenkins nodes are often "hot" with leaked credentials and old build artifacts. By using GitHub-hosted runners or short-lived Kubernetes pods for builds, we ensure that each build starts from a clean state, mitigating the risk of cross-build contamination.
Frameworks and Standards for Supply Chain Integrity
We follow the SLSA (Supply-chain Levels for Software Artifacts) framework. For most LiteLLM deployments, we aim for SLSA Level 3, which requires that the build is performed in a scripted environment and that the provenance of the artifact is verified.
Implementing SLSA Levels
- Level 1: Documentation of the build process. We achieve this by versioning all GitHub Action YAMLs.
- Level 2: Build is service-based and signed. We use GitHub Actions with Cosign.
- Level 3: Hardened build platform. We use isolated environments and prevent the build from accessing the public internet except for trusted registries.
NIST SP 800-161 and the Indian Context
The NIST SP 800-161 standard provides a comprehensive set of guidelines for managing supply chain risks. For Indian firms, integrating these standards helps align with the DPDP Act 2023's mandate for "reasonable security safeguards." We've found that mapping NIST controls to CI/CD triggers is the most effective way to ensure continuous compliance.
Best Practices for Securing Your CI/CD Workflow
Shift-left is not just a buzzword; it's a technical requirement. We integrate pip-audit in the pre-commit hooks. This prevents developers from even committing a vulnerable version of a library like requests (CVE-2024-21538) which is often used deep within the LiteLLM stack.
Enforcing Least Privilege for Pipeline Identities
We never use long-lived AWS IAM keys or GitHub Personal Access Tokens (PATs) in the pipeline. Instead, we use OIDC (OpenID Connect) to allow the GitHub runner to assume a specific role in AWS or Azure for the duration of the build. This role is restricted to only the permissions needed to push to a specific ECR repository.
Using Ephemeral Build Environments
We observed that many Indian SMEs share build runners across multiple projects to save on costs. This is a massive risk. A vulnerability in a legacy project's build script can be used to compromise the runner and steal secrets from a high-security LiteLLM project running on the same node. We always advocate for one-time-use runners.
Example: Using pip-audit to check LiteLLM dependencies
pip-audit --requirement requirements.txt --format json --output litellm-audit.json
Essential Tools for CI/CD Supply Chain Security
We use Trivy not just for container images, but for scanning the entire filesystem of the build environment. This includes checking for hardcoded secrets and misconfigured Terraform files that might be deploying the LiteLLM infrastructure.
Policy-as-Code for Pipeline Governance
We use Open Policy Agent (OPA) to enforce rules on our pipeline configurations. For example, we have a policy that rejects any LiteLLM deployment if the image scan reveals a CRITICAL vulnerability or if the image hasn't been signed by the security team's key.
Scanning the local filesystem for secrets and misconfigs
trivy filesystem --scanners vuln,secret,config ./
Automated SCA with Trivy
In our automated workflows, we set Trivy to exit with a non-zero code if it finds high-severity issues. This effectively "breaks the build" and prevents insecure code from moving forward.
Breaking the build on HIGH/CRITICAL vulnerabilities
trivy image --severity HIGH,CRITICAL --ignore-unfixed --exit-code 1 litellm/olama:latest
Hardening LiteLLM and Trivy in Practice
To illustrate a secure implementation, we've developed a GitHub Action template that specifically addresses the risks of dependency confusion and backdoored images. This template uses hashin to ensure that every package in requirements.txt has a verified checksum.
The pipeline-security.yml Configuration
This configuration ensures that we scan the LiteLLM image and verify the integrity of the Python environment before any deployment occurs.
.github/workflows/pipeline-security.yml
name: Supply Chain Security Scan
on: [push, pull_request]
jobs: security-scan: runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@v4
- name: Scan LiteLLM Image for Backdoors uses: aquasecurity/trivy-action@master with: image-ref: 'litellm/olama:latest' format: 'table' exit-code: '1' ignore-unfixed: true vuln-type: 'os,library' severity: 'CRITICAL,HIGH'
- name: Verify LiteLLM Dependency Integrity run: | pip install hashin # Ensures hashes match to prevent dependency confusion # This will fail if the local requirements.txt doesn't match the PyPI hashes hashin -r requirements.txt
The Role of Private PyPI Mirrors
For larger Indian enterprises, we recommend setting up a private PyPI mirror using JFrog Artifactory or Sonatype Nexus. By proxying all requests through an internal registry, you can block unknown public packages and prevent dependency confusion entirely. This setup also allows for "vulnerability shielding," where you can block a specific version of a library globally across the organization.
Handling CVE-2023-46642 in Trivy
To mitigate risks associated with the scanner itself, we ensure that Trivy is always updated to the latest version in the CI runner and that we do not pass untrusted, user-supplied configuration files to the trivy command. We use a locked version of the trivy-action to prevent upstream supply chain attacks on our security tools.
Monitoring and Audit Logging
Security doesn't end when the pipeline finishes. We feed all CI/CD logs into a centralized SIEM. We look for anomalies such as:
- Unexpected outbound network connections from a build runner (potential exfiltration), which can be identified using techniques similar to Threat Hunting with Windows Event ID 4688.
- A sudden spike in the number of dependencies being pulled.
- Failed signature verification attempts during the deployment phase.
Compliance with DPDP Act 2023
Under the DPDP Act, "Data Fiduciaries" (the companies) are responsible for the actions of "Data Processors" (including the software they use). If LiteLLM is backdoored and leaks Indian citizen data, the organization is liable for fines up to ₹250 crore. Implementing these CI/CD hardening steps provides the "due diligence" defense required by Indian regulators.
Zero Trust CI/CD
We are moving toward a model where the CI/CD runner is not trusted by default. Every action it takes must be authenticated, and every artifact it produces must be verified by an independent third-party service. This "Zero Trust" approach, often facilitated by a zero-trust terminal, is the only way to stay ahead of sophisticated supply chain attackers who specialize in compromising the developer ecosystem.
The Future of LLM Security
As LiteLLM continues to evolve, we expect to see more specific vulnerabilities related to prompt injection and model-weight hijacking. However, the foundation of all these risks is the supply chain. If you can't trust the binary running the model, you can't trust the model's output.
$ trivy image --version
trivy: 0.49.1
$ cosign version
{"GitVersion":"v2.2.3", ...}
Next command: cosign verify --key cosign.pub <your-registry>/litellm-custom:latest to validate the integrity of your production artifacts.
