Skip to content

OpenSSF Best Practices: passing-level self-assessment

The maintainer registers the project at https://www.bestpractices.dev with their GitHub account and fills in the form. Each criterion below has the answer to select, a one-sentence justification and a public evidence URL to paste. Answers are strict: Met only with evidence that can be checked today, N/A only where the criterion allows it, and Unmet with what is missing. The form’s autofill may suggest different values; keep these unless the evidence changed.

Evidence URLs point to main. Files added by the pull request that introduced this document (docs/architecture/security.md and this file) resolve only after it is merged.

Answer MUST SHOULD SUGGESTED Total
Met 40 9 11 60
Unmet 1 0 2 3
N/A 2 1 1 4
Total 43 10 14 67

The passing badge needs every MUST met (or N/A where allowed) and every SHOULD met or explained. One MUST is unmet: release_notes. It needs a first release.

  1. Cut the first release (v0.1.0) as described in releasing: complete the one-time setup, then merge the first release-please pull request after the release checklist. Its vX.Y.Z tag and published GitHub Release with the changelog section meet release_notes (MUST) and the suggested version_semver and version_tags. Until then, answer release_notes Unmet. Its N/A option is only for software that is not reused in several places and is delivered continuously. GuestCraft is installed by many operators. The “no release notes yet” N/A applies to release_notes_vulns, not to release_notes.
  2. Confirm the secure-development statements. know_secure_design and know_common_errors ask whether a primary developer knows these subjects. Security design documents how the project applies them; submitting the form is the maintainer’s own statement that they know them.
  3. Dismiss the CodeQL alerts that are not vulnerabilities, with the reasons in static_analysis_fixed. The exploitable ones are fixed in the same pull request as this document.
  4. Publish a dedicated security contact address in MAINTAINERS.md (not required for passing; private vulnerability reporting already meets it).
  5. After the badge is awarded, add its badge to the README and set quality program row 25 to done. The OpenSSF Scorecard CII-Best-Practices check then stops scoring 0.
