tailscale lock command
tailscale lock
manages tailnet lock for your tailnet.
tailscale lock <subcommand> [flags] <args>
Subcommands:
init
Initializes tailnet lock.status
Outputs the state of tailnet lock.add
Adds one or more trusted signing keys to tailnet lock.remove
Removes one or more trusted signing keys from tailnet lock.sign
Signs a node key and transmits the signature to the coordination server.disable
Consumes a disablement secret to shut down tailnet lock for the tailnet.log
Lists changes applied to tailnet lock.local-disable
Disables tailnet lock for this node only.revoke-keys
Retroactively revoke one or more tailnet lock keys.
Running tailnet lock
with no subcommand and no arguments is equivalent to running tailscale lock status
.
Example:
tailscale lock
Example output:
Tailnet lock is ENABLED.
This node is accessible under tailnet lock.
This node's tailnet-lock key: tlpub:1234abcdef
Trusted signing keys:
tlpub:1234abcdef (us)
lock init
Initializes tailnet lock for the entire tailnet.
tailscale lock init [flags] <tlpub:trusted-key1 tlpub:trusted-key2 ...>
Available flags:
--confirm=false
Whether to prompt for confirmation. Iftrue
, there is no prompt for confirmation.--gen-disablement-for-support
Generate an additional disablement secret and transmit it to Tailscale support. Tailscale support can then use it to disable tailnet lock. We recommend setting this flag. Note that if Tailscale support disables tailnet lock, it will remain disabled and Tailscale support cannot re-enable it, so this would be considered an emergency recovery mechanism, not a temporary disabling of tailnet lock.--gen-disablements <N>
Number of disablement secrets to generate. If not specified, defaults to one disablement secret, which is the minimum required to initialize tailnet lock.
The tailnet lock keys specified are those initially trusted to sign nodes or to make further changes to your tailnet lock configuration. These are tailnet lock public keys. You can identify the tailnet lock key for a node you wish to trust by running tailscale lock
on that node and then copying the node's tailnet lock key.
You must specify the tailnet lock key for the node where you are running tailscale lock init
as one of the trusted tailnet lock keys. The list of additional keys must be space-separated.
The disablement secrets are displayed only when you initialize tailnet lock. Make note of them and secure them in a safe place.
Example:
tailscale lock init --gen-disablements=3 --gen-disablement-for-support \
--confirm tlpub:1234abcdef
Example output:
You are initializing tailnet lock with the following trusted signing keys:
- tlpub:1234abcdef (25519 key)
3 disablement secrets have been generated and are printed below. Take note of them now, they WILL NOT be shown again.
disablement-secret:ABC1234
disablement-secret:DEF5678
disablement-secret:GHI9012
A disablement secret for Tailscale support has been generated and will be transmitted to Tailscale upon initialization.
Initialization complete.
The disablement secrets are long passwords needed to disable your tailnet lock. See the tailscale lock disable
command for more details.
The number of disablement secrets will be the value you specified for --gen-disablements
. If you set --gen-disablement-for-support
, you'll see a message about a disablement secret being generated for Tailscale support.
There is currently a bug where initialization may fail with the following error:
error: 500 Internal Server Error: initialization failed: tka init-begin RPC: request returned (400): bootstrap tka state does not trust the initializing node
even when the tailnet lock key for the node you are running on was specified. As a workaround, logout and login again (via tailscale logout
and tailscale login
) before trying again.
lock status
Outputs the state of tailnet lock. The command shows whether tailnet lock is enabled, the value of the node's tailnet lock public key, and which nodes are locked out by tailnet lock and cannot connect to other nodes.
tailscale lock status [flags]
Available flags:
--json
Return a machine-readable JSON response.
Example:
tailscale lock status
Example output:
Tailnet lock is ENABLED.
This node is accessible under tailnet lock.
This node's tailnet-lock key: tlpub:1234abcdef
Trusted signing keys:
tlpub:1234abcdef (us)
If the node you run tailscale lock status
on doesn't have an accessible key, the output will look like:
This node is LOCKED OUT by tailnet-lock, and action is required to establish connectivity.
Run the following command on a node with a trusted key:
tailscale lock sign nodekey:abcdef12 tlpub:11223344
If one of your peer nodes is locked out of your tailnet, after the list of trusted signing keys, the output will look like:
The following nodes are locked out by tailnet lock and cannot connect to other nodes:
bob.yak-bebop.ts.net. 100.111.222.33, fd7a:115c:a1e0:aabb:ccdd:eeff:0123:4567 n12345CNTRL
lock add
Adds one or more trusted signing keys to tailnet lock.
This command needs to be run from a node with a trusted tailnet lock key.
tailscale lock add <tlpub:trusted-key1, tlpub:trusted-key2, ...>
The tailnet lock keys specified are tailnet lock public keys. You can identify the tailnet lock key by running tailscale lock
on that node and then copying the node's tailnet lock key.
lock remove
Removes one or more trusted signing keys from tailnet lock.
This command needs to be run from a node with a trusted tailnet lock key.
tailscale lock remove [flags] <tlpub:trusted-key1, tlpub:trusted-key2, ...>
Available flags:
--resign
Resign signatures which would be invalidated by removal of trusted signing keys. Defaults to true.
The tailnet lock keys specified are tailnet lock public keys. You can identify the tailnet lock key by running tailscale lock
on that node and then copying the node's tailnet lock key.
lock sign
Performs signing operations. tailscale lock sign
has two signing modes:
- Signs a node key using the tailnet lock key on the current node (the node where the command is running), and transmits the signature to the coordination server.
- Signs a pre-approved auth key, printing it in a form that can be used to bring up nodes under tailnet lock. Specifically, it signs the auth key so it can authenticate a new node without needing to then sign the new node before adding it to the tailnet.
Signing a node key is necessary to establish connectivity for nodes which are locked out by tailnet lock.
If any of the key arguments begin with file:
, the key is retrieved from the file at the path specified in the argument suffix.
This command needs to be run from a node with a trusted tailnet lock key.
tailscale lock sign <node-key> [<rotation-key>]
or
tailscale lock sign <auth-key>
Examples:
This example demonstrates signing a node key, optionally using the node's tailnet lock key (tlpub:trusted-key2
) to support key rotation.
tailscale lock sign nodekey:1abddef1 tlpub:trusted-key2
This example shows signing an auth key. For this example, $AUTH_KEY
is an environment variable set to a pre-approved auth key that you already generated.
tailscale lock sign $AUTH_KEY
The output from successfully running the command will be a signed pre-approved auth key, which you can then use to pre-approve devices in your tailnet.
lock disable
Consumes the specified disablement secret to disable tailnet lock for the entire tailnet.
tailscale lock disable <disablement-secret>
Disabling tailnet lock is a security-relevant operation—if the disablement procedure lacked authorization checks, a compromised control plane could trivially disable tailnet lock (and all its protections) to attack a tailnet as before. To avoid this, use of a disablement secret is required to globally disable tailnet lock.
Disablement secrets are long passwords generated during the process of enabling tailnet lock, when you ran tailscale lock init
. The key derivation function (KDF) derived value of each disablement secret is stored by each node's tailnet key authority (and hence known by every node in a tailnet), but the secret itself remains confidential until use.
When a disablement secret is used, the secret is distributed to all nodes in the tailnet. Each node can then verify the authenticity of the disablement operation by computing the KDF value of the secret, and comparing it to the stored KDF values in their tailnet key authority (TKA). If they match, then the node can be sure the disablement was authentic, and disable tailnet lock locally.
Once the specified disablement-secret
secret is used, it has been distributed to all nodes in the tailnet and should be considered public.
If tailnet lock is re-enabled, new disablement secrets will be generated.
Example:
tailscale lock disable disablement-secret:ABC1234
lock log
List changes applied to tailnet lock.
tailscale lock log [flags]
Available flags:
--json
Return a machine-readable JSON response.--limit
Maximum number of changes to list. Defaults to 50.
Example:
tailscale lock log
Example output:
update 17310b8e655867d3973a72cd20bc7c21f81f7687b4e7911c285f2eb16df5df36 (checkpoint)
Disablement values:
- 1234abcd
- 9876aaaa
- c1d2e3f4
- 8f6e4d2c
Keys:
Type: 25519
KeyID: 1234abcdef
Votes: 1
lock local-disable
Disables tailnet lock for this node only.
tailscale lock local-disable
This command disables tailnet lock for only the current node (the node where the command is running). If tailnet lock is disabled just for this node, the node will now accept traffic from other nodes that are locked out. It does not mean that the node can send or receive traffic from other nodes in the tailnet that are signed.
If you encounter a significant issue with tailnet lock for your entire tailnet and can't disable it via tailscale lock disable
(for example, if you can't locate your disablement secret), you could run tailscale lock local-disable
on each of your nodes to make your tailnet in effect ignore tailnet lock.
lock revoke-keys
Retroactively revoke the specified tailnet lock keys.
This command needs to be run from a node with a trusted tailnet lock key.
tailscale lock revoke-keys <tlpub:key1, tlpub:key2, ...> [flags]
Available flags:
--cosign=false
Continue the key revocation using the tailnet lock key on this device and the provided recovery command from another device with a trusted tailnet lock key that has runtailscale lock revoke-keys
.--finish=false
Finish the recovery process by transmitting the revocation.--fork-from <hash>
(Advanced users only) Hash of the parent authority update message (AUM) from which to rewrite the tailnet key authority state.
The tailnet lock keys specified are tailnet lock public keys. You can identify the tailnet lock key by running tailscale lock
on that node and then copying the node's tailnet lock key.
If you want to remove a key that has not been compromised, use the tailscale lock remove
command instead.
Revocation is a multi-step process that requires several signing nodes to co-sign the revocation. Each step uses the tailscale lock revoke-keys
command.
-
Open a terminal on a signing node that does not have a compromised key.
-
Run the following command, where
<tlpub:compromised-key1 tlpub:compromised-key2>
is a space-separated list of the keys that you want to revoke:tailscale lock revoke-keys tlpub:compromised-key1 tlpub:compromised-key2
The output of this command contains a
tailscale lock revoke-keys --cosign
command, which you will use in the next step. -
On another trusted signing node, run the
tailscale lock revoke-keys --cosign
command. The output of this command contains a newtailscale lock revoke-keys --cosign
command. Repeat this process, always using the new output from each--cosign
command, until the number of times you used--cosign
exceeds the number of revoked keys. For example, if you revoked 3 keys, you need to run thetailscale lock revoke-keys --cosign
command 4 times. -
Finish the process by running the command that was output from the last use of
--cosign
except replace--cosign
with--finish
:tailscale lock revoke-keys --finish <hex-data>
By default, Tailscale will determine the appropriate point in the tailnet lock log to fork. If more signing nodes agree that a key should be revoked than not, then the keys in the fork that Tailscale determined to still be trusted are then used instead of the revoked keys.
If the majority of signing nodes are compromised, you can disable and then re-enable tailnet lock itself.