Guest Configuration Hygiene¶
Rule: guest configuration carries no secrets. No passwords, API tokens,
private keys, cloud credentials, join tokens or long-lived SSH keys go into
spec.userData, cloud-config, guestinfo or a NoCloud seed.
The only tolerated exception is a single-use bootstrap value that is inert without the VM's vTPM proof, for example a one-time enrolment nonce that a broker redeems only together with an attestation from that VM's own vTPM (ADR-0045, ADR-0049). A value that grants anything on its own is a secret.
This page says what banlieue puts into a guest and who else can read it on the way. It is the reason for the rule.
Where user data comes from¶
VirtualMachine.spec.userData is never inline. It names exactly one of a
Secret or a ConfigMap, plus a key (default user-data)
(crates/banlieue-api/src/banlieue/virtualmachine.rs, UserDataSpec). The
banlieue-virtualmachine-userdata-authorization admission policy requires
the VM's creator to be able to get that object (ADR-0042).
The controller reads it (crates/banlieue-controller/src/reconciler/virtualmachine.rs,
resolve_rendered_user_data) and substitutes ${VM_NAME}, ${FQDN},
${IP}, ${PREFIX}, ${GATEWAY}, ${DNS} and ${DOMAIN}
(crates/banlieue-provider-sdk/src/guestdata.rs, render_placeholders).
Nothing scans the content for secret material; the only check is that it
is valid UTF-8.
Where it goes, and who can read it there¶
Referencing a Secret does not keep the content secret. The rendered text is copied in plaintext at each step:
| Copy | Location | Readable by |
|---|---|---|
| Infra machine spec | VSphereMachine.spec.userData, LibvirtMachine.spec.userData, CloudHypervisorMachine.spec.userData (set in crates/banlieue-controller/src/reconciler/infra.rs) |
Anyone with get on that infra kind in the namespace, and etcd backups. See threat model asset A-2 |
| vSphere guestinfo | guestinfo.userdata (base64) in the VM's extraConfig, applied at clone |
Anyone with read on the VM in vCenter, and the guest itself for its lifetime |
| libvirt NoCloud seed | A CIDATA ISO volume in the storage pool, attached as a CD-ROM (ADR-0054) |
Anyone with access to the storage pool, and the guest |
| Cloud Hypervisor seed | <machine dir>/seed.iso, mode 0440, attached read-only |
The provider's host user, host root, and the guest |
Everything in user data is also readable by any process in the guest that can read the config drive or query guestinfo. For a sandbox VM, that means the agent.
What banlieue itself writes into a guest¶
Besides the user's own data, banlieue adds only non-secret identity and network facts:
| Provider | Keys or files |
|---|---|
| vSphere | guestinfo.network.hostname; guestinfo.network.ip, .prefix, .gateway, .dns, .domain for the first interface and guestinfo.network.<i>.ip and so on for interface i >= 1 (static addressing only, ADR-0111); guestinfo.metadata (instance-id, local-hostname); guestinfo.userdata and guestinfo.userdata.encoding when user data is set; ethernetN.pciSlotNumber (crates/banlieue-provider-vsphere/src/reconciler/vspheremachine.rs, build_guestinfo) |
| libvirt | NoCloud meta-data (instance-id = domain UUID, local-hostname) and user-data if set (crates/banlieue-provider-sdk/src/cloudinit/mod.rs) |
| Cloud Hypervisor | The same NoCloud seed, built only when user data is set |
The GuestReady signal (ADR-0043) runs the other way: the guest writes a
marker (guestinfo.banlieue.phase on vSphere, /run/banlieue/phase on
libvirt, a vsock report on Cloud Hypervisor) and the provider only reads
it. On libvirt it is read with guest-file-read only, never guest-exec.
What to do instead¶
- Put credentials the workload needs behind an identity the VM proves at runtime (vTPM attestation, then a short-lived token). For sandboxes this is mediatore's job.
- Keep user data to configuration: packages, users without passwords, the
GuestReadymarker writer, and the address of the broker. - Do not add SSH authorized keys to sandbox user data. Sandboxes accept no inbound connections (ADR-0082).
- If you must use a bootstrap value, make it single-use, short-lived and bound to the VM's vTPM, as above.
Not enforced yet
banlieue does not currently lint user data for secret material. This rule is a deployment obligation until that lands. The alignment report for ADR-0081 and ADR-0082 tracks it as a candidate change.