preauthkeys: Allow specifying key material #684

Closed
opened 2025-12-29 02:22:01 +01:00 by adam · 4 comments
Owner

Originally created by @lorenzleutgeb on GitHub (Apr 5, 2024).

Why

I deploy multiple machines (both machines that run the Tailscale client, but also a machine that runs the Headscale control server). I want to automate the registration of clients to the control server as much as possible.

At the moment, I have to run headscale preauthkeys create which will randomly generate a 24 byte key and store it (along with additional metadata, such as expiry, user, etc.) in the SQLite database.

This means that in order to deploy a client, I first need to run a command on the control server to change its state, take the output, and use that to include it in the state to deploy to the client. Thus, I end up maintaining a list of preauth keys for my clients.

I would prefer to use the same list to also declaratively control the state of the control server. That is, I would like to set the list of preauth keys for the server (or at least add to the list), at the time I deploy it. This way I would be able to generate images for all clients and the control server, and deploy them "in one go", without having to first deploy the control server, executing headscale preauthkyes create and only then deploying clients.

Description

I would like to be able to specify keys that I have securely generate myself when I execute headscale preauthkeys create, for example:

headscale preauthkeys create --key da39a3ee5e6b4b0d3255bfef95601890afd80709ad001730 [...]

A workaround is to use the SQLite database directly, bypassing headscale preauthkeys, but I'd like to avoid that.

The implementation would be rather straightforward, adding another optional argument to pass the key, and if it is not specified call generateKey as it is done unconditionally at the moment.

Originally created by @lorenzleutgeb on GitHub (Apr 5, 2024). ## Why I deploy multiple machines (both machines that run the Tailscale client, but also a machine that runs the Headscale control server). I want to automate the registration of clients to the control server as much as possible. At the moment, I have to run `headscale preauthkeys create` which will [randomly generate a 24 byte key](https://github.com/juanfont/headscale/blob/8a8e25a8d1e6bc5fa27b7f72f99bbf24b290e0a6/hscontrol/db/preauth_keys.go#L218-L226) and store it (along with additional metadata, such as expiry, user, etc.) in the SQLite database. This means that in order to deploy a client, I first need to run a command on the control server to change its state, take the output, and use that to include it in the state to deploy to the client. Thus, I end up maintaining a list of preauth keys for my clients. I would prefer to use the same list to also declaratively control the state of the control server. That is, I would like to set the list of preauth keys for the server (or at least add to the list), at the time I deploy it. This way I would be able to generate images for all clients and the control server, and deploy them "in one go", without having to first deploy the control server, executing `headscale preauthkyes create` and only then deploying clients. ## Description I would like to be able to specify keys that I have securely generate myself when I execute `headscale preauthkeys create`, for example: headscale preauthkeys create --key da39a3ee5e6b4b0d3255bfef95601890afd80709ad001730 [...] A workaround is to use the SQLite database directly, bypassing `headscale preauthkeys`, but I'd like to avoid that. The implementation would be rather straightforward, adding another optional argument to pass the key, and if it is not specified call `generateKey` as it is done unconditionally at the moment. <!-- A clear and precise description of what new or changed feature you want. -->
adam added the enhancementstale labels 2025-12-29 02:22:01 +01:00
adam closed this issue 2025-12-29 02:22:02 +01:00
Author
Owner

@ohdearaugustin commented on GitHub (May 18, 2024):

You can refer to this old discussion about such keys: https://github.com/juanfont/headscale/issues/662

@ohdearaugustin commented on GitHub (May 18, 2024): You can refer to this old discussion about such keys: https://github.com/juanfont/headscale/issues/662
Author
Owner

@github-actions[bot] commented on GitHub (Aug 17, 2024):

This issue is stale because it has been open for 90 days with no activity.

@github-actions[bot] commented on GitHub (Aug 17, 2024): This issue is stale because it has been open for 90 days with no activity.
Author
Owner

@github-actions[bot] commented on GitHub (Aug 24, 2024):

This issue was closed because it has been inactive for 14 days since being marked as stale.

@github-actions[bot] commented on GitHub (Aug 24, 2024): This issue was closed because it has been inactive for 14 days since being marked as stale.
Author
Owner

@LEI commented on GitHub (Oct 27, 2024):

I am using SSH to extract the output of headscale apikey create allowing automated pre-auth keys management via API.

This is the only step that still requires direct SSH access, I see two ways to avoid it:

  • define a static "bootstrap" API key in the configuration file,
  • or add an option to specify the value when creating an API key.

In both cases I guess validation would ensure a long enough key is provided.
Let me know if it needs a dedicated issue.

@LEI commented on GitHub (Oct 27, 2024): I am using SSH to extract the output of `headscale apikey create` allowing automated pre-auth keys management via [API](https://github.com/awlsring/terraform-provider-headscale). This is the only step that still requires direct SSH access, I see two ways to avoid it: - define a static "bootstrap" API key in the configuration file, - or add an option to specify the value when creating an API key. In both cases I guess validation would ensure a long enough key is provided. Let me know if it needs a dedicated issue.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/headscale#684