qnsp — Rust SDK for the Quantum-Native Security Platform
Typed async Rust client for QNSP — post-quantum cryptography (ML-KEM, ML-DSA, SLH-DSA, Falcon via liboqs), PQC-encrypted vault, server-side KMS, immutable audit trails. Same wire contracts as the official @qnsp/* TypeScript SDKs, the qnsp Python SDK, and the github.com/cuilabs/qnsp-public/sdks/go/qnsp Go SDK — pick whichever language fits your stack and the byte-for-byte outputs round-trip.
Free tier available. Free-forever account at https://cloud.qnsp.cuilabs.io/auth — 60-second signup, no credit card. Includes 10 GB PQC storage, 50 000 API calls/month, 20 KMS keys, 25 vault secrets.
Install
Base install (HTTP clients for vault, KMS, audit — no native deps):
With local PQC primitives (qnsp::crypto — wraps the oqs crate 0.11):
The crypto feature pulls in oqs which delegates to oqs-sys; oqs-sys builds liboqs from source via cmake. You'll need a C toolchain and cmake available at build time. macOS / Linux build out of the box; on Windows you'll want the MSVC toolchain plus a cmake install.
Tested on Rust 1.75+. The crate is tokio-based on the async side.
Quick start
use ;
use CreateSecretRequest;
use CreateKeyRequest;
use LogEventRequest;
use ;
async
Local PQC primitives
qnsp::crypto wraps the oqs crate so you don't have to write oqs::kem / oqs::sig calls directly, and so the algorithm-name surface matches the rest of the QNSP ecosystem (TypeScript, Python, Go):
For full lifecycle control (generate once, sign or decapsulate many times), call oqs::kem::Kem::new(qnsp::crypto::kem_algorithm("ML-KEM-768")?) directly — the resolver functions are public.
Verifying inbound webhooks
QNSP signs every webhook with HMAC-SHA-256. Verify the raw body before parsing JSON:
use ;
use ;
async
The verifier runs HMAC comparison in constant time, rejects timestamps older than 5 minutes by default (replay protection), and refuses payloads missing required fields.
Error handling
All errors flow through qnsp::Error:
| Variant | When |
|---|---|
qnsp::Error::Network(_) |
DNS, TLS, timeout, or connection failure |
qnsp::Error::Auth(_) |
API key rejected at activation |
qnsp::Error::Api(_) |
A service returned 4xx/5xx with a structured body |
qnsp::Error::Webhook(_) |
HMAC mismatch, expired timestamp, malformed body, etc. |
match c.vault.get_secret.await
Activation + tier introspection
qnsp::Client performs a one-shot handshake against /billing/v1/sdk/activate on first use. The result is cached in memory; subsequent calls reuse it until ~1 minute before expiry. You can inspect the current activation:
let tenant_id = c.tenant_id.await?;
let tier = c.tier.await?;
let limits = c.limits.await?;
let sse_on = c.has_feature.await?;
If the activation token is rotated server-side, the SDK invalidates its cache and retries the originating request once on a 401.
What's covered today
Customer-facing modules (every QNSP service callable through the edge gateway today):
qnsp::vault—create_secret,get_secret,get_secret_version,rotate_secret,delete_secret,list_secret_versions— wrapsapps/vault-serviceqnsp::kms—create_key,list_keys,get_key,rotate_key,delete_key,sign,verify,wrap,unwrap_— wrapsapps/kms-serviceqnsp::audit—log_event,ingest_events(batch),list_events— wrapsapps/audit-serviceqnsp::auth—login,refresh_token,revoke, WebAuthn passkey lifecycle,mfa_challenge/mfa_verify,federate_saml/federate_oidc,evaluate_risk— wrapsapps/auth-serviceqnsp::tenant—create_tenant,get_tenant,update_tenant,list_tenants,get_crypto_policy,upsert_crypto_policy,get_current_health,get_current_quotas— wrapsapps/tenant-serviceqnsp::access—create_role,get_role,list_roles,delete_role,assign_role,revoke_role_assignment,check_permission— wrapsapps/access-control-serviceqnsp::billing—get_entitlements,ingest_meter,ingest_meters,list_invoices,get_invoice,get_credit_balance— wrapsapps/billing-serviceqnsp::crypto_inventory—list_assets,get_asset,get_asset_stats,discover_assets,get_readiness_score— wrapsapps/crypto-inventory-service(CBOM)qnsp::storage—put_object,get_object,delete_object,list_objects,list_buckets— wrapsapps/storage-service(SSE-X)qnsp::search—create_index,list_indexes,delete_index,upsert_vectors,query— wrapsapps/search-service(vector search)qnsp::ai—register_model, model lifecycle,submit_workload,invoke_inference,register_artifact— wrapsapps/ai-orchestrator
Local primitives + integration:
qnsp::crypto(feature-gated oncrypto) — ML-KEM (512/768/1024), ML-DSA (44/65/87), SLH-DSA (12 variants), Falcon (512/1024), plus HQC, BIKE, FrodoKEM, Classic-McEliece, MAYO, CROSS — every FIPS 203/204/205 finalist exposed byoqs0.11qnsp::parse_webhook/qnsp::verify_webhook_signature— HMAC-SHA-256 signature verification + typedqnsp::WebhookEventqnsp::Client::new— API-key activation against/billing/v1/sdk/activatewith caching and 401 retry
What's coming
- Async streaming for
Storage::get_objecton large objects - Pre-built
qnsp::test_supporthelper that mocks the QNSP API for tests - Generated typed responses (currently
serde_json::Value) for every method
License
Apache-2.0. See LICENSE.