Get started
Login
© 2024

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.
  • revoke-keys Retroactively revoke one or more tailnet lock keys.

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

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 on 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 run tailscale 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.

  1. Open a terminal on a signing node that does not have a compromised key.

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

  3. On another trusted signing node, run the tailscale lock revoke-keys --cosign command. The output of this command contains a new tailscale 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 the tailscale lock revoke-keys --cosign command 4 times.

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