tailscale-devices + policy: mint sidecar auth keys with per-service + host tags #144

Closed
opened 2026-05-26 19:52:55 +00:00 by coilysiren · 0 comments
Owner

Problem

Sub-task of coilysiren/infrastructure#134. The k8s sidecar half of the per-deployment tagging story. Currently every tailscale_tailnet_key minted by terraform/tailscale-devices/ carries only tag:k8s, so the tailnet view can't distinguish "which k8s service is this device" or "which physical host runs it".

Change

terraform/tailscale-devices/main.tf - each tailscale_tailnet_key.service mints with ["tag:k8s", "tag:${each.key}", "tag:host-kai-server"] instead of bare tag:k8s.

terraform/tailscale-policy/main.tf - reads the sibling module's services.yaml via cross-module yamldecode("../tailscale-devices/services.yaml") and registers a tag:<service> tagOwner for each. Single source of truth for the service list stays in tailscale-devices/services.yaml.

Rollout behavior

Changing tags on tailscale_tailnet_key triggers a replace. The new key lands in SSM (/coilysiren/<service>/ts-authkey), but existing sidecar pods don't re-auth - their ts-state Secret carries the original device identity from first boot, and that device keeps tag:k8s only. Gradual rollout: future deployments that wipe ts-state (or new services) get the rich tag set; existing devices keep tag:k8s until a manual re-auth or state-Secret bounce.

If you want every existing sidecar to carry the rich tags now, that's a per-namespace kubectl delete secret ts-state-<service> + kubectl rollout restart deployment/<service> sweep, tracked in a follow-up issue rather than baked into this commit.

Tag model after this lands:

  • tag:k8s - "this is a sidecar device" (all k8s pods)
  • tag:host-kai-server - "the underlying physical host is kai-server"
  • tag:<service> - per-service identity (eco-mcp, repo-recall, forgejo, etc.)

Filed by Claude.

**Problem** Sub-task of coilysiren/infrastructure#134. The k8s sidecar half of the per-deployment tagging story. Currently every `tailscale_tailnet_key` minted by `terraform/tailscale-devices/` carries only `tag:k8s`, so the tailnet view can't distinguish "which k8s service is this device" or "which physical host runs it". **Change** `terraform/tailscale-devices/main.tf` - each `tailscale_tailnet_key.service` mints with `["tag:k8s", "tag:${each.key}", "tag:host-kai-server"]` instead of bare `tag:k8s`. `terraform/tailscale-policy/main.tf` - reads the sibling module's `services.yaml` via cross-module `yamldecode("../tailscale-devices/services.yaml")` and registers a `tag:<service>` tagOwner for each. Single source of truth for the service list stays in `tailscale-devices/services.yaml`. **Rollout behavior** Changing `tags` on `tailscale_tailnet_key` triggers a replace. The new key lands in SSM (`/coilysiren/<service>/ts-authkey`), but existing sidecar pods don't re-auth - their `ts-state` Secret carries the original device identity from first boot, and that device keeps `tag:k8s` only. Gradual rollout: future deployments that wipe `ts-state` (or new services) get the rich tag set; existing devices keep tag:k8s until a manual re-auth or state-Secret bounce. If you want every existing sidecar to carry the rich tags now, that's a per-namespace `kubectl delete secret ts-state-<service>` + `kubectl rollout restart deployment/<service>` sweep, tracked in a follow-up issue rather than baked into this commit. Tag model after this lands: - `tag:k8s` - "this is a sidecar device" (all k8s pods) - `tag:host-kai-server` - "the underlying physical host is kai-server" - `tag:<service>` - per-service identity (eco-mcp, repo-recall, forgejo, etc.) Filed by Claude.
Sign in to join this conversation.
No labels
P0
P1
P2
P3
P4
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
coilyco-flight-deck/infrastructure#144
No description provided.