Trust Center
CryptOS Security
Architecture, appliance design, boot chain, key custody and the fleet of a self-hosted PKI operating system, with the evidence behind each claim.
CryptOS holds no SOC 2 report, ISO 27001 certificate or other certification. This review describes only what is built, links the code and tests behind each claim so an independent reviewer can check it, and lists every known gap. Where a control depends on how you deploy CryptOS, it says so.
1. Scope and how to read this review
CryptOS is an immutable, API-driven PKI operating system. A node boots a signed kernel image into a read-only root, keeps its CA key in the TPM, and is managed only over a mutually authenticated gRPC API. FleetOS Manager is an optional console for many nodes. You run both yourself; the project operates no service and never receives your keys.
This review covers the v0.1.0 release train, currently at release candidate 1. Implemented means the code is on main, with the release it first shipped in. Partial means it is built with a named gap. Planned means it isn't built. Not planned means it is left out on purpose.
CryptOS is pre-1.0. Ceremonies are one person today, high-availability pairs and split-custody recovery aren't built, and a TPM-held CA key can't be backed up. They are described plainly in their sections and collected in Gaps and planned work.
2. Architecture and trust boundaries
A node is one Go program running as PID 1. It serves the management API, the enrolment protocols you turn on, revocation and time-stamping, and keeps its state in an embedded etcd on the encrypted state partition. There is no shell, no SSH server and no login.
| Surface | Port and transport | Who can reach it |
|---|---|---|
| Management API | 443, gRPC over TLS 1.3, client certificate required | Only the admin certificate pinned in the machine config: cryptosctl, or FleetOS Manager holding that node's credential |
| Break-glass socket | /run/cryptos.sock, UNIX socket, no TLS | Software on the box only: the local dashboard and cryptosctl run there |
| ACME | 8555, HTTP | Enrolment clients, when ACME is on; never on a Root |
| EST | 8443, TLS | Enrolment clients, when EST is on; never on a Root |
| SCEP | 80, HTTP | Enrolment clients, when SCEP is on; never on a Root |
| Time-stamping | 318, HTTP | Requesters, when the TSA is on; never on a Root |
| CRL, OCSP, CA certificate | 80, HTTP | Relying parties, when a revocation base URL is set |
| Maintenance mode | 443, TLS, no client certificate | Only before install, to adopt or install the node |
Trust domains: the node trusts one pinned admin certificate for management; its own CA chain for what it issues; and FleetOS Manager's operators are signed by a separate operator CA that the node never sees.
Controls: Architecture and trust boundaries
| Control | Status | Evidence |
|---|---|---|
| ARC-1 No interactive access A node has no SSH server, login prompt, shell or user accounts. The kernel is built without loadable modules and boots with lockdown=confidentiality. | Implemented in v0.1.0-rc.1 | cryptos-appliance/build/kernel/cryptos.config (CONFIG_MODULES unset, forced lockdown)cryptos-appliance/build/uki/assemble.sh (kernel command line)website/apps/docs/docs/concepts/immutable-no-login.md |
| ARC-2 Remote management is mutual TLS only The management API is gRPC over TLS 1.3 with a client certificate required. A certificate that doesn't match the node's pinned admin is refused. | Implemented in v0.1.0-rc.1 | cryptos-node/internal/grpc/authz.gocryptos-node/internal/grpc/authz_test.go (TestAuthorizeAdmin_MismatchIsPermissionDenied)cryptos-node/internal/init/servertls.go |
| ARC-3 Break-glass socket on the box only An unauthenticated UNIX socket serves the same API for on-box use only, with no network listener behind it. An unauthenticated reset works only there; over the network, reset needs the admin and the Root CA name typed back. | Implemented in v0.1.0-rc.1 | cryptos-node/internal/grpc/authz.gocryptos-node/internal/grpc/authz_test.go (TestAuthorizeAdmin_LocalNoPeer)website/apps/docs/docs/deep-dives/trust-from-zero.md |
| ARC-4 Embedded state store on loopback The node's etcd listens on 127.0.0.1 only and keeps its data on the encrypted state partition. | Implemented in v0.1.0-rc.1 | cryptos-node/internal/storage/etcd/etcd.go |
| ARC-5 No web interface in the OS image The node serves no web front end, compiled or otherwise. A web console exists only in FleetOS Manager, which runs off the node. Why: Every web stack on the CA is more code that could be attacked. Nodes stay API-only by design. | Not planned | cryptos-node/README.md |
| ARC-6 No cross-signing between Roots Each Root is its own trust domain. CryptOS doesn't cross-sign one Root with another. Why: Siloed Roots keep a compromise of one hierarchy from reaching another. It stays out until a real need appears. | Not planned | website/apps/docs/docs/concepts/ca-roles.md |
Controls: Issuance and protocols
| Control | Status | Evidence |
|---|---|---|
| ISS-1 RFC 5280 Root certificates The Root certificate the node self-signs is checked by zlint in the test suite with no errors and no warnings. | Implemented in v0.1.0-rc.1 | cryptos-node/internal/ca/ca_test.go (TestSelfSignRoot_ZLintCleanRoot) |
| ISS-2 One profile engine for every issuance path Every path to a certificate, the API and the ACME, EST and SCEP adapters included, goes through one profile engine that decides the extensions. A subordinate's path length is clamped to what its parent allows. | Implemented in v0.1.0-rc.1 | cryptos-node/internal/ca/profile.gocryptos-node/internal/node/signer.go (clampPathLen) |
| ISS-3 No arbitrary CSR signing in production builds The raw SignCSR call is a stub in production builds; it exists only in a debug build tag. | Implemented in v0.1.0-rc.1 | cryptos-node/internal/grpc/signcsr_stub.gocryptos-node/internal/grpc/server_test.go (TestSignCSR_StubReturnsUnimplemented) |
| ISS-4 SCEP (RFC 8894) SCEP enrolment, tested against the sscep client in CI. | Implemented in v0.1.0-rc.1 | cryptos-node/internal/scep/sscep_test.gocryptos-node/.github/workflows/ci-go.yml (Build sscep) |
| ISS-5 ACME (RFC 8555) ACME with http-01 and External Account Binding, and a strict JWS algorithm allow-list. dns-01, wildcards, key change and account deactivation aren't built. | Partial in v0.1.0-rc.1 | cryptos-node/internal/acme/doc.gocryptos-node/internal/acme/jws_test.go (TestVerifyJWSAlgorithmConfusion)Open: cryptos-node#110 ACME HTTP-01/DNS-01 for cert-manager and native clients |
| ISS-6 EST (RFC 7030) An EST enrolment adapter over TLS. | Implemented in v0.1.0-rc.1 | cryptos-node/internal/est/handlers.gocryptos-node/docs/est.md |
| ISS-7 Revocation: CRL and OCSP The node publishes an RFC 5280 CRL and answers RFC 6960 OCSP requests when a revocation URL is set. | Implemented in v0.1.0-rc.1 | cryptos-node/internal/revocation/crl.gocryptos-node/internal/revocation/ocsp.gocryptos-node/internal/revocation/http_test.go |
| ISS-8 Time-stamping (RFC 3161) A built-in time-stamp authority that refuses SHA-1 and MD5 message imprints. | Implemented in v0.1.0-rc.1 | cryptos-node/internal/tsa/responder.gocryptos-node/internal/tsa/responder_test.go |
| ISS-9 Root CAs serve no enrolment protocols Config validation refuses ACME, EST, SCEP and the TSA on a Root, so a Root never answers enrolment requests. | Implemented in v0.1.0-rc.1 | cryptos-node/internal/config/protocols.go |
| ISS-10 Windows autoenrolment (MS-XCEP and WSTEP) Native Windows autoenrolment through Group Policy isn't built. | Planned | Open: cryptos-node#108 Native Windows autoenrolment via GPO (MS-XCEP/WSTEP) |
3. The appliance
The image is a unified kernel image (UKI): systemd-stub, the Linux kernel, a command line with lockdown=confidentiality, and a small initrd that carries a SquashFS root, mounts it read-only and switches into it. The kernel has no loadable modules.
| Part | What it is | Written |
|---|---|---|
| EFI system partition (p1) | FAT, 512 MiB: the UKI and EFI/cryptos/machine.yaml | By the installer and by signed upgrades |
| Root filesystem | SquashFS inside the UKI: init, cryptosctl, cryptos-console, cryptsetup and disk tools | Never; mounted read-only |
| State partition (p2) | LUKS2, aes-xts-plain64, argon2id, ext4 at /var/lib/cryptos: config, etcd, audit | By the node, only after the TPM unseals it |
There is one network interface: management binds its configured address, and the protocol listeners bind all addresses. The local console shows a read-only status screen and has no login prompt.
Controls: Appliance platform
| Control | Status | Evidence |
|---|---|---|
| APP-1 Read-only root filesystem The signed kernel image carries the Go PID 1 and a SquashFS root that is mounted read-only. Only the encrypted state partition is writable. | Implemented in v0.1.0-rc.1 | cryptos-appliance/build/squashfs/build.shcryptos-appliance/internal/switchroot/switchroot.go |
| APP-2 Secure Boot with your own key Releases ship unsigned and the release pipeline checks they are. You sign the kernel image with your own Secure Boot key, so nothing in your chain of trust is signed by the project. | Implemented in v0.1.0-rc.1 | cryptos-appliance/build/uki/sign.shcryptos-appliance/build/release/check-unsigned.shcryptos-appliance/docs/secure-boot.md |
| APP-3 Signed in-place upgrades with rollback An upgrade image is checked against a detached signature before anything is written to the boot partition, and the previous image is kept for one rollback. | Implemented in v0.1.0-rc.1 | cryptos-node/internal/imageupgrade/imageupgrade.gocryptos-node/internal/imageupgrade/imageupgrade_test.go (TestStage_RefusesASignatureOverOtherBytes) |
| APP-4 Remote attestation Measured boot gates the state disk (KEY-2). A node proves its identity by signing a challenge with its CA key; a TPM quote of its boot measurements isn't offered yet. | Partial in v0.1.0-rc.1 | cryptos-node/internal/grpc/attest.go |
| APP-5 A guarded clock A time floor and NTP sync keep certificate validity and time-stamps from going backwards. | Implemented in v0.1.0-rc.1 | cryptos-node/internal/timesync/floor.gowebsite/apps/docs/docs/deep-dives/clock-safety.md |
| APP-6 More platforms Node images are amd64 for VMware today. Proxmox VE, bare-metal installs and an arm64 image are in progress. | Planned | website/apps/docs/docs/introduction/status-roadmap.mdOpen: cryptos-appliance#38 Support Proxmox VE as a VM platformOpen: cryptos-appliance#54 A plain installer ISO for bare-metal serversOpen: cryptos-appliance#117 Build and prove an arm64 appliance image |
4. Boot chain and TPM key custody
| Key | Algorithm | Where it lives |
|---|---|---|
| Storage root key | ECC P-256 | Persistent in the TPM at 0x81000001 |
| State disk key | LUKS2, aes-xts-plain64, 512-bit | Sealed in the TPM under PolicyPCR 7 + 11; blob in LUKS2 token 0 |
| CA key (TPM mode) | ECDSA P-384 with SHA-384, or RSA 3072+ | Created in the TPM under the SRK; wrapped blob in etcd; export refused |
| CA key (nodeid or kms mode) | As above | In software on the encrypted partition, not hardware-protected |
| Ceremony manifest key | Ed25519 | Derived on the node; signs the ceremony record |
| Secure Boot key | RSA, yours | Off the box: you sign the UKI with it |
- The node boots in maintenance mode and installs to disk, staging the machine config on the EFI partition.
- The installed node encrypts its state partition and seals the key to PCR 7 and 11.
- Over the channel pinned to the admin certificate, the ceremony provisions the SRK and creates the CA key inside the TPM.
- The node self-signs the Root certificate, signs the ceremony manifest, and commits both to etcd in one step.
An image upgrade predicts the new PCR 11 and reseals the state key before anything is written, so a signed upgrade keeps the disk readable and a tampered one doesn't.
Controls: Keys and TPM custody
| Control | Status | Evidence |
|---|---|---|
| KEY-1 CA keys are made and used inside the TPM In TPM mode the CA key is created inside the TPM under its storage root key, only its wrapped blob is stored, and export is refused. | Implemented in v0.1.0-rc.1 | cryptos-node/internal/tpm/key.gocryptos-node/internal/init/escrow_test.go (TestExportRefusedWhenNotExportable)website/apps/docs/docs/deep-dives/keys-never-leave-tpm.md |
| KEY-2 The state disk is sealed to the boot chain The LUKS2 state partition's key is sealed in the TPM to PCR 7 (Secure Boot) and PCR 11 (the signed kernel image). A changed boot chain can't unseal it. | Implemented in v0.1.0-rc.1 | cryptos-node/internal/tpm/seal.gocryptos-node/internal/tpm/seal_test.go (TestUnseal_FailsAfterPCRDrift)website/apps/docs/docs/concepts/tpm-sealed-keys.md |
| KEY-3 Sealing follows upgrades and rollbacks Before an upgrade or rollback, the node predicts the new PCR 11 and reseals the state key for exactly the images it can boot, adding before it removes. | Implemented in v0.1.0-rc.1 | cryptos-node/internal/init/statekeyreseal.gocryptos-node/internal/init/statekeyreseal_test.go (TestReseal_KeyFollowsAnUpgradeAndItsRollback) |
| KEY-4 Strong CA key algorithms only CA keys in the TPM are ECDSA P-384 with SHA-384, or RSA of at least 3072 bits. Anything smaller is refused. | Implemented in v0.1.0-rc.1 | cryptos-node/internal/tpm/key.go (MinRSAKeyBits)cryptos-node/internal/tpm/keyalg_test.go (TestPublicTemplateRSAFloor) |
| KEY-5 Software key modes are labelled as such The nodeid (development) and kms modes keep the CA key in software on the encrypted partition, not in the TPM, and the code and docs say so plainly. | Partial in v0.1.0-rc.1 | cryptos-node/internal/init/softroot.gocryptos-node/internal/config/config.go |
| KEY-6 No network HSM for CA keys CA keys live only in the node's own TPM; a network HSM or PKCS#11 device for CA keys is out of scope. The kms mode wraps only the state disk's key with an external KMS. Saying so plainly in the docs is planned. | Planned | Open: website#42 Say that CA keys stay in the TPM and a network HSM is out of scope |
Controls: Ceremonies and quorum
| Control | Status | Evidence |
|---|---|---|
| CER-1 First-boot Root ceremony A Root key and its self-signed certificate are made in a first-boot ceremony, authorised by the admin certificate pinned in the machine config. | Implemented in v0.1.0-rc.1 | cryptos-node/internal/ceremony/ceremony.gowebsite/apps/docs/docs/deep-dives/ceremony-walkthrough.md |
| CER-2 Signed ceremony manifest The ceremony writes an Ed25519-signed manifest, and tampering with it is detected. The signing key is derived on the node; it isn't an operator's signature. | Implemented in v0.1.0-rc.1 | cryptos-node/internal/ceremony/ceremony.gocryptos-node/internal/ceremony/ceremony_test.go (TestVerifyManifest_Tamper) |
| CER-3 M-of-N quorum for Root operations Ceremonies are one person today. Requiring M of N key holders for Root operations isn't built. | Planned | Open: cryptos-node#371 Build M-of-N quorum ceremonies |
| CER-4 Guarded factory reset A reset needs the Root CA name typed back, compared in constant time, and fails closed. A quorum and one-time-code gate on top of it is planned. | Partial in v0.1.0-rc.1 | cryptos-node/internal/reset/reset.gocryptos-node/internal/reset/reset_test.go (TestWipeEmptyRootCNFailsClosed)Open: cryptos-node#361 Require M-of-N quorum plus holder codes for a factory reset |
5. FleetOS Manager and the fleet
FleetOS Manager is a Go service with the web console built in, on one HTTPS listener. Operators sign in with a client certificate from your own operator CA. The manager connects out to each node over mTLS on port 443 with that node's admin credential; nodes never call the manager.
- An admin points the manager at a node in maintenance mode and confirms the certificate fingerprint it presents.
- The manager mints a P-256 clientAuth admin credential for the node and installs CryptOS to the disk the node reports.
- After the reboot the adoption pauses until an admin matches the new management certificate against the Mgmt SHA-256 line on the node's console.
- The manager runs the first-boot ceremony and registers the node.
- An operator supplies the node's address, an admin credential and the CA its management certificate chains to.
- The manager refuses the node unless its certificate verifies, then has it sign a random challenge (SHA-384) with its CA key and pins that key.
- The link is recorded as PENDING.
- An admin approves; the manager checks the node against the pin again, and the node's own operator surface becomes read-only.
| Storage mode | Setting | Persists |
|---|---|---|
| PostgreSQL | database_url | Yes |
| Valkey or Redis (next release) | storage.mode: kv | Yes, with AOF; refuses to start without persistence |
| Memory | storage.mode: memory | No; one replica, health reports degraded |
Controls: FleetOS Manager
| Control | Status | Evidence |
|---|---|---|
| FLT-1 The manager holds no CA key Certificates are issued and revoked on the node that holds the CA. The manager carries CSRs and signed certificates; the only certificates it makes are its own first-run TLS certificate and each node's admin credential. | Implemented in v0.1.0-rc.1 | cryptos-manager/internal/fleet/certs.gocryptos-manager/internal/fleet/adopt_bootstrap.gocryptos-manager/cmd/manager/selfsigned.go |
| FLT-2 A node is pinned before it is trusted Adoption pauses until an admin confirms the node's certificate fingerprint against its console. A link request pins the node's CA key from a signed challenge and waits as pending until an admin approves it. | Implemented in v0.1.0-rc.1 | cryptos-manager/internal/fleet/enrollment.gocryptos-manager/internal/fleet/attest.gocryptos-manager/docs/node-trust.md |
| FLT-3 Both sides verify every connection The node accepts only the admin credential the manager made for it, and the manager accepts only the node certificate it recorded. A node it can't verify is refused. | Implemented in v0.1.0-rc.1 | cryptos-manager/internal/nodeclient/servertrust.gocryptos-manager/docs/node-trust.md |
| FLT-4 Pending-link until managed credentials exist Marking an adopted node pending-link until its managed credentials are provisioned isn't built. | Planned | Open: cryptos-manager#54 Mark adopted nodes pending-link until managed credentials are provisioned |
| FLT-5 A minimal, non-root manager image The manager image is distroless, runs as a non-root user, and its base images are pinned by digest. | Implemented in v0.1.0-rc.1 | cryptos-manager/Dockerfile |
Controls: Identity, access and approvals
| Control | Status | Evidence |
|---|---|---|
| ACC-1 One pinned admin per node A node trusts exactly one admin certificate, pinned in its machine config. There are no roles or accounts on the node itself. | Implemented in v0.1.0-rc.1 | cryptos-node/internal/bootstrap/bootstrap.gocryptos-node/internal/grpc/authz.go |
| ACC-2 Certificate-based roles in FleetOS Manager Operators sign in with a client certificate from your own operator CA. Viewer, operator and admin levels travel in the certificate. No passwords are stored. | Implemented in v0.1.0-rc.1 | cryptos-manager/internal/authz/level.gocryptos-manager/internal/authz/level_test.go (TestLevelFromCertificate)cryptos-manager/docs/operator-ca.md |
| ACC-3 Operator certificates are re-checked for revocation Every request re-checks the operator's certificate against the manager's denylist, the CA's CRL and, where set, its OCSP responder. | Implemented in v0.1.0-rc.1 | cryptos-manager/internal/operatorca/crl.gocryptos-manager/internal/operatorca/ocsp.go |
| ACC-4 No self-approval Certificate requests wait for an operator or admin, the requester can't approve their own, and both identities are audited. | Implemented in v0.1.0-rc.1 | cryptos-manager/internal/approval/approval.go (ErrSelfApproval)website/apps/docs/docs/fleet-manager/approvals.md |
| ACC-5 Agents go through the same checks AI agents on the optional MCP endpoint get keys through an OAuth login that needs the operator's client certificate, and sensitive tools need a person's step-up approval. | Implemented in v0.1.0-rc.1 | cryptos-manager/internal/mcpserver/stepup.gocryptos-manager/docs/mcp.md |
6. Audit, availability and recovery
Each node keeps a SHA-256 hash-chained audit log, signed with a key kept apart from the CA key, which cryptosctl can verify. FleetOS Manager keeps its own hash-chained log with the acting operator and any approver.
A node is a single machine today. A TPM-held CA key can't leave the TPM, so it can't be escrowed; losing that node's TPM loses that CA. Software keys can be escrowed in a passphrase envelope. An encrypted backup of a node's state and export of the audit log to a SIEM are planned, and pairs with failover and split-custody recovery are on the roadmap.
Controls: Audit trail
| Control | Status | Evidence |
|---|---|---|
| AUD-1 Signed, hash-chained node audit log Every node operation is appended to a SHA-256 hash chain, signed with a key kept apart from the CA key, on the encrypted partition. | Implemented in v0.1.0-rc.1 | cryptos-node/internal/audit/doc.gocryptos-node/internal/audit/audit_test.go (TestVerifyChain_DetectsSignatureTamper)website/apps/docs/docs/deep-dives/audit-integrity.md |
| AUD-2 Operators can verify the log cryptosctl lists the audit log and verifies its chain and signatures. | Implemented in v0.1.0-rc.1 | cryptos-node/cmd/cryptosctl/audit.gowebsite/apps/docs/docs/using/audit-log.md |
| AUD-3 Hash-chained manager audit log FleetOS Manager records every change with the acting operator, and the approval and approver where there is one, in a hash chain. | Implemented in v0.1.0-rc.1 | cryptos-manager/internal/auditlog/auditlog.go |
| AUD-4 Audit retention with a signed checkpoint The node log grows without a retention policy today. Trimming it behind a signed checkpoint isn't built. | Planned | Open: cryptos-node#327 Audit retention with a signed checkpoint |
| AUD-5 Audit export to a SIEM Each node keeps its own signed, hash-chained log, which cryptosctl reads and verifies on the node. Shipping it to a SIEM isn't built. | Planned | Open: cryptos-node#408 Export the audit log to a SIEM |
Controls: Availability and recovery
| Control | Status | Evidence |
|---|---|---|
| REC-1 CA key escrow for software keys A software CA key can be exported and imported in a passphrase envelope (Argon2id and AES-256-GCM). A TPM key can't be exported, so it can't be escrowed. | Partial in v0.1.0-rc.1 | cryptos-node/internal/backup/doc.gocryptos-node/internal/init/escrow.go |
| REC-2 Two-node pairs with failover Active and passive pairs with a shared address and lease-gated signing aren't built. | Planned | website/apps/docs/docs/introduction/status-roadmap.md (Phase 3: high-availability pairs) |
| REC-3 Split custody for Root recovery Recovering a Root through split custody (for example Shamir shares or smart cards) isn't built. | Planned | website/apps/docs/docs/introduction/status-roadmap.md (Phase 3: disaster recovery) |
| REC-4 A changed boot chain means a rebuild In TPM mode, if the PCR values drift outside an upgrade the state disk can't be unsealed and the node must be set up again. This is a stated limit, not a recovery path. | Partial in v0.1.0-rc.1 | cryptos-node/internal/init/statekey.go |
| REC-5 Encrypted backup of node state There is no backup of a node's etcd state today; only a software CA key can be escrowed (REC-1). An encrypted snapshot and restore isn't built. | Planned | Open: cryptos-node#407 Encrypted backup and restore of a node's etcd state |
7. Supply chain and development
Release images are built twice and compared byte for byte, and ship with SHA256SUMS and a build manifest. They ship unsigned on purpose: you sign the UKI with your own Secure Boot key, so no project key sits in your chain of trust.
Every change goes through a pull request with CI: Go formatting, lint, vet and tests with a software TPM, interop tests against standard clients, and secret scanning. Scanning for known vulnerabilities with govulncheck and gosec is planned.
Controls: Supply chain and development
| Control | Status | Evidence |
|---|---|---|
| SUP-1 Reproducible release images The release pipeline builds the image twice and compares the outputs byte for byte. Releases carry SHA256SUMS and a build manifest. | Implemented in v0.1.0-rc.1 | cryptos-appliance/build/release/reproducible.shcryptos-appliance/docs/release.md |
| SUP-2 No project signature on releases The project doesn't sign the images you boot. You verify the checksums and sign with your own key (APP-2). Why: A project key in your boot chain would make the project a party to your trust. You hold the keys, not us. | Not planned | cryptos-appliance/docs/secure-boot.md |
| SUP-3 SBOM and build provenance Release images carry no SBOM or provenance attestation; the image build sets them off. Why: Reproducible builds and published checksums are the check today; an SBOM isn't scheduled. | Not planned | cryptos-manager/.github/workflows/job-release-image.yaml |
| SUP-4 Secret scanning Gitleaks runs in CI on every code repository. | Implemented in v0.1.0-rc.1 | cryptos-node/.github/workflows/job-gitleaks.yamlcryptos-appliance/.github/workflows/job-gitleaks.yaml |
| SUP-5 Tests gate every change Go code is formatted, linted, vetted and tested in CI, with a software TPM and interop tests, before it can merge. | Implemented in v0.1.0-rc.1 | cryptos-node/.github/workflows/ci-go.yml |
| SUP-6 Pinned CI actions Third-party GitHub Actions are pinned by commit SHA. A few org and tool references still float. | Partial | cryptos-node/.github/workflows/ci-go.yml |
| SUP-7 Standard library crypto on the certificate path Key generation, signing and X.509 use only the Go standard library and golang.org/x/crypto. It is a written rule; no linter enforces it yet. | Partial in v0.1.0-rc.1 | cryptos-node/internal/ca/doc.go |
| SUP-8 Private vulnerability reporting Vulnerabilities are reported privately through GitHub security advisories; the latest 0.x release gets fixes. | Implemented | .github/SECURITY.md |
| SUP-9 Vulnerability scanning in CI CI scans for secrets and runs the linters and tests, but no workflow checks for known vulnerabilities with govulncheck or runs gosec yet. | Planned | Open: cryptos-node#406 Run govulncheck and gosec in the Go repos' CI |
Gaps and planned work
Every control that is partial or planned, with the open issue or roadmap entry that tracks it. Nothing here is promised for a date.
| Control | Status | Evidence |
|---|---|---|
| KEY-5 Software key modes are labelled as such The nodeid (development) and kms modes keep the CA key in software on the encrypted partition, not in the TPM, and the code and docs say so plainly. | Partial in v0.1.0-rc.1 | cryptos-node/internal/init/softroot.gocryptos-node/internal/config/config.go |
| KEY-6 No network HSM for CA keys CA keys live only in the node's own TPM; a network HSM or PKCS#11 device for CA keys is out of scope. The kms mode wraps only the state disk's key with an external KMS. Saying so plainly in the docs is planned. | Planned | Open: website#42 Say that CA keys stay in the TPM and a network HSM is out of scope |
| CER-3 M-of-N quorum for Root operations Ceremonies are one person today. Requiring M of N key holders for Root operations isn't built. | Planned | Open: cryptos-node#371 Build M-of-N quorum ceremonies |
| CER-4 Guarded factory reset A reset needs the Root CA name typed back, compared in constant time, and fails closed. A quorum and one-time-code gate on top of it is planned. | Partial in v0.1.0-rc.1 | cryptos-node/internal/reset/reset.gocryptos-node/internal/reset/reset_test.go (TestWipeEmptyRootCNFailsClosed)Open: cryptos-node#361 Require M-of-N quorum plus holder codes for a factory reset |
| ISS-5 ACME (RFC 8555) ACME with http-01 and External Account Binding, and a strict JWS algorithm allow-list. dns-01, wildcards, key change and account deactivation aren't built. | Partial in v0.1.0-rc.1 | cryptos-node/internal/acme/doc.gocryptos-node/internal/acme/jws_test.go (TestVerifyJWSAlgorithmConfusion)Open: cryptos-node#110 ACME HTTP-01/DNS-01 for cert-manager and native clients |
| ISS-10 Windows autoenrolment (MS-XCEP and WSTEP) Native Windows autoenrolment through Group Policy isn't built. | Planned | Open: cryptos-node#108 Native Windows autoenrolment via GPO (MS-XCEP/WSTEP) |
| AUD-4 Audit retention with a signed checkpoint The node log grows without a retention policy today. Trimming it behind a signed checkpoint isn't built. | Planned | Open: cryptos-node#327 Audit retention with a signed checkpoint |
| AUD-5 Audit export to a SIEM Each node keeps its own signed, hash-chained log, which cryptosctl reads and verifies on the node. Shipping it to a SIEM isn't built. | Planned | Open: cryptos-node#408 Export the audit log to a SIEM |
| APP-4 Remote attestation Measured boot gates the state disk (KEY-2). A node proves its identity by signing a challenge with its CA key; a TPM quote of its boot measurements isn't offered yet. | Partial in v0.1.0-rc.1 | cryptos-node/internal/grpc/attest.go |
| APP-6 More platforms Node images are amd64 for VMware today. Proxmox VE, bare-metal installs and an arm64 image are in progress. | Planned | website/apps/docs/docs/introduction/status-roadmap.mdOpen: cryptos-appliance#38 Support Proxmox VE as a VM platformOpen: cryptos-appliance#54 A plain installer ISO for bare-metal serversOpen: cryptos-appliance#117 Build and prove an arm64 appliance image |
| FLT-4 Pending-link until managed credentials exist Marking an adopted node pending-link until its managed credentials are provisioned isn't built. | Planned | Open: cryptos-manager#54 Mark adopted nodes pending-link until managed credentials are provisioned |
| REC-1 CA key escrow for software keys A software CA key can be exported and imported in a passphrase envelope (Argon2id and AES-256-GCM). A TPM key can't be exported, so it can't be escrowed. | Partial in v0.1.0-rc.1 | cryptos-node/internal/backup/doc.gocryptos-node/internal/init/escrow.go |
| REC-2 Two-node pairs with failover Active and passive pairs with a shared address and lease-gated signing aren't built. | Planned | website/apps/docs/docs/introduction/status-roadmap.md (Phase 3: high-availability pairs) |
| REC-3 Split custody for Root recovery Recovering a Root through split custody (for example Shamir shares or smart cards) isn't built. | Planned | website/apps/docs/docs/introduction/status-roadmap.md (Phase 3: disaster recovery) |
| REC-4 A changed boot chain means a rebuild In TPM mode, if the PCR values drift outside an upgrade the state disk can't be unsealed and the node must be set up again. This is a stated limit, not a recovery path. | Partial in v0.1.0-rc.1 | cryptos-node/internal/init/statekey.go |
| REC-5 Encrypted backup of node state There is no backup of a node's etcd state today; only a software CA key can be escrowed (REC-1). An encrypted snapshot and restore isn't built. | Planned | Open: cryptos-node#407 Encrypted backup and restore of a node's etcd state |
| SUP-6 Pinned CI actions Third-party GitHub Actions are pinned by commit SHA. A few org and tool references still float. | Partial | cryptos-node/.github/workflows/ci-go.yml |
| SUP-7 Standard library crypto on the certificate path Key generation, signing and X.509 use only the Go standard library and golang.org/x/crypto. It is a written rule; no linter enforces it yet. | Partial in v0.1.0-rc.1 | cryptos-node/internal/ca/doc.go |
| SUP-9 Vulnerability scanning in CI CI scans for secrets and runs the linters and tests, but no workflow checks for known vulnerabilities with govulncheck or runs gosec yet. | Planned | Open: cryptos-node#406 Run govulncheck and gosec in the Go repos' CI |
Left out on purpose
What CryptOS leaves out on purpose, and why. These aren't gaps waiting for a fix.
| Control | Status | Evidence |
|---|---|---|
| ARC-5 No web interface in the OS image The node serves no web front end, compiled or otherwise. A web console exists only in FleetOS Manager, which runs off the node. Why: Every web stack on the CA is more code that could be attacked. Nodes stay API-only by design. | Not planned | cryptos-node/README.md |
| ARC-6 No cross-signing between Roots Each Root is its own trust domain. CryptOS doesn't cross-sign one Root with another. Why: Siloed Roots keep a compromise of one hierarchy from reaching another. It stays out until a real need appears. | Not planned | website/apps/docs/docs/concepts/ca-roles.md |
| SUP-2 No project signature on releases The project doesn't sign the images you boot. You verify the checksums and sign with your own key (APP-2). Why: A project key in your boot chain would make the project a party to your trust. You hold the keys, not us. | Not planned | cryptos-appliance/docs/secure-boot.md |
| SUP-3 SBOM and build provenance Release images carry no SBOM or provenance attestation; the image build sets them off. Why: Reproducible builds and published checksums are the check today; an SBOM isn't scheduled. | Not planned | cryptos-manager/.github/workflows/job-release-image.yaml |