Criterion Level Answer Justification Evidence
description_good MUST Met The README opens by saying GuestCraft is an open-source property management system for hotels and vacation rentals built on Channex, then lists what an installation can do. https://github.com/Spinny03/guestcraft#readme
interact MUST Met The README explains how to obtain the software (deploy or run locally), how to give feedback (GitHub issues and SUPPORT.md) and how to contribute (CONTRIBUTING.md). https://github.com/Spinny03/guestcraft#readme
contribution MUST Met CONTRIBUTING.md explains the process: branch from main, open a focused pull request that fills in the template, pass CI and get a maintainer’s approval. https://github.com/Spinny03/guestcraft/blob/main/CONTRIBUTING.md#commits-and-pull-requests
contribution_requirements SHOULD Met CONTRIBUTING.md states the coding rules (strict TypeScript, error model, money and time types), test levels, coverage thresholds, Conventional Commits, SPDX headers and DCO sign-off. https://github.com/Spinny03/guestcraft/blob/main/CONTRIBUTING.md#code
floss_license MUST Met The core and applications are AGPL-3.0-only; the SDK, client libraries and OpenAPI contract are MIT; documentation is CC-BY-4.0. https://github.com/Spinny03/guestcraft/blob/main/LICENSE
floss_license_osi SUGGESTED Met AGPL-3.0 and MIT, the software licenses, are OSI-approved; CC-BY-4.0 covers documentation only. https://github.com/Spinny03/guestcraft/tree/main/LICENSES
license_location MUST Met LICENSE at the repository root, every license text in LICENSES/, and REUSE.toml plus SPDX headers per file (REUSE-compliant, checked in CI). https://github.com/Spinny03/guestcraft/blob/main/LICENSE
documentation_basics MUST Met The README and installation guide cover installing, starting and first setup; the developer guide covers use; the deployment guides cover secure secrets and the setup code. https://github.com/Spinny03/guestcraft/blob/main/docs/developer/installation.md
documentation_interface MUST Met The external HTTP interface is specified in the committed OpenAPI 3.1 document, described in the API guide, and served as an interactive reference by every instance. https://github.com/Spinny03/guestcraft/blob/main/docs/developer/api.md
sites_https MUST Met The project’s only sites are the GitHub repository, its issues and its releases, all served over HTTPS only. https://github.com/Spinny03/guestcraft
discussion MUST Met GitHub issues and pull requests are searchable, addressable by URL, open to anyone with a free account and need no proprietary client. https://github.com/Spinny03/guestcraft/issues
english SHOULD Met The README, contributor guide, ADRs and developer documentation are in English, and issues and reviews are accepted in English; only the original technical analysis is in Italian. https://github.com/Spinny03/guestcraft/blob/main/CONTRIBUTING.md
maintained MUST Met The repository receives commits and merged pull requests daily, and security reports have published response targets. https://github.com/Spinny03/guestcraft/commits/main
Criterion Level Answer Justification Evidence
repo_public MUST Met The Git repository is public on GitHub. https://github.com/Spinny03/guestcraft
repo_track MUST Met Git records every change with its author, committer and date, and every change reaches main through a pull request. https://github.com/Spinny03/guestcraft/commits/main
repo_interim MUST Met All work is committed to main through reviewed pull requests between releases; the repository is not limited to final releases. https://github.com/Spinny03/guestcraft/pulls?q=is%3Apr
repo_distributed SUGGESTED Met The source repository uses Git. https://github.com/Spinny03/guestcraft
version_unique MUST Met Before the first release, every build is a commit of main identified by its Git commit ID; releases get unique SemVer numbers from release-please. https://github.com/Spinny03/guestcraft/blob/main/docs/developer/releasing.md#versions
version_semver SUGGESTED Unmet SemVer (0.MINOR.PATCH before 1.0) is the documented and automated scheme, but no release exists yet; met by the first release v0.1.0. https://github.com/Spinny03/guestcraft/blob/main/docs/developer/releasing.md#versions
version_tags SUGGESTED Unmet No release tag exists yet; release-please tags each release vX.Y.Z. https://github.com/Spinny03/guestcraft/tags
release_notes MUST Unmet No release has been made, so there are no release notes. Each release will publish its CHANGELOG.md section plus the migrations, API revision and image digests as GitHub Release notes, and the first release meets this criterion. https://github.com/Spinny03/guestcraft/blob/main/docs/developer/releasing.md#how-a-release-happens
release_notes_vulns MUST N/A There are no release notes yet and no publicly known vulnerability in GuestCraft; the release checklist requires future notes to name every fixed one. https://github.com/Spinny03/guestcraft/blob/main/docs/developer/releasing.md#release-checklist
Criterion Level Answer Justification Evidence
report_process MUST Met Bugs are reported as GitHub issues with a bug-report template, as SUPPORT.md and CONTRIBUTING.md explain. https://github.com/Spinny03/guestcraft/issues/new/choose
report_tracker SHOULD Met GitHub Issues tracks individual issues, with bug, enhancement and triage labels from the templates. https://github.com/Spinny03/guestcraft/issues
report_responses MUST Met No bug report has been submitted since the repository was created on 2026-10-25 (public since 2026-10-28); the three issues filed so far, all by the maintainer, were closed as completed. https://github.com/Spinny03/guestcraft/issues?q=is%3Aissue
enhancement_responses SHOULD Met The three enhancement issues filed so far, all by the maintainer, were closed as completed after the pull requests that reference them. https://github.com/Spinny03/guestcraft/issues?q=is%3Aissue+is%3Aclosed
report_archive MUST Met GitHub keeps every issue, pull request and comment publicly searchable. https://github.com/Spinny03/guestcraft/issues?q=
vulnerability_report_process MUST Met SECURITY.md explains how to report a vulnerability, what to include and the response targets; GitHub links it from the Security tab. https://github.com/Spinny03/guestcraft/blob/main/SECURITY.md
vulnerability_report_private MUST Met Private vulnerability reporting is enabled on GitHub, and SECURITY.md links its form; reports are visible only to the maintainers and the reporter. https://github.com/Spinny03/guestcraft/security/advisories/new
vulnerability_report_response MUST N/A No vulnerability has been reported in the last 6 months; the published target is acknowledgement within 72 hours. https://github.com/Spinny03/guestcraft/blob/main/SECURITY.md#what-happens-next
Criterion Level Answer Justification Evidence
build MUST Met pnpm install and Turborepo build every package; the web application builds with pnpm --filter @guestcraft/web build, and the Dockerfile builds the image, as the required smoke check does. https://github.com/Spinny03/guestcraft/blob/main/Dockerfile
build_common_tools SUGGESTED Met The build uses Node.js, pnpm, TypeScript, Turborepo, Next.js and Docker. https://github.com/Spinny03/guestcraft/blob/main/package.json
build_floss_tools SHOULD Met Every build tool is free software (Node.js, pnpm, TypeScript, Turborepo, Next.js, Docker Engine). https://github.com/Spinny03/guestcraft/blob/main/pnpm-workspace.yaml
test MUST Met The Vitest suites (unit, property and PostgreSQL integration tests) are in the repository under the project’s licenses, and CONTRIBUTING.md shows how to run them. https://github.com/Spinny03/guestcraft/blob/main/CONTRIBUTING.md#commands
test_invocation SHOULD Met pnpm test runs the fast tests and pnpm test:coverage runs every test, the standard invocation for a pnpm workspace. https://github.com/Spinny03/guestcraft/blob/main/package.json
test_most SUGGESTED Met Per-package coverage thresholds of 85–99% statements and 80–95% branches are enforced over all handwritten source, with a ratchet that stops coverage from falling. https://github.com/Spinny03/guestcraft/blob/main/vitest.config.ts
test_continuous_integration SUGGESTED Met GitHub Actions runs the full quality suite and the Docker smoke check on every pull request and push to main; both are required to merge. https://github.com/Spinny03/guestcraft/blob/main/.github/workflows/quality.yml
test_policy MUST Met CONTRIBUTING.md requires every change to come with tests at the right level and every bug fix with a test that fails without it. https://github.com/Spinny03/guestcraft/blob/main/CONTRIBUTING.md#tests
tests_are_added MUST Met Recent feature pull requests added tests with the code: custom roles (#45), Channex ARI publication (#41) and cancellation policies (#39) each changed dozens of test files. https://github.com/Spinny03/guestcraft/pull/45/files
tests_documented_added SUGGESTED Met The pull-request template’s checklist and CONTRIBUTING.md both state the test requirement for change proposals. https://github.com/Spinny03/guestcraft/blob/main/.github/PULL_REQUEST_TEMPLATE.md
warnings MUST Met TypeScript runs in strict mode with extra checks, and Biome lints all code with the recommended rules, extra rules and GritQL plugins; dependency-cruiser and Knip check boundaries and dead code. https://github.com/Spinny03/guestcraft/blob/main/biome.json
warnings_fixed MUST Met Lint and type errors fail the required quality check. Biome reports 16 warnings across 727 files: 15 deliberate !important overrides in the print stylesheet of the folio statement, and one unused parameter in a test. https://github.com/Spinny03/guestcraft/blob/main/.github/workflows/quality.yml
warnings_strict SUGGESTED Met strict, noUncheckedIndexedAccess and exactOptionalPropertyTypes are on. Biome uses its recommended rules plus project rules and GritQL plugins, and most of them fail as errors. https://github.com/Spinny03/guestcraft/blob/main/packages/tsconfig/base.json
Criterion Level Answer Justification Evidence
know_secure_design MUST Met The maintainer applies the Saltzer–Schroeder principles, a limited attack surface and allowlist input validation; the security design document maps each principle to its mechanism. https://github.com/Spinny03/guestcraft/blob/main/docs/architecture/security.md#1-design-principles
know_common_errors MUST Met The security design document lists the common web-application vulnerability classes (OWASP Top 10, CWE Top 25) with GuestCraft’s countermeasure and its test or gate for each. https://github.com/Spinny03/guestcraft/blob/main/docs/architecture/security.md#2-common-errors-and-their-countermeasures
crypto_published MUST Met Only published, expert-reviewed algorithms are used: AES-256-GCM, HMAC-SHA-256, SHA-256 and scrypt. https://github.com/Spinny03/guestcraft/blob/main/docs/architecture/security.md#3-cryptography
crypto_call SHOULD Met GuestCraft implements no cryptography; it calls Node.js node:crypto, Web Crypto and Better Auth. https://github.com/Spinny03/guestcraft/blob/main/docs/architecture/security.md#3-cryptography
crypto_floss MUST Met Every cryptographic function comes from free software: Node.js and OpenSSL, and Better Auth (MIT). https://github.com/Spinny03/guestcraft/blob/main/docs/architecture/security.md#3-cryptography
crypto_keylength MUST Met Symmetric keys are 256 bits; the runtime refuses any configured secret shorter than 32 characters, so smaller keys cannot be configured. https://github.com/Spinny03/guestcraft/blob/main/packages/server/src/config/settings.ts
crypto_working MUST Met No default mechanism uses MD4, MD5, single DES, RC4 or Dual_EC_DRBG, and GCM is used with random 96-bit IVs. https://github.com/Spinny03/guestcraft/blob/main/docs/architecture/security.md#3-cryptography
crypto_weaknesses SHOULD Met No default mechanism uses SHA-1 or CBC; hashes are SHA-256 and encryption is AES-256-GCM. https://github.com/Spinny03/guestcraft/blob/main/docs/architecture/security.md#3-cryptography
crypto_pfs SHOULD N/A GuestCraft implements no key-agreement protocol; TLS is negotiated by Node.js/OpenSSL and the hosting platform. https://github.com/Spinny03/guestcraft/blob/main/docs/architecture/security.md#3-cryptography
crypto_password_storage MUST Met Operator passwords are stored as scrypt hashes with a random 16-byte salt per password (Better Auth). https://github.com/Spinny03/guestcraft/blob/main/docs/architecture/security.md#3-cryptography
crypto_random MUST Met Keys, IVs, salts, tokens and identifiers come from crypto.getRandomValues or randomBytes; a lint rule rejects Math.random in the core. https://github.com/Spinny03/guestcraft/blob/main/packages/server/src/http/runtime.ts
delivery_mitm MUST Met The source is delivered only by GitHub over HTTPS or SSH. Vercel installs build from GitHub, and Docker base images are pinned by digest. https://github.com/Spinny03/guestcraft/blob/main/Dockerfile
delivery_unsigned MUST Met No hash is fetched over HTTP. Tool binaries are downloaded over HTTPS and checked against SHA-256 values committed in the repository; Actions are pinned by commit SHA. https://github.com/Spinny03/guestcraft/blob/main/tooling/requirements/tools.json
vulnerabilities_fixed_60_days MUST Met There is no published advisory for GuestCraft and no open Dependabot alert, and osv-scanner runs on every pull request and nightly. https://github.com/Spinny03/guestcraft/blob/main/.github/workflows/dependencies.yml
vulnerabilities_critical_fixed SHOULD Met SECURITY.md puts critical issues ahead of any other work. The 8 dependency advisories found when osv-scanner was introduced were fixed in the same change. https://github.com/Spinny03/guestcraft/blob/main/docs/quality/quality-program.md#43-osv-scanner
no_leaked_credentials MUST Met gitleaks scans all history reachable from the checked-out commit in the required quality check (in a pull request, main plus its commits), and GitHub secret scanning with push protection is on, with no alerts; fixtures use synthetic values only. https://github.com/Spinny03/guestcraft/blob/main/.github/workflows/quality.yml
Criterion Level Answer Justification Evidence
static_analysis MUST Met CodeQL default setup (JavaScript/TypeScript and GitHub Actions) runs on every pull request, every push to main and weekly. Biome, dependency-cruiser and Knip run in the required quality check. https://github.com/Spinny03/guestcraft/blob/main/.github/workflows/quality.yml
static_analysis_common_vulnerabilities SUGGESTED Met CodeQL’s default security queries detect injection, cross-site scripting, ReDoS and unsafe URL handling. https://github.com/Spinny03/guestcraft/security/code-scanning
static_analysis_fixed MUST Met CodeQL’s first scans on 2026-10-28 raised 9 open alerts. The 2 exploitable patterns (super-linear regular expressions on authenticated input, 3 alerts) were fixed the same day; the other 6 alerts are not exploitable (see the table below). https://github.com/Spinny03/guestcraft/blob/main/docs/quality/openssf-best-practices.md#codeql-alerts-of-2026-10-28
static_analysis_often SUGGESTED Met CodeQL and the quality check run on every pull request and every push to main. https://github.com/Spinny03/guestcraft/actions
dynamic_analysis SUGGESTED Met Every pull request runs fast-check property tests (1,000 cases) and Playwright end-to-end tests on the production build; nightly runs use 10,000 cases and StrykerJS mutation testing. https://github.com/Spinny03/guestcraft/blob/main/.github/workflows/nightly.yml
dynamic_analysis_unsafe SUGGESTED N/A GuestCraft is written in TypeScript, a memory-safe language. https://github.com/Spinny03/guestcraft
dynamic_analysis_enable_assertions SUGGESTED Met Property tests assert domain invariants on random inputs; the domain’s invariant checks are always enabled and throw InvariantError. https://github.com/Spinny03/guestcraft/blob/main/docs/adr/0005-testing-and-quality-gates.md
dynamic_analysis_fixed MUST Met No medium or higher vulnerability found by dynamic analysis is open; a failing property, end-to-end or mutation run blocks or is triaged within a working day. https://github.com/Spinny03/guestcraft/blob/main/docs/quality/quality-program.md#33-gates-that-must-be-green

The first CodeQL default-setup scans of the public repository reported these alerts. Each one was checked against the code that reaches it.

Alert Rule Location Assessment Action
#3, #6 js/redos, js/polynomial-redos packages/core/src/properties/index.ts Exploitable. The property time-zone pattern backtracked exponentially, and the API allows 64 characters, so one request could stall the server. Fixed: separators and name characters are disjoint; a regression test covers it
#1 js/polynomial-redos packages/auth/src/team.ts Exploitable. The invitation address pattern backtracked quadratically on a request body of up to 1 MiB. Fixed: linear pattern and a 254-character cap; a regression test covers it
#4 js/polynomial-redos packages/core/src/shared/measures.ts Not reachable: no production code calls the area and length parsers. Dismiss as “won’t fix”; make it linear when the parsers get a caller
#5 js/polynomial-redos packages/ui/src/components/money-input.tsx Runs in the operator’s own browser on their own input; it cannot affect anyone else. Dismiss as “won’t fix”
#2 js/polynomial-redos packages/channex-client/src/transport.ts Applies only to the configured Channex base URL, never to request input. Dismiss as “won’t fix”
#7, #8, #10 js/bad-tag-filter, js/incomplete-url-substring-sanitization, js/incomplete-hostname-regexp test files Assertions in tests, not sanitizers in shipped code. Dismiss as “used in tests”

Silver requires passing first. Its 55 criteria (44 MUST) add, among others: governance, roles and access continuity (governance, roles_responsibilities, access_continuity, bus_factor); a code of conduct; a roadmap, architecture, security and quick-start documentation, all current; DCO; coding standards that are enforced; repeatable builds and a standard installation; dependency monitoring and updateable components; integration tests, regression tests for at least half of the bugs and 80% statement coverage; signed releases; documented input validation, hardening and an assurance case; vulnerability-report credit and a documented response process; TLS 1.2 and certificate verification for network cryptography.

Many are already in place (GOVERNANCE.md, CODE_OF_CONDUCT.md, ADRs, the security design, Biome, Renovate and Dependabot, PostgreSQL integration tests, coverage thresholds). The known gaps are the following:

  • bus_factor: one maintainer.
  • access_continuity: repository access and release credentials are not shared yet (GOVERNANCE.md, “Continuity”).
  • signed_releases: the release workflow signs image provenance and SBOM attestations through Sigstore, but no release has run yet (quality program row 24).
  • documentation_roadmap: no published roadmap for the next year.
  • assurance_case: no assurance case yet; the security design is its starting point.

Assess silver in this file after the passing badge is awarded.