Skip to main content
Connect Tailscale so agent machines can securely reach private services inside your network: internal databases, staging APIs, package registries, anything on your tailnet. Machines in enabled projects join your tailnet as ephemeral nodes at boot, tagged with a tag you choose, so you control exactly what they can access with your Tailscale ACLs. No public exposure, no static IP allow lists.

Connect your tailnet

1

Define a tag for Capy machines

In your tailnet policy file, add a tagOwners entry for the tag Capy machines will carry. We recommend tag:capy:
The tag lets your ACL rules single out Capy machines; the owner list is who may assign it.
2

Create an OAuth client

On the Trust credentials page, click Credential and choose OAuth:
Tailscale's new credential page with the OAuth option selected

Trust credentials → Credential → OAuth

On the Scopes step pick Custom scopes, expand the Keys section, and check Write on Auth Keys; the tag picker that appears is required for the write scope — select the tag from the previous step. Leave every other scope unchecked:
The Auth Keys scope with Write checked and tag:capy selected

Keys → Auth Keys → Write, with your tag selected

Generate the credential and copy the client ID and secret; the secret is shown once and starts with tskey-client-.
3

Connect Capy

Go to Settings → Integrations → Tailscale, click Connect, and enter the client ID, client secret, and your tag. Capy validates the credentials against your tailnet before saving, and the secret is stored encrypted. Any org member can connect; each Capy org holds one Tailscale connection.
4

Enable projects

The Projects section appears on the same page once connected. Turn on each project whose machines should join your tailnet; machines in other projects never join.

How it works

When a machine in an enabled project boots or wakes, Capy mints a single-use, short-lived auth key from your OAuth client and the machine joins your tailnet as an ephemeral node named capy-<machine-id>, carrying your tag. From that point, agent commands on the machine can reach whatever your ACLs allow.
  • Ephemeral and self-cleaning. Nodes are removed by Tailscale automatically when a machine pauses or is destroyed; a resumed machine rejoins with a fresh key. Your machine list never accumulates stale entries.
  • Never blocking. A failed join never blocks a machine from booting; the machine runs without tailnet access and rejoins on its next wake.
  • Keys stay on the machine. Each auth key is minted per machine, expires after five minutes, and is delivered to a root-owned file readable by no other user. Keys never appear in process arguments, environment variables, or logs, and never persist into machine snapshots.

Controlling access with ACLs

Capy machines have exactly the access your ACL grants their tag, and nothing else by default. For example, to let agents reach a private Postgres instance, declare its address as a host alias and accept traffic to its port:
A destination can be a hosts alias, a Tailscale IP or CIDR, or another tag (for example tag:database:5432 if your database nodes are themselves on the tailnet). Scope the tag’s rules to the specific services agents need; there is no reason for Capy machines to see your whole tailnet.

Disconnecting

Turning a project off stops its machines from joining at their next boot or wake. Disconnecting the integration (the menu on the connection card) removes the stored credentials and stops all new joins immediately. Either way, already-running machines keep their tailnet session until they pause or stop. To cut one off immediately, remove its node from your Tailscale machines list, and revoke the OAuth client in Tailscale if the credentials themselves should die.

Troubleshooting

Capy verifies the client by minting and immediately revoking a probe key. Check that the OAuth client has Keys → Auth Keys write scope, that the tag on the scope matches the tag you entered, and that the tag exists in your policy file’s tagOwners.
Your tailnet definitively rejected the credentials, usually because the OAuth client was revoked or the tag was removed from tagOwners. Machines keep booting without tailnet access until you reconnect with working credentials.
Check that its project’s toggle is on; only machines booted or woken after enabling join. A machine whose join failed rejoins on its next wake, so pausing and resuming it retries immediately.
That’s an ACL question: nodes tagged with your tag need an accept rule to the service’s host and port. Test from the machine with tailscale ping <host>.
No; machine infrastructure uses dynamic addresses. The tag is the stable identity, which is exactly what the ACL rules key on.