Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ The build phases (project-wide):
- 🧠 [`cryptos-node`](https://github.com/CryptOS-PKI/cryptos-node) — the OS / CA engine (UKI; bare metal or VM), and the node API protos.
- 🛰️ [`cryptos-manager`](https://github.com/CryptOS-PKI/cryptos-manager) — Fleet Manager backend, and the fleet API protos.
- 🎨 [`cryptos-web`](https://github.com/CryptOS-PKI/cryptos-web) — Fleet Manager web frontend.
- ⚓ [`cryptos-release`](https://github.com/CryptOS-PKI/cryptos-release) — the release manifest and the Helm chart for the control plane.
- ⚓ [`cryptos-release`](https://github.com/CryptOS-PKI/cryptos-release) — a deprecated Helm chart for the control plane.

## 🙏 Acknowledgements

Expand Down
14 changes: 5 additions & 9 deletions docs/about/repos.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: "🗂️ The repos"

# 🗂️ The repos

CryptOS is built in the open in the [CryptOS-PKI](https://github.com/CryptOS-PKI) organization on GitHub. Four repos make up the system itself: `cryptos-node`, `cryptos-appliance`, `cryptos-manager` and `cryptos-web`. A few more hold the things around it: the release manifest and Helm chart, test tooling, this site and the organization profile. Every repo on this page is public.
CryptOS is built in the open in the [CryptOS-PKI](https://github.com/CryptOS-PKI) organization on GitHub. Four repos make up the system itself: `cryptos-node`, `cryptos-appliance`, `cryptos-manager` and `cryptos-web`. A few more hold the things around it: a deprecated Helm chart, test tooling, this site and the organization profile. Every repo on this page is public.

## How they fit together

Expand Down Expand Up @@ -67,11 +67,7 @@ What it holds:
| `test/image/`, `test/integration/` | The QEMU + `swtpm` full-image suites. |
| `docs/` | Secure Boot and image upgrade guides. |

Each `v*` tag attaches its release assets to the GitHub Release: the unsigned UKI and installer ISO, TPM-backed and `nodeid` variants.

:::caution[Release images are for evaluation]
The release UKIs and ISOs carry no Secure Boot signature and no upgrade anchor. A node installed from one cannot be upgraded in place. For real use, build the image with your own Secure Boot key. See [Secure Boot](../install-deploy/secure-boot.md).
:::
Each `v*` tag attaches the unsigned release assets to the GitHub Release: the UKI and installer ISO (TPM-backed and `nodeid` variants), `cryptosctl` for Linux and macOS on amd64 and arm64, a `build-manifest.json` build record and a `SHA256SUMS` file -- but never a project-signed image. Every image you run is signed by you: enroll your own Secure Boot key and sign the downloaded image, or build and sign from source. See [Download the unsigned image](../install-deploy/build-bootable-image.md#download-the-unsigned-image), [Secure Boot](../install-deploy/secure-boot.md) and [Check the source you built](./verify-source.md).

To write your own Go client for a node, use the stubs as a Go module:

Expand Down Expand Up @@ -102,7 +98,7 @@ The Fleet Manager is never an issuing authority. Its certificate lacks `keyCertS
| `Dockerfile` | Builds the single image, with the `cryptos-web` bundle embedded. |
| `docs/` | Operator guides: operator certificates, standalone deployment, the MCP endpoint and error codes. |

A release tag builds the container image `ghcr.io/cryptos-pki/cryptos-manager` and pushes the chart to `oci://ghcr.io/cryptos-pki/charts/fleet-manager`. Before the first release tag there is no published image, so you build it yourself. The build context is a folder that holds the `cryptos-manager` and `cryptos-web` checkouts side by side, as `manager` and `web`.
A release tag builds the container image `ghcr.io/cryptos-pki/cryptos-manager` and pushes the chart to `oci://ghcr.io/cryptos-pki/charts/fleet-manager`. Pull either directly, or build the image yourself from a folder that holds the `cryptos-manager` and `cryptos-web` checkouts side by side, as `manager` and `web`.

See the [Fleet Manager overview](../fleet-manager/overview.md).

Expand All @@ -120,15 +116,15 @@ See [The web UI](../fleet-manager/web-ui.md).

| Repo | What it holds |
|---|---|
| ⚓ [cryptos-release](https://github.com/CryptOS-PKI/cryptos-release) | The release manifest (`manifest/release.yaml`, the pinned appliance image, manager image digest and web console of a release) and a deprecated Helm chart, `charts/manager`. See [Deploy with Helm](../fleet-manager/helm.md). |
| ⚓ [cryptos-release](https://github.com/CryptOS-PKI/cryptos-release) | A deprecated Helm chart, `charts/manager`. See [Deploy with Helm](../fleet-manager/helm.md). |
| 🧪 [cryptos-lab](https://github.com/CryptOS-PKI/cryptos-lab) | Scripts for testing CryptOS on real and virtual hardware. `esxi/` boots CryptOS on VMware ESXi with `govc`: upload an ISO, create a UEFI VM, boot it and capture the serial console. Bare metal is planned. |
| 📚 [website](https://github.com/CryptOS-PKI/website) | This site. Docusaurus 3, with the pages under `docs/` and the sidebar in `sidebars.ts`. |
| 🏠 [.github](https://github.com/CryptOS-PKI/.github) | The organization profile README shown on the CryptOS-PKI GitHub page. |

The `api` repo, which held both protos before they moved to the services that serve them, is archived.

:::info[Two Fleet Manager charts]
There are two Helm charts for the Fleet Manager today: `charts/manager` in the `cryptos-release` repo, and `chart/fleet-manager` in the `cryptos-manager` repo. The `cryptos-manager` repo's chart is the one its release tags publish, to `oci://ghcr.io/cryptos-pki/charts/fleet-manager`.
There are two Helm charts for the Fleet Manager today: `charts/manager` in the `cryptos-release` repo, and `chart/fleet-manager` in the `cryptos-manager` repo. `chart/fleet-manager` is the one its release tags publish, to `oci://ghcr.io/cryptos-pki/charts/fleet-manager`.
:::

## Which repo do I need?
Expand Down
54 changes: 54 additions & 0 deletions docs/about/verify-source.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
title: "🔎 Check the source you built"
---

# 🔎 Check the source you built

CryptOS ships source only: a release is a tag, its notes and the source archive at that tag, with no prebuilt image, binary or chart. Since you build everything yourself, the thing worth checking is that the source you built from is really the source the release points at.

## 1. Check the tag's commit

Every release names the commit it was cut from, in the release notes and in the pins that reference it (for example `cryptos-appliance`'s pin of `cryptos-node`, or `cryptos-release`'s notes on a `cryptos-manager` version). Compare that SHA with the one you have checked out:

```bash
git fetch --tags
git rev-parse v0.1.0^{commit}
git log -1 --format=%H
```

The two commits should match. `^{commit}` resolves an annotated tag to the commit it points at, so this works whether the tag is lightweight or annotated.

## 2. Verify the tag's signature, if it's signed

Check whether a tag carries a GPG signature before relying on one:

```bash
git cat-file -p v0.1.0 | grep -q "^-----BEGIN PGP SIGNATURE-----" && echo signed || echo "not signed"
```

If it is, verify it with the maintainer's public key imported into your keyring:

```bash
git verify-tag v0.1.0
```

:::info[Not every tag is signed]
CryptOS-PKI doesn't sign every release tag today. Where a tag isn't signed, the commit-SHA comparison above is the check that matters; don't treat an unsigned tag as unverified on its own; treat it the same as any other commit you build from.
:::

## 3. Check the pins a build resolves

A build pulls in more than the one repository you cloned:

- **`cryptos-appliance`** pins `cryptos-node` in `go.mod`; `go.sum` pins every dependency's content hash. `go mod verify` checks your local module cache against `go.sum`.
- **`cryptos-manager`** pins `cryptos-node` the same way, and pins the `cryptos-web` build it embeds via the `WEB_RELEASE_REF` repository variable (a tag or commit, never a floating branch) when it builds a release image.
- **`cryptos-web`**'s `package-lock.json` pins every npm dependency by resolved version and integrity hash; `npm ci` refuses to install anything that doesn't match.

```bash
go mod verify
npm ci # fails closed on an integrity mismatch
```

## 4. Know what "tested" means

CI and a lab gate build the exact tagged source with throwaway keys, and prove install, boot, upgrade and rollback before a release goes out. That gate runs on the project's infrastructure, not yours -- it tells you the source was provably buildable and bootable at that commit, not that the binary in front of you matches it. Building from the same commit yourself, with the checks above, is what closes that gap.
7 changes: 4 additions & 3 deletions docs/concepts/image-factory.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,18 @@ A node accepts upgrades only from the key its image was built with. If you lose

## Unsigned images

`task iso:unsigned` builds the same ISO with no signature and no upgrade anchor, named with `-unsigned`, for example `cryptos-amd64-vmware-unsigned.iso`. The project's public release assets are built this way:
`task iso:unsigned` builds the same ISO with no signature and no upgrade anchor, named with `-unsigned`, for example `cryptos-amd64-vmware-unsigned.iso`. This is how the public release assets are built: the project never signs an image, so every one it publishes is this unsigned form, built from the exact tagged source:

| Asset | What it is |
|---|---|
| `cryptos-amd64-vmware.uki.unsigned`, `cryptos-amd64-vmware-nodeid.uki.unsigned` | the UKI, TPM and nodeid variants |
| `cryptos-amd64-vmware-unsigned.iso`, `cryptos-amd64-vmware-nodeid-unsigned.iso` | the same UKIs on bootable ISOs |
| `cryptosctl-{linux,darwin}-{amd64,arm64}` | the CLI |
| `build-manifest.json` | the build record: commit, dirty state, version and build tag |
| `SHA256SUMS` | SHA-256 of every asset |

:::caution[Unsigned images are for evaluation]
An unsigned image boots only with Secure Boot off, and a node installed from one can never be upgraded in place, because it has no anchor to check a new image against. For a CA you intend to keep, build with your own key.
:::caution[Unsigned images need your signature before Secure Boot]
An unsigned image boots only with Secure Boot off, and carries no upgrade anchor, so a node installed from one can never be upgraded in place. Every image you run is signed by you: sign the downloaded image with your own Secure Boot key to boot with Secure Boot on (there is no in-place upgrade path from it), or build and sign from source for a CA you intend to keep and upgrade. See [Download the unsigned image](../install-deploy/build-bootable-image.md#download-the-unsigned-image).
:::

## Upgrading in place
Expand Down
2 changes: 1 addition & 1 deletion docs/fleet-manager/first-run/break-glass.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ spec:
type: RuntimeDefault
containers:
- name: reset
image: ghcr.io/cryptos-pki/cryptos-manager:0.1.0
image: ghcr.io/cryptos-pki/cryptos-manager:0.1.0 # or the image you built and pushed
args: ["-config", "/etc/cryptos/fleet/config.yaml", "-reset-first-run"]
securityContext:
readOnlyRootFilesystem: true
Expand Down
4 changes: 2 additions & 2 deletions docs/fleet-manager/helm.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ The chart renders four objects:
| Object | What it is for |
|---|---|
| ConfigMap `fleet-manager-config` | The manager's `config.yaml`, mounted at `/etc/cryptos/fleet/config.yaml`. It holds no secrets. |
| Deployment `fleet-manager` | One container named `manager`, running `ghcr.io/cryptos-pki/cryptos-manager`. |
| Deployment `fleet-manager` | One container named `manager`, running `ghcr.io/cryptos-pki/cryptos-manager` by default, or an image you built and pushed yourself. |
| Service `fleet-manager` | Port `443` forwarded to `8443` in the container, and port `80` to `8080` for the redirect to HTTPS. |
| PersistentVolumeClaim `fleet-manager-node-creds` | The node credentials folder. Not created when you name your own claim in `nodeCreds.existingClaim`. |

Expand Down Expand Up @@ -90,7 +90,7 @@ The full list is in [`chart/fleet-manager/values.yaml`](https://github.com/Crypt
| Key | Default | What it does |
|---|---|---|
| `replicaCount` | `1` | Number of manager pods. See the caution below before raising it. |
| `image.repository` | `ghcr.io/cryptos-pki/cryptos-manager` | The manager image. |
| `image.repository` | `ghcr.io/cryptos-pki/cryptos-manager` | The manager image. Pull the published image at a release tag, or build and push your own and point this at it. |
| `image.tag` | `""` | Empty means the chart's app version. |
| `service.port` / `service.targetPort` | `443` / `8443` | The Service port and the container's HTTPS listener. |
| `service.httpPort` / `service.httpTargetPort` | `80` / `8080` | The redirect-to-HTTPS port and its listener. |
Expand Down
6 changes: 3 additions & 3 deletions docs/fleet-manager/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ title: "🚢 Fleet Manager overview"
# 🚢 Fleet Manager overview

:::tip[Works today]
The Fleet Manager and its web UI are part of the alpha. They have run a two-tier hierarchy (a Root and an Intermediate) on VMware, with both nodes reported as established and healthy. There is no published container image or chart, so you build it yourself; see [Deploy with Helm](./helm.md) for where each install path stands.
The Fleet Manager and its web UI are part of the alpha. They have run a two-tier hierarchy (a Root and an Intermediate) on VMware, with both nodes reported as established and healthy. A release tag publishes the container image and chart; see [Deploy with Helm](./helm.md) for where each install path stands.
:::

A single CryptOS node is managed with `cryptosctl`, one node at a time. Once you have several nodes, a Root and the CAs under it, you want one place to see all of them. That place is the **Fleet Manager**.
A single CryptOS node is managed with `cryptosctl`, one node at a time. Once you have several nodes, a Root and the CAs under it, you want one place to see all of them. That place is the **Fleet Manager**, also called FleetOS Manager.

The Fleet Manager is optional. A node never needs it to issue certificates, and a node that has never been linked to one is managed with `cryptosctl` only.
The Fleet Manager is optional. A node never needs it to issue certificates, and a node that has never been linked to one is managed with `cryptosctl` only. It runs on Kubernetes or standalone (a VM) -- never the CA itself, which runs only on the CryptOS appliance.

## What it is

Expand Down
32 changes: 30 additions & 2 deletions docs/install-deploy/build-bootable-image.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ A CryptOS node boots from one file: a **Unified Kernel Image** (UKI). The UKI ho

This page shows how to build the ISO from the `cryptos-appliance` source code, which pins the `cryptos-node` engine at a version and builds `init`, `cryptosctl` and the console from it by import path.

The CA runs only on the image you build here — its own hardware or VM — never on Kubernetes: a CA there can't be TPM-sealed and would be a single point of failure. FleetOS Manager, the optional multi-node console, runs separately, on Kubernetes or standalone (a VM); see the [Fleet Manager overview](../fleet-manager/overview.md).

## Two choices to make first

Two settings shape the image. Both are chosen when you build, not later.
Expand Down Expand Up @@ -91,9 +93,35 @@ task iso:unsigned PLATFORM=vmware STATEKEY=nodeid

This writes `build/out/cryptos-amd64-vmware-unsigned.iso` (or `...-vmware-nodeid-unsigned.iso`).

## Release downloads
## Download the unsigned image

Every image you run is signed by you. The project never signs one: nothing it publishes
is ready to boot with Secure Boot on until you sign it yourself, or build and sign from
source.

Each tagged `cryptos-appliance` release attaches an unsigned image built this way from
that tag: the ISO for both `STATEKEY` variants, the UKI inside it (renamed with the build
tag), `cryptosctl` for Linux and macOS on amd64 and arm64, a `build-manifest.json` build
record and a `SHA256SUMS` file. Verify what you downloaded before using it -- either check
it against the published sums, or rebuild from the same tag and compare:

```bash
sha256sum -c SHA256SUMS
```

The build is meant to be bit-for-bit reproducible, so rebuilding `task iso:unsigned` from
the tagged source and diffing the hash is an equally valid check.

From there you have two paths:

- **Sign it with your own Secure Boot key** so it boots with Secure Boot on; see
[Secure Boot](./secure-boot.md).
- **Build from source** instead (above). This is also the only way to get an in-place
upgrade: an image signed after the fact carries no upgrade anchor, so a node installed
from the downloaded image can't be upgraded in place until a later release adds signing
with the upgrade anchor built in.

Each tagged `cryptos-appliance` release attaches ready-made files to its GitHub Release: the unsigned UKIs and ISOs for both `STATEKEY` variants, `cryptosctl` for Linux and macOS on amd64 and arm64, and a `SHA256SUMS` file. They are built exactly like `task iso:unsigned` above, so they are for evaluation with Secure Boot off. For a node you plan to keep, build a signed image yourself.
Either way, see [Check the source you built](../about/verify-source.md).

## Next step

Expand Down
4 changes: 2 additions & 2 deletions docs/install-deploy/secure-boot.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Pre10Notice from '@site/docs/_partials/pre-1-0-notice.mdx';
This describes CryptOS as it works right now.
:::

CryptOS ships **no signing key** and asks you to trust none. You make your own Secure Boot key, build the image with it, and enroll its certificate in the firmware of the machines you run. The same certificate is stamped into the image as its **upgrade anchor**, so the key that makes an image bootable is also the only key that can replace it later.
Every image you run is signed by you. CryptOS ships **no signing key** and asks you to trust none: the project's images are always unsigned, and nothing it publishes is ready to boot with Secure Boot on until you sign it (or build and sign from source). You make your own Secure Boot key, build the image with it, and enroll its certificate in the firmware of the machines you run. The same certificate is stamped into the image as its **upgrade anchor**, so the key that makes an image bootable is also the only key that can replace it later.

This page is the short version. The full guide, with every verification command, is [Secure Boot: build and sign with your own key](https://github.com/CryptOS-PKI/cryptos-appliance/blob/main/docs/secure-boot.md) in the `cryptos-appliance` repository.

Expand Down Expand Up @@ -222,7 +222,7 @@ A node accepts a new image only if the image's `.sig` verifies against the ancho
cryptosctl --endpoint 192.0.2.10:443 --trust node-trust.pem image stage --image build/out/cryptos-amd64.uki
```

An image signed by any other key is refused before anything is written. The [in-place upgrade guide](https://github.com/CryptOS-PKI/cryptos-appliance/blob/main/docs/image-upgrade.md) covers staging, activating and rolling back.
An image signed by any other key is refused before anything is written. [Upgrade a node in place](./upgrade-in-place.md) covers staging, activating and rolling back.

`cryptosctl` runs on Linux and macOS.

Expand Down
Loading
Loading