Skip to content

Commit 96bcc30

Browse files
committed
the newest trust root was missing from the page that lists them
`[system.ca_certificates]` shipped with a CHANGELOG entry and a commented example, and no prose anywhere. Two of the three gaps that leaves are the ones a stranger hits. SECURITY.md's "Your declaration is the trust boundary" enumerates every string you can name to opt into a trust root, and did not name the most direct one on the list: a certificate there is trusted for every TLS connection the machine makes. That is the same defect 0.10 fixed in this file when it claimed kuma adds no third-party repositories while mesa_freeworld() was adding RPM Fusion on every desktop build. concepts.md gains the section the feature never got. The completeness test cannot catch this: its row is Declared("system"), and a Declared row only asserts the schema section exists, so prose is outside what it can see. Also fixes the table of contents, which was missing three sections. Both 0.13 commits that added one (the permissions page, the out-of-scope page) left it unlinked, and 0.12's menu section did too.
1 parent c752c94 commit 96bcc30

2 files changed

Lines changed: 55 additions & 0 deletions

File tree

‎SECURITY.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,14 @@ into each:
5959
into the image.
6060
- **`services.enable`** starts units that are already in the image. It cannot
6161
introduce one.
62+
- **`system.ca_certificates`** is trust in a certificate authority, and it is
63+
the most direct entry on this list: a certificate named there is trusted for
64+
every TLS connection the machine makes, by every program that reads the
65+
system trust store. It is copied to `/etc/pki/ca-trust/source/anchors/` and
66+
`update-ca-trust` runs in the same build layer. `kuma check` rejects a value
67+
that is not a PEM certificate, and rejects one containing a private key
68+
outright rather than warning, because a key there would be baked
69+
world-readable into every image built from that declaration.
6270

6371
Names in these lists are validated before they reach dnf, flatpak, systemctl,
6472
or brew: no leading dashes, so a name can't become a flag, and no shell

‎docs/concepts.md‎

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@ and [the glossary](glossary.md) defines the vocabulary.
88
- [What happens to changes you make by hand](#what-happens-to-changes-you-make-by-hand)
99
- [Where the base system comes from](#where-the-base-system-comes-from)
1010
- [What every image carries](#what-every-image-carries)
11+
- [The menu](#the-menu)
1112
- [Why a desktop installs things you did not name](#why-a-desktop-installs-things-you-did-not-name)
1213
- [What a build records: kuma.lock](#what-a-build-records-kumalock)
1314
- [What updates itself, and what waits for you](#what-updates-itself-and-what-waits-for-you)
1415
- [Why a file you edited by hand keeps winning](#why-a-file-you-edited-by-hand-keeps-winning)
16+
- [Permissions, and a file kuma does not own](#permissions-and-a-file-kuma-does-not-own)
17+
- [What your machine trusts](#what-your-machine-trusts)
18+
- [What a declaration does not reproduce](#what-a-declaration-does-not-reproduce)
1519
- [Boot health and automatic rollback](#boot-health-and-automatic-rollback)
1620
- [What an install decides that a declaration cannot](#what-an-install-decides-that-a-declaration-cannot)
1721

@@ -444,6 +448,49 @@ into a home. One app declares into one store: flatpak merges the two with the
444448
user store winning per key, so an app declared in both would be a file where
445449
half your lines quietly lose to the other half.
446450

451+
## What your machine trusts
452+
453+
Every TLS connection the machine makes is checked against a set of certificate
454+
authorities, and that set is state of an awkward kind. You add to it by
455+
dropping a file in a directory and running a command, it survives every
456+
rebuild because it lives in `/etc`, and afterwards nothing on the machine
457+
says why it is there. A machine could trust something its declaration could
458+
not say.
459+
460+
`[system.ca_certificates]` says it, keyed by the name each anchor gets on
461+
disk:
462+
463+
```toml
464+
[system.ca_certificates]
465+
"my-root-ca" = """
466+
-----BEGIN CERTIFICATE-----
467+
MIIBkTCB+wIJAKZ...
468+
-----END CERTIFICATE-----
469+
"""
470+
```
471+
472+
**The certificate goes in the file rather than beside it.** A declaration that
473+
points at a path somewhere else is not one file any more: carry it to a second
474+
machine and the anchor is missing, with nothing to say so.
475+
476+
Inlining is safe here for a reason that does not generalise, and the boundary
477+
is worth stating exactly. **A CA certificate is public by construction.** A
478+
private key is not, so one pasted into this table is refused rather than
479+
warned about: it would otherwise be baked world-readable into every image
480+
built from the file and pushed to a registry. That is `[user]`'s
481+
password-hash boundary, one file format over. A value that is not a
482+
certificate at all is refused by `kuma check` for the ordinary reason.
483+
484+
The anchor is copied to `/etc/pki/ca-trust/source/anchors/` and
485+
`update-ca-trust` runs in the same build layer that adds it, rather than being
486+
left for a boot to remember. Landing under `/etc` also puts it inside the
487+
`etc` check above, so a local edit that ever shadows it is reported rather
488+
than silently winning.
489+
490+
Adding a trust root is the most consequential thing this file can do in one
491+
line, which is why it is named again in `SECURITY.md` alongside the other
492+
roots a declaration opts into.
493+
447494
## What a declaration does not reproduce
448495

449496
A machine that boots from this image carries state the file never mentions,

0 commit comments

Comments
 (0)