OpenSSF Best Practices: passing-level self-assessment
Questi contenuti non sono ancora disponibili nella tua lingua.
- Status: prepared on 2026-10-28 against
main. The project is not registered yet, and no badge has been awarded. - Criteria: passing level, read on 2026-10-28
(67 criteria, from the badge project’s
criteria.yml) - Related: quality program gap row 25, security design, releasing, SECURITY.md
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.
Summary
Section titled “Summary”| 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.
What the maintainer has to do
Section titled “What the maintainer has to do”- 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. ItsvX.Y.Ztag and published GitHub Release with the changelog section meetrelease_notes(MUST) and the suggestedversion_semverandversion_tags. Until then, answerrelease_notesUnmet. 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 torelease_notes_vulns, not torelease_notes. - Confirm the secure-development statements.
know_secure_designandknow_common_errorsask 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. - 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. - Publish a dedicated security contact address in MAINTAINERS.md (not required for passing; private vulnerability reporting already meets it).
- After the badge is awarded, add its badge to the README and set quality program row 25 to
done. The OpenSSF Scorecard
CII-Best-Practicescheck then stops scoring 0.
Basics
Section titled “Basics”| 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 |
Change control
Section titled “Change control”| 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 |
Reporting
Section titled “Reporting”| 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 |
Quality
Section titled “Quality”| 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 |
Security
Section titled “Security”| 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 |
Analysis
Section titled “Analysis”| 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 |
CodeQL alerts of 2026-10-28
Section titled “CodeQL alerts of 2026-10-28”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” |
Next step: silver
Section titled “Next step: silver”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.