Craton HSM
Contributing
Contributing
This page covers how to contribute code, documentation, or bug reports to
Craton HSM. The canonical CONTRIBUTING.md in each repository remains the
source of truth; this page summarises the workflow and calls out the
points that trip people up the first time.
CLA, not DCO
Craton HSM uses a Contributor License Agreement, not a Developer Certificate of Origin. On your first pull request the CLA Assistant bot posts a comment with a sign-off instruction; replying to that comment records your acceptance. The CLA is one-time and covers all future pull requests from the same GitHub account.
The CLA grants the project maintainer (Craton Inc.) the rights to distribute your contribution under the project license and to re-license it for the Enterprise workspace, which ships under BSL-1.1. Without those rights the dual-license model would not be possible, which is why a DCO is not sufficient here. See license for the legal detail.
Before You Start
- Read ../reference/faq and ../reference/compatibility-matrix to confirm the feature or platform you're targeting is in scope.
- For large changes, open a GitHub issue or discussion first. Architecture changes, new public API surface, and dependency bumps with non-trivial transitive surface benefit from an ADR-style discussion before the first commit.
- Security-impacting changes should go through the private channel in security-advisories, not a public PR.
Development Setup
Prerequisites:
- Rust 1.75 or newer (install via rustup). 1.75 is the MSRV; CI tests both stable and 1.75.
- Git.
Optional, only if you touch the relevant workspace members:
protoc3.x or newer — required to build the gRPC daemon.cmake3.x or newer plus a C compiler — required for theaws-lc-rsbackend.- LLVM/Clang with
LIBCLANG_PATHset — required foraws-lc-rson Windows. - Go 1.21 or newer — required for the Enterprise
craton-hsm-awslccrate with thefipsfeature.
Clone and build:
git clone https://github.com/craton-co/craton-hsm-core.git
cd craton-hsm-core
cargo build
cargo build --workspace
Running the Tests
PKCS#11 defines a single global state per process
(C_Initialize / C_Finalize). If tests run in parallel, they race on
the global OnceLock<Arc<HsmCore>>. Always pass --test-threads=1:
cargo test -- --test-threads=1
cargo test --features awslc-backend -- --test-threads=1
For special suites:
cargo test --test zeroization -- --ignored --test-threads=1
cargo test --test persistence -- --test-threads=1
CI splits the Core test suite into two jobs: a parallel-safe crypto
subset (--test-threads=8) and a serial PKCS#11 ABI subset
(--test-threads=1). The cargo-nextest evaluation that would eliminate
this split entirely is a near-term roadmap item.
Fuzz targets use cargo-fuzz on nightly:
cargo install cargo-fuzz
cargo +nightly fuzz run fuzz_c_abi -- -max_total_time=300
Linting
cargo fmt --check
cargo clippy -- -D warnings
cargo fmt is the formatter and is not negotiable. Clippy warnings are
denied in CI.
Commit Style
The project does not enforce Conventional Commits but strongly prefers a short, imperative subject line (under ~72 characters) followed by a body that explains why the change is made, not just what. Reference the issue number when applicable.
Fix per-key AES-GCM nonce-counter allocation
The counter was global across all keys, which meant a multi-key workload
could hit the 2^32 birthday bound prematurely. Switch to per-key counters
keyed on the SHA-256 of key material.
Fixes #412.
Sign tags and release commits with GPG; see the Enterprise
MAINTAINERS.md release section.
Pull Request Checklist
- CLA signed (the bot will prompt on first PR).
- Tests pass (
cargo test -- --test-threads=1). - No clippy warnings (
cargo clippy -- -D warnings). - Formatted (
cargo fmt). - New functionality has tests. Integration tests go in
tests/. unsafeblocks carry a// SAFETY:comment explaining the invariant.- No key material in logs or
Debugoutput ([REDACTED]is the convention). CHANGELOG.mdupdated under## [Unreleased]for user-facing changes.- Documentation updated in the same PR for any affected behaviour.
Review Process
The repository uses a CODEOWNERS file and GitHub branch protection to
route reviews. On the Enterprise side, paths under craton-hsm-auth,
craton-hsm-certified, craton-hsm-awslc, craton-hsm-openssl, and
craton-hsm-pkcs11 additionally require a review from the security team
because a bug in those paths has a direct path to key compromise, auth
bypass, or FIPS non-compliance.
Review SLA (Enterprise; Core targets are similar):
| PR class | Initial response | Decision target |
|---|---|---|
| Security fix (embargoed) | 1 business day | 3 business days |
| Bug fix (regression) | 2 business days | 5 business days |
| Feature / enhancement | 3 business days | 5 business days |
| Documentation only | 3 business days | 5 business days |
| Dependency bump | 3 business days | 5 business days |
If no maintainer has responded within SLA, @-mention @craton-inc/core-team
on the PR or email engineering@craton.io.
Code Guidelines for Cryptographic Paths
This is a cryptographic module. Crypto-sensitive code carries extra rules on top of the usual style guidance:
- No key bytes anywhere visible. Use the custom
Debugimpls that print[REDACTED]. Neverprintln!("{:?}", key)even in tests. - Zeroize on drop. All key material must live inside
RawKeyMaterial, which providesmlockplusZeroizeOnDrop. - Constant-time comparison. Use
subtle::ConstantTimeEqfor every secret comparison. Do not compare PINs, HMACs, or signatures with==. catch_unwind. Everyextern "C"function wraps its body incatch_unwind; unwinding across the FFI boundary is undefined behaviour.unsafeis confined. Allunsafelives in the ABI layer and themlockwrappers; safe modules (audit,session,config,store,token) carry#![forbid(unsafe_code)].
Where to File
| Kind | Where |
|---|---|
| Bug report | GitHub Issues (bug_report.yml template) |
| Feature request | GitHub Issues (feature_request.yml template) |
| Usage / how-to | GitHub Discussions |
| Security vulnerability | See security-advisories |
| Commercial licensing | licensing@craton.io |
Good bug reports include the crate and version, the exact cargo command,
rustc --version, OS and architecture, the feature flags enabled, and a
minimal reproducer. Redact secrets, PINs, and identifiers before posting;
for reports that require sensitive material, file a redacted public
report and send the sensitive parts to security@craton.io.
Why is Cargo.lock committed?
Craton HSM ships both a library (rlib) and a shared library (cdylib).
The cdylib is a final build artefact loaded by PKCS#11 consumers, so
Cargo.lock is checked in for reproducible builds. This matches the
Cargo FAQ
recommendation for binary/artefact projects.