OpenSSF Best Practices: self-assessment (passing level)
Badge: passing, awarded 2026-10-17 (bestpractices.dev/en/projects/15625).
This page
records the answer and the evidence for every "passing" criterion, in the order of the badge form, so the answers can
be checked against the repository. Links point at main.
Project details on the form: name FortProof; description "Evidence-driven application security assurance
(OWASP SAMM/ASVS): controls are judged from verified, signed pipeline evidence, never from configuration alone.";
licence Apache-2.0; implementation languages Python, TypeScript.
Basics
| Criterion |
Answer |
Justification |
| description_good |
Met |
The README says what FortProof does and for whom: https://github.com/cipherfort/fortproof#readme |
| interact |
Met |
The README links to the documentation, issues, discussions and contribution guide. Docs: https://fortproof.dev/ |
| contribution |
Met |
https://github.com/cipherfort/fortproof/blob/main/CONTRIBUTING.md |
| contribution_requirements |
Met |
Coding standards, required checks and DCO sign-off: https://github.com/cipherfort/fortproof/blob/main/CONTRIBUTING.md |
| floss_license |
Met |
Code Apache-2.0; documentation CC BY-SA 4.0 (LICENSE-docs). |
| floss_license_osi |
Met |
Apache-2.0 is OSI-approved. |
| license_location |
Met |
https://github.com/cipherfort/fortproof/blob/main/LICENSE |
| documentation_basics |
Met |
Getting started, install (Helm, Compose), configuration and user guide: https://fortproof.dev/ |
| documentation_interface |
Met |
REST API reference generated from the OpenAPI contract, and the settings reference: https://fortproof.dev/reference/api/ and https://fortproof.dev/reference/settings/ |
| sites_https |
Met |
The repository (GitHub) and the documentation site (GitHub Pages) are served only over HTTPS. |
| discussion |
Met |
GitHub Issues and Discussions: https://github.com/cipherfort/fortproof/issues and https://github.com/cipherfort/fortproof/discussions |
| english |
Met |
Documentation and code are in English; reports in English are accepted. |
| maintained |
Met |
Actively maintained: https://github.com/cipherfort/fortproof/commits/main |
Change control
| Criterion |
Answer |
Justification |
| repo_public |
Met |
https://github.com/cipherfort/fortproof |
| repo_track |
Met |
Git records every change, its author and date. |
| repo_interim |
Met |
Work between releases is committed to the public repository through pull requests. |
| repo_distributed |
Met |
Git. |
| version_unique |
Met |
Each release gets a unique semantic version (release-please): https://github.com/cipherfort/fortproof/blob/main/RELEASING.md |
| version_semver |
Met |
Semantic Versioning 2.0.0: https://github.com/cipherfort/fortproof/blob/main/RELEASING.md |
| version_tags |
Met |
Releases are tagged vX.Y.Z by release-please, and a repository ruleset makes release tags immutable. No release has been cut yet. |
| release_notes |
N/A |
No release has been made yet. Each release will get human-readable notes in CHANGELOG.md, generated by release-please: https://github.com/cipherfort/fortproof/blob/main/CHANGELOG.md |
| release_notes_vulns |
N/A |
No release has been made yet, so no release has fixed a publicly known vulnerability. Release notes will identify any that are fixed (RELEASING.md). |
Reporting
| Criterion |
Answer |
Justification |
| report_process |
Met |
Bug reports through GitHub Issues, with templates: https://github.com/cipherfort/fortproof/issues/new/choose |
| report_tracker |
Met |
GitHub Issues. |
| report_responses |
Met |
Maintainers respond to reports through GitHub Issues. No bug reports have been received yet. |
| enhancement_responses |
Met |
Enhancement requests are answered through GitHub Issues and Discussions. None have been received yet. |
| report_archive |
Met |
Reports and responses are publicly archived and searchable: https://github.com/cipherfort/fortproof/issues?q=is%3Aissue |
| vulnerability_report_process |
Met |
https://github.com/cipherfort/fortproof/blob/main/SECURITY.md |
| vulnerability_report_private |
Met |
Private reporting through GitHub private vulnerability reporting (enabled), or email: https://github.com/cipherfort/fortproof/security/advisories/new |
| vulnerability_report_response |
N/A |
No vulnerability reports have been received. SECURITY.md commits to acknowledging within 3 working days and assessing within 10: https://github.com/cipherfort/fortproof/blob/main/SECURITY.md |
Quality
| Criterion |
Answer |
Justification |
| build |
Met |
Backend with uv, UI with npm and Vite, container image with Docker, Helm chart. Instructions in CONTRIBUTING.md. |
| build_common_tools |
Met |
uv, npm, Docker and Helm. |
| build_floss_tools |
Met |
All build tools are FLOSS. |
| test |
Met |
Automated suite (pytest; 343 tests including PostgreSQL integration tests), database security-property tests, an API contract test (Schemathesis) and a Helm install/upgrade test on kind, all run in CI. How to run them: CONTRIBUTING.md. |
| test_invocation |
Met |
uv run pytest (backend), npm run build (UI type check and build), documented in CONTRIBUTING.md. |
| test_most |
Met |
Backend line coverage is 77% (pytest-cov, all non-opt-in tests). |
| test_continuous_integration |
Met |
Every pull request and push to main runs the full suite: https://github.com/cipherfort/fortproof/actions/workflows/ci.yml |
| test_policy |
Met |
New functionality comes with tests: CONTRIBUTING.md and the pull-request checklist ("Tests added or updated"): https://github.com/cipherfort/fortproof/blob/main/.github/PULL_REQUEST_TEMPLATE.md |
| tests_are_added |
Met |
Recent changes added tests with the code, e.g. the TLS 1.2 floor for the syslog sink in https://github.com/cipherfort/fortproof/pull/16 |
| tests_documented_added |
Met |
The pull-request template requires tests: https://github.com/cipherfort/fortproof/blob/main/.github/PULL_REQUEST_TEMPLATE.md |
| warnings |
Met |
ruff (lint) and mypy (strict) for Python; TypeScript strict with noUnusedLocals/noUnusedParameters; actionlint, zizmor and shellcheck for workflows and scripts. |
| warnings_fixed |
Met |
CI fails on any warning from these tools, so none can merge. |
| warnings_strict |
Met |
mypy --strict over the whole backend package; TypeScript strict. |
Security
| Criterion |
Answer |
Justification |
| know_secure_design |
Met |
The maintainer works in application security. The design is documented in the threat model and security architecture: https://github.com/cipherfort/fortproof/blob/main/docs/security/platform-security-architecture.md |
| know_common_errors |
Met |
The maintainer works in application security (OWASP ASVS/SAMM, the domain of this project). Mitigations for common errors are recorded in the threat model: https://github.com/cipherfort/fortproof/blob/main/docs/security/platform-security-architecture.md |
| crypto_published |
Met |
Only published algorithms: SHA-256, RS256 (JWT), ECDSA P-256 and Sigstore signatures, TLS. |
| crypto_call |
Met |
Cryptography is delegated to libraries: Python cryptography, pyjwt, sigstore and ssl. |
| crypto_floss |
Met |
All of these are FLOSS. |
| crypto_keylength |
Met |
The project does not generate long-term keys: evidence is signed keylessly (Sigstore), and GitHub generates the GitHub App's RSA key. Verification accepts RS256 and ECDSA P-256 only. |
| crypto_working |
Met |
No broken algorithms in security functions. The only SHA-1 seeds demo data and is marked usedforsecurity=False. |
| crypto_weaknesses |
Met |
No algorithms or modes with known serious weaknesses are used. |
| crypto_pfs |
Met |
Network connections use TLS through Python's ssl defaults (TLS 1.3 and ECDHE suites); the syslog sink enforces TLS 1.2 or later. |
| crypto_password_storage |
N/A |
FortProof stores no user passwords: people sign in through an external OIDC identity provider, and service credentials are kept in a secret store. |
| crypto_random |
Met |
Tokens and generated credentials use Python's secrets module (a CSPRNG). |
| delivery_mitm |
Met |
Source is delivered over HTTPS from GitHub. The release workflow signs container images with cosign (keyless) and publishes SLSA provenance. |
| delivery_unsigned |
Met |
Nothing is fetched over HTTP. The container build verifies downloaded tools against SHA-256 digests pinned in the Dockerfile. |
| vulnerabilities_fixed_60_days |
Met |
There are no unpatched vulnerabilities of medium or higher severity in FortProof. Dependabot alerts in CI-only tooling (Checkov's dependencies, no upstream fix yet) are triaged with recorded reasons. |
| vulnerabilities_critical_fixed |
Met |
Critical vulnerabilities are fixed promptly. SECURITY.md targets 30 days for critical and high. |
| no_leaked_credentials |
Met |
No credentials in the repository. gitleaks scans the full history on every pull request, and GitHub secret scanning with push protection is enabled. |
Analysis
| Criterion |
Answer |
Justification |
| static_analysis |
Met |
CodeQL (Python, TypeScript, Actions) on every pull request and push, plus ruff, mypy (strict), Checkov, zizmor, actionlint and shellcheck in CI: https://github.com/cipherfort/fortproof/blob/main/.github/workflows/codeql.yml |
| static_analysis_common_vulnerabilities |
Met |
CodeQL's security queries look for common vulnerabilities; zizmor for workflow injection; Checkov for infrastructure. |
| static_analysis_fixed |
Met |
Findings are fixed or triaged promptly, e.g. the first CodeQL scan's TLS finding was fixed the same day: https://github.com/cipherfort/fortproof/pull/16 |
| static_analysis_often |
Met |
On every pull request and push to main, and weekly. |
| dynamic_analysis |
Met |
Schemathesis fuzzes the API against its OpenAPI contract in CI. Hypothesis property-based fuzzing covers the parsers and verifiers (200 examples per run, 5,000 nightly). |
| dynamic_analysis_unsafe |
N/A |
FortProof is written in memory-safe languages (Python, TypeScript). |
| dynamic_analysis_enable_assertions |
Met |
Python assertions stay enabled in tests and fuzzing, and Schemathesis checks every response against the API contract. |
| dynamic_analysis_fixed |
Met |
Fuzzing found crashes in the SARIF and SBOM parsers and the component verifier. They were fixed before the first public commit, and the cases are kept as regression tests. |
OpenSSF Baseline, level 1
Badge: Baseline level 1, awarded 2026-10-17 (bestpractices.dev/en/projects/15625/baseline-1),
against Baseline criteria version 2026.08.28. Repository and organization settings were checked through the GitHub API
when the answers were given (for example, two-factor authentication is required for the cipherfort organization).
| Control |
Answer |
Justification |
| OSPS-AC-01.01 |
Met |
The cipherfort GitHub organization requires two-factor authentication for every member (Organization settings, Authentication security). |
| OSPS-AC-02.01 |
Met |
The organization's base repository permission is Read; anything more is granted manually per collaborator or team. |
| OSPS-AC-03.01 |
Met |
A repository ruleset on main requires a pull request and all CI checks to pass; direct pushes are rejected. |
| OSPS-AC-03.02 |
Met |
The same ruleset blocks deletion and force-pushes of main. |
| OSPS-BR-01.01 |
Met |
Workflows never interpolate untrusted event data into scripts; values pass through environment variables. actionlint, zizmor and CodeQL (Actions) check every pull request: https://github.com/cipherfort/fortproof/blob/main/.github/workflows/ci.yml |
| OSPS-BR-01.03 |
Met |
Pull requests run on the pull_request trigger (never pull_request_target): forks get no secrets and a read-only token. The default workflow token is read-only and checkouts do not persist credentials. |
| OSPS-BR-03.01 |
Met |
Official channels are HTTPS only: https://github.com/cipherfort/fortproof and https://fortproof.dev/ |
| OSPS-BR-03.02 |
Met |
Source is distributed over HTTPS from GitHub; images and charts over HTTPS from GHCR, signed with cosign (keyless) and with SLSA provenance: https://github.com/cipherfort/fortproof/blob/main/RELEASING.md |
| OSPS-BR-07.01 |
Met |
gitleaks scans the full history on every pull request, and GitHub secret scanning with push protection is enabled. |
| OSPS-DO-01.01 |
Met |
User documentation covers installation, configuration and use: https://fortproof.dev/ |
| OSPS-DO-02.01 |
Met |
How to report a bug: https://github.com/cipherfort/fortproof/blob/main/CONTRIBUTING.md#reporting-a-bug |
| OSPS-GV-02.01 |
Met |
GitHub Issues and Discussions: https://github.com/cipherfort/fortproof/issues and https://github.com/cipherfort/fortproof/discussions |
| OSPS-GV-03.01 |
Met |
https://github.com/cipherfort/fortproof/blob/main/CONTRIBUTING.md |
| OSPS-LE-02.01 |
Met |
Code Apache-2.0 (OSI-approved); documentation CC BY-SA 4.0. |
| OSPS-LE-02.02 |
Met |
Released images and Helm charts are Apache-2.0. |
| OSPS-LE-03.01 |
Met |
https://github.com/cipherfort/fortproof/blob/main/LICENSE (code) and https://github.com/cipherfort/fortproof/blob/main/LICENSE-docs (documentation) |
| OSPS-LE-03.02 |
Met |
The image ships /app/LICENSE and /app/NOTICE (label org.opencontainers.image.licenses=Apache-2.0); the release workflow packages LICENSE and NOTICE into the Helm chart. |
| OSPS-QA-01.01 |
Met |
https://github.com/cipherfort/fortproof |
| OSPS-QA-01.02 |
Met |
Git records every change, its author and date: https://github.com/cipherfort/fortproof/commits/main |
| OSPS-QA-02.01 |
Met |
Direct dependencies are declared in backend/pyproject.toml and frontend/package.json, with lockfiles (uv.lock, package-lock.json). |
| OSPS-QA-04.01 |
N/A |
The project is a single repository: https://github.com/cipherfort/fortproof |
| OSPS-QA-05.01 |
Met |
No generated executables are committed; build outputs are git-ignored and produced in CI. |
| OSPS-QA-05.02 |
Met |
The only binary file is a documented test fixture (a snappy-compressed public Sigstore bundle, decoded by the tests): https://github.com/cipherfort/fortproof/blob/main/backend/tests/fixtures/attestations/README.md |
| OSPS-VM-02.01 |
Met |
Security contacts: https://github.com/cipherfort/fortproof/blob/main/SECURITY.md |