Skip to content
Lucas Grifoni edited this page Sep 15, 2026 · 6 revisions

πŸ›‘οΈ OSS Security Policy as Code Starter Kit

Pass/fail security gates for OSS repositories β€” where every verdict says how much it can be trusted

PyPI Python License CI


πŸ“¦ Release 🎯 Profiles πŸ” Controls ⌨️ Commands 🐍 Python
v10.0.22 56 222 23 3.12+

Quickstart Β· Limits Β· Profiles Β· Contracts Β· Repository


🧭 How it works

flowchart LR
    subgraph IN ["what goes in"]
        A["Repository clone"]
        B["Evidence files<br/>optional, API-backed"]
        S["Scanner output<br/>SARIF or JSON"]
        W["Waivers<br/>owner, reason, expiry"]
    end

    C(["evaluate"])

    subgraph OUT ["what comes out"]
        D["evaluation-report.md"]
        E["evaluation-report.json"]
        F["results.sarif"]
    end

    G{"exit code"}
    H["CI gate"]

    A --> C
    B --> C
    S --> C
    W --> C
    C --> D
    C --> E
    C --> F
    C --> G
    G --> H
Loading

The kit reads what is visible in a clone. Anything it cannot see from there β€” branch protection, MFA, org settings β€” it will not claim, unless you hand it API-backed evidence.


βš–οΈ The part that makes it different

Most tools give you a verdict. This one also tells you how that verdict was reached, so a wrong result can be argued with evidence instead of taken on faith.

flowchart LR
    D["🟒 deterministic"] --> D1["Read straight from the clone.<br/>Highest confidence."]
    S["🟑 signal"] --> S1["Heuristic and corroborating.<br/>Never elevates a grade on its own."]
    E["πŸ”΅ evidence-backed"] --> E1["Rests on API-backed evidence you supply.<br/>As strong as that evidence is."]
Loading

Important

A control that fires wrongly is worse than one that does not exist. False-positive reports are genuinely welcome β€” the assurance label exists so you can make that argument precisely.


πŸš€ Three minutes to a working gate

pip install oss-policy-kit
python -m oss_policy_kit init --target . --with-evidence --with-workflow
python -m oss_policy_kit evaluate --target . --profile github-level-1 --fail-on fail

You get evaluation-report.md to read, evaluation-report.json to automate against, and a non-zero exit when the threshold is crossed β€” which is what makes it a gate rather than a report.


🚫 What it will not do

Warning

This section comes early on purpose. A security tool that oversells is worse than none.

It does not Because
Certify CRA, SLSA, OSPS, SSDF or AI Act compliance It produces readiness signals, not conformity assessments
Replace SAST, SCA, secret scanning, pentesting or threat modeling It composes their output as evidence; it is not a scanner
Prove branch protection, rulesets, MFA or cloud posture Not visible in a clone β€” supply API-backed evidence and it will
Claim SLSA Build L3 The real trust model is written down in supply-chain-verification.md

🎯 Pick a starting profile

Profile Use when
🟩 github-level-1 First gate on a public GitHub repository
🟦 github-level-2 Stricter governance and CI/CD posture
πŸ“¦ oss-publish-readiness-1 About to publish or release an OSS package
πŸ”¬ appsec-sast-sca-1 You already have scanner output to compose
πŸ›οΈ osps-baseline-2026-1 Reviewing against the OpenSSF OSPS Baseline
πŸ‡ͺπŸ‡Ί cra-eu-conformance-evidence-1 EU CRA Article 13/14 evidence signals
πŸ€– ai-agent-baseline-1 The repository ships an AI agent
πŸ”Œ appsec-mcp-server-1 The repository ships an MCP server
All 56 profiles, by lane
Lane Covers
Platform GitHub, Azure DevOps, AWS CodeBuild/CodePipeline, GitLab CI
Release hardening OIDC publishing, provenance evidence, artifact verification, immutable releases
Regulatory EU CRA Article 13/14, EU AI Act Annex IV
Supply chain Dependency review, SBOM, pinning, signing
AI and agents AI agent source-side checks, MCP server security, OWASP Agentic ASI
IaC and container Terraform, Bicep, CloudFormation, Pulumi, Kubernetes, image hardening
Baselines OpenSSF OSPS Baseline, NIST SSDF, S2C2F
python -m oss_policy_kit profiles

πŸ“ Contracts you can pin

reports/2.0 is the only report contract. The pre-2.0 contracts were removed in v9.0.0 under ADR-043 β€” --report-json-contract accepts only 2.0, and anything else is a clean exit-2 error rather than a silent fallback.

Tip

Downstream parsers should pin the public schemas under reports/schema/ β€” never the packaged copies inside the wheel.

Exit Meaning In CI
0 Threshold not crossed βœ… pass
1 Threshold was crossed ❌ fail
2 Usage, validation or load error ⚠️ broken invocation
3 Unexpected internal error πŸ› report it

Exit codes are a supported contract covered by tests. Automate against them.


🧩 Beyond the basics

correlate-findings β€” one ranked list instead of five tool-shaped ones

Merges every composed scanner into a single deduplicated findings/1.0 artifact, ranked by CISA KEV and EPSS rather than by raw CVSS. Stateless: one run, one artifact, no database.

Interop exports β€” speak the ecosystem's formats

CycloneDX VEX Β· OpenVEX Β· SPDX Β· OSCAL Assessment Results Β· Gemara Layer 5 Β· in-toto Β· CEL and Rego policy export.

Waivers β€” exceptions that stay visible

Every waiver carries an owner, a reason, a scope and an expiry. A silent suppression is a lie the next auditor inherits; an expiring waiver is a decision someone signed.


πŸ“Š Project status

Note

Maintenance. v10.0.0 completed the planned end-state. Releases since have been hardening and correctness work, not new surface. Issues and questions still get answered β€” there is simply no large roadmap queued behind them.