tailscale lock command

tailscale lock manages tailnet lock for your tailnet.

tailscale lock <sub-command> [sub-flags] <args>

Sub-commands:

  • 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.

Running tailnet lock with no sub-command 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. If true, 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 public key, which nodes are locked out by tailnet lock and cannot connect to other nodes, etc.

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 <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 sign

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.

Signing a node key is necessary to establish connectivity for nodes which are locked out by tailnet lock.

This command needs to be run from a node with a trusted tailnet lock key.

tailscale lock sign <node-key> [<rotation-key>]
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 tskey-wrap

Signs a pre-approved auth key for use with 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.

This command needs to be run from a node with a trusted tailnet lock key.

tailscale lock tskey-wrap <tskey-auth-XXXXCTRL-NNNNNN-->

Example:

For this example, $AUTH_KEY is an environment variable set to a pre-approved auth key that you already generated.

tailscale lock tskey-wrap $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 on your tailnet.

Last updated

WireGuard is a registered
trademark of Jason A. Donenfeld.

© 2023 Tailscale Inc.

Privacy & Terms