Skip to content

feat(access): per-environment access on a self-hosted tailnet #348

Open
0 of 6 issues completed
Open

Description

@PiquelChips

Problem

Access to piqueld's private routes is decided by tailnet membership alone. Every member reaches every private route, so a QA tester can't be limited to staging. The tailnet also runs on Tailscale's hosted service, behind a Google login, and people's tailnet access is managed outside piqueld.

This is piqueld's part of sourceorigin-dev/infra#7, which moves the infrastructure to a self-hosted Headscale control server, with piqueld as the single place that manages everyone's access.

Model

  • Tailnet: one tailnet on a self-hosted control server, on the operator's Pi. piqueld's private ingress keeps working as today: an apps node on the tailnet, whois to identify callers, private routes on its address.
  • Network policy: written in the infra repo. It lets every member reach the apps node (tag:apps) and nothing else; it can't tell environments apart, since they share one address.
  • Account link: a tailnet user maps to one piqueld account.
  • Private route: reachable by a tailnet node whose linked account holds apps:access on the route's environment.
  • Control plane: the dashboard and API stay behind a passkey session or token. A tailnet node proves network membership, never piqueld access.
  • Enrollment: by hand over the operator's SSH until feat(auth): invitations enroll the invitee on the tailnet #344. piqueld never holds a Headscale API key: those have no scopes, so any key is full admin of the network.

Phases

sourceorigin-dev/infra#7 runs in phases. piqueld is involved in two:

Decisions

Roadmap

Phase Issue Depends on
3 #343 tailnet nodes on a self-hosted control server a Headscale release with Serve
4 #342 environment-scoped grants none
4 #345 link tailnet users to piqueld accounts #343
4 #346 private routes need an environment grant #342, #345
4 #344 invitations enroll the invitee on the tailnet #343, #345
4 #193 pass the account's identity to private routes #345, #346

Docs and NixOS module changes ship with each issue's pull request.

Related


Written with Claude Opus 5.5 in Claude Code (via T3 Code).

Activity

  1. changed the title [-]feat(access): a WireGuard access network and environment access[/-] [+]feat(access): per-environment access on a self-hosted tailnet[/+] on Oct 29, 2026
  2. self-assigned this
    on Oct 30, 2026
  3. moved this from Needs Triage to No status in origin-src.devon Oct 30, 2026
  4. added this to the 0.1 milestone on Oct 30, 2026
  5. modified the milestones: 0.1, 0.2 on Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

Relationships

None yet

Development

No branches or pull requests

Issue actions