What is SPIFFE Spire?
SPIFFE is a specification that describes a system for trusting workloads running on platforms.
Spire is the official reference implementation of SPIFFE.
There are many ways to deploy Spire, but generally you have these components.
- A central spire-server; holds an intermediate CA that can issue certificates
- Any number of spire-agent instances, running on all your nodes. They phone home to the spire-server
- Your running code, aka a workload; The workload (or, perhaps, a service mesh sidecar to the workload), talks to the local spire-agent, usually over a unix domain socket. If the spire-agent decides your workload is not an attacker (a process they call workload attestation), it requests a new cert identity (the so-called SVID in Spire jargon), and gives it back to your workload
In practical terms, Spire is a structured way to do mTLS across a fleet of microservices, with minimal attack surface. The operator trusts a select few components (the cloud platform, maybe), sets up Spire, and gets mTLS and short-lived, frequently-rotated certificates.
On Kubernetes, a spire-agent runs as a DaemonSet, and it’s privileged. The spire-agent listens on a unix socket at a well-known path on the underlying host. Workloads mount that socket from the host, and talk to the agent that way.
Spire + LXD?
I am trying to think of a least-privilege way one would do this in an LXD server, or even an LXD cluster.
One strategy is to run the spire-agent directly on the LXD host, and bind mount a socket in.
Another strategy is to run agents inside each container Instance, and just treat them as whole unix systems, using the already-existing Unix attester plugin. But that seems like a waste of resources, at least compared to K8s.
Is there a way to run the agent in a container and share a bind mount only between containers? Is there a way to do this without privileged containers? Furthermore, can the LXD daemon be queried to determine the following information about what’s running on a server:
- processes running in a container, UID, GID
- where binaries are on the “real host”
The spire-agent itself usually needs high privileges, although this can be adjusted based on your security posture. But it usually needs access to PID namespace, user namespace; And if you want to checksum the binaries of running processes, you need access to the filesystem.
Anyway, if anyone has ideas, I’d appreciate it. I want to see what’s possible with LXD.
UPDATE: Sharing a folder between unprivileged containers is apparently possible with shiftfs, which I haven’t tried yet LXD usecases of shiftfs (volume-/disk-share)