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:

  • protoc 3.x or newer — required to build the gRPC daemon.
  • cmake 3.x or newer plus a C compiler — required for the aws-lc-rs backend.
  • LLVM/Clang with LIBCLANG_PATH set — required for aws-lc-rs on Windows.
  • Go 1.21 or newer — required for the Enterprise craton-hsm-awslc crate with the fips feature.

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/.
  • unsafe blocks carry a // SAFETY: comment explaining the invariant.
  • No key material in logs or Debug output ([REDACTED] is the convention).
  • CHANGELOG.md updated 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 classInitial responseDecision target
Security fix (embargoed)1 business day3 business days
Bug fix (regression)2 business days5 business days
Feature / enhancement3 business days5 business days
Documentation only3 business days5 business days
Dependency bump3 business days5 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 Debug impls that print [REDACTED]. Never println!("{:?}", key) even in tests.
  • Zeroize on drop. All key material must live inside RawKeyMaterial, which provides mlock plus ZeroizeOnDrop.
  • Constant-time comparison. Use subtle::ConstantTimeEq for every secret comparison. Do not compare PINs, HMACs, or signatures with ==.
  • catch_unwind. Every extern "C" function wraps its body in catch_unwind; unwinding across the FFI boundary is undefined behaviour.
  • unsafe is confined. All unsafe lives in the ABI layer and the mlock wrappers; safe modules (audit, session, config, store, token) carry #![forbid(unsafe_code)].

Where to File

KindWhere
Bug reportGitHub Issues (bug_report.yml template)
Feature requestGitHub Issues (feature_request.yml template)
Usage / how-toGitHub Discussions
Security vulnerabilitySee security-advisories
Commercial licensinglicensing@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.