Skip to content

EffortlessMetrics/uselesskey

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

630 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

uselesskey

CI Codecov ripr+ scanner-safe fixtures

GitHub release crates.io downloads docs.rs

MSRV License: MIT OR Apache-2.0

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.

Start Here

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

Generate, 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-audit

Use --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 strict

Rust 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-verification

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

Why this exists

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.

What problem it solves

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.

What you get

Fixture families

  • 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

Output shapes

  • 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

Negative artifacts

  • corrupt PEM
  • truncated DER
  • mismatched keypairs
  • expired / revoked / hostname-mismatch / unknown-CA certificates

Pick The Lane First

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.

Choose the smallest feature set

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

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

Quick start

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.

Feature reminders for common snippets

  • rsa for PEM/DER, tempfiles, and negative-key examples
  • rsa + jwk for public_jwk() / public_jwks()
  • x509 for certificate, rustls, and tonic examples
  • token for token-shaped fixtures only
  • pgp for armored/binary OpenPGP fixtures

Dependency Snippet Reminders

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" }

JWK / JWKS

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();

Tempfiles

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());

X.509 Certificates

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();

X.509 negative fixtures

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");

Negative fixtures (keys)

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

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);

Scanner-safe bundles and exports

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

The 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-oidc

For 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

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.

TLS config builders (uselesskey-rustls)

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();

ring signing keys (uselesskey-ring)

[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();

RustCrypto types (uselesskey-rustcrypto)

[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();

aws-lc-rs types (uselesskey-aws-lc-rs)

[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();

gRPC TLS (uselesskey-tonic)

[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");

Runnable Examples

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

Workspace Crates

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.

Implementation Crates

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

Adapter Crates

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

Feature Flags

The uselesskey facade defaults to no features.

Extension traits by feature:

  • rsa: RsaFactoryExt
  • ecdsa: EcdsaFactoryExt
  • ed25519: Ed25519FactoryExt
  • hmac: HmacFactoryExt
  • pgp: PgpFactoryExt
  • token: TokenFactoryExt
  • x509: X509FactoryExt

For output-family coverage and dependency implications, use the matrix below.

Feature matrix

Facade features (uselesskey crate)

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

Adapter crate key-type support

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

Why this crate

Order-independent determinism

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.

Cache-by-identity

RSA keygen is expensive. Per-factory caching by (domain, label, spec, variant) makes runtime generation cheap enough to replace committed fixtures.

Shape-first outputs

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.

Negative artifacts as first-class

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.

When not to use this crate

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

Ecosystem

Use uselesskey when you need realistic test fixtures that should not live in git history.

Reach for:

  • rcgen when you need runtime certificate generation outside a fixture-centric workflow
  • rustls when you need TLS runtime integration and validation
  • x509-parser when you need parsing/inspection/validation work

Community

Stability and versioning

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

License

Licensed under either of:

at your option.

About

Deterministic cryptographic key and certificate fixtures for Rust tests. Never commit secrets again.

Topics

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors