Why this matters for migration
Most quantum-readiness work begins with discovery, and discovery usually ends in the same place: a list of the algorithms an organisation is running and the systems that depend on them. The list is necessary. It is also where a lot of programmes stall, because the next question is harder than the first one.
If AES-256-GCM or RSA-2048 is named directly in two hundred services, then changing it is two hundred code changes, two hundred reviews, and two hundred deployments — coordinated across teams that own their own release calendars. The cryptography is not the bottleneck. The coupling is.
CryptoServe's answer is to stop naming algorithms in application code. The application declares what it is protecting; the algorithm is resolved from policy outside the application. Changing the algorithm then becomes a policy change rather than a code change.
What CryptoServe is
CryptoServe is an independent open-source project, licensed Apache 2.0, that provides cryptography and key management as a service. It has two halves that are useful at different stages of a migration.
A command-line scanner
Finds cryptography already present in a codebase — libraries, algorithms, weak patterns, hardcoded secrets — and exports a CBOM. Runs offline, no server needed.
A cryptography service
Applications call it to encrypt and decrypt. It resolves the algorithm from declared context and policy, and manages the keys underneath.
A policy engine
Rules evaluated before every operation. Minimum key sizes, blocked algorithms, and compliance requirements, with allow, warn, or block outcomes.
An audit trail
Every operation records identity, context, algorithm, key ID, and outcome, with an HMAC-SHA256 integrity hash over the record.
Contexts instead of algorithms
The unit of configuration is a context — a name for a class of data. Application code refers to the context; it does not refer to an algorithm.
from cryptoserve import CryptoServe
crypto = CryptoServe(app_name="payments", team="backend")
ciphertext = crypto.encrypt(b"4111-1111-1111-1111", context="card-data")
plaintext = crypto.decrypt(ciphertext, context="card-data")
Nothing in that snippet names a cipher, a key size, or a mode. CryptoServe's own documentation puts it plainly: no cryptographic decisions are required by your application code. The decision is made instead from five layers of declared context — what the data is, what regulations apply, who the adversary is, how it is accessed, and the technical constraints.
The threat-model layer is the one that matters most for quantum readiness, because it is where the exposure window is declared:
threat_model = ThreatModel(
adversary_capability="nation_state",
attack_vectors=["network", "insider", "quantum"],
protection_duration_years=10,
quantum_threat=True
)
Data that must stay confidential for ten years is data whose protection has to survive the arrival of a cryptographically relevant quantum computer. Declaring that once, against the context, is what lets the algorithm choice follow from the requirement instead of from whichever library a developer reached for.
Key management
Keys are derived with HKDF-SHA256 rather than stored directly, and each tenant and context receives distinct key material. The property that matters for migration is how rotation behaves.
| Concern | How CryptoServe handles it |
|---|---|
| Rotating a key | Zero downtime. New writes use the new key; existing data decrypts with the key it was written under. |
| Reading old data after an algorithm change | Ciphertext is self-describing and carries a version header, so older formats stay parseable. |
| Re-encrypting the estate | Not required to rotate. Re-encryption becomes a deliberate, scheduled operation rather than a precondition. |
| Key storage | Derived via HKDF-SHA256 from a master key, with HSM and KMS backends available on the self-hosted server. |
Available symmetric algorithms include AES-256-GCM, AES-128-GCM, ChaCha20-Poly1305, AES-256-CBC with HMAC, AES-256-CCM, and AES-256-XTS. Post-quantum support is provided through liboqs and covers ML-KEM (FIPS 203), ML-DSA (FIPS 204), and SLH-DSA (FIPS 205), along with hybrid key exchange combining X25519 with ML-KEM.
Governance for custom-built software
In-house software is usually the hardest part of an estate to govern. Vendor products can be assessed at procurement, and infrastructure can be scanned from outside; custom applications encrypt things in ways no external scan reliably reveals.
Routing that cryptography through a service gives a security team three things it does not otherwise have.
Enforcement before the operation, not after the incident. The policy engine evaluates rules on every call and can block rather than warn:
{
"type": "algorithm",
"name": "require-256-bit-keys",
"rule": {
"min_key_bits": 256,
"blocked_algorithms": ["AES-128-*", "DES", "3DES", "RC4"]
},
"severity": "block"
}
Compliance expressed as configuration. Regulatory requirements attach to the contexts they govern, rather than living in a policy document that developers are expected to have read:
{
"type": "compliance",
"name": "hipaa-encryption",
"rule": {
"require_algorithms": ["AES-256-GCM", "AES-256-CBC"],
"require_audit": true,
"require_key_rotation_days": 365
},
"severity": "block",
"applies_to": ["health-data"]
}
Evidence that was produced automatically. Each operation writes a tamper-evident record carrying timestamp, operation, identity, algorithm, key ID, outcome, sizes, latency, and an HMAC-SHA256 integrity hash. That is the material auditors ask for under PCI-DSS, HIPAA, and SOC 2, gathered as a by-product of normal operation rather than assembled before an audit.
Use cases by sector
The five context layers include a regulatory layer, and the frameworks below are the ones it recognises directly.
| Sector | The problem | What the service handles |
|---|---|---|
| Financial services | Card data and transaction records under PCI-DSS, with retention periods long enough that harvest-now-decrypt-later is a real exposure. | PCI-DSS as a declared regulatory framework; cryptoserve pqc --profile financial for a PCI-focused readiness view; audit records usable as compliance evidence. |
| Healthcare | Protected health information that must stay confidential for decades, spread across clinical systems built at different times. | A HIPAA compliance policy bound to health-data contexts, enforcing approved algorithms, mandatory audit, and a maximum key age. |
| Government and public sector | FIPS obligations, long classification lifetimes, and procurement that expects documented cryptographic control. | FedRAMP as a declared regulatory framework mapping to FIPS-approved algorithms, and a FIPS 140-2/3 compliance mode on the self-hosted server. |
| Enterprise platform teams | Many services, many teams, no single view of what any of them encrypt or with what. | Centralised policy and key management, RBAC, OAuth against GitHub, Google, Azure, or Okta, HSM and KMS backends, and SIEM forwarding. |
| Any team starting discovery | No inventory of what cryptography is already deployed. | The offline scanner: 6 languages, 133 algorithms, 22 of them flagged weak with a named replacement, plus optional binary scanning of ELF, PE, Mach-O, .class, and .NET files. |
Getting started
Scan first
The scanner needs no account, no server, and no install. It is the fastest way to see whether any of the rest is relevant to you.
# Inventory the cryptography in a project
npx cryptoserve scan .
# Score post-quantum readiness, with a sector profile
npx cryptoserve pqc --profile financial
# Export a Cryptographic Bill of Materials
npx cryptoserve cbom --format cyclonedx
# Fail a build on weak algorithms
npx cryptoserve gate . --fail-on-weak --format sarif --output crypto.sarif
Every finding carries the file:line that produced it, and the SARIF output loads into the GitHub Security tab and pull-request annotations.
Then the SDK
pip install cryptoserve # Python SDK and CLI
npm install -g cryptoserve # JavaScript CLI and SDK
The SDKs work in local mode without a server. The optional self-hosted server is what adds centralised key management, policy enforcement, audit logging, and a dashboard:
docker run -d -p 8003:8003 -p 3000:3000 \
-v cryptoserve-data:/data ghcr.io/ecolibria/crypto-serve
Where it fits in QRAMM
QRAMM assesses quantum readiness across four dimensions. CryptoServe is relevant to two of them, and it is worth being precise about which.
| QRAMM dimension | Relevance |
|---|---|
| Dimension 1 — Cryptographic Visibility & Inventory | Directly. The scanner and CBOM export address practice 1.1, discovery and inventory management. |
| Dimension 3 — Data Protection Engineering | Directly. Centralised key management and policy-driven algorithm selection are the engineering controls this dimension assesses. |
| Dimension 2 — Strategic Governance & Risk Management | Partially. It produces audit evidence, but governance structures and third-party risk remain organisational work. |
An assessment tells you where you stand. Discovery tells you what you are running. Neither changes anything on its own — the migration still has to happen, and how expensive it is depends mostly on how tightly the cryptography is bound to the code. That is the specific problem this tool exists to address.
Questions
encrypt with a context such as card-data and receives ciphertext back. The algorithm, key size, and rotation schedule are resolved from policy outside the application, so a developer does not select an algorithm at the call site. Integrating the SDK is still development work; choosing ciphers stops being development work.Start with what you already run
One command inventories the cryptography in a project, with no install and no account. Whether the rest of this is relevant follows from what it finds.
View on GitHub Take QRAMM AssessmentRelated resources
- Cryptographic Agility - Why decoupling algorithms from code is the precondition for migration
- Cryptographic Inventory Guide - Building the inventory that precedes this work
- PQC Migration Planning - Sequencing a migration programme
- Harvest Now, Decrypt Later - Why retention period drives urgency
- CryptoScan Guide - Source code cryptographic discovery