Some checks failed
Run Check Script / check (pull_request) Failing after 13s
98 lines
3.9 KiB
Markdown
98 lines
3.9 KiB
Markdown
# Fleet enrollment and device secrets
|
|
|
|
Enrollment gives a Linux device its Fleet identity and installs the agent. It
|
|
does not, by itself, authorize group placement or make application secrets
|
|
available.
|
|
|
|
## Enroll a device
|
|
|
|
Use the `example_fleet_device_enroll` binary as the current enrollment driver.
|
|
It runs locally or targets a device over SSH:
|
|
|
|
```bash
|
|
cargo run -p example_fleet_device_enroll -- \
|
|
--target ssh://pi@10.0.0.42 \
|
|
--issuer-url https://sso.example.com \
|
|
--audience <fleet-project-id> \
|
|
--nats-url wss://nats.example.com \
|
|
--admin-oidc-client-id <numeric-client-id> \
|
|
--agent-binary ./build/fleet-agent-aarch64 \
|
|
--device-id warehouse-042 \
|
|
--labels site=warehouse-east,arch=aarch64
|
|
```
|
|
|
|
The operator must authenticate to Zitadel through the browser flow or provide
|
|
`HARMONY_ZITADEL_ADMIN_TOKEN`. Enrollment then finds or creates the device
|
|
machine user, grants the requested project role, and mints a new JSON machine
|
|
key. Zitadel does not return an existing private key, so a repeated enrollment
|
|
mints another key.
|
|
|
|
`FleetDeviceSetupScore` installs Podman, the unprivileged `fleet-agent` user,
|
|
the root updater, systemd units, the agent binary, and its configuration. When a
|
|
machine key is supplied or minted, the Score writes it to
|
|
`/etc/fleet-agent/zitadel-key.json` with mode `0640`. The device cannot obtain
|
|
that long-lived key from NATS or OpenBao automatically.
|
|
|
|
The device ID must be a valid Kubernetes RFC 1123 subdomain. Labels are
|
|
self-reported placement data. Do not treat labels such as `group=production` as
|
|
authorization.
|
|
|
|
Verify the installation on the device and control plane:
|
|
|
|
```bash
|
|
systemctl status fleet-agent harmony-fleet-updater
|
|
journalctl -u fleet-agent -u harmony-fleet-updater
|
|
kubectl -n <namespace> get devices.fleet.nationtech.io
|
|
```
|
|
|
|
## Identity and tokens
|
|
|
|
The device stores only its Zitadel machine key. On each NATS connection, the
|
|
agent signs a 60-second JWT assertion and exchanges it at Zitadel's token
|
|
endpoint. Production requires the returned `id_token`: it is a JWT that the NATS
|
|
callout and OpenBao can verify against Zitadel's JWKS. Zitadel's default
|
|
`access_token` is opaque and is not suitable for this path.
|
|
|
|
The `id_token` is cached in memory and renewed before expiry. No refresh token
|
|
is stored. Rotating a machine key requires installing the replacement on the
|
|
device and deleting the old key in Zitadel.
|
|
|
|
## Group placement and OpenBao
|
|
|
|
The intended authorization rule is:
|
|
|
|
```text
|
|
admin-managed group membership AND self-reported target labels
|
|
```
|
|
|
|
`allowedGroups` names the authorized groups; `targetSelector` narrows placement
|
|
within those groups. An empty group list authorizes no device.
|
|
|
|
The operator supports a Zitadel-backed group source and OpenBao policy grant
|
|
synchronization, but the public production composition does not configure
|
|
either one today. Without an explicit group source, deployments match no
|
|
devices. Without OpenBao administrator configuration, changing
|
|
`allowedGroups` does not create or attach OpenBao policies.
|
|
|
|
OpenBao use therefore requires an operator to configure all of the following:
|
|
|
|
- the agent's OpenBao URL and secret prefix during device setup;
|
|
- Zitadel group roles and device grants;
|
|
- the operator group source;
|
|
- OpenBao JWT auth, deployment policies, and group-policy attachments;
|
|
- secret values under the configured deployment prefix.
|
|
|
|
Do not assume enrollment completed these steps. The E2E tests exercise explicit
|
|
group and grant setup, not the default production composition.
|
|
|
|
## Revocation
|
|
|
|
For a compromised device, remove or deactivate its Zitadel machine keys and
|
|
revoke any active OpenBao identity or token. Rotate secrets the device could
|
|
read. Group removal takes effect only after the device obtains a token carrying
|
|
the new claims; policy detachment or secret rotation is the immediate control.
|
|
|
|
See [ADR-025](../adr/025-fleet-device-secret-access.md) for the intended group
|
|
model. Treat its unwired portions as design until production composition adds
|
|
and verifies the required configuration.
|