Approved Dependency Allow-Lists as Machine-Readable Policy
Machine-readable policy turns dependency approval into testable, enforceable decisions.

Reproducible environments for AI coding agents and tool servers require a version-controlled manifest that pins the approved dependency graph and toolchain, with enforcement from local execution through CI to production. An approved dependency allow-list becomes policy only when machines can evaluate it against the actual environment and block deviations. Rebuilding from that known configuration instead of patching a long-lived environment helps deal with drift between runs.
Why an allow-list stored in a document cannot function as policy
A shared document informs only the people who choose to consult it. It does not govern an installation, inspect a resolved dependency graph, or reject an artifact. A developer can install an unapproved package without changing the written list. An AI coding agent can suggest a hallucinated or compromised package name, and a CI job can pass because nothing checked provenance. The document records a decision without controlling its execution.
Two pressures expose this gap from different directions. Compromised upstream tools can turn a familiar build process into a way to attack, while agents can add dependencies without a person checking each choice. Both can happen even when everyone agrees with the written policy. Approval on paper does not establish what actually ran.
The March 2026 LiteLLM/Trivy incident illustrates that distinction. Attackers compromised the Trivy security scanner upstream at Aqua Security, and LiteLLM’s CI/CD pipeline then executed the poisoned scanner. That execution exfiltrated LiteLLM’s PyPI publishing token, which attackers used to publish poisoned versions 1.82.7 and 1.82.8. LiteLLM’s security update describes a credential stealer targeting environment variables, SSH keys, cloud provider credentials, Kubernetes tokens, and database passwords.
What machine-readable policy actually requires: declaration, depth, and scope
Machine-readable policy must turn approval into a testable decision. It needs approved and banned package identifiers, approved SPDX license identifiers, vulnerability severity thresholds, and explicit scope. Exceptions must identify specific CVE IDs, expiry dates, and dependency paths rather than leaving tools to interpret a general waiver. Rules must also distinguish direct from transitive dependencies and apply differently to different parts of a project. These distinctions define what a gate can decide.
Depth is essential because direct dependencies are only part of the installed graph. A policy limited to packages named in a source manifest leaves nested dependencies outside its reach. Approval therefore needs to extend through the resolved dependency paths. Scope serves a different purpose. It keeps an exception for one path or project area from becoming permission everywhere.
Files such as deny.toml, .snyk, trivy.yaml, and suppression.xml span TOML, incompatible YAML schemas, and XML, while other tools use Rego or proprietary web interfaces. Their vocabularies differ too, including “allowed,” “permitted,” and “authorized,” with identifiers ranging from SPDX values to freeform strings and internal IDs. One CVE decision can require several incompatible suppression files. Version control gives that decision a reviewable, reversible record, while a UI-only policy without an exportable representation cannot serve as the shared input for downstream gates.
The SBOM as the inventory that makes allow-list enforcement testable
An allow-list declares what is permitted, but it cannot establish what an artifact contains. A software bill of materials, or SBOM, supplies that inventory. The distinction is between intended dependencies and the components actually resolved into a build. The policy needs a machine-readable inventory that is generated continuously so it has a reliable record to test. A source manifest can stay the same even as the environment drifts.
CISA’s 2026 Minimum Elements for an SBOM, published July 29, 2026, updates and replaces the 2021 NTIA list. The guidance specifies author and signature, timestamp, format and version, generation context, generating tool and version, and SBOM version. Component records include name, version, producer, identifiers, and license, together with a hash value, hash algorithm, and dependency relationships. Fields with unknown values must be retained and marked as unknown. Generation context also identifies whether the inventory was produced before, during, or after the build, because that timing affects completeness.
SPDX, standardized as ISO/IEC 5962:2021, and CycloneDX, standardized as ECMA-424, provide widely used machine-readable formats that most SCA tooling can produce. Operationally, the inventory needs automatic build generation, release versioning, a signature, and storage the security team can query. An SBOM made only when someone asks for it cannot keep up with each build. Hashes provide the identity link between inventory and enforcement. They allow a gate to compare the actual component with the approved component by hash.
Regulatory mandates that now require machine-readable inventories and policy evidence
The infrastructure needed for dependency security also produces evidence that buyers and agencies can require. That reinforces the case for building it, but does not replace the security rationale. The US federal position changed materially by 2026. Inventory, assurance, and evidence now operate within a more agency-specific framework.
Executive Order 14306, signed in June 2025, changed EO 14144 from January 2025. It removed the requirement for suppliers to submit machine-readable attestations and supporting artifacts to CISA for central validation, as well as the mandate for CISA to audit a sample. It also directed NIST to establish an industry consortium at the National Cybersecurity Center of Excellence for SSDF implementation guidance. Separately, it required preliminary and final updates to the SSDF. The change cut back central validation, but assurance was still needed.
OMB Memorandum M-26-05, issued January 23, 2026, rescinded M-22-18 and M-23-16. Agencies no longer have to collect the common attestation form, but they must keep complete software and hardware inventories and put risk-based assurance policies in place. They may also require a current SBOM through contractual terms. For suppliers, evidence requests can therefore vary by buyer. NIST SSDF practice SSDF.PS.3 maps to archived and protected release artifacts, while SSDF.PW.4 maps to vetted components, dependency policy, and KEV/CVE gates.
How can an AI coding agent use the exact same dependencies every run? Enforcement at the local boundary
Local enforcement acts before an unauthorized dependency is committed. This is also where an agent with package-install privileges can cause harm before any downstream gate runs. Rejecting a dependency later cannot undo code that has already run on the developer’s machine. The agent’s execution context therefore needs the same rules for packages as a human developer’s shell. CI complements that control.
Install-time execution is a concrete boundary within that environment. Running npm install --ignore-scripts blocks lifecycle scripts, while pnpm’s onlyBuiltDependencies permits them for a narrowly approved set. The axios compromise introduced the malicious transitive dependency plain-crypto-js, whose postinstall hook delivered a remote access trojan. Installation alone was enough to execute the payload. Script policy therefore governs an install-time execution path.
Reproducibility requires more than an approved package name. A declarative, version-controlled environment manifest must pin the dependency set and toolchain that local tooling uses for all team members and operating systems. Floating version ranges, untracked system libraries, and changing repositories can otherwise alter an environment between builds. The same criterion applies to runtime environments for tool servers. Discarding environments and rebuilding them from a known configuration helps deal with those sources of drift, while the allow-list sets which configurations are allowed.
Enforcement at CI: gates that reject non-compliant artifacts before they merge
CI applies a common policy in a controlled environment that individual contributors do not configure. Its decision rests on the artifact. Software composition analysis must therefore check the SBOM from the actual build, including transitive dependencies. A gate rejects components if their hashes are missing from the approved inventory. This hash-level check catches version substitution that approval by name would miss.
The gate itself also depends on a trustworthy pipeline. CI actions and pipeline dependencies need commit SHA pins. The March 2025 tj-actions/changed-files compromise repointed every version tag at a malicious commit that dumped CI secrets into workflow logs. Repositories pinned to a commit SHA were untouched. CircleCI’s published orb versions are immutable once released, so an exact version suffices there.
Pinning need not mean freezing dependencies indefinitely. Renovate can open updates for Actions and GitLab includes, while Dependabot keeps existing Action pins current for GitHub Actions. Signed provenance attestations then establish that an artifact came from a known source through a known build process, with SLSA build track levels formalizing those requirements. Policy translation remains a separate maintenance cost. When every gate uses one version-controlled policy, translated for each tool where needed, incompatible suppression files cannot become separate sources of approval.
Enforcement at production: admission control and runtime blocking
A successful CI result does not make deployment exempt from policy. Production admission is another decision point, where the artifact presented for execution must satisfy the approved conditions. Kubernetes-native engines including Sigstore policy-controller, Kyverno, and ratify support artifact policy through custom resource definitions. Admission rules can reject images that are unsigned, whose component hashes do not match the approved inventory, or that were built from non-pinned bases. The check happens before the image runs.
A known input-derived hash connects that decision to the build-time inventory. Admission can match the artifact against its approved identity without rescanning it, while the stored SBOM provides the component relationships needed when a new CVE appears. That allows targeted hash-level blocking without having to search logs or rebuild images just to find out what they contain. The registry boundary offers a related control. In the LiteLLM incident, an enforced registry-proxy allow-list would have blocked the unapproved poisoned versions from entering environments through that proxy.
A tool-server allow-list controls which capabilities an AI agent may invoke, applying the same approval principle to tool servers. Approval to use a dependency does not by itself give an agent permission to invoke a capability. Rollback provides another runtime control when the full environment graph is captured in a versioned, hash-identified manifest. Such an environment can return atomically to a prior known-good state without rebuilding or rescanning, rather than depending solely on patching forward under pressure.
How allow-list enforcement reshapes developer onboarding and platform engineering
The same manifest that constrains execution can remove decisions from onboarding. A new engineer activates an approved environment and receives the dependency set and toolchain without choosing packages from a document. A new agent can activate that same manifest. Package governance then follows the environment rather than requiring a separate agent-specific configuration. The first productive environment is also the policy-compliant one.
This is the operational value of a golden path. A pre-approved environment template incorporates compliance into provisioning, removing an additional task after setup. Platform teams that automate provisioning and embed enforcement in self-service templates can compress onboarding from weeks to hours. The developer need not operate the policy machinery. Local controls, CI gates, and production admission still apply, but the inputs they share come with the environment.
Platform engineering teams should provide extensible base environments that encode organizational security policy and spare developers from translating mandates themselves. Sharing those environments by name and keeping them in version control lets team members and agents get the current approved stack when they need it. That creates a maintained interface between policy owners and the people or agents executing code. An approval change becomes a versioned infrastructure change.


