What is software supply chain security?
Software supply chain security protects all components, tools, and people involved in building, testing, and delivering software. It covers open-source libraries, CI/CD pipelines, build systems, and proprietary code to block malicious code injection or tampering before production. A weakness in any of these elements can introduce malicious or vulnerable code into the final application. Security controls aim to maintain the integrity and provenance of software throughout its lifecycle.
Key risks and vectors:
- Vulnerable open-source dependencies: Known flaws in third-party libraries can introduce exploitable weaknesses into applications.
- Malicious packages: Attackers can publish packages designed to steal credentials, execute malware, or compromise development environments.
- Compromised dependencies and maintainer accounts: Attackers can compromise trusted projects or publisher accounts and distribute malicious releases.
- Dependency confusion: Public packages can impersonate internal dependencies and be mistakenly retrieved during builds.
- Typosquatting attacks: Malicious packages use names similar to legitimate dependencies to trick developers or automated systems.
- Transitive dependency risks: Indirect dependencies can introduce vulnerabilities or malicious code that developers did not explicitly select.
- Compromised source code repositories: Unauthorized repository access can enable code modification, secret theft, or changes to build workflows.
- CI/CD pipeline compromise: Attackers can manipulate builds, artifacts, deployments, or privileged credentials without modifying the original source code.
Core best practices:
- Minimize unnecessary dependencies: Remove unused packages and avoid introducing dependencies when existing application or platform functionality is sufficient.
- Pin and lock dependency versions: Control exact dependency versions and use lockfiles to prevent unexpected package changes between builds.
- Continuously scan dependencies for vulnerabilities: Scan throughout development, builds, container creation, and production as vulnerability information changes.
- Prioritize exploitable vulnerabilities over CVSS alone: Combine severity with reachability, exploitability, exposure, configuration, and business impact.
- Combine code, build, runtime, and cloud context: Connect findings across the software lifecycle to determine whether vulnerable components reach production and create practical exposure.
- Integrate security into developer workflows: Provide security checks and remediation information through IDEs, pull requests, source control, and CI/CD pipelines.
Why is software supply chain security important?
Modern applications depend on third-party code, automated build systems, and external development tools, and each dependency and system adds a potential attack path. Software supply chain security reduces these risks by protecting software from development through deployment:
- Limits third-party risk: Vulnerabilities or malicious code in open source packages and vendor components can affect every application that uses them.
- Protects build pipelines: Securing CI/CD systems prevents attackers from modifying source code, build processes, or release artifacts.
- Prevents dependency attacks: Controls such as dependency scanning and package verification help detect compromised, outdated, or impersonated packages.
- Maintains software integrity: Code signing, artifact verification, and provenance checks confirm that deployed software matches the intended build.
- Improves vulnerability response: SBOMs and dependency inventories help teams identify which applications contain an affected component and prioritize remediation.
- Supports compliance: Supply chain controls provide records of software components, changes, and build processes that can support security audits and regulatory requirements.
What does the software supply chain include?
Source code and repositories
Every application starts as source code, and repositories such as GitHub, GitLab, and Bitbucket store that code along with branches, configuration files, commit histories, and other development assets. Access to these repositories can allow a user to change software before it enters the build process.
Teams can protect repositories with strong authentication, least-privilege permissions, branch protection, and mandatory code reviews. Secret scanning and signed commits can provide additional protection by detecting exposed credentials and helping verify who made a change.
Open-source and third-party dependencies
Applications often use open-source libraries, frameworks, SDKs, and commercial components instead of implementing every function internally. These dependencies may also depend on other packages, creating a large tree of direct and transitive dependencies.
A vulnerable or compromised dependency can introduce risk without changes to an application’s own code. Teams should inventory dependencies, scan them for known vulnerabilities, review high-risk components, and control when dependency versions are updated.
Related content: Read our guide to dependency management
Package managers and registries
Package managers such as npm, pip, Maven, and NuGet automate the process of downloading and installing software dependencies. They usually retrieve packages from public or private registries, making those registries an important trust point in the supply chain.
Attackers can target this process through malicious packages, account compromise, dependency confusion, or typosquatting. Version pinning, trusted registries, package integrity checks, and restricted publishing permissions can reduce the chance of an untrusted package entering a build.
Build systems and CI/CD pipelines
Build systems transform source code and dependencies into deployable software. CI/CD pipelines automate related tasks such as testing, security scanning, packaging, signing, and deployment, often using privileged credentials to access repositories and production environments.
A compromised pipeline can modify software even when the original source code is secure. Teams should restrict pipeline permissions, protect secrets, isolate build environments, review workflow changes, and generate verifiable records showing how release artifacts were built.
Containers and container images
Containers package applications with the libraries and runtime components they need. Container images act as reusable templates for these environments and are commonly stored in registries before being deployed to development, testing, or production systems.
Images can contain vulnerable packages, embedded secrets, malicious files, or unnecessary software that increases the attack surface. Teams should use trusted base images, scan images, remove unneeded components, sign releases, and verify image signatures before deployment.
Cloud and runtime environments
Cloud and runtime environments are where software operates after deployment. They include virtual machines, Kubernetes clusters, serverless platforms, cloud services, operating systems, and the identities and configuration used to access these resources.
Weak permissions or insecure runtime configuration can undermine security controls applied earlier in the supply chain. Organizations should enforce least privilege, manage secrets securely, monitor workloads, patch runtime components, and verify that deployed artifacts match approved releases.
Software updates and distribution
The supply chain continues after the initial software release. Update servers, application stores, content delivery systems, package repositories, and other distribution channels deliver new versions and security patches to users and production environments.
If attackers compromise an update or distribution mechanism, they can potentially deliver malicious software through a channel users already trust. Digital signatures, integrity checks, protected signing keys, secure update protocols, and controlled release processes help ensure recipients receive authentic, unmodified software.
Common software supply chain security risks
Vulnerable open-source dependencies
Open-source libraries and frameworks can contain vulnerabilities that expose applications to attacks such as remote code execution, authentication bypass, or information disclosure. When an application includes a vulnerable version, it may inherit the weakness even if its own source code is secure.
The problem becomes harder to manage when organizations use thousands of components across multiple applications. Some vulnerable libraries may remain unnoticed because they are included indirectly or are no longer actively maintained.
How to overcome: Teams should maintain an inventory of dependencies and continuously scan them against vulnerability databases. Updates should be prioritized by whether each vulnerability can be exploited in the application’s environment and how exposed the application is, with the severity score as one input rather than the deciding factor.
Malicious packages
Attackers can deliberately publish packages containing malicious code to public package registries. The code may steal environment variables, credentials, source code, or authentication tokens. It can also download additional malware or establish remote access.
Malicious behavior may execute during package installation, compilation, testing, or application runtime. Installation scripts are particularly useful to attackers because they can run automatically when developers or CI systems install a package.
How to overcome: Organizations should restrict which registries and packages developers can use. Package allowlists, automated malware analysis, lockfiles, and reviews of newly introduced dependencies can reduce the chance of malicious packages entering builds.
Compromised dependencies and maintainer accounts
Attackers do not always need to create a new malicious package. They can compromise an existing project or a maintainer’s account and publish malicious code as a new version of a trusted dependency.
This approach is dangerous because developers and automated dependency tools already trust the package. A malicious release may therefore spread quickly across applications that automatically retrieve newer versions.
How to overcome: Package maintainers can reduce the risk with multi-factor authentication, protected publishing credentials, and restricted release permissions. Software consumers should pin important dependencies, monitor unexpected releases, and verify package signatures or provenance when available.
Related content: Read our analysis of the XZ Utils backdoor
Dependency confusion
Dependency confusion exploits situations where organizations use private packages whose names are not reserved in public registries. An attacker publishes a public package using the same name and often assigns it a higher version number.
Depending on package manager and registry configuration, the build system may download the public package instead of the intended internal version. Malicious code can then execute inside developer workstations or CI environments.
How to overcome: Teams can prevent this by explicitly defining trusted package sources and preventing internal dependencies from being resolved through public registries. Reserving internal package names and namespaces in relevant public registries can provide another layer of protection.
Typosquatting attacks
Typosquatting attacks use package names that closely resemble legitimate dependencies. Attackers may remove a character, swap two letters, use common spelling mistakes, or select names that visually resemble popular packages.
A developer who mistypes a package name may install the malicious package without realizing it. Automated scripts can also introduce the package when dependency names are copied incorrectly from documentation or other projects.
How to overcome: Organizations should verify package names and publishers before approving new dependencies. Automated controls can flag unfamiliar packages, unusual naming patterns, and recently created packages before they become part of production builds.
Transitive dependency risks
Applications frequently depend on packages that themselves depend on additional packages. These indirect components are called transitive dependencies, and they can create dependency trees containing hundreds or thousands of components.
Developers may not know these components are present because they never selected them directly. A vulnerability or compromise deep in the dependency tree can still affect the final application and may be difficult to trace manually.
How to overcome: Software composition analysis tools can map direct and transitive dependencies and identify affected versions. SBOMs also provide a structured inventory that teams can use to locate impacted applications when new vulnerabilities or supply chain compromises are discovered.
Compromised source code repositories
Source code repositories contain application code, configuration, development history, and often CI/CD workflow definitions. Attackers who compromise a developer or administrator account can modify these resources or insert malicious code.
Repository access can also expose sensitive information such as API keys, access tokens, private endpoints, or credentials accidentally committed to source control. Attackers may use these secrets to move from the repository into cloud or production environments.
How to overcome: Strong authentication, least-privilege permissions, protected branches, and mandatory code reviews can limit unauthorized changes. Organizations should also scan repositories for secrets and monitor unusual commits, access patterns, permission changes, and administrative activity.
CI/CD pipeline compromise
CI/CD systems are high-value targets because they connect source code with build, testing, packaging, and deployment environments. Pipelines often have privileged access to package registries, cloud services, signing systems, and production infrastructure.
An attacker who compromises a pipeline may alter software during the build process without changing the original source code. This makes malicious modifications harder to detect through source code review alone. Stolen pipeline credentials can also provide direct access to other systems.
How to overcome: Organizations should isolate build environments, minimize pipeline privileges, protect secrets, and require reviews for workflow configuration changes. Reproducible builds, artifact signing, provenance records, and verification before deployment can help detect unauthorized modifications and establish how an artifact was produced.
Related content: Read our article about software supply chain attacks
How software supply chain security works
1. Discover software components and dependencies
The first step is identifying the components that make up an application. This includes direct dependencies selected by developers as well as transitive dependencies introduced by other packages.
To create an accurate inventory, teams can analyze:
- Package manifests
- Lockfiles
- Repositories
- Container images
- Compiled artifacts
This information can also be recorded in an SBOM, which provides a structured list of software components and their versions. Discovery should occur continuously because dependencies change as developers add packages and release new application versions. Scanning both source repositories and deployed artifacts can also reveal components that are missing from package manifests.
2. Identify vulnerabilities and supply chain risks
Once components are identified, security tools compare their names and versions with vulnerability intelligence and other risk data. This can identify known vulnerabilities, malicious packages, outdated dependencies, suspicious package behavior, and components with security or maintenance concerns.
Supply chain analysis can also examine package metadata, release history, maintainers, and provenance. For example, an unexpected maintainer change or unusual package release may require investigation even when no known vulnerability has been reported. Because new vulnerabilities are continuously disclosed, applications need to be reassessed after deployment. A dependency considered safe during development may become a security risk when new information becomes available.
3. Analyze dependency reachability
A vulnerable package being present does not necessarily mean the application executes the vulnerable code. Reachability analysis examines how application code interacts with dependencies to determine whether it can reach the affected function, method, or code path.
This analysis can follow function calls from application code through direct and transitive dependencies. If no executable path reaches the vulnerable code, the finding may represent a lower immediate risk than a vulnerability used directly by the application.
Reachability information reduces the number of findings developers need to investigate manually. However, it should be treated as one source of risk context because dynamic behavior, reflection, configuration, and runtime loading can make some execution paths difficult to identify statically. Newer AI-based approaches trace the path the way an engineer reading the code would, which lets them follow framework routing and dynamic calls that a static call graph loses track of.
4. Determine whether vulnerabilities are exploitable
Exploitability analysis considers whether an attacker could actually exploit a reachable vulnerability in your environment. That depends on whether the conditions the vulnerability needs are present, including:
- Attacker-controlled input reaching the vulnerable code
- Application configuration
- Network exposure
- Authentication requirements
- Privileges
- Security controls in front of the vulnerable code
For example, a vulnerable function may be reachable but only process trusted internal data. Another vulnerability might be exposed through an unauthenticated internet-facing endpoint, making exploitation considerably more practical.
Answering these questions means combining code analysis with configuration and runtime information, and doing that by hand for every finding takes more security engineering time than most teams have, which is the work AI-native tools are now built to take on. Evidence of active exploitation elsewhere, such as a listing in CISA’s Known Exploited Vulnerabilities catalog, shows how likely attackers are to try, so it belongs in prioritization alongside whether the vulnerability can be exploited here, particularly when the affected application handles sensitive data or provides access to critical systems.
5. Prioritize findings based on runtime and business context
Severity scores alone do not show the actual risk a vulnerability creates for an organization. Prioritization adds context such as whether the component runs in production, whether vulnerable code is executed, and whether the workload is exposed to attackers.
Business context matters too, because a vulnerability affecting one of the following may require faster remediation than the same vulnerability in an isolated development environment:
- A public payment service
- An identity system
- An application containing sensitive customer data
Combining technical and business context gives teams a smaller, more actionable set of findings. This helps security teams focus remediation work on vulnerabilities that create the greatest practical risk instead of treating every finding equally.
6. Remediate vulnerabilities and track fixes
Remediation typically involves one of the following:
- Upgrading a dependency to a patched version
- Replacing an unsafe component
- Changing configuration
- Removing an unnecessary package
When an immediate update is not possible, teams may apply compensating controls that reduce exposure until a permanent fix is available. Dependency updates must be tested because new versions can introduce compatibility problems or behavioral changes. Automated tests and controlled deployment processes help teams verify that security fixes do not break application functionality.
Teams should track findings from discovery through remediation and verify that fixes are present in new builds and deployed environments. Continuous rescanning is important because previously resolved vulnerabilities can reappear through dependency changes, older container images, or application rollbacks.
Challenges of software supply chain security
Large and complex dependency trees
Modern applications often rely on many direct dependencies, each of which can introduce additional dependencies. A relatively small set of packages can therefore produce a dependency tree containing hundreds or thousands of components.
These relationships make it difficult to determine where a vulnerable component originated and whether removing or upgrading it will affect other packages. Different applications may also use different versions of the same component, increasing the complexity of remediation.
How to address: Automated dependency analysis can map these relationships and identify which direct dependency introduced a vulnerable component. This gives developers the information needed to select upgrades or replacements without manually tracing the entire dependency tree.
Limited visibility into transitive dependencies
Transitive dependencies are installed indirectly because they are required by other packages. Developers may not see or manage them in the application’s primary dependency manifest, even though their code becomes part of the resulting software.
This creates security gaps because an organization may be affected by vulnerabilities in components its developers did not knowingly select. Transitive dependencies can also change when a direct dependency is updated, introducing new components without explicit developer action.
How to address: Lockfiles, software composition analysis, and SBOMs can improve visibility into these dependencies. Teams should analyze both source-level dependency information and build artifacts to identify components that are actually included in released software.
Too many vulnerability findings
Dependency and container scanners can generate large numbers of vulnerability findings, and in practice many of them are false positives. A finding can carry a high severity score while the vulnerable code is never reached, can’t be exploited in that environment, or isn’t present in a production workload.
Without additional context, teams may spend significant time investigating findings that create little practical risk. Large backlogs can also make critical vulnerabilities harder to identify and delay remediation of issues attackers can realistically exploit.
How to address: Teams can reduce this problem by combining severity with reachability, exploitability, runtime exposure, and business impact. AI-native tools take this further by investigating each finding the way a security engineer would and closing the ones that can’t be exploited, with the evidence behind each decision, so developers start with the vulnerabilities that create the greatest risk.
Vulnerabilities across code, containers, and cloud
Software risk does not stop at application dependencies. Vulnerabilities can also exist in container base images, operating system packages, runtime components, cloud configuration, and the infrastructure used to build and deploy applications.
These layers are often scanned by separate security tools, which can produce disconnected findings about the same application. Security teams may struggle to determine whether a vulnerable package identified in source code is included in a container and whether that container is actually running in production.
How to address: Connecting findings across code, build artifacts, containers, and cloud workloads provides clearer risk context. It allows teams to trace a vulnerable component from development to runtime and prioritize remediation based on its actual production exposure.
Key software supply chain security capabilities
Continuous dependency discovery
Continuous dependency discovery identifies the open-source and third-party components used across applications. It examines sources such as package manifests, lockfiles, repositories, build artifacts, and container images.
Discovery should run as software changes rather than relying on periodic inventories. This allows teams to detect newly introduced packages, version changes, and transitive dependencies before they become difficult to track.
Continuous discovery also helps organizations locate affected applications when a new vulnerability is disclosed. Teams can quickly determine where a particular package and version are used across their software estate.
Software bill of materials management
A software bill of materials (SBOM) provides a structured inventory of the components included in a software product. It can record package names, versions, suppliers, licenses, and relationships between components.
SBOM management involves generating, storing, updating, and querying these inventories across applications and releases. Common formats such as SPDX and CycloneDX make component information easier to exchange between organizations and security tools.
Accurate SBOMs support incident response and vulnerability management. When a component is compromised, teams can search their SBOM data to determine which products and releases contain it.
Software composition analysis
Software composition analysis (SCA) examines open-source and third-party components used by an application. It identifies dependencies and compares them with vulnerability, license, and other component risk information.
SCA can run during development, CI/CD builds, or analysis of completed artifacts. Scanning earlier provides developers with feedback before release, while artifact scanning can confirm which components are actually included in distributed software.
SCA also helps identify dependency relationships and available fixed versions. This gives developers information they can use to upgrade, replace, or remove risky components.
Vulnerability detection
Vulnerability detection identifies components affected by known security flaws. Tools typically match component names and versions against vulnerability databases, security advisories, and vendor information.
Accurate identification is important because package names and version schemes can vary between ecosystems. Poor matching can create false positives or fail to detect affected components.
Detection should continue after deployment because vulnerability information changes over time. A component with no known vulnerabilities when released may later be associated with a newly disclosed security issue.
Reachability analysis
Reachability analysis determines whether application code can execute the exact part of a dependency containing a vulnerability. It traces code paths between the application and vulnerable functions or methods.
This provides more useful context than package presence alone. A dependency may contain a critical vulnerability, but the affected code might never be called by the application.
Reachability results help reduce unnecessary remediation work and prioritize vulnerabilities that can affect application behavior. Analysis may need to account for indirect calls, frameworks, reflection, and dynamically loaded code.
Exploitability analysis
Exploitability analysis evaluates whether an attacker can practically take advantage of a vulnerability in the application’s environment. It considers more than the vulnerability’s technical severity.
Relevant factors include network exposure, required privileges, authentication, application configuration, attacker-controlled input, and the security controls in front of the vulnerable code. Whether a public exploit exists is a separate question, because it tells you how likely an attack is rather than whether the conditions for one exist in your environment.
This analysis helps distinguish theoretical exposure from practical attack paths. Teams can use the results to direct remediation toward the vulnerabilities that can actually be exploited in their environment.
Runtime context
Runtime context connects software supply chain findings with information about deployed workloads. It can show whether an affected component is running in production, exposed to external networks, or associated with sensitive systems.
This information helps security teams understand the real-world impact of a finding. A vulnerable package in an unused development image generally presents different risk from the same package in an internet-facing production service.
Runtime context can also identify differences between development inventories and deployed software. This helps teams verify which vulnerable artifacts are active and where remediation should occur.
Vulnerability prioritization
Vulnerability prioritization ranks findings according to the risk they create rather than relying only on severity scores. Useful inputs include reachability, exploitability, runtime exposure, asset criticality, and business impact.
For example, an actively exploited vulnerability in a reachable component on a public production service should generally receive higher priority than an unreachable vulnerability in an internal test workload.
Risk-based prioritization reduces large vulnerability backlogs into more manageable remediation queues. It also gives developers clearer reasons for why particular findings require urgent attention.
Automated triage and remediation
Automated triage processes findings using predefined policies and security context. It can group duplicate findings, identify affected applications, assign owners, suppress low-risk results, and route important issues to development teams. AI-native triage goes further by reasoning through each finding with context from the code, build, and cloud instead of matching it against static rules, so it can close the findings that can’t be exploited and explain why.
Remediation automation can go further by recommending fixed dependency versions or creating pull requests that update vulnerable packages. CI/CD controls can then test these changes before they are merged and released.
Automation reduces repetitive work, but changes still need appropriate validation. Testing, approval policies, and rescanning help confirm that a proposed fix removes the vulnerability without introducing compatibility problems or new supply chain risks.
Software supply chain security best practices
1. Minimize unnecessary dependencies
Every dependency introduces code that the organization may not directly control. It can also introduce additional transitive dependencies, vulnerabilities, licensing concerns, and maintenance requirements. Teams should avoid adding packages for functionality that can be implemented safely with existing application or platform features.
Dependencies that are no longer used should be removed from source code, manifests, and build configurations. Dependency reviews can also consider project maintenance, release activity, security history, and the number of additional packages introduced. Keeping dependency trees smaller reduces both the attack surface and the amount of software teams must monitor.
Key actions:
- Remove unused dependencies from code and build configurations.
- Avoid packages when existing functionality meets the requirement.
- Review dependency maintenance, security history, and transitive packages.
2. Pin and lock dependency versions
Unrestricted dependency versions can cause builds to retrieve newer package releases automatically. If a package is compromised or introduces an unexpected change, builds may include it without developers explicitly approving the new version. Version pinning specifies which dependency versions an application can use.
Lockfiles go further by recording the exact versions resolved across direct and transitive dependencies, helping produce consistent builds. Teams should commit lockfiles where supported and review dependency updates before merging them. Integrity hashes and trusted registries can provide additional assurance that the retrieved package matches the expected artifact.
Key actions:
- Pin dependencies to controlled versions.
- Commit and maintain lockfiles where supported.
- Review updates and verify package integrity before merging.
3. Continuously scan dependencies for vulnerabilities
Dependency scanning should occur throughout development rather than only before a release. Scans can run when developers create pull requests, during CI/CD builds, against container images, and after software reaches production. Continuous scanning is important because vulnerability information changes.
A package that passes security checks during a build may later be associated with a newly disclosed vulnerability. Teams should also rescan existing applications when vulnerability databases and security advisories are updated. This allows them to identify affected software without waiting for another code change or release.
Key actions:
- Scan dependencies during development and CI/CD builds.
- Scan container images and deployed applications.
- Rescan existing software as vulnerability intelligence changes.
4. Prioritize exploitable vulnerabilities over CVSS alone
CVSS provides a standardized measure of vulnerability severity, but it does not describe the complete risk to a specific application. A high CVSS score does not necessarily mean vulnerable code is reachable or exposed to an attacker. Prioritization should include factors such as reachability, exploit availability, active exploitation, network exposure, required privileges, and application configuration.
Business criticality and the sensitivity of affected data should also influence remediation priority. Combining these signals helps teams focus on vulnerabilities that present realistic attack paths. CVSS remains useful as one input, but it should not be the only factor used to determine remediation order.
Key actions:
- Evaluate reachability, exploitability, and network exposure.
- Consider active exploitation and required attacker privileges.
- Include application criticality and data sensitivity in prioritization.
5. Combine code, build, runtime, and cloud context
Supply chain risks can appear differently at each stage of the software lifecycle. Source analysis may identify a vulnerable dependency, while build data shows whether it entered an artifact and runtime data confirms whether that artifact is actually deployed. Connecting these layers provides a clearer view of exposure.
For example, teams can determine whether a vulnerable library is included in a production container, whether the affected code executes, and whether the workload is reachable from the internet. Cloud context adds information about identities, network configuration, permissions, and asset criticality. Combining these signals makes it easier to trace risks from source code to production and prioritize the findings with the greatest impact.
Key actions:
- Trace vulnerable components from source code to deployed artifacts.
- Verify whether affected code is running and externally reachable.
- Add cloud identity, permissions, network, and asset context.
6. Integrate security into developer workflows
Security checks are more effective when developers receive findings through tools they already use. Dependency scanning and policy checks can be integrated into IDEs, pull requests, source control systems, and CI/CD pipelines. Early feedback allows developers to address vulnerable or unapproved dependencies before they reach production.
Findings should include useful remediation information, such as the affected package, dependency path, fixed version, and evidence explaining the risk. Automation can create tickets or dependency update pull requests for appropriate findings. However, teams should avoid blocking development for every low-risk issue and instead enforce policies based on exploitability, severity, and application context.
Key actions:
- Run security checks in IDEs, pull requests, and CI/CD pipelines.
- Provide dependency paths, fixed versions, and risk context.
- Automate remediation while applying risk-based enforcement.
Securing dependencies and code in your software supply chain with Maze Code
Open source dependencies and the code your team writes produce most of the vulnerability findings in a software supply chain, and the practices in this guide for handling them come down to giving each finding the context it needs, which takes more security engineering time than most teams have. Maze’s founders saw this while working with security teams whose tools could list every vulnerable package but couldn’t gather the context to say which ones could be exploited, and they built Maze so every vulnerability gets the investigation those teams never had time to run.
Maze Code uses AI to find, investigate, and fix vulnerabilities across your third-party dependencies (AI-SCA) and the code your team writes (AI-SAST) in one place, and AI-SAST runs on every pull request and across your entire codebase. It was built from the ground up so its AI can gather the context it needs and reason through each vulnerability the way your best security engineer would. Instead of handing security teams another long list of findings to research, Maze traces each vulnerability through your code and cloud, determines whether it can be exploited in your environment, and routes a fix to the developer or coding agent responsible. Findings that are reachable but can’t be exploited in practice are closed before they ever reach your backlog.
Key capabilities of Maze Code:
- Every dependency investigated with deep context: Maze uses AI to find the vulnerabilities in your direct and transitive dependencies, then investigates each one with context from your code and cloud to determine which create real risk for your organization. If you already run something like Dependabot, Maze investigates and deduplicates those findings too.
- Trace the vulnerable code with AI, not static call graphs: A static call graph is built ahead of time from the code’s structure, so the path often goes missing at dynamic calls, reflection, dependency injection, and framework routing, and a missing path makes an exploitable vulnerability look unreachable. Maze’s AI reads your code the way an engineer would and traces the path from an entry point to the vulnerable function regardless of those gaps, however many hops deep it sits, in whatever language you write, then checks runtime and cloud context to confirm whether that path can be exploited.
- Exploitability, not just reachability: Maze checks whether an attacker can control what reaches the vulnerable code and whether a setting or control blocks it, so it shows what can be exploited in your environment rather than what is simply reachable in your code, and exploitable findings are ranked by risk to your environment.
- Fixes shipped to the right developer: Maze traces where a vulnerability came from, identifies the owner of the affected code, and opens a pull request directly with them. When no fix exists yet, it recommends a mitigation instead.
- Built into developer workflows: Maze Code runs in CI/CD pipelines such as GitHub Actions, GitLab CI, and CircleCI, surfaces findings at the pull request, and passes fixes to the coding agent your team already uses, such as Claude Code or Cursor, so developers don’t need to check another dashboard.
- Zero-day sweeps: When a new vulnerability is disclosed, Maze picks it up in near real time and runs the same investigation against code you’ve already shipped, so you know whether it affects you without waiting for the next build.
- One investigation across code and cloud: Maze Code and Maze Cloud gather context and share it across every investigation, so a vulnerable library running in a production container behind a public-facing load balancer is assessed as the distinct risk it is, with one ticket per issue instead of several.
- Transparent, evidence-based verdicts: Every conclusion is grounded in evidence from your code, cloud, and business context, and you can open any verdict to see exactly why Maze reached it.
Learn more about Maze Code and see how Maze investigates, proves, and fixes the vulnerabilities in your dependencies and code that actually matter.



