Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
35c1a9b
feat(v0.0.9): workspace conversion + Phase 0 security hot-fixes
sebastienrousseau May 19, 2026
f687960
docs(v0.0.9): SECURITY.md, CHANGELOG.md, ADR-0006
sebastienrousseau May 19, 2026
2555b74
feat(v0.0.9): Phase 1 — RustCrypto migration, PHC, verify_and_upgrade
sebastienrousseau May 19, 2026
2b2af6d
feat(v0.0.9): Phase 2 — operational hardening
sebastienrousseau May 19, 2026
23cc102
feat(v0.0.9): Phase 3 — pepper / KMS integration
sebastienrousseau May 19, 2026
2f05b50
feat(v0.0.9): Phase 4 — PBKDF2 + Backend(FIPS) contract
sebastienrousseau May 19, 2026
115c467
feat(v0.0.9): Phase 5 — hsh-cli, packaging, migration guides
sebastienrousseau May 19, 2026
903595e
feat(v0.0.9): Phase 6 — hsh-digest general-purpose hashing crate
sebastienrousseau May 19, 2026
af89d77
docs(v0.0.9): Phase 7 — v1.0 stabilisation contract + runbooks
sebastienrousseau May 19, 2026
ac1de91
refactor(policy): builder pattern + workspace lints + CI hygiene
sebastienrousseau May 19, 2026
425826a
docs: per-crate READMEs + 9 themed examples + 43 coverage tests + BEN…
sebastienrousseau May 19, 2026
c5e0edc
ci: fix workspace clippy, cargo-deny, cargo-hack, Miri, CodeQL config
sebastienrousseau May 19, 2026
97ef043
ci: cargo fmt — wrap compile_error cfg attrs
sebastienrousseau May 19, 2026
ce1c9e1
ci(codeql): drop top-level paths to keep actions-language discovery w…
sebastienrousseau May 19, 2026
537107e
fix(hsh-digest): gate `use digest::Digest` on sha2/sha3 features
sebastienrousseau May 19, 2026
e8e3d72
ci: pin actions to commit SHAs + add explicit permissions
sebastienrousseau May 19, 2026
68bcfc3
ci: drop workflow-level permissions:{} that broke reusable callers
sebastienrousseau May 19, 2026
ee30cf7
ci: per-job permissions, drop reusable security, add local dep-review
sebastienrousseau May 19, 2026
fef1914
ci: switch from upstream tarpaulin to local cargo-llvm-cov
sebastienrousseau May 19, 2026
a4d4c34
ci(codeql): move hsh-kms inline tests to tests/ + Noyalib-Standard RE…
sebastienrousseau May 19, 2026
9d114b3
ci(codacy): silence markdownlint rules incompatible with Noyalib READ…
sebastienrousseau May 19, 2026
c449202
ci(codacy): disable remark-lint + exclude all prose paths
sebastienrousseau May 19, 2026
1ca2342
ci(codacy): broaden doc/ exclude to cover top-level files
sebastienrousseau May 19, 2026
1cbfb1c
ci(codacy): quote $(uname -m) substitution in Dockerfile
sebastienrousseau May 19, 2026
e937043
ci: add MSRV gate, cross-platform tests, clippy.toml workspace knobs
sebastienrousseau May 19, 2026
c7d57ae
test: property tests for hsh-digest, insta snapshots for hsh-cli, bro…
sebastienrousseau May 19, 2026
535a04e
feat(api)!: breaking — Outcome reshape, AsRef<[u8]> passwords, struct…
sebastienrousseau May 19, 2026
0418a86
ci: fix MSRV / Windows / Coverage jobs added in e937043
sebastienrousseau May 19, 2026
5075457
docs: refresh crate-level //! and add # Errors sections workspace-wide
sebastienrousseau May 19, 2026
9c7cb08
ci: drop unworkable MSRV 1.75 lib job + gate help-snapshot tests to unix
sebastienrousseau May 19, 2026
db8f96e
test: push coverage from 73.77% -> 82.30% lines
sebastienrousseau May 19, 2026
cb95d8e
test: algorithm trait + branch coverage (82.30 -> 83.24% lines)
sebastienrousseau May 19, 2026
121a62a
test: branch coverage push (83.24 -> 89.31% lines)
sebastienrousseau May 20, 2026
0a6abf5
test: 89.31 -> 91.61% line coverage
sebastienrousseau May 20, 2026
f51017e
test: 91.61 -> 92.83% line coverage (94.38% region)
sebastienrousseau May 20, 2026
a636406
test: 92.83 -> 93.49% lines / 94.81% regions (final coverage push)
sebastienrousseau May 20, 2026
4800213
ci(msrv): bump workspace floor 1.85 → 1.88 for rpassword 7.5 let-chains
sebastienrousseau May 20, 2026
2a98e07
docs(readme): apply v0.0.9 release-prep critique
sebastienrousseau May 20, 2026
69beb1f
chore(repo): align workspace structure with noyalib standard
sebastienrousseau May 20, 2026
b4e22c4
ci(codacy): exclude crates/*/doc/** + new top-level docs
sebastienrousseau May 20, 2026
d5c1ab7
docs(crates): flesh out per-crate doc/ with README + guides
sebastienrousseau May 20, 2026
7e4af97
docs: drop the misplaced doc/README.md index files
sebastienrousseau May 20, 2026
513fe0a
test: 93.49 -> 95.87% lines (hit the 95% mandate)
sebastienrousseau May 20, 2026
b6d9c2c
ci(coverage): raise --fail-under-lines from 93 → 95 + exclude legacy …
sebastienrousseau May 20, 2026
fb94ded
ci(clippy): silence rand::* path-not-reachable warnings
sebastienrousseau May 20, 2026
6196673
chore(qa): achieve 95%+ coverage, implement fuzzing/benches, and guar…
sebastienrousseau May 20, 2026
d453d45
fix(api): Phase 1 correctness — scrypt policy, rehash drift, calibrat…
sebastienrousseau May 21, 2026
34a567e
fix(api): P0-2 — bcrypt prehash mode now round-trips end-to-end
sebastienrousseau May 21, 2026
a9d3647
docs: P0-3 — align readiness claims for KMS / FIPS + correct stale Ou…
sebastienrousseau May 21, 2026
cd7b5a0
feat(cli): P1-3 — hsh inspect-backend + richer calibrate JSON + OPERA…
sebastienrousseau May 21, 2026
a90c223
docs: P2-1 — passkey-era positioning + hybrid-auth recipes
sebastienrousseau May 21, 2026
5acb078
docs: P2-2 — IP / standards governance — patent watchlist + annual re…
sebastienrousseau May 21, 2026
66b51f3
build(deps): consolidate eligible dependabot bumps + fix Miri timeout
sebastienrousseau May 21, 2026
17fc606
fix(docs+examples): regression-pass corrections
sebastienrousseau May 21, 2026
8259234
docs: deep consistency pass — kill remaining drift across the doc tree
sebastienrousseau May 21, 2026
445dfbe
build(deps): bump bcrypt / log / assert_cmd (rolls in #175 #176 #177)
sebastienrousseau May 23, 2026
b8f13ab
ci: retrigger Codacy after stale ACTION_REQUIRED on 445dfbe
sebastienrousseau May 23, 2026
b79fd8f
ci: upload coverage to Codacy so the diff-coverage gate can resolve
sebastienrousseau May 23, 2026
5807f0e
ci: drop Codacy
sebastienrousseau May 23, 2026
d3f897d
ci: confirm Codacy is detached
sebastienrousseau May 23, 2026
28df616
release: prep v0.0.9 — CHANGELOG cut, docs publish workflow, release.…
sebastienrousseau May 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .github/codeql/codeql-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: CodeQL config for `hsh`

# Path filters for the CodeQL analysis. Test / example / bench / fuzz
# code legitimately carries hard-coded passwords, salts, and KDF
# parameters as fixtures — those are *not* security issues.
#
# Production code under `crates/*/src/` is analysed normally; so are
# the workflow YAMLs under `.github/workflows/` for the `actions`
# language. We use `paths-ignore` exclusively here so language
# discovery isn't restricted (a top-level `paths:` would scope
# everything to those globs, including GitHub Actions YAMLs).

paths-ignore:
- crates/*/tests/**
- crates/*/examples/**
- crates/*/benches/**
- fuzz/fuzz_targets/**
- pkg/**

# Queries are the defaults. The `rust/hard-coded-cryptographic-value`
# rule is *expected* to fire in test/example/bench/fuzz code (which is
# why we exclude those paths above); for any production-code finding
# we want the alert.
queries:
- uses: security-and-quality
26 changes: 21 additions & 5 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
version: 2
updates:
- package-ecosystem: "cargo"
- package-ecosystem: cargo
directory: "/"
schedule:
interval: "daily"

- package-ecosystem: "github-actions"
interval: weekly
day: monday
time: "09:00"
timezone: "UTC"
open-pull-requests-limit: 10
groups:
minor-and-patch:
update-types: [minor, patch]
labels: ["dependencies", "rust"]
commit-message:
prefix: "chore(deps)"
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: "daily"
interval: weekly
day: monday
time: "09:00"
timezone: "UTC"
open-pull-requests-limit: 5
labels: ["dependencies", "github-actions"]
commit-message:
prefix: "chore(deps)"
15 changes: 15 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
documentation:
- changed-files:
- any-glob-to-any-file: ['**/*.md', 'docs/**']
rust:
- changed-files:
- any-glob-to-any-file: ['**/*.rs', 'Cargo.toml', 'Cargo.lock']
ci:
- changed-files:
- any-glob-to-any-file: ['.github/workflows/**']
tests:
- changed-files:
- any-glob-to-any-file: ['**/tests/**', '**/*_test.rs']
dependencies:
- changed-files:
- any-glob-to-any-file: ['Cargo.lock']
28 changes: 0 additions & 28 deletions .github/workflows/audit.yml

This file was deleted.

24 changes: 0 additions & 24 deletions .github/workflows/check.yml

This file was deleted.

214 changes: 214 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
name: CI
on:
push:
branches: [main, feat/**]
pull_request:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

# Minimum permissions are declared per-job (workflow level intentionally
# omitted so reusable callers can still claim what they need).

jobs:
ci:
uses: sebastienrousseau/pipelines/.github/workflows/rust-ci.yml@main
permissions:
contents: read
pull-requests: read
with:
rust-version: 'stable'
# Upstream's tarpaulin-based coverage step trips `ld.so` assertions
# under our `-Clink-dead-code` + heavy-generic surface (clap + serde
# derive in hsh-cli). We run coverage locally via cargo-llvm-cov below,
# which is more stable on that workload.
run-coverage: false

# Note: we previously called sebastienrousseau/pipelines's security
# reusable workflow, but its CodeQL job doesn't accept a
# `config-file` input — so test/example fixtures kept tripping
# `rust/hard-coded-cryptographic-value`. CodeQL now runs only from
# the local `codeql.yml` (which pins `.github/codeql/codeql-config.yml`),
# cargo-audit / cargo-deny live in `supply-chain.yml`, and the
# dependency-review piece is inlined below.
coverage:
name: Coverage (cargo-llvm-cov)
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 1
persist-credentials: false
- uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # master
with:
toolchain: stable
components: llvm-tools-preview
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@213ccc1a076163c093f914550b94feb90fab916d # v2.79.2
with:
tool: cargo-llvm-cov
- name: Generate coverage + enforce threshold
# --fail-under-lines = 95 enforced workspace-wide after the
# extracted-helpers refactor in `api.rs` (see CHANGELOG v0.0.9).
# Workspace region coverage sits at 98%+.
#
# --ignore-filename-regex excludes files whose lines are
# structurally untestable from external input:
# - KMS stub provider files (aws/gcp/azure/vault.rs) — stub
# interfaces awaiting real network impls
# - hsh/src/lib.rs (binary entry-point boilerplate)
# - hsh-cli/src/main.rs (bin entry shim)
# - hsh/src/algorithms/{argon2id,bcrypt,scrypt,pbkdf2}.rs —
# thin wrappers over RustCrypto crates whose remaining
# uncovered lines are `.map_err` closures fired only by
# internal-primitive failures (e.g. argon2 hash_password
# rejecting params that Params::new already validated).
# The RustCrypto crates have their own test suites.
# - hsh/src/models/hash.rs — legacy compat-v0_0_x surface,
# scheduled for removal in v0.2.0 per doc/API-STABILITY.md.
run: |
cargo llvm-cov --workspace --all-features --lcov \
--ignore-filename-regex '(crates/hsh-kms/src/(aws|gcp|azure|vault)\.rs|crates/hsh/src/lib\.rs|crates/hsh-cli/src/main\.rs|crates/hsh/src/algorithms/(argon2id|bcrypt|scrypt|pbkdf2)\.rs|crates/hsh/src/models/hash\.rs)' \
--fail-under-lines 95 \
--output-path lcov.info
- name: Upload to Codecov
uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1
with:
files: lcov.info
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: false

dependency-review:
name: Dependency Review
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 1
persist-credentials: false
- uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4.9.0
with:
fail-on-severity: moderate

docs:
if: github.ref == 'refs/heads/main'
uses: sebastienrousseau/pipelines/.github/workflows/docs.yml@main
permissions:
contents: write
pages: write
id-token: write
with:
type: rust
redirect-crate: hsh

feature-checks:
name: Feature permutations (cargo-hack)
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # master
with:
toolchain: stable
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
- name: Install cargo-hack
uses: taiki-e/install-action@213ccc1a076163c093f914550b94feb90fab916d # v2.79.2
with:
tool: cargo-hack
- name: Check feature powerset (excl. hsh-digest)
# `--no-dev-deps` skips features that only exist for dev to keep
# the matrix size sane; `--exclude-features` skips the FIPS marker
# since enabling it without a real backend changes no behaviour.
run: cargo hack check --workspace --exclude hsh-digest --feature-powerset --no-dev-deps --exclude-features fips
- name: Check feature powerset (hsh-digest, at-least-one algorithm)
# hsh-digest requires at least one of sha2/sha3/blake3 — the
# empty feature set is rejected by a `compile_error!`.
run: cargo hack check -p hsh-digest --feature-powerset --no-dev-deps --at-least-one-of sha2,sha3,blake3

public-api:
name: Public API diff vs main
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: false
- uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # master
with:
toolchain: nightly
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
- name: Install cargo-public-api
uses: taiki-e/install-action@213ccc1a076163c093f914550b94feb90fab916d # v2.79.2
with:
tool: cargo-public-api
- name: Diff public API
# Advisory only — flags additions/removals for reviewer attention.
# A breaking removal must be paired with a semver-major intent
# per doc/API-STABILITY.md.
run: |
cargo public-api --diff-git-checkouts origin/main HEAD --simplified -p hsh || true
cargo public-api --diff-git-checkouts origin/main HEAD --simplified -p hsh-kms || true
cargo public-api --diff-git-checkouts origin/main HEAD --simplified -p hsh-digest || true

msrv-1-88:
name: MSRV — workspace minimum (1.88)
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # master
with:
toolchain: "1.88"
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
key: msrv-1.88
- name: Workspace check at 1.88 floor
# The *workspace* effective floor is 1.88:
# - `hsh-cli` uses edition = "2024" (needs Cargo 1.85+).
# - The `rpassword` 7.5+ dep uses `let` chains (stable in 1.88).
# The library crates declare `rust-version = "1.75"` for
# downstream consumability (documentation only — downstream
# consumers depend on the lib crates without pulling `hsh-cli`
# into their workspace, so they keep the 1.75 floor).
run: cargo +1.88 check --locked --workspace --all-features

cross-platform:
name: Test (${{ matrix.os }})
runs-on: ${{ matrix.os }}
permissions:
contents: read
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # master
with:
toolchain: stable
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
key: ${{ matrix.os }}
- name: cargo test --locked --workspace
# --locked = fail if Cargo.lock would change.
# --no-fail-fast = let the matrix see every failure, not just the first.
run: cargo test --locked --workspace --all-features --no-fail-fast
Loading
Loading