Trust Center
What protects your CA, and what doesn't
Every control below says whether it is built, the release it shipped in and the code and tests that prove it. Gaps link the open work that tracks them, and the things CryptOS leaves out on purpose say why.
- 38Implemented
- 8Partial
- 11Planned
- 4Not planned
CryptOS holds no certifications. It is open-source software you run yourself, not a hosted service, so there is no SOC 2 report or ISO 27001 certificate to share. Every claim here links to the code, so your own reviewers can test it.
CryptOS is pre-1.0 (v0.1.0-rc.1 is the latest release). Expect the gaps listed here to change from one release candidate to the next.
Architecture
How it fits
The node's surfaces and where each trust boundary sits, then the appliance from firmware to the CA. The security review adds the boot chain, key custody and the fleet.
Controls
Controls by
Implemented means it is built and on main, with the release it first shipped in. Partial means it is built with a named gap. Planned means it isn't built yet. Not planned means it is left out on purpose.
Architecture and trust boundaries 6
No shell and no login: one mutually authenticated API, and a break-glass socket that never leaves the box.
ARC-1 No interactive access
Implemented in v0.1.0-rc.1A node has no SSH server, login prompt, shell or user accounts. The kernel is built without loadable modules and boots with lockdown=confidentiality.
Evidence (3)
- code cryptos-appliance/build/kernel/cryptos.config · CONFIG_MODULES unset, forced lockdown
- code cryptos-appliance/build/uki/assemble.sh · kernel command line
- doc website/apps/docs/docs/concepts/immutable-no-login.md
ARC-2 Remote management is mutual TLS only
Implemented in v0.1.0-rc.1The 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.
Evidence (3)
- code cryptos-node/internal/grpc/authz.go
- test cryptos-node/internal/grpc/authz_test.go · TestAuthorizeAdmin_MismatchIsPermissionDenied
- code cryptos-node/internal/init/servertls.go
ARC-3 Break-glass socket on the box only
Implemented in v0.1.0-rc.1An 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.
Evidence (3)
- code cryptos-node/internal/grpc/authz.go
- test cryptos-node/internal/grpc/authz_test.go · TestAuthorizeAdmin_LocalNoPeer
- doc website/apps/docs/docs/deep-dives/trust-from-zero.md
ARC-4 Embedded state store on loopback
Implemented in v0.1.0-rc.1The node's etcd listens on 127.0.0.1 only and keeps its data on the encrypted state partition.
Evidence (1)
ARC-5 No web interface in the OS image
Not plannedThe 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.
Evidence (1)
ARC-6 No cross-signing between Roots
Not plannedEach 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.
Evidence (1)
Keys and TPM custody 6
CA keys made and used inside the TPM, and a state disk that only the expected boot chain can open.
KEY-1 CA keys are made and used inside the TPM
Implemented in v0.1.0-rc.1In 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.
Evidence (3)
- code cryptos-node/internal/tpm/key.go
- test cryptos-node/internal/init/escrow_test.go · TestExportRefusedWhenNotExportable
- doc website/apps/docs/docs/deep-dives/keys-never-leave-tpm.md
KEY-2 The state disk is sealed to the boot chain
Implemented in v0.1.0-rc.1The 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.
Evidence (3)
- code cryptos-node/internal/tpm/seal.go
- test cryptos-node/internal/tpm/seal_test.go · TestUnseal_FailsAfterPCRDrift
- doc website/apps/docs/docs/concepts/tpm-sealed-keys.md
KEY-3 Sealing follows upgrades and rollbacks
Implemented in v0.1.0-rc.1Before 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.
Evidence (2)
- code cryptos-node/internal/init/statekeyreseal.go
- test cryptos-node/internal/init/statekeyreseal_test.go · TestReseal_KeyFollowsAnUpgradeAndItsRollback
KEY-4 Strong CA key algorithms only
Implemented in v0.1.0-rc.1CA keys in the TPM are ECDSA P-384 with SHA-384, or RSA of at least 3072 bits. Anything smaller is refused.
Evidence (2)
- code cryptos-node/internal/tpm/key.go · MinRSAKeyBits
- test cryptos-node/internal/tpm/keyalg_test.go · TestPublicTemplateRSAFloor
KEY-5 Software key modes are labelled as such
Partial in v0.1.0-rc.1The 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.
Evidence (2)
KEY-6 No network HSM for CA keys
PlannedCA 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.
Open work: website#42 Say that CA keys stay in the TPM and a network HSM is out of scope
Ceremonies and quorum 4
How a Root comes into being, what records it, and what still needs more than one person.
CER-1 First-boot Root ceremony
Implemented in v0.1.0-rc.1A Root key and its self-signed certificate are made in a first-boot ceremony, authorised by the admin certificate pinned in the machine config.
CER-2 Signed ceremony manifest
Implemented in v0.1.0-rc.1The 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.
Evidence (2)
- code cryptos-node/internal/ceremony/ceremony.go
- test cryptos-node/internal/ceremony/ceremony_test.go · TestVerifyManifest_Tamper
CER-3 M-of-N quorum for Root operations
PlannedCeremonies are one person today. Requiring M of N key holders for Root operations isn't built.
Open work: cryptos-node#371 Build M-of-N quorum ceremonies
CER-4 Guarded factory reset
Partial in v0.1.0-rc.1A 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.
Evidence (2)
- code cryptos-node/internal/reset/reset.go
- test cryptos-node/internal/reset/reset_test.go · TestWipeEmptyRootCNFailsClosed
Open work: cryptos-node#361 Require M-of-N quorum plus holder codes for a factory reset
Issuance and protocols 10
Every path to a certificate runs through one profile engine, held to the RFCs.
ISS-1 RFC 5280 Root certificates
Implemented in v0.1.0-rc.1The Root certificate the node self-signs is checked by zlint in the test suite with no errors and no warnings.
Evidence (1)
- test cryptos-node/internal/ca/ca_test.go · TestSelfSignRoot_ZLintCleanRoot
ISS-2 One profile engine for every issuance path
Implemented in v0.1.0-rc.1Every 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.
Evidence (2)
- code cryptos-node/internal/ca/profile.go
- code cryptos-node/internal/node/signer.go · clampPathLen
ISS-3 No arbitrary CSR signing in production builds
Implemented in v0.1.0-rc.1The raw SignCSR call is a stub in production builds; it exists only in a debug build tag.
Evidence (2)
- code cryptos-node/internal/grpc/signcsr_stub.go
- test cryptos-node/internal/grpc/server_test.go · TestSignCSR_StubReturnsUnimplemented
ISS-4 SCEP (RFC 8894)
Implemented in v0.1.0-rc.1SCEP enrolment, tested against the sscep client in CI.
Evidence (2)
- test cryptos-node/internal/scep/sscep_test.go
- ci cryptos-node/.github/workflows/ci-go.yml · Build sscep
ISS-5 ACME (RFC 8555)
Partial in v0.1.0-rc.1ACME 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.
Evidence (2)
- code cryptos-node/internal/acme/doc.go
- test cryptos-node/internal/acme/jws_test.go · TestVerifyJWSAlgorithmConfusion
Open work: cryptos-node#110 ACME HTTP-01/DNS-01 for cert-manager and native clients
ISS-6 EST (RFC 7030)
Implemented in v0.1.0-rc.1An EST enrolment adapter over TLS.
Evidence (2)
ISS-7 Revocation: CRL and OCSP
Implemented in v0.1.0-rc.1The node publishes an RFC 5280 CRL and answers RFC 6960 OCSP requests when a revocation URL is set.
ISS-8 Time-stamping (RFC 3161)
Implemented in v0.1.0-rc.1A built-in time-stamp authority that refuses SHA-1 and MD5 message imprints.
Evidence (2)
ISS-9 Root CAs serve no enrolment protocols
Implemented in v0.1.0-rc.1Config validation refuses ACME, EST, SCEP and the TSA on a Root, so a Root never answers enrolment requests.
Evidence (1)
ISS-10 Windows autoenrolment (MS-XCEP and WSTEP)
PlannedNative Windows autoenrolment through Group Policy isn't built.
Open work: cryptos-node#108 Native Windows autoenrolment via GPO (MS-XCEP/WSTEP)
Identity, access and approvals 5
One pinned admin on each node; certificate-based roles and approvals in FleetOS Manager.
ACC-1 One pinned admin per node
Implemented in v0.1.0-rc.1A node trusts exactly one admin certificate, pinned in its machine config. There are no roles or accounts on the node itself.
Evidence (2)
ACC-2 Certificate-based roles in FleetOS Manager
Implemented in v0.1.0-rc.1Operators sign in with a client certificate from your own operator CA. Viewer, operator and admin levels travel in the certificate. No passwords are stored.
Evidence (3)
- code cryptos-manager/internal/authz/level.go
- test cryptos-manager/internal/authz/level_test.go · TestLevelFromCertificate
- doc cryptos-manager/docs/operator-ca.md
ACC-3 Operator certificates are re-checked for revocation
Implemented in v0.1.0-rc.1Every request re-checks the operator's certificate against the manager's denylist, the CA's CRL and, where set, its OCSP responder.
Evidence (2)
ACC-4 No self-approval
Implemented in v0.1.0-rc.1Certificate requests wait for an operator or admin, the requester can't approve their own, and both identities are audited.
Evidence (2)
- code cryptos-manager/internal/approval/approval.go · ErrSelfApproval
- doc website/apps/docs/docs/fleet-manager/approvals.md
ACC-5 Agents go through the same checks
Implemented in v0.1.0-rc.1AI 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.
Evidence (2)
Audit trail 5
Hash-chained, signed logs on the node and in the manager, and what they don't do yet.
AUD-1 Signed, hash-chained node audit log
Implemented in v0.1.0-rc.1Every node operation is appended to a SHA-256 hash chain, signed with a key kept apart from the CA key, on the encrypted partition.
Evidence (3)
- code cryptos-node/internal/audit/doc.go
- test cryptos-node/internal/audit/audit_test.go · TestVerifyChain_DetectsSignatureTamper
- doc website/apps/docs/docs/deep-dives/audit-integrity.md
AUD-2 Operators can verify the log
Implemented in v0.1.0-rc.1cryptosctl lists the audit log and verifies its chain and signatures.
Evidence (2)
AUD-3 Hash-chained manager audit log
Implemented in v0.1.0-rc.1FleetOS Manager records every change with the acting operator, and the approval and approver where there is one, in a hash chain.
Evidence (1)
AUD-4 Audit retention with a signed checkpoint
PlannedThe node log grows without a retention policy today. Trimming it behind a signed checkpoint isn't built.
Open work: cryptos-node#327 Audit retention with a signed checkpoint
AUD-5 Audit export to a SIEM
PlannedEach node keeps its own signed, hash-chained log, which cryptosctl reads and verifies on the node. Shipping it to a SIEM isn't built.
Open work: cryptos-node#408 Export the audit log to a SIEM
Appliance platform 6
A read-only image you sign yourself, with signed upgrades and a guarded clock.
APP-1 Read-only root filesystem
Implemented in v0.1.0-rc.1The signed kernel image carries the Go PID 1 and a SquashFS root that is mounted read-only. Only the encrypted state partition is writable.
APP-2 Secure Boot with your own key
Implemented in v0.1.0-rc.1Releases 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.
APP-3 Signed in-place upgrades with rollback
Implemented in v0.1.0-rc.1An 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.
Evidence (2)
- code cryptos-node/internal/imageupgrade/imageupgrade.go
- test cryptos-node/internal/imageupgrade/imageupgrade_test.go · TestStage_RefusesASignatureOverOtherBytes
APP-4 Remote attestation
Partial in v0.1.0-rc.1Measured 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.
Evidence (1)
APP-5 A guarded clock
Implemented in v0.1.0-rc.1A time floor and NTP sync keep certificate validity and time-stamps from going backwards.
APP-6 More platforms
PlannedNode images are amd64 for VMware today. Proxmox VE, bare-metal installs and an arm64 image are in progress.
Evidence (1)
Open work: cryptos-appliance#38 Support Proxmox VE as a VM platform; cryptos-appliance#54 A plain installer ISO for bare-metal servers; cryptos-appliance#117 Build and prove an arm64 appliance image
FleetOS Manager 5
An optional console that carries requests to the nodes and never holds a CA key.
FLT-1 The manager holds no CA key
Implemented in v0.1.0-rc.1Certificates 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.
FLT-2 A node is pinned before it is trusted
Implemented in v0.1.0-rc.1Adoption 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.
FLT-3 Both sides verify every connection
Implemented in v0.1.0-rc.1The 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.
Evidence (2)
FLT-4 Pending-link until managed credentials exist
PlannedMarking an adopted node pending-link until its managed credentials are provisioned isn't built.
Open work: cryptos-manager#54 Mark adopted nodes pending-link until managed credentials are provisioned
FLT-5 A minimal, non-root manager image
Implemented in v0.1.0-rc.1The manager image is distroless, runs as a non-root user, and its base images are pinned by digest.
Evidence (1)
Availability and recovery 5
What happens when a node is lost: escrow for software keys today, pairs and split custody later.
REC-1 CA key escrow for software keys
Partial in v0.1.0-rc.1A 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.
Evidence (2)
REC-2 Two-node pairs with failover
PlannedActive and passive pairs with a shared address and lease-gated signing aren't built.
Evidence (1)
- doc website/apps/docs/docs/introduction/status-roadmap.md · Phase 3: high-availability pairs
REC-3 Split custody for Root recovery
PlannedRecovering a Root through split custody (for example Shamir shares or smart cards) isn't built.
Evidence (1)
- doc website/apps/docs/docs/introduction/status-roadmap.md · Phase 3: disaster recovery
REC-4 A changed boot chain means a rebuild
Partial in v0.1.0-rc.1In 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.
Evidence (1)
REC-5 Encrypted backup of node state
PlannedThere 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.
Open work: cryptos-node#407 Encrypted backup and restore of a node's etcd state
Supply chain and development 9
Reproducible, unsigned releases, secret scanning, CI gates and how to report a vulnerability.
SUP-1 Reproducible release images
Implemented in v0.1.0-rc.1The release pipeline builds the image twice and compares the outputs byte for byte. Releases carry SHA256SUMS and a build manifest.
SUP-2 No project signature on releases
Not plannedThe 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.
Evidence (1)
SUP-3 SBOM and build provenance
Not plannedRelease 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.
Evidence (1)
SUP-4 Secret scanning
Implemented in v0.1.0-rc.1Gitleaks runs in CI on every code repository.
SUP-5 Tests gate every change
Implemented in v0.1.0-rc.1Go code is formatted, linted, vetted and tested in CI, with a software TPM and interop tests, before it can merge.
Evidence (1)
SUP-6 Pinned CI actions
PartialThird-party GitHub Actions are pinned by commit SHA. A few org and tool references still float.
Evidence (1)
SUP-7 Standard library crypto on the certificate path
Partial in v0.1.0-rc.1Key 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.
Evidence (1)
SUP-8 Private vulnerability reporting
ImplementedVulnerabilities are reported privately through GitHub security advisories; the latest 0.x release gets fixes.
Evidence (1)
SUP-9 Vulnerability scanning in CI
PlannedCI scans for secrets and runs the linters and tests, but no workflow checks for known vulnerabilities with govulncheck or runs gosec yet.
Open work: cryptos-node#406 Run govulncheck and gosec in the Go repos' CI
Documents
The security review is the long form of this page: architecture, the appliance, the boot chain and key custody, the fleet, and every control with its evidence.
Security review
Architecture, appliance design, boot chain and TPM key custody, the fleet, and every control with its evidence, in four numbered figures.
Security policy
How to report a vulnerability and which versions get fixes.
Secure Boot with your own key
Why releases ship unsigned and how you sign the image you boot.
Keys never leave the TPM
How the CA key is made, used and kept inside the TPM.
Sub-processors
CryptOS is self-hosted. The project runs no service that sees your keys, certificates or audit trail. The only outside services are the project's own infrastructure and the ones you choose to connect.
| Service | Purpose | Data it sees | Scope |
|---|---|---|---|
| GitHub | Source code, CI, releases, container images and private vulnerability reports | No customer data. You download images and releases from it. | Project infrastructure |
| Cloudflare Pages | Hosts this website and the docs | Visitors' requests to these sites. No product data. | Project infrastructure |
| Your storage for FleetOS Manager | The manager's inventory, approvals and audit log | Fleet metadata and certificates, never a CA private key | Chosen and run by you; none is bundled |
| Your operator CA | Signs the certificates FleetOS Manager operators sign in with | Operator names and access levels | Chosen and run by you |
Report a vulnerability
Found a vulnerability? Tell us
Please don't open a public issue, discussion or pull request for a suspected vulnerability.
- Open the affected repository on GitHub, go to the Security tab and choose Report a vulnerability.
- Say what you found, how to reproduce it, and the version or commit affected.
- Expect an acknowledgement within a few business days. We'll agree a fix and a disclosure timeline with you, and credit you in the advisory unless you'd rather not be named.