EffortlessMetrics/uselesskey-swarm

GitHub: EffortlessMetrics/uselesskey-swarm

Stars: 0 | Forks: 0

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 | | --- | --- | --- | | write Rust tests | facade crate | `uselesskey = { version = "0.9.1", features = ["rsa"] }` | | install CI fixtures | installed CLI bundle | `uselesskey bundle --profile scanner-safe --out target/uselesskey-bundle` | | test negative verifier paths | contract packs | `uselesskey bundle --profile oidc --out target/uselesskey-oidc` | | review bundle evidence | verify + inspect + audit | `uselesskey inspect-bundle target/uselesskey-webhook` | | keep runtime material disposable | `target/` output | `uselesskey audit-bundle target/uselesskey-webhook --ci --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.9.1 --locked 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 target/uselesskey-webhook uselesskey inspect-bundle target/uselesskey-webhook uselesskey audit-bundle target/uselesskey-webhook --ci --out target/uselesskey-webhook-audit Use `--ci --expect-profile --policy strict --out ` when the audit is part of a downstream CI gate: uselesskey audit-bundle target/uselesskey-webhook --ci --expect-profile webhook --policy strict --out target/uselesskey-webhook-audit Rust test authors start with the facade crate: [dev-dependencies] uselesskey = { version = "0.9.1", 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](docs/how-to/start-here.md) for the task router, [docs/how-to/verify-a-fixture-bundle.md](docs/how-to/verify-a-fixture-bundle.md) for the verify/audit loop, or [docs/status/PUBLIC_CLAIMS.md](docs/status/PUBLIC_CLAIMS.md) for the full proof index. For downstream-shaped clean projects, use the [external examples index](examples/external/README.md). ## 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. ## 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](docs/how-to/choose-features.md) for feature selection. Use [docs/how-to/choose-lane.md](docs/how-to/choose-lane.md) when deciding between entropy, token, semantic, and materialized fixture workflows. See [docs/reference/dependency-economics.md](docs/reference/dependency-economics.md) and [docs/reference/audit-surface.md](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.9.1", default-features = false, features = ["entropy"] } # RSA fixtures [dev-dependencies] uselesskey = { version = "0.9.1", features = ["rsa"] } # Token-only fixtures, no RSA/X.509 pull-in [dev-dependencies] uselesskey = { version = "0.9.1", default-features = false, features = ["token"] } # RSA + JWK/JWKS [dev-dependencies] uselesskey = { version = "0.9.1", features = ["rsa", "jwk"] } # X.509 fixtures [dev-dependencies] uselesskey = { version = "0.9.1", 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.9.1", default-features = false } # Specialized RSA PKCS#8 build-time path [build-dependencies] uselesskey-cli = { version = "0.9.1", 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](docs/how-to/choose-features.md). For downstream bot/reviewer policy, use [docs/how-to/downstream-fixture-policy.md](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](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.9.1", features = ["rsa"] } - **Token-only** [dev-dependencies] uselesskey = { version = "0.9.1", default-features = false, features = ["token"] } - **JWT/JWK** [dev-dependencies] uselesskey = { version = "0.9.1", features = ["rsa", "jwk"] } - **X.509 + rustls** [dev-dependencies] uselesskey = { version = "0.9.1", features = ["x509"] } uselesskey-rustls = { version = "0.9.1", features = ["tls-config", "rustls-ring"] } - **jsonwebtoken adapter** [dev-dependencies] uselesskey = { version = "0.9.1", features = ["rsa", "ecdsa", "ed25519", "hmac"] } uselesskey-jsonwebtoken = { version = "0.9.1", features = ["all"] } ### 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 target/uselesskey-bundle # Print a human-readable summary without exposing fixture payloads uselesskey inspect-bundle 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`](examples/scanner-safe-bundle/README.md). For OIDC/JWT validator-test recipes see [`docs/how-to/test-oidc-jwks-validation.md`](docs/how-to/test-oidc-jwks-validation.md) and [`docs/how-to/test-jwt-negative-validation.md`](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`](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.9.1", features = ["x509"] } uselesskey-rustls = { version = "0.9.1", 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.9.1", features = ["rsa"] } uselesskey-ring = { version = "0.9.1", 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.9.1", features = ["rsa"] } uselesskey-rustcrypto = { version = "0.9.1", 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.9.1", features = ["rsa"] } uselesskey-aws-lc-rs = { version = "0.9.1", 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.9.1", features = ["x509"] } uselesskey-tonic = "0.9.1" 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/`](crates/uselesskey/examples/) directory contains standalone programs. Because the facade default feature set is empty, run them with `cargo run -p uselesskey --example --features ""` using one working feature set below: | Example | Feature(s) | Description | |---------|------------|-------------| | [adapter_jsonwebtoken](crates/uselesskey/examples/adapter_jsonwebtoken.rs) | `rsa,ecdsa,ed25519,hmac` | Sign and verify JWTs using `jsonwebtoken` crate integration | | [adapter_rustls](crates/uselesskey/examples/adapter_rustls.rs) | `x509` | Convert X.509 fixtures into rustls `ServerConfig` / `ClientConfig` | | [basic_ecdsa](crates/uselesskey/examples/basic_ecdsa.rs) | `ecdsa,jwk` | Generate ECDSA keypairs for P-256 and P-384 in PEM, DER, JWK | | [basic_ed25519](crates/uselesskey/examples/basic_ed25519.rs) | `ed25519,jwk` | Generate Ed25519 keypairs in PEM, DER, and JWK formats | | [basic_hmac](crates/uselesskey/examples/basic_hmac.rs) | `hmac,jwk` | Generate HMAC secrets for HS256, HS384, and HS512 | | [basic_rsa](crates/uselesskey/examples/basic_rsa.rs) | `rsa,jwk` | Generate RSA keypairs in PEM, DER, and JWK formats | | [basic_token](crates/uselesskey/examples/basic_token.rs) | `token` | Generate API key, bearer token, and OAuth access-token fixtures | | [basic_usage](crates/uselesskey/examples/basic_usage.rs) | `ecdsa,ed25519,rsa,jwk` | All-in-one: RSA, ECDSA, and Ed25519 fixture generation | | [deterministic](crates/uselesskey/examples/deterministic.rs) | `rsa` | Reproducible fixtures from seeds - same seed always yields the same key | | [deterministic_mode](crates/uselesskey/examples/deterministic_mode.rs) | `rsa,ecdsa,ed25519` | Order-independent deterministic derivation guarantees | | [jwk_generation](crates/uselesskey/examples/jwk_generation.rs) | `ecdsa,ed25519,hmac,rsa,jwk` | Build JWKs and JWKS with `JwksBuilder` across key types | | [jwk_jwks](crates/uselesskey/examples/jwk_jwks.rs) | `ecdsa,ed25519,hmac,rsa,jwk` | JWK sets from multiple key types with metadata inspection | | [jwks](crates/uselesskey/examples/jwks.rs) | `rsa,ecdsa,jwk` | Build a JWKS from RSA and ECDSA public keys | | [jwks_server_mock](crates/uselesskey/examples/jwks_server_mock.rs) | `rsa,ecdsa,ed25519,jwk` | Generate a JWKS response body for a mock `/.well-known/jwks.json` endpoint | | [jwt_rs256_jwks](crates/uselesskey/examples/jwt_rs256_jwks.rs) | `rsa,jwk` | RSA keypairs with JWK/JWKS extraction for JWT verification flows | | [jwt_signing](crates/uselesskey/examples/jwt_signing.rs) | `rsa,jwk` | JWT signing with deterministic RSA, ECDSA, and HMAC keys (ECDSA/HMAC optional) | | [negative_fixtures](crates/uselesskey/examples/negative_fixtures.rs) | `x509` | Intentionally invalid certificates and keys for error-path testing | | [negative_payload_shapes](crates/uselesskey/examples/negative_payload_shapes.rs) | `rsa,jwk,token` | Scanner-safe negative JWK/JWKS and token shapes for validator tests | | [tempfile_paths](crates/uselesskey/examples/tempfile_paths.rs) | `rsa,ed25519` | Write key fixtures to temporary files for path-based APIs | | [tempfiles](crates/uselesskey/examples/tempfiles.rs) | `x509` | Write X.509 cert, key, and identity PEM to temp files | | [tls_server](crates/uselesskey/examples/tls_server.rs) | `x509` | Certificate chain generation for TLS server testing | | [token_generation](crates/uselesskey/examples/token_generation.rs) | `token` | Realistic API keys, bearer tokens, and OAuth tokens for tests | | [x509_certificates](crates/uselesskey/examples/x509_certificates.rs) | `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`](https://crates.io/crates/uselesskey) | Public facade — re-exports all key types and traits behind feature flags | | [`uselesskey-core`](https://crates.io/crates/uselesskey-core) | Factory, deterministic derivation, caching, and negative-fixture helpers | | [`uselesskey-entropy`](https://crates.io/crates/uselesskey-entropy) | Deterministic high-entropy byte fixtures for scanner-safe and placeholder tests | | [`uselesskey-rsa`](https://crates.io/crates/uselesskey-rsa) | RSA 2048/3072/4096 keypairs (PKCS#8, SPKI, PEM, DER) | | [`uselesskey-ecdsa`](https://crates.io/crates/uselesskey-ecdsa) | ECDSA P-256 / P-384 keypairs | | [`uselesskey-ed25519`](https://crates.io/crates/uselesskey-ed25519) | Ed25519 keypairs | | [`uselesskey-hmac`](https://crates.io/crates/uselesskey-hmac) | HMAC HS256/HS384/HS512 secrets | | [`uselesskey-ssh`](https://crates.io/crates/uselesskey-ssh) | Deterministic OpenSSH key and certificate fixtures | | [`uselesskey-pgp`](https://crates.io/crates/uselesskey-pgp) | OpenPGP key fixtures (armored + binary keyblocks) | | [`uselesskey-token`](https://crates.io/crates/uselesskey-token) | API key, bearer token, and OAuth access-token fixtures | | [`uselesskey-webhook`](https://crates.io/crates/uselesskey-webhook) | Deterministic webhook fixtures for GitHub, Stripe, and Slack signature tests | | [`uselesskey-jwk`](https://crates.io/crates/uselesskey-jwk) | Typed JWK/JWKS models and builders | | [`uselesskey-x509`](https://crates.io/crates/uselesskey-x509) | X.509 self-signed certificates and certificate chains | | [`uselesskey-cli`](https://crates.io/crates/uselesskey-cli) | Command-line fixture generation, bundling, and export helpers | | [`uselesskey-test-server`](https://crates.io/crates/uselesskey-test-server) | Deterministic OIDC discovery and JWKS HTTP test server fixtures | | [`uselesskey-pkcs11-mock`](https://crates.io/crates/uselesskey-pkcs11-mock) | PKCS#11 mock provider fixtures for HSM/provider integration tests | | [`uselesskey-webauthn`](https://crates.io/crates/uselesskey-webauthn) | WebAuthn credential and assertion fixtures for passkey tests | ### Adapter Crates | Crate | Description | |-------|-------------| | [`uselesskey-axum`](https://crates.io/crates/uselesskey-axum) | `axum` auth-test helpers with deterministic JWKS/OIDC routes | | [`uselesskey-jsonwebtoken`](https://crates.io/crates/uselesskey-jsonwebtoken) | `jsonwebtoken` `EncodingKey` / `DecodingKey` | | [`uselesskey-rustls`](https://crates.io/crates/uselesskey-rustls) | `rustls` `ServerConfig` / `ClientConfig` builders | | [`uselesskey-tonic`](https://crates.io/crates/uselesskey-tonic) | `tonic::transport` TLS identity / config for gRPC | | [`uselesskey-ring`](https://crates.io/crates/uselesskey-ring) | `ring` 0.17 native signing key types | | [`uselesskey-rustcrypto`](https://crates.io/crates/uselesskey-rustcrypto) | RustCrypto native types (`rsa::RsaPrivateKey`, etc.) | | [`uselesskey-aws-lc-rs`](https://crates.io/crates/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` | ## 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 ## 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: - Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE)) - MIT license ([LICENSE-MIT](LICENSE-MIT)) at your option.
标签:通知系统