What offline mode is
Offline mode is the same binary doing the same discovery, with the submission step replaced by a local assessment. Instead of posting findings to an API and letting the platform score them, the agent scores them itself and writes the finished result next to itself on disk.
Concretely, in this mode the agent:
- opens no outbound connection of any kind — no submission, no telemetry, no update check, no licence call, no DNS beyond what a network target you explicitly configured would need;
- accepts no API URL and no API key. There is no credential to provision for an air-gapped host, and none to leak on one;
- needs no installation. It is a single statically-built executable; there is no runtime, interpreter or shared library to satisfy inside the enclave;
- writes only to the output directory you name, and reads everything else read-only.
Nothing about the enclave leaves the enclave. The only artifacts that exist are the three files in your output directory, on the machine you ran it on. Whether they cross your boundary, and after what review, is entirely your decision — the tool has no opinion and no channel.
Everything needed to reach a verdict is compiled into the binary: the compliance rules, the risk model, the remediation-ownership classifier, the parameter-set-to-NIST-level mapping and the CycloneDX writer. There is no rules file to keep current and no lookup to perform.
Why an air-gapped enclave still owes an inventory
On June 22, 2026 the White House signed “Securing the Nation Against Advanced Cryptographic Attacks”, turning post-quantum migration from guidance into mandate. OMB's binding execution memo followed two days later: every agency owes a PQC Migration Plan within 120 days — roughly October 22, 2026 — and the memo names its first phase (2026–2027) explicitly as inventorying cryptographic systems.
Scope is federal high-value assets and high-impact systems. Which is to say: the mandate lands hardest precisely on the systems that are hardest to inventory. A disconnected enclave cannot be reached by a network scanner, cannot call an API, and frequently runs the oldest cryptography in the estate — and none of that is an exemption. The plan is still due. The deadlines still apply.
The CBOM language is aimed at tooling
The order directs CISA and NIST to define the minimum elements of a Cryptographic
Bill of Materials, which must “enable the automated assessment of the
cryptographic assets utilized by a hardware or software element.” That
phrase is the bar: a document a human can read is not enough, it has to be
assessable by machine. It is why this agent puts the quantum verdict in
nistQuantumSecurityLevel and a dependencies graph rather
than only in vendor-namespaced properties —
see what the CBOM actually contains.
Not a government-only deadline
The order directs the first proposed contractor FAR rule within 180 days, so anyone selling to the federal government inherits the requirement through procurement and passes it to their own suppliers. If you run a segregated or classified environment on behalf of an agency, the obligation arrives in your contract rather than in the Federal Register. Section 6 goes further, directing shared procurement of PQC tools — the order does not merely permit agencies to buy cryptographic discovery tooling, it organizes how they will buy it.
Offline mode is the compliance path for the systems that have no other one. The enclave produces its own inventory, its own CBOM and its own readiness assessment, on the host, and you carry out three files. Nothing about the enclave has to be exposed to satisfy a requirement about the enclave.
What runs offline
All eight discovery sources run in offline mode — the mode changes what happens to the findings, not how they are found. Worth being precise about one thing: “offline” means no route to us, not necessarily no network at all. An enclave with its own internal LAN can still scan the endpoints and appliances on it; the agent simply never reaches beyond them.
| Source | Needs | What it finds |
|---|---|---|
| Filesystem certs & keys | Nothing | PEM/DER/CRT/CER, RSA/ECC/Ed25519 keys, multi-cert bundles, OpenSSL trust-augmented entries, CSRs and key-exchange parameter files. |
| Native OS certificate store | Nothing | Windows CryptoAPI (MY/Root/CA/TrustedPublisher, LocalMachine and CurrentUser) or the macOS System and login Keychains. Always scanned, no configuration. |
| SSH keys | Nothing | Host and user keys, authorized_keys, known_hosts. |
| Keystores | Nothing |
JKS/JCEKS/PKCS#12/BKS/UBER/Oracle Wallet/NSS, each entry inventoried at store#alias. |
| Source code (CBOM) | Nothing | Weak-crypto call sites in your own code — MD5, SHA-1, DES, RC4, ECB, undersized RSA. Set code_scan_paths; this is the source-level half of a CBOM and it needs no network whatsoever. |
| Database columns | Local or LAN DSN | Certificates and keys stored in tables. Structural metadata only — the raw value is parsed and discarded. |
| Live TLS endpoints | LAN reachability | A real handshake against host:port inside the enclave, inspecting whatever certificate is actually being served. |
| F5 / NetScaler appliances | LAN + read-only account | The appliance's own certificate store via iControl REST / NITRO, including staged certs bound to nothing. |
A fully isolated single host still gets five of the eight without configuring anything at all — filesystem, native store, SSH, keystores and source code are all local reads. The other three are opt-in and only need to reach machines you already control.
Get it in, verified
An air gap moves the trust problem to the boundary: whatever you carry across, you should be able to prove is what we published. Verify on the connected side, then carry the verified bytes in.
The four binaries
Each is a self-contained executable — no installer, no package manager, no
dependencies. On a connected Linux or macOS host,
install.sh downloads and
verifies in one step into the current directory (it does not touch anything
system-wide), which is a convenient way to prepare transfer media.
Verify before it crosses
Every release is published with a SHA256SUMS manifest signed
twice: classically with Ed25519, and with post-quantum
ML-DSA-65 (FIPS 204). A tool that tells you your signatures will not
survive a quantum adversary ought to be signed with one that will.
BASE=https://api.pqcrypta.com/stream/downloads/discovery-agent curl -O $BASE/linux # or windows | macos | macos-intel curl -o SHA256SUMS $BASE/verify/SHA256SUMS curl -o SHA256SUMS.sig $BASE/verify/SHA256SUMS.sig curl -o SHA256SUMS.mldsa.sig $BASE/verify/SHA256SUMS.mldsa.sig curl -o pqcrypta-agent-signing.pub $BASE/verify/pqcrypta-agent-signing.pub # 1. classical signature over the manifest openssl pkeyutl -verify -pubin -inkey pqcrypta-agent-signing.pub \ -rawin -in SHA256SUMS -sigfile SHA256SUMS.sig # 2. the manifest pins the binary sha256sum -c SHA256SUMS --ignore-missing
The public keys are published from a second, independent origin — the append-only discovery-agent-keys repository — so you can compare the key you verified with against a copy we do not serve. The full procedure, including ML-DSA verification, is in §2 of the guide.
Verify the manifest signature, not just the hash. A hash alone only proves the file matches a list; the signature is what proves the list is ours. Both checks are cheap and neither needs the enclave.
Configuration presets
With no --config, the agent uses its built-in per-OS path catalog, which is
a good default for a first look. For a repeatable air-gapped scan, carry a TOML file in
alongside the binary: when one is supplied its scan_paths are
authoritative — the agent scans exactly that list and nothing
else, which is usually what an enclave's change control wants to see.
The three reference-* catalogs are the built-in defaults written out as
editable files, so no config at all and --config reference-linux.toml
scan the same set. To narrow a scan, delete paths; to widen it, add your own. Two
settings matter more than usual on an isolated host:
keystore_passwords— passwords tried against locked PKCS#12/PFX/JCEKS containers. A container that stays locked is reported as a gap in coverage rather than a clean result, because an unopened keystore and an empty one otherwise look identical. Passwords are never written to any output file.excluded_paths— pairs with--full-disk-scanto keep a whole-volume sweep out of pseudo-filesystems and build caches.
Running it
One flag switches the run from “submit” to “assess locally”:
--offline-report <dir>. The directory is created if it does not exist.
Linux / macOS
chmod +x ./pqcrypta-discovery
./pqcrypta-discovery --config linux-web-server.toml \
--offline-report ./assessment --deep-scan
Windows
.\pqcrypta-discovery.exe --config windows-server.toml `
--offline-report .\assessment --deep-scan
Flags that change what an offline run covers:
| Flag | Effect |
|---|---|
--deep-scan |
Raises the directory recursion limit from 10 to 20 levels. Worth it on nested application trees; costs time, not correctness. |
--full-disk-scan |
Adds the filesystem root to the targets. Pair with a config whose
excluded_paths skips pseudo-filesystems and noise. |
--algorithms <list> |
Keep only assets whose algorithm matches, e.g. RSA,ECDSA.
Filters the inventory, not the walk. |
--targets <path> |
Override the config's paths entirely for a one-off scan. |
--verbose |
Debug logging, including every file considered. Useful the first time you run inside an enclave and want to see exactly what was touched. |
Elevation changes coverage, not behaviour. Unprivileged, the agent reports the directories it could not read rather than skipping them silently — those warnings are the honest edge of your inventory. Running elevated closes them.
What it produces
Three files, written to the directory you named. They are deliberately different artifacts for three different readers — a person, a tool, and a system of record.
| File | For | What it is |
|---|---|---|
report.html |
A person | A single self-contained assessment you can open on the host itself. |
cbom.json |
A machine | CycloneDX 1.6 Cryptographic Bill of Materials, schema-valid. |
inventory.json |
Your systems | Every asset, every field, plus the assessment for each. |
One file. Every style rule and every row of data is inlined, so it makes no external request of any kind — no CDN, no font, no analytics, no image fetch. It opens in a browser on a machine that has never been online, and it renders identically on the outside.
What is in it
- Header line — generation time in UTC, the host and its OS,
the scan UUID, and an
OFFLINE / AIR-GAPbadge that marks the provenance of the document. - Five headline figures — total cryptographic assets, post-quantum readiness as a percentage, actionable (you own), critical risk, and high risk. The second and third are the ones that matter: readiness is the migration measure, and “actionable” is the part you can start on without waiting for a vendor.
- By remediation owner — assets grouped into
internal,public_ca,os_vendor,language_ecosystem,hardware_vendorandunknown. This is what turns a flat list into a work plan. - Top algorithms — the estate by algorithm, so “what are we actually running” is answered in one glance.
- Host cryptographic posture — what the machine itself offers, which bounds what it can migrate to: TPM, Secure Boot, disk encryption, OpenSSL version, the crypto libraries present, and the CPU's crypto instructions. A check that could not run says Not assessed rather than rendering blank, because on an unprivileged run several of them cannot be read and a blank would look like a negative result.
- Full asset inventory — location, algorithm, bits, status, risk, owner and expiry for every asset, sorted worst-first.
It stays usable at scale
A stock Windows host yields well over seven thousand assets. The table is paginated and filterable from data embedded in the page — free-text search plus dropdowns for status, risk and owner, and an actionable only toggle — all of it working with no server, no network and no build step. With scripting disabled the first hundred rows are still present as plain markup, and a print stylesheet renders the whole thing on white for a paper trail.
A CycloneDX 1.6 Cryptographic Bill of Materials, validated against
the published bom-1.6.schema.json with zero errors.
This is the file to hand to an auditor, feed to a tool, or diff against last
quarter's.
The document identifies its own subject
metadata.component names the machine the inventory is about,
not just the tool that produced it — because cbom.json is the file
most likely to travel on its own, separated from the report and inventory that name
the host in prose. A fresh serialNumber per run means two assessments
are never mistaken for one another.
{
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"serialNumber": "urn:uuid:9736ddc0-9a4b-440e-821f-ada23574ff26",
"version": 1,
"metadata": {
"timestamp": "2026-08-07T20:26:54.361158110+00:00",
"tools": [{ "vendor": "PQCrypta", "name": "discovery-agent", "version": "1.0.16" }],
"component": {
"type": "device",
"bom-ref": "host:pqcrypta.com",
"name": "pqcrypta.com",
"version": "Ubuntu 24.04.4 LTS"
},
"properties": [{ "name": "pqcrypta:mode", "value": "offline" }]
}
}
The host component also carries the machine's cryptographic posture as
properties — TPM, Secure Boot, disk encryption, OpenSSL
version, CPU crypto features, and whether the scan ran privileged, since an
unprivileged scan has blind spots the reader should know about. CycloneDX has
no schema field for any of that, and properties is precisely what
the spec provides for it. The network inventory is deliberately left
out: addresses, MACs, gateways and subnets stay in
inventory.json, because the CBOM is the artifact most likely to
leave the enclave and an isolated estate's internal topology has no business
travelling with it.
Every asset is a component
assetType selects the shape: certificates carry
certificateProperties, key material carries
relatedCryptoMaterialProperties, source-code findings and parameter
files carry algorithmProperties. The SHA-256 goes in the standard
hashes field over the complete DER, so the same certificate is
identifiable against openssl x509 -fingerprint -sha256 and against your
other tooling.
{
"type": "cryptographic-asset",
"bom-ref": "5cc3d78e…70fd@/etc/ssl/certs/CFCA_EV_ROOT.pem",
"name": "CFCA EV ROOT",
"cryptoProperties": {
"assetType": "certificate",
"certificateProperties": {
"subjectName": "CFCA EV ROOT",
"issuerName": "CFCA EV ROOT",
"notValidBefore": "2012-08-08T03:07:01+00:00",
"notValidAfter": "2029-12-31T03:07:01+00:00",
"certificateFormat": "X.509"
}
},
"hashes": [{ "alg": "SHA-256", "content": "5cc3d78e…70fd" }],
"evidence": { "occurrences": [{ "location": "/etc/ssl/certs/CFCA_EV_ROOT.pem" }] },
"properties": [
{ "name": "pqcrypta:location", "value": "/etc/ssl/certs/CFCA_EV_ROOT.pem" },
{ "name": "pqcrypta:algorithm", "value": "RSA" },
{ "name": "pqcrypta:key_size", "value": "4096" }
]
}
Each bom-ref is unique as the spec requires, scoped by fingerprint
and location: one certificate legitimately appears at many paths on a host
— each vendored cacert.pem, the OS trust store, the live endpoint
serving it — so each occurrence is its own component, carrying
evidence.occurrences[].location and a shared
pqcrypta:sha256 that correlates them back to one certificate.
The quantum verdict is in spec fields, not ours
This is the part that makes the file assessable rather than merely
readable. Every asset is linked through the dependencies graph to a
shared algorithm component carrying the CycloneDX primitive, the
parameterSetIdentifier, and
nistQuantumSecurityLevel — where
0 is the spec's way of saying “offers no security against a
quantum adversary”.
{
"type": "cryptographic-asset",
"bom-ref": "algorithm:ecc-secp256r1--p-256-",
"name": "ECC-secp256r1 (P-256)",
"cryptoProperties": {
"assetType": "algorithm",
"algorithmProperties": {
"primitive": "key-agree",
"parameterSetIdentifier": "secp256r1 (P-256)",
"nistQuantumSecurityLevel": 0
}
},
"properties": [{ "name": "pqcrypta:quantum_vulnerable", "value": "true" }]
}
// …and the edge that makes it reachable from the asset:
{
"ref": "5cc3d78e…70fd@/etc/ssl/certs/CFCA_EV_ROOT.pem",
"dependsOn": ["algorithm:rsa-4096"]
}
A consumer that has never heard of PQCrypta can therefore answer “which of
these assets are quantum-vulnerable, and which primitive family do they belong
to” from standard fields alone. The primitive value also splits
the estate into the two workloads federal guidance treats separately:
kem and key-agree are key establishment;
signature is digital signatures.
Everything the agent found and everything it concluded, with nothing dropped for
presentation. Five top-level keys — scan_id,
host, generated, host_metadata and
assets — with up to 55 fields per asset and
35 fields of host posture.
host_metadata is the machine's own security posture, collected
during the same scan: platform and kernel, TPM, Secure Boot, disk encryption,
SELinux/AppArmor, firewall, antivirus, UAC, SIP/Gatekeeper, OpenSSL version,
crypto libraries, CPU crypto features, virtualisation and container runtime,
plus the host's network interfaces and addresses. On an air-gapped host this is
the only place that information is going to be recorded, so none of it is
dropped.
Four groups of fields
- Identity & location —
location,location_type,asset_type,sha256_fingerprint,hostname,port,owner,application,environment, file size, permissions and modification time. - Cryptography —
algorithm,key_size,curve_name,hash_algorithm,key_format. - Full X.509 detail — subject and issuer broken into CN/O/OU/C/ST/L, serial, validity window, CA flag and path length, self-signed flag, SANs, key usage and extended key usage, CRL distribution points, OCSP URLs, policy OIDs, and both key identifiers.
- The assessment —
compliance_status,risk_level,recommendation,remediation_owner,is_actionableandremediation_note.
{
"location": "/etc/ssl/fated/server/smtp.fated.org.key",
"location_type": "filesystem",
"asset_type": "private_key",
"algorithm": "RSA",
"key_size": 4096,
"sha256_fingerprint": "66c2dc47f67b…d739",
"compliance_status": "legacy",
"risk_level": "high",
"recommendation": "Quantum-vulnerable. Migrate to Hybrid (ML-KEM-1024 + ML-DSA-87) or Pure PQ.",
"remediation_owner": "internal",
"is_actionable": true,
"remediation_note": "You hold the private key — this key material is yours to rotate."
}
No secret material is ever written. A private key is recorded as an asset — algorithm, size, curve, format, whether it is passphrase-protected — but its key bytes are not copied into any output file. Database column values are parsed for structure and discarded. Keystore passwords you supply are used to open containers and never appear in output.
Scored on the host — and scored the same way
An offline assessment is worth little if it is a lesser assessment. Post-quantum scoring, risk grading, remediation-ownership classification and CBOM assembly all run on the agent, using the same rules the platform applies at ingestion, and the two implementations are pinned against drift by parity tests: an air-gapped report reads identically to a connected one for the same asset.
Five compliance statuses, applied identically in both modes:
| Status | Meaning |
|---|---|
| compliant | Standardised post-quantum cryptography — ML-KEM, ML-DSA, SLH-DSA, HQC and friends. |
| legacy | Classical and quantum-vulnerable: RSA, ECC, finite-field DH, EdDSA. Works today, must migrate. |
| deprecated | Quantum-resistant but not the standard — pre-FIPS round-3 parameter sets, for example. |
| forbidden | Broken independent of quantum: MD5, SHA-1 in a verified signature, DES, RC4, ECB, undersized RSA. |
| unknown | Honestly undetermined — an encrypted key whose algorithm is inside the ciphertext, an unrecognised algorithm OID, or a container that could not be opened. Never guessed. |
Unattended & repeatable
An inventory is a maintenance obligation, not a one-off. The agent is a single-shot process with no daemon and no state directory, which makes scheduling it trivial — each run overwrites the previous bundle, or writes to a dated directory if you want the history.
0 3 1 * * /opt/pqcrypta/pqcrypta-discovery \
--config /etc/pqcrypta/agent.toml --deep-scan \
--offline-report /var/lib/pqcrypta/$(date +\%Y-\%m) >> /var/log/pqcrypta-scan.log 2>&1
schtasks /create /tn "PQCrypta Assessment" /sc monthly /d 1 /st 03:00 /ru SYSTEM ` /tr "C:\pqcrypta\pqcrypta-discovery.exe --config C:\pqcrypta\agent.toml --deep-scan --offline-report C:\pqcrypta\assessment"
Running as SYSTEM (or root) is what closes the permission-denied gaps
— unprivileged runs report the directories they could not read rather than
pretending they were empty.
Exit codes
| Code | Meaning |
|---|---|
0 | The bundle was written. Including when individual paths were unreadable — those are reported in the log and are a coverage note, not a failed run. |
1 | The run could not produce a bundle: no mode selected, an unwritable output directory, an unparseable config. |
So a scheduler that only watches the exit status will not notice reduced coverage.
If that matters, watch the log for Access is denied /
Permission denied lines, or diff the asset count between runs —
a sharp drop is the signal.
A third mode: raw findings
Between submitting and a full assessment there is --output <file>,
which writes the discovered assets as raw JSON with no local
assessment — no compliance status, no risk, no ownership, no CBOM.
It exists for pipelines that do their own scoring. If you want the assessment, use
--offline-report; the two are alternatives, not layers.
Carrying results out
What crosses the boundary is your call; the tool has no channel of its own. In practice there are two useful patterns:
- Review inside, carry out the machine-readable pair. Read
report.htmlon the host, then movecbom.jsonandinventory.jsonout for aggregation. Both are plain text and diff cleanly, so they survive whatever review your boundary imposes. - Carry out the CBOM only. It identifies its own subject host, so it
stands alone, and it contains no filesystem detail beyond
evidence.occurrences[].location— which you can strip if paths themselves are sensitive.
On the outside, the same inventory can be loaded into the Compliance Dashboard alongside connected hosts, so an air-gapped enclave appears in the same estate-wide readiness numbers as everything else rather than living in a spreadsheet nobody re-runs.
Re-running is cheap and produces a directly comparable document: same fields, fresh
serialNumber, new timestamp. Quarterly re-runs turn a one-off audit into a
trend line — which is what “maintain a cryptographic inventory”
actually asks for.
“But the CBOM format isn't settled yet”
True — and not a reason to wait. The June 2026 executive order “Securing the Nation Against Advanced Cryptographic Attacks” directs CISA and NIST to define the minimum elements of a Cryptographic Bill of Materials: the fields a CBOM must carry to enable automated assessment of cryptographic assets. Those minimum elements have not been published yet. The migration deadlines they support have: key establishment by December 31, 2030, digital signatures by December 31, 2031.
Why the format is the easy part
A CBOM is a serialisation of an inventory. Producing one means you have already discovered every cryptographic asset you hold, parsed each one deeply enough to know its algorithm and parameter set, and classified it. That work is format-independent, and it is the part that takes quarters rather than an afternoon.
Once you hold it, re-issuing in a different schema is a re-export — a mechanical transformation of data you already have. Building the inventory for the first time is a project. An organisation that waits for the format spends the intervening years without an inventory and then still has to build one, on a shorter clock, against the same deadlines.
What we commit to
- Today the agent emits CycloneDX 1.6, validated against the
official schema, with the spec-standard fields —
primitive,parameterSetIdentifier,nistQuantumSecurityLevel, adependenciesgraph — that make automated assessment possible rather than merely promised. - When CISA and NIST publish the minimum elements, PQCrypta will emit that format too, from the same inventory, as an additional export — not a replacement. CycloneDX will keep working for everyone whose tooling already speaks it.
- Because the inventory is the durable asset and the export is derived, that transition is a re-export of scans you already ran. Nothing you inventory now is wasted by a format that lands later.
The clock is on the migration, not the paperwork. Every quarter spent waiting for a schema is a quarter not spent finding the 4,096-bit RSA key on a host nobody remembered, or the SHA-1 signature in a chain that still verifies. Run the scan. Get the CBOM. Reformat it later — that part is a script.
Ready to start? Grab a verified binary, take a config preset, and produce your first assessment in about the time it takes to read this page. The full guide covers connected operation, every scan type and the complete configuration reference.
When you do have a network
Offline mode is complete for one host at one moment. What it cannot do is
accumulate. Point the same binary at an API with
--api-url and --api-key instead of
--offline-report, and the findings stop being a file and start
being an estate.
| Offline | Connected | |
|---|---|---|
| Discovery & parsing | Identical | Identical |
| Scoring & ownership | On the host | At ingestion — same rules, pinned by parity tests |
| Scope | One host, one run | Every host, every run, in one inventory |
| Change over time | Compare files yourself | Assets that disappear are retired; staleness tracked per host |
| CBOM | Per host, on disk | Per host or estate-wide, filtered, on demand |
What connected mode adds
- The Compliance Dashboard — total assets and devices, the compliance split, quantum readiness with a qualitative stage label rather than a bare percentage, organization-controlled versus vendor-controlled progress, and a Discovery Coverage checklist. Most cards jump straight into a pre-filtered inventory.
- Estate-wide CBOM export — one CycloneDX document across every host, filtered by any combination of source, device, algorithm, certificate role and compliance status. CSV and JSON report exports share the identical filter set, so a selection always describes the same rows.
- A policy engine — compliance rules evaluated against every stored asset at ingestion and on demand, so “no RSA under 3072 in production” becomes a check rather than a convention.
- Threat-intelligence correlation — CISA KEV and NVD data matched against the OpenSSL versions your scans actually observed, so a vulnerable library is a current finding rather than a mailing-list post.
- SIEM delivery — real webhook POST or RFC 3164 syslog to a registered destination, so findings land where your analysts already look.
- Lifecycle — assets a scan no longer observes are retired automatically, with a guard that refuses to write off most of a host at once because that is the signature of a narrowed scan, not a decommissioning.
Everything above is in the full guide; the overview covers all eight discovery sources.
Portable: run the whole platform yourself
There is a third option between “one file on one host” and “send it to a vendor”: run the entire platform inside your own network. The self-hosted deployment is a Docker Compose stack of three containers — database, API and dashboard — and no data ever leaves your network. It is the tier for data-sovereignty requirements, ATO scope limits, and enclaves that can have an internal network but no route to a vendor.
| Component | Image | Exposed |
|---|---|---|
| PostgreSQL 16 + pgvector | pgvector/pgvector:pg16 |
Internal only — never published to the host |
| API (Rust) | pqcrypta/api |
Port 3003 |
| Compliance Dashboard (Apache + PHP) | pqcrypta/dashboard |
Port 8080 |
cd deploy/onprem cp .env.example .env # set the secrets: openssl rand -hex 32 # drop your licence at license/license.json docker compose up -d --build # Dashboard http://<host>:8080/dashboard/ # API health http://<host>:3003/health
The schema and policy seed apply automatically on first start. Agents anywhere on your network then submit to your API rather than ours:
./pqcrypta-discovery --config agent.toml \
--api-url http://<host>:3003 --api-key <key>
It installs air-gapped too
The same stack ships as a transferable bundle, which is the case this page cares about most: an enclave large enough to have its own network can run the connected product entirely inside the boundary — dashboard, history, estate-wide CBOM and all — with nothing crossing it.
# on a connected build host deploy/onprem/scripts/build-airgap-bundle.sh # → pqcrypta-onprem-airgap-<date>.tar.gz (+ .sha256) # carry it in, verify the checksum, extract, then on the disconnected host scripts/install-airgap.sh # loads images — no registry pull, ever
Every image and the signed agent artifacts are inside the tarball; nothing is fetched from the internet at install time or afterwards.
The licence does not phone home either
A self-hosted licence would be worthless if validating it required the network it exists to avoid. The licence is a JSON envelope signed with ML-DSA (Dilithium3) and verified offline at API startup against a public key compiled into the binary — no callback, no activation server, no heartbeat. A missing or expired licence degrades to a grace mode rather than stopping work; only a tampered one is refused outright.
Requirements are modest: a Linux host with Docker Engine and the Compose plugin, roughly 2 vCPU and 4 GB RAM to start, scaling with inventory size.
Self-hosting is a licensed tier rather than a public download — talk to us and we will issue a licence and the bundle. If you only need the assessment and not the platform, everything above this section still applies: the agent alone is free to download, and the three files it writes are yours.