panurus

OSPS Baseline Level 3

Self-assessment of Panurus against Level 3 of the OpenSSF Security Baseline, version v2026.02.19.

Level 3 applies to code projects with a large, consistent user base and builds on Level 1 and Level 2. It is documented here as a longer-term target: most of its controls concern release provenance, support lifecycle and formal security analysis, none of which exist yet. Requirement wording below is abbreviated; the authoritative text is the Baseline v2026.02.19 control list.

Access Control

Control Requirement Status Evidence / notes
OSPS-AC-04.02 Jobs are assigned only the minimum privileges necessary Met Every workflow declares a minimal top-level token and elevates only at the job level where needed. token-validation-benchmark.yml grants pull-requests: write only to the compare job (which never executes PR code); nightly-fuzz.yml grants issues: write only to the fuzz job; docs.yml pins the build job to contents: read and scopes pages: write and id-token: write exclusively to the deploy job (lines 81-82); scorecard.yml uses read-all at the top level and grants security-events: write and id-token: write only to its analysis job; codeql-analysis.yml uses permissions: {} at the top level with per-job grants; tests.yml, protect-integration-test-types.yml, and nightly-fsc.yml pin contents: read with no per-job elevations; md_links.yml declares pull-requests: write workflow-wide as it has a single job.

Build and Release

Control Requirement Status Evidence / notes
OSPS-BR-01.04 Input from trusted collaborators is sanitized and validated before use Not Met Two workflow_dispatch inputs are interpolated directly into shell steps without validation or an env: variable indirection: fsc-version in tests.yml lines 38-40 (go mod edit -replace=...=$) and fuzztime in nightly-fuzz.yml line 169 (-fuzztime="$"). Both inputs come from trusted collaborators but are exactly the pattern this control targets.
OSPS-BR-02.02 Every asset in a release is clearly associated with the release identifier Met Releases publish only GitHub’s auto-generated source archives, which are named after the tag, and each Go module carries a tag bearing the same version (v0.17.0, cmd/tokengen/v0.17.0, integration/v0.17.0, …).
OSPS-BR-07.02 A defined policy for storing, accessing and rotating secrets and credentials Not Met Workflows consume credentials only through the GitHub secrets context, but no document states who may add a secret, how access is reviewed, or when secrets are rotated.

Documentation

Control Requirement Status Evidence / notes
OSPS-DO-03.01 Instructions to verify the integrity and authenticity of release assets Not Met No such instructions exist, and there is nothing to verify against today (see OSPS-BR-06.01 in Level 2). Module consumers do get go.sum checksum verification, which is not documented as a verification procedure.
OSPS-DO-03.02 Instructions to verify the expected identity of the release author Not Met Release tags are unsigned, so author identity cannot be verified cryptographically and no procedure is documented.
OSPS-DO-04.01 A descriptive statement about the scope and duration of support for each release Not Met versioning explains SemVer mechanics, but no page states how long any given minor release is supported.
OSPS-DO-05.01 A descriptive statement of when releases stop receiving security updates Not Met No end-of-life or security-support window is documented.

Governance

Control Requirement Status Evidence / notes
OSPS-GV-04.01 A documented policy that code collaborators are reviewed before permissions are escalated Not Met MAINTAINERS.md lists who holds elevated access, and the LFDT charter governs the project, but no repository document describes the review that precedes granting escalated permissions.

Quality

Control Requirement Status Evidence / notes
OSPS-QA-02.02 Compiled released assets are delivered with a software bill of materials Not Met No SBOM is generated or published. Applicability is partly limited because releases currently ship source and Go modules rather than compiled binaries, but the container images and CLI tools built from this repository are not accompanied by an SBOM either.
OSPS-QA-04.02 Subprojects enforce security requirements at least as strict as the primary codebase Met Panurus is a single repository with no external subprojects. Its Go modules share one set of gates: checks.mk and the lint target iterate over $(GO_MODULES), and tests.yml runs them for the whole tree. The auxiliary tools module is the one exception — it appears in TIDY_GO_MODULES only, so it is tidy-checked but not linted or vetted.
OSPS-QA-06.02 Documentation clearly states when and how tests are run Met Testing guide covers unit, fuzz, integration and Fabric-X tests with the exact commands; Makefile guide documents the targets; the nightly fuzz matrix is described alongside nightly-fuzz.yml.
OSPS-QA-06.03 A documented policy that major changes add or update automated tests Partially Met AGENTS.md requires a fuzz target for every new parser of untrusted input and describes the expected unit/integration test practice, and docs/development/testing.md documents how to add tests. Neither CONTRIBUTING.md nor DEVELOPMENT.md states the general rule that a major change must come with tests.
OSPS-QA-07.01 The version control system requires at least one non-author human approval before merge Partially Met DEVELOPMENT.md section 3 states a “One Approve Policy”, but the active branch ruleset sets required_approving_review_count: 0, so the platform does not enforce it. The “Code Quality Copilot review for default branch” ruleset (id 19363822) has enforcement: disabled, so it has no effect on merge gating.

Security Assessment

Control Requirement Status Evidence / notes
OSPS-SA-03.02 Threat modeling and attack surface analysis of critical code paths Not Met No threat model is published. Individual hardening notes exist (for example selector resource limits), and the driver and validator documentation describes trust boundaries, but there is no systematic attack-surface analysis.

Vulnerability Management

Control Requirement Status Evidence / notes
OSPS-VM-04.02 Non-exploitable vulnerabilities in components are accounted for in a VEX document Not Met No VEX documents are produced.
OSPS-VM-05.01 A documented threshold for remediating SCA findings (vulnerabilities and licenses) Not Met No documented severity threshold for dependency findings.
OSPS-VM-05.02 A documented policy to address SCA violations before any release Not Met The release process does not document a dependency-scanning gate.
OSPS-VM-05.03 All changes are automatically evaluated against a documented policy for malicious and vulnerable dependencies, and blocked on violation Partially Met Automated dependency updates are demonstrably active — the v0.17.0 release notes contain several build(deps) pull requests opened by Dependabot — and the repository now checks in .github/dependabot.yml, which watches the SHA-pinned GitHub Actions weekly and groups major vs. minor/patch bumps into separate reviewable PRs (Go modules are intentionally out of scope, handled by the Nightly FSC workflow). Still missing for full compliance: the alerting configuration is not publicly readable, no documented remediation policy exists, and no gate blocks a change on a dependency finding.
OSPS-VM-06.01 A documented threshold for remediating SAST findings Partially Met The de facto threshold is zero: codeql-analysis.yml scans every push and pull request, and the checks job of tests.yml fails on any golangci-lint, staticcheck, go vet or ineffassign finding. That threshold is not written down anywhere, and CodeQL results are not gated.
OSPS-VM-06.02 All changes are automatically evaluated for security weaknesses and blocked on violation Partially Met Evaluation happens on every pull request (CodeQL, golangci-lint, staticcheck, nightly fuzzing). Blocking is by convention: the only required status check on main is DCO, and the ruleset that required CodeQL is disabled — see OSPS-QA-03.01 in Level 2.

Summary

Status Count
Met 4
Partially Met 5
Not Met 12
Unverified 0
Total 21

Level 3 is not a near-term goal. With workflow permissions: now declared on every workflow (OSPS-AC-04.02), the cheapest remaining wins that also help Level 2 are passing the fsc-version and fuzztime inputs through env: variables (OSPS-BR-01.04) and writing down the SAST/SCA thresholds that CI already enforces in practice. Release signing plus SBOM and VEX generation are the substantial items.