Deterministic auth, TLS, webhook, token, and test fixtures with metadata-only audit receipts.
uselesskey is a test-fixture factory, not a crypto library. It generates deterministic auth, TLS, webhook, token, and test fixtures; keeps raw generated material out of git by default; audits what was generated; and makes the proof boundary explicit.
Pick the job first; the repo proof machinery is behind links when you need it.
| I need to... | Start with | Copy this |
|---|---|---|
| use fixtures in Rust tests | facade crate | uselesskey = { version = "0.10.0", features = ["rsa"] } |
| generate deterministic bundles on disk | installed CLI | uselesskey bundle --profile scanner-safe --out target/uselesskey-bundle |
| test webhook, TLS, or OIDC/JWKS verifier paths | contract-pack profiles | uselesskey profiles |
| fail CI on bundle drift | downstream policy pack | uselesskey audit-bundle --path target/uselesskey-webhook --ci --expect-profile webhook --policy strict |
| share a reviewer packet without cloning the repo | installed bundle audit | uselesskey audit-bundle --path target/uselesskey-webhook --out target/uselesskey-webhook-audit |
| prove repo public claims from a checkout | repo verification pack | cargo xtask verification-pack --out target/uselesskey-verification |
Install the CLI when you want fixture bundles outside this workspace:
cargo install uselesskey-cli --version 0.10.0
uselesskey doctor
uselesskey profiles
uselesskey bundle --profile webhook --explainGenerate, verify, inspect, and audit a webhook bundle:
uselesskey bundle --profile webhook --out target/uselesskey-webhook
uselesskey verify-bundle --path target/uselesskey-webhook
uselesskey inspect-bundle --path target/uselesskey-webhook
uselesskey audit-bundle --path target/uselesskey-webhook --out target/uselesskey-webhook-auditUse --ci --expect-profile <profile> --policy strict when the audit is part
of a downstream CI gate:
uselesskey audit-bundle --path target/uselesskey-webhook --ci --expect-profile webhook --policy strictRust test authors start with the facade crate:
[dev-dependencies]
uselesskey = { version = "0.10.0", features = ["rsa"] }Then generate deterministic fixtures at runtime:
use uselesskey::{Factory, RsaFactoryExt, RsaSpec};
let fx = Factory::deterministic_from_str("test-seed");
let key = fx.rsa("issuer", RsaSpec::rs256());
let pkcs8_pem = key.private_key_pkcs8_pem();Reviewer and maintainer proof is repo-local. From a checkout, public claims can be packaged as a metadata-only proof bundle:
cargo xtask verification-pack --out target/uselesskey-verificationWhat this does not prove:
- production key generation, key custody, or secret management;
- production PKI, provider compatibility, or webhook delivery semantics;
- permission to commit generated secret-shaped payloads;
- downstream verifier correctness;
- repo public claims unless you run the repo-local proof commands.
Start with docs/how-to/start-here.md for the task router, docs/reference/bundle-inspect-vs-audit.md for the inspect/audit split, or docs/status/PUBLIC_CLAIMS.md for the full proof index.
uselesskey is a test-fixture layer, not a runtime crypto service.
Use it when you need realistic cryptographic fixtures without committing PEM/DER/JWK files.
It exists to remove this test friction:
- scanners inspect every commit in a PR, not just the final diff
- fake-looking keys still trigger policy, push protection, and review friction
uselesskey replaces security exceptions + path ignores + fixture directories with one dev-dependency and runtime generation.
Do not use this crate for production key generation or certificate management. Deterministic mode is intentionally predictable by design. Random mode is for tests only.
Without this layer, teams commonly end up with one of these:
| Approach | Problem |
|---|---|
| Commit PEM/DER files | Triggers scanners and push protection |
| Generate keys ad hoc in tests | Repeated boilerplate, slow RSA, no shared determinism |
| Use raw crypto crates directly | You still have to assemble PEM/DER/JWK/X.509 shapes yourself |
Use rcgen or other runtime crates directly |
Useful, but not centered on fixture ergonomics, determinism, or negative cases |
uselesskey is built specifically for test artifacts.
- RSA (2048, 3072, 4096)
- ECDSA (P-256, P-384)
- Ed25519
- HMAC (HS256, HS384, HS512)
- OpenPGP (RSA 2048/3072, Ed25519)
- Token fixtures (API key, bearer, OAuth access-token / JWT shape)
- X.509 self-signed certificates and certificate chains
- PKCS#8 PEM/DER
- SPKI PEM/DER
- OpenPGP armored and binary keyblocks
- JWK / JWKS
- tempfiles for path-based APIs
- X.509 leaves and chains, and negative variants
- corrupt PEM
- truncated DER
- mismatched keypairs
- expired / revoked / hostname-mismatch / unknown-CA certificates
Start with the cheapest lane that preserves the test's semantics.
| I need | Recommended lane | Why |
|---|---|---|
| entropy / scanner-shape only | uselesskey-entropy or facade features = ["entropy"] |
deterministic bytes without key-generation baggage |
| JWT / bearer / API-token shapes only | uselesskey-token or facade features = ["token"] |
token-shaped fixtures without RSA/X.509 pull-in |
| valid runtime crypto semantics | leaf crates such as uselesskey-rsa, uselesskey-x509, uselesskey-ssh |
real PKCS#8/JWK/X.509/SSH fixture behavior |
| build-time materialized fixtures | uselesskey-cli materialize + verify |
clean shape-only OUT_DIR / include_bytes! workflow, with RSA materialization as an explicit opt-in |
| reproducible fixture bundles + handoff | uselesskey-cli bundle + verify-bundle + inspect-bundle + export |
deterministic scanner-safe bundle of fixtures, manifest, and receipts; Kubernetes/Vault payload handoff without committing real secrets |
Start with docs/how-to/choose-features.md for feature selection. Use docs/how-to/choose-lane.md when deciding between entropy, token, semantic, and materialized fixture workflows. See docs/reference/dependency-economics.md and docs/reference/audit-surface.md for the current local-cost and advisory receipts.
The uselesskey facade has an empty default feature set. Enable only the fixture families you need.
Common starting points:
# Entropy-only fixtures
[dev-dependencies]
uselesskey = { version = "0.10.0", default-features = false, features = ["entropy"] }# RSA fixtures
[dev-dependencies]
uselesskey = { version = "0.10.0", features = ["rsa"] }# Token-only fixtures, no RSA/X.509 pull-in
[dev-dependencies]
uselesskey = { version = "0.10.0", default-features = false, features = ["token"] }# RSA + JWK/JWKS
[dev-dependencies]
uselesskey = { version = "0.10.0", features = ["rsa", "jwk"] }# X.509 fixtures
[dev-dependencies]
uselesskey = { version = "0.10.0", features = ["x509"] }The following materialization commands are repo-checkout examples. Installed
CLI users can run the same subcommands as uselesskey materialize ... and
uselesskey verify ....
# Build-time materialization, shape-only common lane
cargo run -p uselesskey-cli -- materialize --manifest crates/materialize-shape-buildrs-example/uselesskey-fixtures.toml --out-dir target/tmp-fixtures
cargo run -p uselesskey-cli -- verify --manifest crates/materialize-shape-buildrs-example/uselesskey-fixtures.toml --out-dir target/tmp-fixturesFor build.rs consumers:
# Common shape-only build-time path
[build-dependencies]
uselesskey-cli = { version = "0.10.0", default-features = false }# Specialized RSA PKCS#8 build-time path
[build-dependencies]
uselesskey-cli = { version = "0.10.0", default-features = false, features = ["rsa-materialize"] }Use the facade for convenience. Depend on leaf crates only when compile-time minimization matters enough to justify the sharper API.
If you are unsure which flags to start with, start from docs/how-to/choose-features.md. For downstream bot/reviewer policy, use docs/how-to/downstream-fixture-policy.md. For a crate-by-crate support contract (stable/incubating/experimental, audience, and publish status), see docs/reference/support-matrix.md.
use uselesskey::{Factory, RsaFactoryExt, RsaSpec};
// Random mode: different keys every run
let fx = Factory::random();
// Deterministic mode: stable output for a seed string
let fx = Factory::deterministic_from_str("my-test-seed");
// Or use env-var seed with random fallback
let fx = Factory::deterministic_from_env("USELESSKEY_SEED")
.unwrap_or_else(|_| Factory::random());
let rsa = fx.rsa("issuer", RsaSpec::rs256());
let pkcs8_pem = rsa.private_key_pkcs8_pem();
let spki_der = rsa.public_key_spki_der();The core shape is always:
(mode, domain, label, spec, variant) -> artifact
That keeps fixtures stable in deterministic mode and cacheable in both modes.
rsafor PEM/DER, tempfiles, and negative-key examplesrsa+jwkforpublic_jwk()/public_jwks()x509for certificate, rustls, and tonic examplestokenfor token-shaped fixtures onlypgpfor armored/binary OpenPGP fixtures
Dependency snippets:
-
Quick start (RSA)
[dev-dependencies] uselesskey = { version = "0.10.0", features = ["rsa"] }
-
Token-only
[dev-dependencies] uselesskey = { version = "0.10.0", default-features = false, features = ["token"] }
-
JWT/JWK
[dev-dependencies] uselesskey = { version = "0.10.0", features = ["rsa", "jwk"] }
-
X.509 + rustls
[dev-dependencies] uselesskey = { version = "0.10.0", features = ["x509"] } uselesskey-rustls = { version = "0.10.0", features = ["tls-config", "rustls-ring"] }
-
jsonwebtoken adapter
[dev-dependencies] uselesskey = { version = "0.10.0", features = ["rsa", "ecdsa", "ed25519", "hmac"] } uselesskey-jsonwebtoken = { version = "0.10.0" }
Requires features = ["rsa", "jwk"].
use uselesskey::{Factory, RsaSpec, RsaFactoryExt};
let fx = Factory::random();
let rsa = fx.rsa("issuer", RsaSpec::rs256());
let jwk = rsa.public_jwk();
let jwks = rsa.public_jwks();use uselesskey::{Factory, RsaSpec, RsaFactoryExt};
let fx = Factory::random();
let rsa = fx.rsa("server", RsaSpec::rs256());
let keyfile = rsa.write_private_key_pkcs8_pem().unwrap();
assert!(keyfile.path().exists());Requires features = ["x509"].
Self-signed certificates for simple TLS tests:
use uselesskey::{Factory, X509FactoryExt, X509Spec};
let fx = Factory::random();
let cert = fx.x509_self_signed("my-service", X509Spec::self_signed("test.example.com"));
let cert_pem = cert.cert_pem();
let key_pem = cert.private_key_pkcs8_pem();Three-level chains (root intermediate leaf):
use uselesskey::{Factory, X509FactoryExt, ChainSpec};
let fx = Factory::random();
let chain = fx.x509_chain("my-service", ChainSpec::new("test.example.com"));
// Standard TLS server chain: leaf + intermediate, no root
let chain_pem = chain.chain_pem();
// Individual artifacts for custom setups
let root_pem = chain.root_cert_pem();
let leaf_key = chain.leaf_private_key_pkcs8_pem();These are for error-path tests, not validation logic.
use uselesskey::{Factory, X509FactoryExt, ChainSpec};
let fx = Factory::random();
let chain = fx.x509_chain("my-service", ChainSpec::new("test.example.com"));
// Expired leaf certificate
let expired = chain.expired_leaf();
// Hostname mismatch (SAN doesn't match expected hostname)
let wrong_host = chain.hostname_mismatch("wrong.example.com");
// Signed by an unknown CA (not in your trust store)
let unknown = chain.unknown_ca();
// Revoked leaf with CRL signed by the intermediate CA
let revoked = chain.revoked_leaf();
let crl_pem = revoked.crl_pem().expect("CRL present for revoked variant");use uselesskey::{Factory, RsaSpec, RsaFactoryExt};
use uselesskey::negative::CorruptPem;
let fx = Factory::random();
let rsa = fx.rsa("issuer", RsaSpec::rs256());
let bad_pem = rsa.private_key_pkcs8_pem_corrupt(CorruptPem::BadBase64);
let truncated = rsa.private_key_pkcs8_der_truncated(32);
let mismatched_pub = rsa.mismatched_public_key_spki_der();Token fixtures are artifact shapes, not an auth framework. They exist so tests can use realistic-looking token values without committing blobs.
use uselesskey::{Factory, TokenFactoryExt, TokenSpec};
let fx = Factory::random();
let api_key = fx.token("billing", TokenSpec::api_key());
let bearer = fx.token("gateway", TokenSpec::bearer());
let oauth = fx.token("issuer", TokenSpec::oauth_access_token());
assert!(api_key.value().starts_with("uk_test_"));
assert!(bearer.authorization_header().starts_with("Bearer "));
assert_eq!(oauth.value().split('.').count(), 3);The uselesskey-cli bundle workflow generates a deterministic directory of fixtures, a manifest, and per-artifact receipts that downstream tests can verify, inspect, and hand off to Kubernetes or Vault without committing real secret material.
# Generate a scanner-safe fixture bundle (default profile)
uselesskey bundle --profile scanner-safe --out target/uselesskey-bundle
# Verify the bundle against its recorded manifest and receipts
uselesskey verify-bundle --path target/uselesskey-bundle
# Print a human-readable summary without exposing fixture payloads
uselesskey inspect-bundle --path target/uselesskey-bundle
# Render Kubernetes / Vault payloads from the verified bundle
uselesskey export k8s \
--bundle-dir target/uselesskey-bundle \
--name uselesskey-fixtures \
--namespace tests \
--out target/uselesskey-bundle/secret.yaml
uselesskey export vault-kv-json \
--bundle-dir target/uselesskey-bundle \
--out target/uselesskey-bundle/kv-v2.jsonThe oidc profile emits an OIDC/JWKS contract pack with valid JWKS and JWT-shape fixtures plus duplicate-kid, missing-kid, alg: none, and bad-audience negatives:
uselesskey bundle --profile oidc --out target/uselesskey-oidcFor the reference manifest, receipts, and payload shapes see examples/scanner-safe-bundle/README.md. For OIDC/JWT validator-test recipes see docs/how-to/test-oidc-jwks-validation.md and docs/how-to/test-jwt-negative-validation.md.
For a task-first list of scanner-safe, TLS, OIDC/JWKS, and webhook profiles,
see docs/contract-packs/README.md.
Adapter crates are separate packages, not facade features. That keeps integration versioning explicit and avoids coupling the facade to every downstream ecosystem type.
Use them when you want native third-party library types returned directly from fixture artifacts.
With the tls-config feature, build rustls configs in one step:
[dev-dependencies]
uselesskey = { version = "0.10.0", features = ["x509"] }
uselesskey-rustls = { version = "0.10.0", features = ["tls-config", "rustls-ring"] }use uselesskey::{ChainSpec, Factory, X509FactoryExt};
use uselesskey_rustls::{RustlsServerConfigExt, RustlsClientConfigExt};
let fx = Factory::random();
let chain = fx.x509_chain("my-service", ChainSpec::new("test.example.com"));
let server_config = chain.server_config_rustls();
let client_config = chain.client_config_rustls();[dev-dependencies]
uselesskey = { version = "0.10.0", features = ["rsa"] }
uselesskey-ring = { version = "0.10.0", features = ["all"] }use uselesskey::{Factory, RsaFactoryExt, RsaSpec};
use uselesskey_ring::RingRsaKeyPairExt;
let fx = Factory::random();
let rsa = fx.rsa("signer", RsaSpec::rs256());
let ring_kp = rsa.rsa_key_pair_ring();[dev-dependencies]
uselesskey = { version = "0.10.0", features = ["rsa"] }
uselesskey-rustcrypto = { version = "0.10.0", features = ["all"] }use uselesskey::{Factory, RsaFactoryExt, RsaSpec};
use uselesskey_rustcrypto::RustCryptoRsaExt;
let fx = Factory::random();
let rsa = fx.rsa("signer", RsaSpec::rs256());
let rsa_pk = rsa.rsa_private_key();[dev-dependencies]
uselesskey = { version = "0.10.0", features = ["rsa"] }
uselesskey-aws-lc-rs = { version = "0.10.0", features = ["native", "all"] }use uselesskey::{Factory, RsaFactoryExt, RsaSpec};
use uselesskey_aws_lc_rs::AwsLcRsRsaKeyPairExt;
let fx = Factory::random();
let rsa = fx.rsa("signer", RsaSpec::rs256());
let lc_kp = rsa.rsa_key_pair_aws_lc_rs();[dev-dependencies]
uselesskey = { version = "0.10.0", features = ["x509"] }
uselesskey-tonic = "0.10.0"use uselesskey::{ChainSpec, Factory, X509FactoryExt};
use uselesskey_tonic::{TonicClientTlsExt, TonicServerTlsExt};
let fx = Factory::random();
let chain = fx.x509_chain("grpc", ChainSpec::new("test.example.com"));
let server_tls = chain.server_tls_config_tonic();
let client_tls = chain.client_tls_config_tonic("test.example.com");The crates/uselesskey/examples/ directory contains standalone programs. Because the facade default feature set is empty, run them with cargo run -p uselesskey --example <name> --features "<flags>" using one working feature set below:
| Example | Feature(s) | Description |
|---|---|---|
| adapter_jsonwebtoken | rsa,ecdsa,ed25519,hmac |
Sign and verify JWTs using jsonwebtoken crate integration |
| adapter_rustls | x509 |
Convert X.509 fixtures into rustls ServerConfig / ClientConfig |
| basic_ecdsa | ecdsa,jwk |
Generate ECDSA keypairs for P-256 and P-384 in PEM, DER, JWK |
| basic_ed25519 | ed25519,jwk |
Generate Ed25519 keypairs in PEM, DER, and JWK formats |
| basic_hmac | hmac,jwk |
Generate HMAC secrets for HS256, HS384, and HS512 |
| basic_rsa | rsa,jwk |
Generate RSA keypairs in PEM, DER, and JWK formats |
| basic_token | token |
Generate API key, bearer token, and OAuth access-token fixtures |
| basic_usage | ecdsa,ed25519,rsa,jwk |
All-in-one: RSA, ECDSA, and Ed25519 fixture generation |
| deterministic | rsa |
Reproducible fixtures from seeds - same seed always yields the same key |
| deterministic_mode | rsa,ecdsa,ed25519 |
Order-independent deterministic derivation guarantees |
| jwk_generation | ecdsa,ed25519,hmac,rsa,jwk |
Build JWKs and JWKS with JwksBuilder across key types |
| jwk_jwks | ecdsa,ed25519,hmac,rsa,jwk |
JWK sets from multiple key types with metadata inspection |
| jwks | rsa,ecdsa,jwk |
Build a JWKS from RSA and ECDSA public keys |
| jwks_server_mock | rsa,ecdsa,ed25519,jwk |
Generate a JWKS response body for a mock /.well-known/jwks.json endpoint |
| jwt_rs256_jwks | rsa,jwk |
RSA keypairs with JWK/JWKS extraction for JWT verification flows |
| jwt_signing | rsa,jwk |
JWT signing with deterministic RSA, ECDSA, and HMAC keys (ECDSA/HMAC optional) |
| negative_fixtures | x509 |
Intentionally invalid certificates and keys for error-path testing |
| negative_payload_shapes | rsa,jwk,token |
Scanner-safe negative JWK/JWKS and token shapes for validator tests |
| tempfile_paths | rsa,ed25519 |
Write key fixtures to temporary files for path-based APIs |
| tempfiles | x509 |
Write X.509 cert, key, and identity PEM to temp files |
| tls_server | x509 |
Certificate chain generation for TLS server testing |
| token_generation | token |
Realistic API keys, bearer tokens, and OAuth tokens for tests |
| x509_certificates | x509 |
Self-signed certs, cert chains, and negative X.509 fixtures |
uselesskey is a facade crate that re-exports from focused implementation crates.
Depend on the facade for convenience, or on individual crates to minimize compile time.
| Crate | Description |
|---|---|
uselesskey |
Public facade — re-exports all key types and traits behind feature flags |
uselesskey-core |
Factory, deterministic derivation, caching, and negative-fixture helpers |
uselesskey-entropy |
Deterministic high-entropy byte fixtures for scanner-safe and placeholder tests |
uselesskey-rsa |
RSA 2048/3072/4096 keypairs (PKCS#8, SPKI, PEM, DER) |
uselesskey-ecdsa |
ECDSA P-256 / P-384 keypairs |
uselesskey-ed25519 |
Ed25519 keypairs |
uselesskey-hmac |
HMAC HS256/HS384/HS512 secrets |
uselesskey-ssh |
Deterministic OpenSSH key and certificate fixtures |
uselesskey-pgp |
OpenPGP key fixtures (armored + binary keyblocks) |
uselesskey-token |
API key, bearer token, and OAuth access-token fixtures |
uselesskey-webhook |
Deterministic webhook fixtures for GitHub, Stripe, and Slack signature tests |
uselesskey-jwk |
Typed JWK/JWKS models and builders |
uselesskey-x509 |
X.509 self-signed certificates and certificate chains |
uselesskey-cli |
Command-line fixture generation, bundling, and export helpers |
uselesskey-test-server |
Deterministic OIDC discovery and JWKS HTTP test server fixtures |
uselesskey-pkcs11-mock |
PKCS#11 mock provider fixtures for HSM/provider integration tests |
uselesskey-webauthn |
WebAuthn credential and assertion fixtures for passkey tests |
| Crate | Description |
|---|---|
uselesskey-axum |
axum auth-test helpers with deterministic JWKS/OIDC routes |
uselesskey-jsonwebtoken |
jsonwebtoken EncodingKey / DecodingKey |
uselesskey-rustls |
rustls ServerConfig / ClientConfig builders |
uselesskey-tonic |
tonic::transport TLS identity / config for gRPC |
uselesskey-ring |
ring 0.17 native signing key types |
uselesskey-rustcrypto |
RustCrypto native types (rsa::RsaPrivateKey, etc.) |
uselesskey-aws-lc-rs |
aws-lc-rs native types |
The uselesskey facade defaults to no features.
Extension traits by feature:
rsa:RsaFactoryExtecdsa:EcdsaFactoryExted25519:Ed25519FactoryExthmac:HmacFactoryExtpgp:PgpFactoryExttoken:TokenFactoryExtx509:X509FactoryExt
For output-family coverage and dependency implications, use the matrix below.
| Feature | Extension Trait | Algorithms / Outputs | Implies |
|---|---|---|---|
rsa |
RsaFactoryExt |
RSA 2048/3072/4096 — PKCS#8, SPKI, PEM, DER | — |
ecdsa |
EcdsaFactoryExt |
P-256 (ES256), P-384 (ES384) — PKCS#8, SPKI | — |
ed25519 |
Ed25519FactoryExt |
Ed25519 — PKCS#8, SPKI | — |
hmac |
HmacFactoryExt |
HS256, HS384, HS512 | — |
pgp |
PgpFactoryExt |
OpenPGP RSA 2048/3072, Ed25519 — armored, binary | — |
token |
TokenFactoryExt |
API key, bearer access token, and OAuth access token | — |
x509 |
X509FactoryExt |
Self-signed certs, cert chains, negative certs | rsa |
jwk |
— | JWK/JWKS output for all enabled key types | — |
all-keys |
— | (bundle) | rsa ecdsa ed25519 hmac pgp |
full |
— | (everything) | all-keys token x509 jwk |
Each adapter crate has per-algorithm feature flags (rsa, ecdsa, ed25519, hmac) and an all convenience flag.
| Adapter | RSA | ECDSA | Ed25519 | HMAC | X.509 / TLS | Extra features |
|---|---|---|---|---|---|---|
uselesskey-jsonwebtoken |
✓ | ✓ | ✓ | ✓ | — | — |
uselesskey-ring |
✓ | ✓ | ✓ | — | — | — |
uselesskey-rustcrypto |
✓ | ✓ | ✓ | ✓ | — | — |
uselesskey-aws-lc-rs |
✓ | ✓ | ✓ | — | — | native (enables aws-lc-rs dep) |
uselesskey-rustls |
✓ | ✓ | ✓ | — | ✓ | tls-config, rustls-ring, rustls-aws-lc-rs |
uselesskey-tonic |
— | — | — | — | ✓ | — |
Fixtures derive from stable identity components:
seed + (domain, label, spec, variant) -> derived seed -> artifact
Adding new fixtures doesn't perturb existing ones. Test order doesn't matter.
RSA keygen is expensive. Per-factory caching by (domain, label, spec, variant) makes runtime generation cheap enough to replace committed fixtures.
Ask for shapes first: PKCS#8, SPKI, PEM, DER, JWK, JWKS, or tempfiles. Consumers ask for artifact shapes; low-level crypto primitives are intentionally not the default output.
Corrupt PEM, truncated DER, mismatched keys, expired certs, revoked leaves with CRLs: these are exactly the artifacts teams otherwise handcraft and commit.
uselesskey makes them deterministic, cheap, and disposable.
- production key generation
- runtime certificate authority behavior
- certificate validation logic
- HSM / TPM / hardware-backed keys
- signing or verification APIs as the primary abstraction
For runtime certificate generation, reach for rcgen directly. For validation, use rustls, x509-parser, or the library actually responsible for verification.
Use uselesskey when you need realistic test fixtures that should not live in git history.
Reach for:
rcgenwhen you need runtime certificate generation outside a fixture-centric workflowrustlswhen you need TLS runtime integration and validationx509-parserwhen you need parsing/inspection/validation work
- CHANGELOG — release history
- CONTRIBUTING — how to build, test, and add new key types
- SECURITY — security policy (this is a test-only crate)
- CODE_OF_CONDUCT — Contributor Covenant
- SUPPORT — how to get help
Derivation stability
Artifacts for a given (seed, domain, label, spec, variant) tuple are stable within the same DerivationVersion.
If derivation logic changes, a new derivation version is introduced instead of mutating the old one.
Semver
Breaking API changes bump the minor version until 1.0, then the major version.
MSRV The minimum supported Rust version is 1.95 (edition 2024).
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
at your option.