Skip to content

tailcat: add Server.RemoveAllowedClient to revoke a client at runtime - #125

Closed
ybaelli wants to merge 1 commit into
tailscale:mainfrom
ybaelli:remove-allowed-client
Closed

ybaelli wants to merge 1 commit into
tailscale:mainfrom
ybaelli:remove-allowed-client

Conversation

@ybaelli

@ybaelli ybaelli commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Counterpart of AddAllowedClient: revoke a key while the server runs, and drop the client if it is connected, instead of restarting serve and disconnecting everyone. Verified in the new test that a revoked client's dial fails within seconds, so no engine-level peer eviction was needed.
Fixes #124

AddAllowedClient could add a key while running but nothing could take
one back: revoking a client meant restarting serve with a shorter
--allow, which also drops every other client until they re-meow.

RemoveAllowedClient deletes the key from the allowlist and, if the
client is connected, drops it from the network map so its tunnel is
torn down. Client IDs now come from a counter instead of
len(clients)+2, which would collide with a live peer after a removal.

Fixes tailscale#124
bradfitz added a commit that referenced this pull request Sep 26, 2026
…and DisconnectClient

Server.AllowedClients and Server.AddAllowedClient are replaced by a
single Server.AllowClient func(key.NodePublic) bool, asked about each
client as it connects. A nil hook allows all clients, which is the one
fail-open rule. The old slice's "empty means open" semantics forced
the CLI's --allow=none to insert a zero key as a sentinel; an empty
KeySet now simply allows nobody.

The hook runs with the backend mutex released, so unlike the hook
proposed in #120 it may block on an external lookup and may call other
Server methods. onMeow already runs in its own goroutine per meow
ping, so a slow answer delays only that client. A pendingAllow map
keeps a client's once-a-second meow retries from starting a second
call for the same key while one is in flight.

The new KeySet type is a mutex-guarded set of node keys whose Contains
method is the ready-made hook for a fixed or hand-maintained list, so
the runtime add that AddAllowedClient offered is still available, and
removal comes with it. The new Server.DisconnectClient drops a
connected client from the network map so its traffic is blackholed in
both directions; it does not reset its connections. Revoking a client
is then two orthogonal steps the caller composes: make the hook reject
the key, then disconnect it.

Client IDs now come from a counter that is never reused, since after a
removal len(clients)+2 could collide with a live peer.

Supersedes #120 and #125, which each added a second admission form
alongside the slice.

Fixes #119
Fixes #124

Co-authored-by: Jormen Janssen <j.janssen@riwo.eu>
Co-authored-by: Yann <y.baelli05@gmail.com>
@bradfitz

Copy link
Copy Markdown
Member

Merged, but folded into #134

@bradfitz bradfitz closed this Sep 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Server: allow revoking a client key at runtime (RemoveAllowedClient)

2 participants