If you're a developer, this vignette may strike a chord: You're deep in the flow, making great progress on your latest feature, when someone from the security team sends you an urgent message. A vulnerability has been discovered in one of your dependencies and has failed a compliance review. Suddenly, your day is derailed as you shift from coding to a gauntlet of bureaucratic meetings.
This is an unfortunate reality for developers at organizations where security and compliance are bolt-on processes rather than integrated parts of the whole. Your valuable development time is consumed with digging through arcane compliance documentation, attending security reviews and being relegated to compliance training sessions. Every context switch becomes another drag on your productivity, and every delayed deployment impacts your ability to ship code.
Two niche DevSecOps/software supply chain technologies have come together to transform the dynamic between developers and organizational policy—software bills of materials (SBOMs) and policy-as-code (PaC). Together, they dramatically reduce the friction between development velocity and risk management requirements by making policy evaluation and enforcement:
- Automated and consistent
- Integrated into your existing workflows
- Visible early in the development process
In this guide, we'll explore how SBOMs and policy-as-code work, the specific benefits they bring to your daily development work, and how to implement them in your environment. By the end, you'll understand how these tools can help you spend less time manually doing someone else's job and more time doing what you do best—writing great code.
Interested to learn about all of the software supply chain use-cases that SBOMs enable? Read our new white paper and start unlocking enterprise value.
A Brief Introduction to Policy-as-Code
You're probably familiar with Infrastructure-as-Code (IaC) tools like Terraform, AWS CloudFormation, or Pulumi. These tools allow you to define your cloud infrastructure in code rather than clicking through web consoles or manually running commands. Policy-as-Code (PaC) applies this same principle to policies from other departments of an organization.
What is policy-as-code?
At its core, policy-as-code translates organizational policies—whether they're security requirements, licensing restrictions, or compliance mandates—from human-readable documents into machine-readable representations that integrate seamlessly with your existing DevOps platform and tooling.
Think of it this way: IaC gives you a DSL for provisioning and managing cloud resources, while PaC extends this concept to other critical organizational policies that traditionally lived outside engineering teams. This creates a bridge between development workflows and business requirements that previously existed in separate silos.
Why do I care?
Let's play a game of would you rather. Choose the activity from the table below that you'd rather do:
Before Policy-as-Code | After Policy-as-Code |
Read lengthy security/legal/compliance documentation to understand requirements | Reference policy translated into code with clear comments and explanations |
Manually review your code policy compliance and hope you interpreted policy correctly | Receive automated, deterministic policy evaluation directly in CI/CD build pipeline |
Attend compliance training sessions because you didn't read the documentation | Learn policies by example as concrete connections to actual development tasks |
Setup meetings with security, legal or compliance teams to get code approval | Get automated approvals through automated policy evaluation without review meetings |
Wait till end of sprint and hope VP of Eng can get exception to ship with policy violations | Identify and fix policy violations early when changes are simple to implement |
While the game is a bit staged, it isn't divorced from reality. PaC is meant to relieve much of the development friction associated with the external requirements that are typically hoisted onto the shoulders of developers.
From oral tradition to codified knowledge
Perhaps one of the most under appreciated benefits of policy-as-code is how it transforms organizational knowledge. Instead of policies living in outdated Word documents or in the heads of long-tenured employees, they exist as living code that evolves with your organization.
When a developer asks "Why do we have this restriction?" or "What's the logic behind this policy?", the answer isn't "That's just how we've always done it" or "Ask Alice in Compliance." Instead, they can look at the policy code, read the annotations, and understand the reasoning directly.
In the next section, we'll explore how software bills of materials (SBOMs) provide the perfect data structure to pair with policy-as-code for managing software supply chain security.
A Brief Introduction to SBOMs (in the Context of PaC)
If policy-as-code provides the rules engine for your application's dependency supply chain, then Software Bills of Materials (SBOMs) provide the structured, supply chain data that the policy engine evaluates.
What is an SBOM?
An SBOM is a formal, machine-readable inventory of all components and dependencies used in building a software artifact. If you're familiar with Terraform, you can think of an SBOM as analogous to a dev.tfstate
file but it stores the state of your application code's 3rd-party dependency supply chain which is then reconciled against a main.tf
file (i.e., policy) to determine if the software supply chain is compliant or in violation of the defined policy.
SBOMs vs package manager dependency files
You may be thinking, "Don't I already have this information in my package.json
, requirements.txt
, or pom.xml
file?" While these files declare your direct dependencies, they don't capture the complete picture:
- They don't typically include transitive dependencies (dependencies of your dependencies)
- They don't include information about the components within container images you're using
- They don't provide standardized metadata about vulnerabilities, licenses, or provenance
- They aren't easily consumable by automated policy engines across different programming languages and environments
SBOMs solve these problems by providing a standardized format that comprehensively documents your entire software supply chain in a way that policy engines can consistently evaluate.
A universal policy interface: How SBOMs enable policy-as-code
Think of SBOMs as creating a standardized "policy interface" for your software's supply chain metadata. Just as APIs create a consistent way to interact with services, SBOMs create a consistent way for policy engines to interact with your software's composable structure.
This standardization is crucial because it allows policy engines to operate on a known data structure rather than having to understand the intricacies of each language's package management system, build tool, or container format.
For example, a security policy that says "No components with critical vulnerabilities may be deployed to production" can be applied consistently across your entire software portfolio—regardless of the technologies used—because the SBOM provides a normalized view of the components and their vulnerabilities.
In the next section, we'll explore the concrete benefits that come from combining SBOMs with policy-as-code in your development workflow.
How do I get Started with SBOMs and Policy-as-Code
Now that you understand what SBOMs and policy-as-code are and why they're valuable, let's walk through a practical implementation. We'll use Anchore Enterprise as an example of a policy engine that has a DSL to express a security policy which is then directly integrated into a CI/CD runbook. The example will focus on a common software supply chain security best practice: preventing the deployment of applications with critical vulnerabilities.
Tools we'll use
For this example implementation, we'll use the following components from Anchore:
- AnchoreCTL: A software composition analysis (SCA) tool and SBOM generator that scans source code, container images or application binaries to populate an SBOM with supply chain metadata
- Anchore Enforce: The policy engine that evaluates SBOMs against defined policies
- Anchore Enforce JSON: The Domain-Specific Language (DSL) used to define policies in a machine-readable format
While we're using Anchore in this example, the concepts apply to other SBOM generators and policy engines as well.
Step 1: Translate human-readable policies to machine-readable code
The first step is to take your organization's existing policies and translate them into a format that a policy engine can understand. Let's start with a simple but effective policy.
Human-Readable Policy:
Applications with critical vulnerabilities must not be deployed to production environments.
This policy needs to be translated into the Anchore Enforce JSON policy format:
{
"id": "critical_vulnerability_policy",
"version": "1.0",
"name": "Block Critical Vulnerabilities",
"comment": "Prevents deployment of applications with critical vulnerabilities",
"rules": [
{
"id": "block_critical_vulns",
"gate": "vulnerabilities",
"trigger": "package",
"comment": "Rule evaluates each dependency in an SBOM against vulnerability database. If the dependency is found in the database, all known vulnerability severity scores are evaluated for a critical value. If match if found policy engine returns STOP action to CI/CD build task",
"parameters": [
{ "name": "package_type", "value": "all" },
{ "name": "severity_comparison", "value": "=" },
{ "name": "severity", "value": "critical" },
],
"action": "stop"
}
]
}
This policy code instructs the policy engine to:
- Examine all application dependencies (i.e., packages) in the SBOM
- Check if any dependency/package has vulnerabilities with a severity of "critical"
- If found, return a "stop" action that will fail the build
If you're looking for more information on the capabilities of the Anchore Enforce DSL, our documentation provides the full capabilities of the Anchore Enforce policy engine.
Step 2: Deploy Anchore Enterprise with the policy engine
With the example policy defined, the next step is to deploy Anchore Enterprise (AE) and configure the Anchore Enforce policy engine. The high-level steps are:
- Deploy Anchore Enterprise platform in your test environment via Helm Chart (or other); includes policy engine
- Load your policy into the policy engine
- Configure access controls/permissions between AE deployment and CI/CD build pipeline
If you're interested to get hands-on with this, we have developed a self-paced workshop that walks you through a full deployment and how to set up a policy. You can get a trial license by signing up for our free trial.
Step 3: Integrate SBOM generation into your CI/CD pipeline
Now you need to generate SBOMs as part of your build process and have them evaluated against your policies. Here's an example of how this might look in a GitHub Actions workflow:
name: Build App and Evaluate Supply Chain for Vulnerabilities
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build-and-evaluate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build Application
run: |
# Build application as container image
docker build -t myapp:latest .
- name: Generate SBOM
run: |
# Install AnchoreCTL
curl -sSfL https://anchorectl-releases.anchore.io/v1.0.0/anchorectl_1.0.0_linux_amd64.tar.gz | tar xzf - -C /usr/local/bin
# Execute supply chain composition scan of container image, generate SBOM and send to policy engine for evaluation
anchorectl image add --wait myapp:latest
- name: Evaluate Policy
run: |
# Get policy evaluation results
RESULT=$(anchorectl image check myapp:latest --policy critical_vulnerability_policy)
# Handle the evaluation result
if [[ $RESULT == *"Status: pass"* ]]; then
echo "Policy evaluation passed! Proceeding with deployment."
else
echo "Policy evaluation failed! Deployment blocked."
exit 1
fi
- name: Deploy if Passed
if: success()
run: |
# Your deployment steps here
This workflow:
- Builds your application as a container image using Docker
- Installs AnchoreCTL
- Scans container image with SCA tool to map software supply chain
- Generates an SBOM based on the SCA results
- Submits the SBOM to the policy engine for evaluation
- Gets evaluation results from policy engine response
- Continues or halts the pipeline based on the policy response
Step 4: Test the integration
With the integration in place, it's time to test that everything works as expected:
- Create a test build that intentionally includes a component with a known critical vulnerability
- Push the build through your CI/CD pipeline
- Confirm that:
- The SBOM is correctly generated
- The policy engine identifies the vulnerability
- The pipeline fails as expected
If all goes well, you've successfully implemented your first policy-as-code workflow using SBOMs!
Step 5: Expand your policy coverage
Once you have the basic integration working, you can begin expanding your policy coverage to include:
- Security policies
- Compliance policies
- Software license policies
- Custom organizational policies
- Environment-specific requirements (e.g., stricter policies for production vs. development)
Work with your security and compliance teams to translate their requirements into policy code, and gradually expand your automated policy coverage. This process is a large upfront investment but creates recurring benefits that pay dividends over the long-term.
Step 6: Profit!
With SBOMs and policy-as-code implemented, you'll start seeing the benefits almost immediately:
- Fast feedback on security and compliance issues
- Reduced manual compliance tasks
- Better documentation of what's in your software and why
- Consistent evaluation and enforcement of policies
- Certainty about policy approvals
The key to success is getting your security and compliance teams to embrace the policy-as-code approach. Help them understand that by translating their policies into code, they gain more consistent enforcement while reducing manual effort.
Wrap-Up
As we've explored throughout this guide, SBOMs and policy-as-code represent a fundamental shift in how developers interact with security and compliance requirements. Rather than treating these as external constraints that slow down development, they become integrated features of your DevOps pipeline.
Key takeaways
- Policy-as-Code transforms organizational policies from static documents into dynamic, version-controlled code that can be automated, tested, and integrated into CI/CD pipelines.
- SBOMs provide a standardized format for documenting your software's components, creating a consistent interface that policy engines can evaluate.
- Together, they enable "shift-left" security and compliance, providing immediate feedback on policy violations without meetings or context switching.
- Integration is straightforward with pre-built plugins for popular DevOps platforms, allowing you to automate policy evaluation as part of your existing build process.
- The benefits extend beyond security to include faster development cycles, reduced compliance burden, and better visibility into your software supply chain.
Get started today
Ready to bring SBOMs and policy-as-code to your development environment? Anchore Enterprise provides a comprehensive platform for generating SBOMs, defining policies, and automating policy evaluation across your software supply chain.