User Identification

Hi,

Just started experimenting with tailscale. Very interesting product.

When I visit https://hello.ipn.dev/ the application running there seems to access some data which allows it to correlate the incoming connection with a specific user (it displays my email/name).

Can someone elaborate it does this? I would like to use similar things to integrate tailscale more deeply into the system.

-Adam

Hi, the ā€œtailscale local APIā€ used to do this is still evolving and requires a sufficiently new tailscale version. (I canā€™t remember if this was in v1.6.0 or not, but if you build from the main branch, itā€™s there). A sample client library (in Go) you can play with is here: https://github.com/tailscale/tailscale/tree/main/client/tailscale. This is the one hello.ipn.dev is using.

1 Like

Hi, Iā€™m interested in this type of thing as well-- I feel it could considerably simplify identity management when writing small web applications intended to be used by people on your network (instead of needing to login to a 3rd party provider, just ask tailscale on the web server level as the requests come in).

I spent a couple of hours this evening hacking up a quick prototype based on my reading of the client library, but got a bit stumped when it came to using the whois endpoint (the daemon just responds with ā€œbad requestā€). Iā€™m not sure if this is just not supported or if Iā€™m doing something dumb:

It looks like it might be possible to do a poor personā€™s version of this using the TailScale API and getting /devices, but that only seems to give you the user id.

Thereā€™s a bit of a simpler way. Hereā€™s a little python script that will dump all of the Tailscale IP addresses for the current machine:

#!/usr/bin/env python3

import json
import subprocess

status_data = subprocess.check_output(["tailscale", "status", "--json"]).decode("utf-8")
status_data = json.loads(status_data)

for ip in status_data["TailscaleIPs"]:
    print(ip)

As of today, here are all of the keys in the JSON response:

>>> info.keys()
dict_keys(['Version', 'BackendState', 'AuthURL', 'TailscaleIPs', 'Self', 'MagicDNSSuffix', 'CertDomains', 'Peer', 'User'])

I hope this can help! Iā€™d be curious to see what other fun things you could do with this. There is a way to do this natively from Go (which is how the hello server works), however as of today we do not currently have this exposed to other applications. Iā€™d suggest querying tailscale status and attaching the user information as a part of an on-server session store.

1 Like

That worked! tailscale status --json has a rich amount of data, including the userā€™s full name.

As a proof-of-concept, I hacked up a small prototype which sets the (default) username for etherpad-lite using this metadata (obviously not intended to be used in the real world):

Awesome! You may want to cache that in prod but it should work great!

Very neat! Weā€™ve been meaning to do the same thing with our internal grafana instance. Logging in manually is so passĆ© :slight_smile:

į§