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.
- 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.
- 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.
- 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-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 |
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 |
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.