We self-hosted headscale, but wanted to move to their cloud product for higher reliablity.
The way that tailscale authenticates for an email like denzell.f@trieve.ai is:
- Makes a call to https://trieve.ai/.well-known/webfinger?resource=acct:denzell.f@trieve.ai. The response should look like this
{
"links": [
{
"href": "https://auth.trieve.ai/realms/trieve-organization",
"rel": "http://openid.net/specs/connect/1.0/issuer"
}
],
"subject": "acct:denzell.f@trieve.ai"
}- Makes calls to your oidc provider based on the
hrefvalue.
this is gist a blog and Tailscale has pretty good documentation on everything after webfinger
in their docs and in this blog.
Settting up webfinger is an excersize left to the reader.
The blog reccomends to have .well-known/web-finger just return a static response.

This doesn't work for multiple users, this is how we setup a simple webfinger server to support multiple users.
git clone https://gist.github.com/cdxker/160f5cd730fcd6818dbf32c954b5577c web-finger
cd web-finger
echo "OAUTH_SERVER_URL=auth.trieve.ai" > .env # Replace this with your auth-server url
docker compose -f 4_docker-compose.yml up -d --buildWe use Caddy to host our static files, so all we have to do is setup a rule to redirect traffic to trieve.ai/.well-known/webfinger
I made a simple flask server to make this more dynamic.
Made a basic Dockerfile, python is annoying on bare metal.
Setup for docker-compose so you can easily deploy
Caddyfile for directing traffic to different servers and assigning the SSL