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. I’ve known that the feature overcomes the issue but I’d never worked too closely 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 just anyone but anyone reading wouldn’t be reading unless they already knew some of the concepts.

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 example.com everywhere.

Pre-requisites

Set the primary e-mail address for your Codeberg account

While Codeberg allows setting of multiple e-mail addresses to the account, it’s only the primary e-mail that will be looked at for verification. It will also be the e-mail address you use as your Tailscale login. I think a reasonable choice is to use something like codeberg@example.com.

Configure a repository to use a custom domain through Codeberg Pages

This requires creating a .domains file in the root of the repository and setting the correct DNS records for your domain name to point to Codeberg. Codeberg has a good page detailing how to do all of this. You might want to place a temporary index.html with some filler content so you can verify that the Codeberg page with the custom domain is working together and then check to see that https://example.com (replace with your real domain) loads properly.

WebFinger setup

A WebFinger is needed for Tailscale to know what OIDC issuer to being used (Codeberg in this case) as well as the account that’s being verified against on the Codeberg 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 until I decided to open the Integrating with Keycloak article in the Codeberg Docs which eventually mentions that the Discover endpoint is at https://codeberg.org/.well-known/openid-configuration. Navigating there we see:

{
    "issuer": "https://codeberg.org/",
    ...
}

This is unsurprising and exactly what we need so our final WebFinger will look like:

{
  "subject": "acct:codeberg@example.com",
  "links": [
    {
      "rel": "http://openid.net/specs/connect/1.0/issuer",
      "href": "https://codeberg.org/"
    }
  ]
}

If everything has been done correctly, navigate to https://example.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 codeberg@example.com to determine if your WebFinger is valid.

Configure an OAuth2 Application in Codeberg

Under Settings ➔ Applications ➔ Manage OAuth2 Applications, create a new OAuth2 Application by setting Application Name as Tailscale and Redirect URIs as https://login.tailscale.com/a/oauth_response. Once the OAuth2 application has been created, take note of the Client ID and Client Secret. The latter will only be viewable on the first page load so make sure you have a copy to be accessed later.

Tailscale setup

We’re almost done! We just need to sign up to Tailscale with OIDC. This can be done at https://login.tailscale.com/start/oidc. We need to enter codeberg@example.com into the Email address field which should update the WebFinger URL to the right place. I’ll leave the rest to the official Tailscale setup section rather than just repeating eveything.