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: