# A Linux client
Proof that a machine with no Secure Enclave can read a secret held by a Mac, with the
fingerprint happening on the Mac.
This container holds **no store and no key**. `passbox get` opens a TCP connection to the
Mac's broker over the tailnet, a Touch ID prompt appears there naming this machine, and the
value comes back. A copy of the container is worth nothing.
## On the Mac
The broker has to be running already. One spawned by an incoming connection cannot raise a
Touch ID prompt, which is measured, not assumed: a process without a GUI session gets
`canEvaluatePolicy` false.
```bash
tailscale status # up, and this machine has a 100.x address
passbox ls # starts a broker, which then listens on the tailnet too
```
The broker binds to the tailnet address only. Not loopback, which has none of the unix
socket's `0600` protection, and not every interface, which would put a secrets daemon on
the LAN. With Tailscale down it opens no port at all and says so.
## Here
```bash
docker build -t passbox-client examples/linux-client
docker run -it --rm \
--cap-add NET_ADMIN --device /dev/net/tun \
-e TS_AUTHKEY=tskey-auth-... \
-e PASSBOX_HOST=m4 \
passbox-client
```
Then inside:
```bash
passbox get github/token
```
`PASSBOX_HOST` is the Mac's tailnet name, or `name:port` for a port other than 8787. It can
also live in `~/.passbox/host`, which is what the entrypoint writes.
## What this does not give you
**The client cannot list.** `ls` needs names, which needs the store key, which lives on the
Mac. Ask for a name you know.
**The agent name is still self declared.** `PASSBOX_AGENT` is whatever the caller sets. Over
the tailnet the broker also runs `tailscale whois` on the peer address, and *that* name the
control plane authenticated, so the prompt shows a machine rather than a claim.
**The Mac has to be awake, unlocked, and lid open.** No prompt can be answered otherwise, and
a closed lid fails with `canEvaluatePolicy` false rather than anything clearer.