jason-riddle / ansible-role-tailscale

Tailscale on Linux.
https://galaxy.ansible.com/ui/standalone/roles/jason_riddle/tailscale/
MIT License
6 stars 0 forks source link

Possible to Run Up with Oauth Key? #104

Closed jason-riddle closed 4 months ago

jason-riddle commented 5 months ago

Looking through the tailscale up code, it looks like it's possible to run up with an oauth key. Here's what I've been looking at

https://github.com/tailscale/tailscale/blob/4f95b6966bc91372dad00a32358d80828befeda7/cmd/tailscale/cli/up.go#L1120-L1130

// resolveAuthKey either returns v unchanged (in the common case) or, if it
// starts with "tskey-client-" (as Tailscale OAuth secrets do) parses it like
//
//  tskey-client-xxxx[?ephemeral=false&bar&preauthorized=BOOL&baseURL=...]
//
// and does the OAuth2 dance to get and return an authkey. The "ephemeral"
// property defaults to true if unspecified. The "preauthorized" defaults to
// false. The "baseURL" defaults to https://api.tailscale.com.
// The passed in tags are required, and must be non-empty. These will be
// set on the authkey generated by the OAuth2 dance.
func resolveAuthKey(ctx context.Context, v, tags string) (string, error) {

I can't find any documentation on the tailscale website to support this though

jason-riddle commented 5 months ago

It seems possible, but it also seems messy.

Looking at https://github.com/artis3n/ansible-role-tailscale/blob/main/tasks/install.yml#L83-L107, I think the up command would need to look like the following.

# Not sure what `preauthorized=false` does?
# Tags are required when using oauth keys.
tailscale up --authkey="tskey-client-xxxx?ephemeral=false&preauthorized=false&baseURL=https://api.tailscale.com" --advertise-tags="tag:server,tag:homelab"

Supporting this feature would require adding another variable to set ephemeral, preauthorized, and baseURL. This could be one large string such as

up_authkey_api_args: "ephemeral=false&preauthorized=false&baseURL=https://api.tailscale.com"

But then I would need to know when an Oauth key is being passed in order to add these arguments. That would require additional parsing logic and would be very messy to maintain.

jason-riddle commented 5 months ago

A different idea is to not directly support using oauth keys through the CLI, but instead use something externally like curl and create an auth key using an oauth key via the API, and then pass that to the up command. That could be messy and depends on an external tool such as curl being available, unless I use ansible native's curl equivalent.

Resources

jason-riddle commented 5 months ago

So, I think a good idea is to not add any additional logic to support this and just document this as a feature. I could add the following example

- hosts: all

  vars:
    tailscale_up_node: true
    # TODO: Requires `devices:write` scope?
    # TODO: https://github.com/tailscale/tailscale/blob/4f95b6966bc91372dad00a32358d80828befeda7/cmd/tailscale/cli/up.go#L1179
    # TODO: https://github.com/tailscale/tailscale/blob/main/client/tailscale/keys.go#L75
    # TODO: https://github.com/tailscale/tailscale/blob/main/client/tailscale/keys.go#L102
    # Where TAILSCALE_OAUTHKEY_WITH_ARGS="tskey-client-xxxx?ephemeral=false&preauthorized=false&baseURL=https://api.tailscale.com"
    tailscale_up_authkey: "{{ lookup('env', 'TAILSCALE_OAUTHKEY_WITH_ARGS') }}"
    tailscale_up_extra_args: "--advertise-tags="tag:server,tag:homelab"

  roles:
    - jason_riddle.tailscale

It's not the cleanest as I'm just jamming in the http args into the authkey var, but it works.

jason-riddle commented 4 months ago

Meh, I think this would be too much of a headache to add in without enough to gain. Closing.