I think Tailscale is a great product. Despite this, I’ve been hesitant to use it for everything due to not being able to use it without using Big Tech as an identity provider. The options have historically been to use either Microsoft, GitHub (basically Microsoft), Google or Apple. None of these companies align with my personal values. One workaround is to use Headscale which is a self-hosted implementation of the Tailscale control server which removes the need to use an identity provider altogether.
The identity provider dilemma has been somewhat resolved with the introduction of custom OIDC providers by Tailscale. I’ve known that the feature overcomes the issue but I’d never worked too closely (few SAML integration in project management level, rather than integration) with OIDC to be confident enough to make sure I was doing it the right way. Yesterday, I challenged myself to get it working—it was actually quite easy! I’ve decided to write this post to share what’s involved in case someone else out there might find it valuable (or just future me who is wondering how I did any of it).
We will largely be following what’s on the Tailscale documentation linked above. There are a few technical ideas here that would not be appropriate, but anyone reads wouldn’t already know some concepts. I’m not a Pro for OIDC or Oauth, this guide worked for me, but probably has a lot of space for improvement, and you are welcome to give suggestions.
Assumptions
The domain name used everywhere needs to be consistent in many places and controlled by you (so no gmail.com
). This guide will assume you own and want to use yourdomain.com
everywhere.
Zitadel is opensource Identity Infrastructure, comes with two options, Cloud and Self-hosted. You can find great documentation from Zitadel for your curiosity how to get started with Zitadel?.
Pre-requisites
Set the primary e-mail address for your Zitadel account
While Zitadel allows setting of multiple e-mail addresses to the account, it’s one the primary e-mail that will be looked at for verification. You can also add another e-mail address be the e-mail address you use as your Tailscale login. I think a reasonable choice is to use something like [email protected]
.
Configure an instance to use a custom domain through Zitadel Cloud
This requires creating an instance in the Zitadel Cloud and create a project for Tailscale. Zitadel has a good page detailing how to do all of this here.
WebFinger setup
A WebFinger is needed for Tailscale to know what OIDC issuer to being used (Zitadel in this case) as well as the account that’s being verified against on the Zitadel side. Tailscale’s custom OIDC documentation has a reference we can base it on. There we see that we need to substitute two variables ${email}
and ${issuer URL}
.
I was stuck on the latter for a while. I didn’t know where to get value for it. I have gone through various Reddit posts and blogs, somewhere I found this article and it confused me more than before, until I found this https://<your_domain>.zitadel.cloud/.well-known/openid-configuration
in Zitadel’s documentation for Apache 2.0. It is nothing but the Zitadel Cloud Instance URL. Navigating there we see:
{
"issuer": "https://<your-instance-domain>.zitadel.cloud",
...
}
This is unsurprising and exactly what we need so our final WebFinger will look like:
{
"subject": "acct:[email protected]",
"links": [
{
"rel": "http://openid.net/specs/connect/1.0/issuer",
"href": "https://<your-instance-domain>.zitadel.cloud"
}
]
}
So the learning here is always read the product Documentation page 😄. I don’t know how to host .well-known/webfinger
in my website domain becuase they use Hugo
and Jekyll
. Later I found this comment in Github that provides a way to host .well-known/webfinger
in Github Pages.
If everything has been done correctly, navigate to https://yourdomain.com/.well-known/webfinger
. If you’re presented with a file then you can move on to using the WebFinger Lookup tool (located at https://webfinger.net/lookup/) where you can enter [email protected]
to determine if your WebFinger is valid.
Verify your webfinger with Tailscale. This is where we are going to Sign up with OIDC in Tailscale. Our own domain without using Big Tech as an identity provider and our actual goal.
Zitadel App setup for Tailscale
If you don’t encounter any error after clicking Get OIDC Issuer and Tailscale is asking for a ClientID and Secret, then you are good to go further down below steps, else you have to go back to previous steps from starting.
Now, time to create the Tailscale application in Zitadal. This is the easy part. Login to your Zitadal Cloud or self-hosted server with Zitadel admin account. In our case it is [email protected]
. Create a new project Tailscale. Create a new app Tailscale, with the following settings: Skip the wizard and chose Pro.
- Name: Tailscale
- Application Type: Web
- Grant Types: Authorization Code and Refresh Token. (Caution: Two items here)
- Response Types: Code
- Authenticatio Method: Basic
- Redirect URIs and Post Logout URIs:
https://login.tailscale.com/a/oauth_response
. Don’t forget to click+
button to add them.
Copy your ClientID and Secret and go back to Tailscale. Key in the information accordingly, and check consent
, login
, select_account
. WARNING Before clicking Next, make sure your Zitadal running on the URL you desired, you will have to contact the Tailscale support team to change your IdP if you got it wrong. Tailscale should transfer you to your Zitadal server for login, after login, you will back to Tailscale and your network is already created. Ready to set up your first device.
Congrats 🥳! now you are ready to go. In the future, when you log in to Tailscale, just use your Zitadal account and Tailscale will automatically transfer you to your Zitadal server for login.