Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
164 commits
Select commit Hold shift + click to select a range
7483ea5
Update to use separate cosign keys per registry (#88)
kylewidmann May 26, 2026
378dad2
chore: auto-promote changelog fragments
github-actions[bot] May 26, 2026
c90808c
Update to use dynamic validator auth and static registry (#89)
kylewidmann May 26, 2026
3125018
chore: auto-promote changelog fragments
github-actions[bot] May 26, 2026
6239185
Apparmor update (#90)
kylewidmann May 26, 2026
42c3d55
chore: auto-promote changelog fragments
github-actions[bot] May 26, 2026
e2af8cd
Update to rotate luks passphrase for root volume on each boot (#91)
kylewidmann May 26, 2026
119b6b4
Additional rtmr3 measurements
kylewidmann May 27, 2026
664b024
chore: auto-promote changelog fragments
github-actions[bot] May 27, 2026
30242ce
Use dynamic key for cosign and helm (#95)
kylewidmann May 29, 2026
2c4fd6d
chore: auto-promote changelog fragments
github-actions[bot] May 29, 2026
d60b4eb
Update boot flow to use mTLS for all calls (#96)
kylewidmann May 29, 2026
8738d58
chore: auto-promote changelog fragments
github-actions[bot] May 29, 2026
a9e6ef0
Update service manager to handle masked service
kylewidmann May 30, 2026
76a7d45
chore: auto-promote changelog fragments
github-actions[bot] May 30, 2026
8fd34a2
Move kubectl to a signed image
kylewidmann May 30, 2026
c6da01c
chore: auto-promote changelog fragments
github-actions[bot] May 30, 2026
2608f65
Fix host pre-req for XFS volumes
kylewidmann May 30, 2026
b2a664e
chore: auto-promote changelog fragments
github-actions[bot] Jun 10, 2026
9826c17
Merge branch 'main' into release/next
kylewidmann Jul 9, 2026
52c3af4
Add missing stdin for force evict
kylewidmann Jun 9, 2026
fd7a6ac
Kernel update (#116)
kylewidmann Jul 15, 2026
c22400e
chore: auto-promote changelog fragments
github-actions[bot] Jul 15, 2026
221a1c2
Registry mTLS (#117)
kylewidmann Jul 18, 2026
6d8dae1
chore: auto-promote changelog fragments
github-actions[bot] Jul 18, 2026
ef75288
Feat/direct boot (#118)
kylewidmann Jul 23, 2026
e71bb34
chore: auto-promote changelog fragments
github-actions[bot] Jul 23, 2026
e2fec57
Update to use same CA for VM lifecycle (#121)
kylewidmann Jul 25, 2026
ae944c1
chore: auto-promote changelog fragments
github-actions[bot] Jul 25, 2026
5e99936
Update to usa RSA instead of PGP (#123)
kylewidmann Jul 29, 2026
e93a5b5
chore: auto-promote changelog fragments
github-actions[bot] Jul 29, 2026
bf2e776
Feat/log service (#122)
kylewidmann Aug 4, 2026
4dfec35
chore: auto-promote changelog fragments
github-actions[bot] Aug 4, 2026
dc208ad
Unblock 25.10->26.04 hop from sgx-dcap-pccs
kylewidmann Aug 4, 2026
e6f13fc
chore: auto-promote changelog fragments
github-actions[bot] Aug 4, 2026
e8e7194
Update domain for CVM
kylewidmann Aug 5, 2026
db612b3
Bump kernel version
kylewidmann Aug 5, 2026
aa3af9f
Feat/rc gate (#124)
kylewidmann Aug 19, 2026
84fa99b
chore: auto-promote changelog fragments
github-actions[bot] Aug 19, 2026
39332f5
Merge branch 'main' into release/next
kylewidmann Aug 19, 2026
7311846
Remove 25.10 support
kylewidmann Aug 19, 2026
d0b91d3
chore: auto-promote changelog fragments
github-actions[bot] Aug 19, 2026
b9e9faf
Ensure tdx measure is always up to date
kylewidmann Aug 19, 2026
0bce598
Debug step
kylewidmann Aug 19, 2026
541d760
Update profile capture and measurement generation
kylewidmann Aug 19, 2026
2d9348f
chore: auto-promote changelog fragments
github-actions[bot] Aug 19, 2026
835bac2
Fix yaml ordering
kylewidmann Aug 20, 2026
3514941
Update prod build to handle re-run against luks encrypted root
kylewidmann Aug 20, 2026
45c1a1e
Cleanup for offline only measurements
kylewidmann Aug 20, 2026
c84880b
Update to support RC key
kylewidmann Aug 20, 2026
fa28e9c
Use main tdx-measure branch
kylewidmann Aug 20, 2026
69fa74a
chore: auto-promote changelog fragments
github-actions[bot] Aug 20, 2026
555dc99
Improve output for host verification
kylewidmann Aug 20, 2026
07518d5
Add chutes cvm setup script and entrypoint
kylewidmann Aug 20, 2026
c4d533c
chore: auto-promote changelog fragments
github-actions[bot] Aug 20, 2026
cb70e22
Move scripts
kylewidmann Aug 20, 2026
1f872bc
Add discover profile entrypoint
kylewidmann Aug 20, 2026
8821708
Remove thing wrappers and migrate to chutes-cvm cli
kylewidmann Aug 20, 2026
bc6f6a9
Update docs
kylewidmann Aug 20, 2026
b20ed27
Update to display error message from API for attestation failures
kylewidmann Aug 21, 2026
0c27c9b
Consolidate to chutes-cvm package/CLI
kylewidmann Aug 22, 2026
76281fd
chore: auto-promote changelog fragments
github-actions[bot] Aug 22, 2026
017062d
Add preflight checks to CLI
kylewidmann Aug 22, 2026
bbe6336
Split out launch script flags into subcommands
kylewidmann Aug 22, 2026
2d71530
Fix GPU tools bundling and consolidate install paths
kylewidmann Aug 23, 2026
2d1f08f
Update versioning for chtues-cvm
kylewidmann Aug 23, 2026
5a702a7
Cleanup CLI and measurement commands
kylewidmann Aug 24, 2026
79896a5
Merge branch 'release/next' of github.com:chutesai/sek8s into release…
kylewidmann Aug 24, 2026
c84acef
chore: auto-promote changelog fragments
github-actions[bot] Aug 24, 2026
d38d09f
Remove selftest and preflight commands
kylewidmann Aug 25, 2026
6d0ef0c
Merge branch 'release/next' of github.com:chutesai/sek8s into release…
kylewidmann Aug 25, 2026
4b69305
Clean up image management commands
kylewidmann Aug 25, 2026
5e6e02f
Consolidate host setup
kylewidmann Aug 25, 2026
65144a0
chore: auto-promote changelog fragments
github-actions[bot] Aug 25, 2026
83c108e
Migrate launch to CLI
kylewidmann Aug 26, 2026
46ddd1a
Consolidate host commands
kylewidmann Aug 26, 2026
1ec6620
Cleanup imports
kylewidmann Aug 26, 2026
fb1313f
Consolidate guest commands
kylewidmann Aug 26, 2026
06abcc3
Remove baseline
kylewidmann Aug 26, 2026
88ab353
lint fixes
kylewidmann Aug 26, 2026
1e16b1d
Add util script to generate key pair for RC release
kylewidmann Aug 26, 2026
3c064fb
Use absolute path for measurement artifacts
kylewidmann Aug 26, 2026
fd3d367
chore: auto-promote changelog fragments
github-actions[bot] Aug 26, 2026
894838e
Simplify public key extension
kylewidmann Aug 26, 2026
a7a5fe0
Move image prep out of bash
kylewidmann Aug 26, 2026
fa2eb92
Fix scripts dir for udev rules
kylewidmann Aug 26, 2026
991318e
Update measurement generation use API profiles
kylewidmann Aug 26, 2026
e171125
chore: auto-promote changelog fragments
github-actions[bot] Aug 26, 2026
effaf2b
Handle pending measurement warning
kylewidmann Aug 26, 2026
d152448
Update to include pending profiles for pipeline and CLI
kylewidmann Aug 26, 2026
8acf267
chore: auto-promote changelog fragments
github-actions[bot] Aug 26, 2026
1d7ec5d
Use launch config class instead of flat dict
kylewidmann Aug 26, 2026
2fcc731
Split out preflight check
kylewidmann Aug 27, 2026
d97228e
Make stop also use graceful shutdown
kylewidmann Aug 27, 2026
f778418
Fix proxy profile for socket
kylewidmann Aug 27, 2026
b409105
Update to log failed shutdown command
kylewidmann Aug 27, 2026
ae4b198
Update rules to allow graceful shutdown
kylewidmann Aug 27, 2026
c8c8885
Add log shipper to app armor
kylewidmann Aug 27, 2026
434a9b8
App armor updates
kylewidmann Aug 27, 2026
dcc1b40
Make k3s checks more resilient
kylewidmann Aug 27, 2026
41b863b
Fix server cert path for proxy
kylewidmann Aug 28, 2026
5042b55
Fix crictl access for log shipper
kylewidmann Aug 28, 2026
5417af7
Fix build time warning for sym links
kylewidmann Aug 28, 2026
21d53ad
Fix cosign mtls
kylewidmann Aug 29, 2026
e541269
Fix registry-tls group
kylewidmann Aug 29, 2026
9433a54
Update services exposed via API
kylewidmann Aug 29, 2026
8e08200
Update logging
kylewidmann Aug 29, 2026
ddac637
chore: auto-promote changelog fragments
github-actions[bot] Aug 29, 2026
241f84e
Fix k3s post start watchdog and timeout
kylewidmann Aug 29, 2026
351c4f1
Fix bus permission errors
kylewidmann Aug 29, 2026
5f703f1
Fix ip tables to clamp mss
kylewidmann Aug 29, 2026
7330423
chore: auto-promote changelog fragments
github-actions[bot] Aug 29, 2026
9519df4
App armor update
kylewidmann Aug 29, 2026
03a1e9a
Fix log shipper permissions
kylewidmann Aug 29, 2026
e5f81fa
Update proxy to sign evidence requests
kylewidmann Aug 30, 2026
90dde97
chore: auto-promote changelog fragments
github-actions[bot] Aug 30, 2026
3d1ebdb
Fix secret for attestation signing
kylewidmann Aug 30, 2026
03df87a
Make miner credentials update
kylewidmann Aug 30, 2026
d19f02d
Make cli install fail closed on conflict
kylewidmann Aug 30, 2026
4c7007d
Add version to cli
kylewidmann Aug 30, 2026
2a5b950
Fix submit profile to not require a valid host
kylewidmann Aug 30, 2026
f60f229
Add default args with env override
kylewidmann Aug 30, 2026
aedaa92
Code and doc cleanup
kylewidmann Aug 31, 2026
6a6295e
lint fixes
kylewidmann Aug 31, 2026
6775700
Cleanup proxy updates
kylewidmann Aug 31, 2026
4880c13
Update to use the signing key from R2 instead of local
kylewidmann Aug 31, 2026
2af270e
Fix first boot token
kylewidmann Aug 31, 2026
ca51f42
Fix measurements post luks
kylewidmann Aug 31, 2026
8ebf23b
Update to use hotkey PoP instead of RSA
kylewidmann Aug 31, 2026
dfa22da
Fix src dir for sr25519 build
kylewidmann Sep 1, 2026
2e8c771
Fix rust depdencies for build
kylewidmann Sep 1, 2026
8f04e26
Fix warning
kylewidmann Sep 1, 2026
6139547
Update chutes cvm to use new preflight endpoint
kylewidmann Sep 1, 2026
b1087db
chore: auto-promote changelog fragments
github-actions[bot] Sep 1, 2026
97edf2f
Fix measurement generation for prod
kylewidmann Sep 2, 2026
13b1f44
Fix submit profile to respect target OS and gate on unsupported OS
kylewidmann Sep 2, 2026
f6a55d3
chore: auto-promote changelog fragments
github-actions[bot] Sep 2, 2026
d29f72f
Fix messages for host verification and profiles
kylewidmann Sep 2, 2026
8ecd918
Refactor measure and luks into prepare boot image role
kylewidmann Sep 2, 2026
a6a059d
chore: auto-promote changelog fragments
github-actions[bot] Sep 2, 2026
7d176c3
Fix measurements overridng each other
kylewidmann Sep 2, 2026
9f4af1e
chore: auto-promote changelog fragments
github-actions[bot] Sep 2, 2026
993b840
Fix build clearing /opt/sek8s and removing chute log shipper user
kylewidmann Sep 2, 2026
cbc7d06
Fix apparmor and permission errors for prod
kylewidmann Sep 2, 2026
119f4a0
chore: auto-promote changelog fragments
github-actions[bot] Sep 2, 2026
39ad119
Add check for whitespace in luks passphrase
kylewidmann Sep 3, 2026
b03ded4
Update to split out app armor profiles
kylewidmann Sep 3, 2026
e6343ce
Pin sorting
kylewidmann Sep 3, 2026
5a4a82b
Fix syntax
kylewidmann Sep 3, 2026
dacea8e
Add debug flag for k3s post start
kylewidmann Sep 3, 2026
4523867
Cleanup comments
kylewidmann Sep 3, 2026
ad27c48
chore: auto-promote changelog fragments
github-actions[bot] Sep 3, 2026
741d3e8
Fix measurement variability
kylewidmann Sep 3, 2026
c531cac
chore: auto-promote changelog fragments
github-actions[bot] Sep 3, 2026
064aeba
Fix UUID for luks container
kylewidmann Sep 3, 2026
5c9b270
Add source epoch to fix last soruce of RTMR2 drift
kylewidmann Sep 3, 2026
357c00c
chore: auto-promote changelog fragments
github-actions[bot] Sep 3, 2026
9e9a92e
Fix missing binaries in initramfs
kylewidmann Sep 4, 2026
48e88eb
chore: auto-promote changelog fragments
github-actions[bot] Sep 4, 2026
0861319
Fix binary check
kylewidmann Sep 4, 2026
d89e951
Fix log shipper log reading
kylewidmann Sep 4, 2026
2dd8f09
chore: auto-promote changelog fragments
github-actions[bot] Sep 4, 2026
d348360
Fix sudo access for system manager
kylewidmann Sep 4, 2026
af05a72
Merge branch 'main' into release/next
kylewidmann Sep 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
22 changes: 22 additions & 0 deletions .github/workflows/version-tag.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,27 @@ jobs:
echo "No proxy-domain changes detected."
fi

# --- chutes-cvm domain ---
# src/chutes-cvm/* → src/chutes-cvm/VERSION
needs_cvm_bump=false
while IFS= read -r f; do
[ -z "$f" ] && continue
case "$f" in
src/chutes-cvm/*) needs_cvm_bump=true; break ;;
esac
done <<< "$changed_files"

if [ "$needs_cvm_bump" = true ]; then
if ! echo "$changed_files" | grep -qx "src/chutes-cvm/VERSION"; then
echo "::error::Changes under src/chutes-cvm/ require an src/chutes-cvm/VERSION bump."
errors=$((errors + 1))
else
echo "chutes-cvm domain: src/chutes-cvm/VERSION bumped."
fi
else
echo "No chutes-cvm-domain changes detected."
fi

if [ "$errors" -gt 0 ]; then
exit 1
fi
Expand Down Expand Up @@ -178,3 +199,4 @@ jobs:
tag_if_ready "src/sek8s/VERSION" "sek8s-v" "changelogs/sek8s"
tag_if_ready "src/sek8s-common/VERSION" "sek8s-common-v" ""
tag_if_ready "src/attestation-proxy/VERSION" "attestation-proxy-v" "changelogs/attestation-proxy"
tag_if_ready "src/chutes-cvm/VERSION" "chutes-cvm-v" "changelogs/chutes-cvm"
35 changes: 30 additions & 5 deletions AGENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ Do not introduce alternate frameworks (e.g., Prisma, NextAuth, Firebase). Stay w

- **Never install a new dependency** without discussion first
- **Never modify database schemas** without showing the migration plan (sek8s has no DB; this applies if one is added)
- **Python services**: Poetry packages under `src/sek8s/` (import name `sek8s`), `src/sek8s-common/` (`sek8s_common`), and `src/attestation-proxy/` (`attestation_proxy`); tests under `tests/`
- **Shell scripts** in `host-tools/scripts/` and `guest-tools/`
- **Python services**: Poetry packages under `src/sek8s/` (import name `sek8s`), `src/sek8s-common/` (`sek8s_common`), `src/attestation-proxy/` (`attestation_proxy`), and `src/chutes-cvm/` (`chutes_cvm`, the host CLI/toolkit); tests under `tests/`
- **Shell scripts** in `host-tools/scripts/`, `guest-tools/`, and the bundled `src/chutes-cvm/chutes_cvm/scripts/`
- **Ansible roles** in `ansible/guest/roles/`
- **OPA policies** in `ansible/guest/roles/admission-controller/files/policies/`
- **Environment variables** go in config files (pydantic-settings, Ansible vars) — never hardcoded
Expand All @@ -35,7 +35,7 @@ Do not introduce alternate frameworks (e.g., Prisma, NextAuth, Firebase). Stay w
- **Never commit or alter git history** without explicit human approval for that specific action — including `git commit`, `git commit --amend`, rebase, history-changing `reset`, `cherry-pick`, branch delete, or force-push. Leave changes for the author to review and commit unless they clearly asked you to perform a named git operation.
- **Never modify Ansible roles** without understanding the guest image build pipeline
- **Never hardcode attestation keys or measurements**
- **Version bumps** — Three domains; see [docs/versioning.md](docs/versioning.md) for the full policy. **VM domain** (`ansible/guest/*`, `src/sek8s/*`, `src/sek8s-common/*`, `nvevidence/*`, root `pyproject.toml`/`poetry.lock`): bump `ansible/guest/VERSION`. Changes under **`ansible/host/`** do not bump the guest image version. **Proxy domain** (`src/attestation-proxy/*`): bump `src/attestation-proxy/VERSION`. **Ops domain** (`ansible/host/*`, `host-tools/*`, `.github/workflows/*`): bump `changelogs/ops/VERSION` using CalVer `YYYY.MM.PATCH` (e.g. `2026.05.0`; increment PATCH for a second release in the same month). Per-package `VERSION` files are the source of truth for `[tool.poetry] version` — keep them in sync via `scripts/sync_pyproject_versions.py`. Version bumps happen at release time, not during feature development.
- **Version bumps** — Four domains; see [docs/versioning.md](docs/versioning.md) for the full policy. **VM domain** (`ansible/guest/*`, `src/sek8s/*`, `src/sek8s-common/*`, `nvevidence/*`, root `pyproject.toml`/`poetry.lock`): bump `ansible/guest/VERSION`. Changes under **`ansible/host/`** do not bump the guest image version. **Proxy domain** (`src/attestation-proxy/*`): bump `src/attestation-proxy/VERSION`. **chutes-cvm domain** (`src/chutes-cvm/*`, the independently installable host CLI): bump `src/chutes-cvm/VERSION` (SemVer); changelog fragments go in `changelogs/chutes-cvm/`. **Ops domain** (`ansible/host/*`, `host-tools/*`, `.github/workflows/*`): bump `changelogs/ops/VERSION` using CalVer `YYYY.MM.PATCH` (e.g. `2026.05.0`; increment PATCH for a second release in the same month). Per-package `VERSION` files are the source of truth for `[tool.poetry] version` — keep them in sync via `scripts/sync_pyproject_versions.py`. Version bumps happen at release time, not during feature development.
- **Changelog fragments** — As you make changes, keep `changelogs/<component>/unreleased/<branch-name>.md` up to date using [Keep a Changelog](https://keepachangelog.com/) category headers (`### Added`, `### Changed`, `### Fixed`, `### Removed`). This is the only changelog file you should ever touch during development. **Never write `## [x.y.z]` version headings or edit `CHANGELOG.md` directly** — that is done by `make promote-changelogs` (or CI) at release time. PRs to `main` must have no unreleased fragments remaining.

## Patterns
Expand All @@ -50,6 +50,30 @@ Do not introduce alternate frameworks (e.g., Prisma, NextAuth, Firebase). Stay w
- **One concern per module** — keep files focused; split when they grow large
- **Follow existing naming** — check neighboring files and packages for conventions

### chutes-cvm: bash vs Python

**Python owns decisions and data; bash owns privileged, linear sequences of external-tool calls.**
The language boundary must fall at a **data handoff**: Python resolves the values, then hands them
to a bash step that performs the root-level system mutation. Never split a decision from its
execution across the boundary (bash deciding *and* executing while Python builds args downstream is
the anti-pattern).

- **Put it in Python** when it makes decisions (precedence, validation, branching on parsed data),
models/validates structured data (config schema, manifest, GPU/topology profiles, measurements),
constructs commands from data (e.g. `guest/qemu.py` building the QEMU cmdline), is measurement- or
security-critical (must be unit-tested), or is the dispatch/UX surface (argparse, help, exit codes).
- **Put it in bash** (bundled under `chutes_cvm/scripts/`) when it is a thin, mostly-linear sequence
of privileged system mutations via external tools (cryptsetup/qemu-nbd/mkfs/losetup, ip/iptables,
aria2c, lspci/nvidia-smi) where the logic *is* the tool invocations, branching is shallow, there is
no structured data to model, and a reviewer benefits from reading the literal root commands. These
need root + real devices, so they are untestable in unit tests regardless — porting them to Python
buys indirection, not testability.
- **Smell tests**: a bash script carrying real precedence/parsing/validation logic → that logic
belongs in Python (the script shrinks to its system-mutation steps). A Python module that is only
`subprocess.run([...])` calls with no data modeling → fine to keep, but don't Pythonize a
cryptsetup sequence for purity. Standalone operator/diagnostic tools meant to be read and run
directly (e.g. `discover-profile.sh`) legitimately stay bash.

## Architecture Overview

| Component | Purpose |
Expand All @@ -61,12 +85,13 @@ Do not introduce alternate frameworks (e.g., Prisma, NextAuth, Firebase). Stay w
| **src/sek8s-common/sek8s_common/** | Shared config, server, auth, and constants for all sek8s packages |
| **src/attestation-proxy/attestation_proxy/** | Dual-port attestation proxy (separate lean Docker image) |
| **nvevidence/** | NVIDIA attestation SDK wrapper (separate Poetry package) |
| **host-tools/** | Host setup (`chutes.host`), GPU binding/VM launch (`chutes.guest`), networking, orchestration (`quick-launch.sh`) |
| **src/chutes-cvm/** | The `chutes-cvm` CLI + toolkit. `install.sh` is the **single source of truth for install** (fetch + venv + shims; repo-present=editable, standalone curl\|bash=non-editable). Under `chutes_cvm/` (import `chutes_cvm`, console script `chutes-cvm`): host setup (`host/`), GPU binding & VM launch (`guest/`), offline measurement generation (`measurement/`), and bundled data under `scripts/` — the privileged volume/network/teardown shell helpers the Python launch orchestrator (`guest/launch.py`) drives, config schema/template, and the nvidia-gpu-tools wheel (`scripts/gpu-tools/`). The GPU-tools **build recipe** is `tools/gpu-tools/` (`make bundle-gpu-tools`), outside the shipped package. |
| **host-tools/** | Operator config examples (`scripts/config/`) and docs. The install script, VM-management scripts, and the GPU-tools wheel all moved into the `chutes-cvm` package; only the guest firmware (`firmware/`, MRTD-measured, image-bound) stays external to it. |
| **guest-tools/** | TDX VM image builder, boot measurement extraction |
| **ansible/guest/** | Ansible roles for guest image build (k3s, GPU drivers, attestation services, LUKS) |
| **ansible/host/** | Operational Ansible (setup / launch / upgrade) for bare-metal TDX hosts over SSH |
| **opa/** | OPA policy files for admission controller |
| **guest-tools/** | Boot measurement extraction tools (`extract-acpi.sh`, `extract-vm-measurements.sh`) |
| **guest-tools/** | Guest measurement & verification tooling (`measurement/`), image build output (`image/`), and R2 publish (`publish-image.sh`) |

## Environment Setup

Expand Down
21 changes: 19 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,28 @@ DC=docker compose -p ${PROJECT} -f ${COMPOSE_FILE} -f ${COMPOSE_BASE_FILE}
POETRY ?= "poetry"

SRC_DIR := src
PACKAGES := $(shell ls $(SRC_DIR))
# Python packages only: the Python tooling below derives src/<pkg>/<import>/ paths and
# -p/--cov import names from this list, so non-Python packages under src/ (e.g. the
# sr25519-signer Rust crate) must not appear in it.
PACKAGES := $(patsubst $(SRC_DIR)/%/pyproject.toml,%,$(wildcard $(SRC_DIR)/*/pyproject.toml))
VERSION := $(shell head ansible/guest/VERSION | grep -Eo "\d+.\d+.\d+")

# Package filter: "make <target> sek8s" selects one package
PKG_FILTER := $(filter $(PACKAGES),$(MAKECMDGOALS))
SELECTED_PKGS := $(or $(PKG_FILTER),$(PACKAGES))

# Wire package goal into PROJECT for docker targets (build/tag/push/sign)
# Standalone docker images: docker/<name> with a Dockerfile and no matching src/ package.
# Image filter: "make images busybox" selects one image; bare "make images" builds all.
STANDALONE_IMAGES := $(shell for d in docker/*/; do n=$$(basename "$$d"); [ -f "$$d/Dockerfile" ] && [ ! -d "src/$$n" ] && echo $$n; done)
IMG_FILTER := $(filter $(STANDALONE_IMAGES),$(MAKECMDGOALS))
SELECTED_IMGS := $(or $(IMG_FILTER),$(STANDALONE_IMAGES))

# Wire package/image goal into PROJECT for docker targets (build/tag/push/sign)
ifeq ($(PROJECT),)
ifneq ($(PKG_FILTER),)
override PROJECT := $(firstword $(PKG_FILTER))
else ifneq ($(IMG_FILTER),)
override PROJECT := $(firstword $(IMG_FILTER))
endif
endif

Expand All @@ -45,6 +56,12 @@ $(PKG_FILTER):
@:
endif

# Allow standalone image names as make goals (no-op targets)
ifneq ($(IMG_FILTER),)
$(IMG_FILTER):
@:
endif

.DEFAULT_GOAL := help

.EXPORT_ALL_VARIABLES:
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ Confidential GPU infrastructure for Chutes miners and zero-trust workloads. This
| `**docs/**` | Integration guide with [chutes-miner](https://github.com/chutesai/chutes-miner) and system-status service documentation |
| `ansible/guest/` | Ansible roles for guest image build automation |
| `sek8s/`, `nvevidence/` | Python services running inside the guest (attestation, evidence verification, system status) |
| `guest-tools/` | Boot measurement extraction tools (`extract-acpi.sh`, `extract-vm-measurements.sh`) |
| `guest-tools/` | Guest measurement & verification tooling (`measurement/`), image build output (`image/`), R2 publish (`publish-image.sh`) |


---

## Quick start roadmap

1. **Set up the host** — Use `[host-tools/](host-tools/)` to prepare your TDX-capable machine with the required kernel, PCCS, and networking.
2. **Download the VM image** — Run `./quick-launch.sh --download` from `host-tools/scripts/` to fetch the prebuilt guest image (requires `aria2`).
3. **Configure and launch** — Run `./quick-launch.sh --template` to generate a `config.yaml`, fill in your miner credentials and network settings, then `./quick-launch.sh config.yaml` to create volumes, configure GPUs, and boot the VM in one command.
2. **Download the VM image** — Run `chutes-cvm image download` to fetch + verify the prebuilt guest image set (requires `aria2`).
3. **Configure and launch** — Run `chutes-cvm config init` to generate a `config.yaml`, fill in your miner credentials and network settings, then `chutes-cvm guest launch config.yaml` to create volumes, configure GPUs, and boot the VM in one command.
4. **Understand the integration** — Read `[docs/end-to-end-miner.md](docs/end-to-end-miner.md)` to see how this repo integrates with the [chutes-miner](https://github.com/chutesai/chutes-miner) control plane.
5. **Build the guest image** (optional) — Use `[guest-tools/](guest-tools/)` and `[ansible/guest/](ansible/guest/)` to customize or rebuild the encrypted VM image.
6. **Monitor VM status** — See `[docs/system-status.md](docs/system-status.md)` for using the system-status API to inspect service health and GPU telemetry inside the VM.
Expand All @@ -46,7 +46,7 @@ The `config.yaml` defines your deployment: VM identity, miner credentials, netwo
## Key Documentation

- `**[host-tools/README.md](host-tools/README.md)`** — Setting up the TDX host and launching VMs
- `**[guest-tools/README.md](guest-tools/README.md)**` — Building and measuring the encrypted VM image
- `**[docs/specs/tdx-measurement-verification.md](docs/specs/tdx-measurement-verification.md)**` — How the guest image's TDX measurements are structured, reproduced, and independently verified (on-host capture in `guest-tools/measurement/`; offline replay/generation in `chutes_cvm.measurement`)
- `**[docs/end-to-end-miner.md](docs/end-to-end-miner.md)**` — Complete integration workflow with chutes-miner
- `**[docs/system-status.md](docs/system-status.md)**` — System status API for monitoring service health and GPU telemetry

Expand Down
20 changes: 10 additions & 10 deletions ansible/guest/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ The build process:
3. Applies security hardening and admission policies
4. Encrypts root filesystem with LUKS
5. Configures initramfs for TDX-based boot unlock
6. Outputs final encrypted image under `guest-tools/image/<build_env>/<vm_version>.qcow2` (see `playbooks/group_vars/host.yml` and inventory `build_env`; `vm_version` comes from `ansible/guest/VERSION`; append `-debug` when `debug_build` is true)
6. Outputs the final encrypted image SET under `guest-tools/image/<build_env>/<vm_version>/` — the `<vm_version>.qcow2`, its direct-boot `.vmlinuz`/`.initrd`/`.cmdline` sidecars, and `manifest.json` (see `playbooks/group_vars/host.yml` and inventory `build_env`; `vm_version` comes from `ansible/guest/VERSION`; a debug build appends `-debug` to both the directory and the image name). The directory is a ready-to-use image set: copy it into `/var/lib/chutes/base-images/<variant>/` to boot it with `chutes-cvm guest launch`.

At the **start** of `chutes-miner-vm.yml` (before the build VM is launched), the playbook prints the build configuration and **pauses for confirmation** (press Enter to continue, Ctrl+C to abort).

Expand All @@ -91,10 +91,10 @@ Host tools automatically configure iptables rules for k3s API (port 6443) and No

### Configuration Volumes

Production VMs require three attached volumes (created by `quick-launch.sh`):
Production VMs require three attached volumes (created by `chutes-cvm guest launch`):

#### Config Volume (`tdx-config`)
- **Created by**: `host-tools/scripts/volumes/create-config.sh`
- **Created by**: `src/chutes-cvm/chutes_cvm/scripts/volumes/create-config.sh`
- **Filesystem**: ext4 with label `tdx-config`
- **Mount point**: `/var/config`
- **Contents**:
Expand All @@ -106,14 +106,14 @@ Production VMs require three attached volumes (created by `quick-launch.sh`):
- `docker-hub-token` - (optional) Docker Hub PAT for authenticated pulls and cosign

#### Cache Volume (`tdx-cache`)
- **Created by**: `host-tools/scripts/volumes/create-cache.sh`
- **Created by**: `src/chutes-cvm/chutes_cvm/scripts/volumes/create-cache.sh`
- **Filesystem**: XFS with label `tdx-cache`
- **Mount point**: `/var/snap`
- **Purpose**: Persistent storage for HF/model caches (e.g., `/var/snap/cache` for model weights)
- **Size**: Configurable (default 5000G)

#### Storage Volume (`storage`)
- **Created by**: `host-tools/scripts/volumes/create-cache.sh` (with label `storage`)
- **Created by**: `src/chutes-cvm/chutes_cvm/scripts/volumes/create-cache.sh` (with label `storage`)
- **Filesystem**: XFS with label `storage`
- **Mount point**: `/cache/storage` (contents bind-mounted into standard paths)
- **Purpose**: Persistent k3s state, containerd data, kubelet pods, admission controller certs, and chutes agent state
Expand Down Expand Up @@ -168,11 +168,11 @@ See role-specific defaults for component configuration.

This Ansible playbook builds the VM image only. The following are handled by host-tools:

- ❌ TDX-enabled host system setup → See `host-tools/scripts/chutes/host/`
- ❌ GPU passthrough configuration → Handled automatically by `run-td`
- ❌ Network infrastructure → See `host-tools/scripts/network/setup-bridge.sh`
- ❌ Config/cache/storage volume creation → See `host-tools/scripts/volumes/create-*.sh`
- ❌ VM launch and orchestration → See `host-tools/scripts/quick-launch.sh`
- ❌ TDX-enabled host system setup → See `src/chutes-cvm/chutes_cvm/host/`
- ❌ GPU passthrough configuration → Handled automatically by `chutes-cvm guest launch`
- ❌ Network infrastructure → See `src/chutes-cvm/chutes_cvm/scripts/network/setup-bridge.sh`
- ❌ Config/cache/storage volume creation → See `src/chutes-cvm/chutes_cvm/scripts/volumes/create-*.sh`
- ❌ VM launch and orchestration → Handled by `chutes-cvm guest launch`
- ✅ Guest OS and k3s installation
- ✅ GPU drivers and attestation services
- ✅ Security hardening and admission control
Expand Down
2 changes: 1 addition & 1 deletion ansible/guest/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.3.1
1.4.0
35 changes: 35 additions & 0 deletions ansible/guest/inventory-reproduce.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
# inventory-reproduce.yml
#
# Reproduce the Chutes production guest image and its measurements as an independent third party.
# Identical to inventory.yml except it needs NONE of our secrets:
# * luks_passphrase is a hardcoded, published constant (below) instead of the LUKS_PASSPHRASE env.
# It does NOT affect the measured registers — MRTD/RTMR0-3 cover the firmware, kernel, initrd,
# cmdline and the baked configs (incl. the root key), not the LUKS container — so any value
# yields the same measurements; first-boot rotation replaces it anyway.
# * The root RSA PUBLIC key is fetched from R2 (root_signing_key_url), same as our own builds.
# Everything else is the standard prod build. Build, then compare your measurements to the published
# ones at GET https://api.chutes.ai/servers/tee/measurements.
all:
children:
vm:
hosts: # Dynamically populated by playbook
host:
hosts:
localhost:
ansible_connection: local

vars:
ansible_user: "{{ lookup('env', 'USER') }}"
# Root RSA PUBLIC key — fetched from R2 (public), baked into the image, measured into RTMR3.
root_signing_key_url: "https://vm.chutes.ai/root-signing-key.pem"
root_signing_key_path: "/tmp/chutes-root-signing-key.pem"
# Published constant — intentionally NOT a secret (does not affect measurements; see header).
luks_passphrase: "chutes"
tdx_base_url: "https://cvm.chutes.ai"
validator_base_url: "https://api.chutes.ai"
build_env: "prod"
prime_wait_timeout: 300

debug_build: false
guest_ssh_keys: []
Loading
Loading