# Tailscale

## Tested Versions

- [Authelia]
  - [v4.38.0](https://github.com/authelia/authelia/releases/tag/v4.38.0)
- [Tailscale]
  - [v1.38.4](https://github.com/tailscale/tailscale/releases/tag/v1.38.4)

{{% oidc-common %}}

### Assumptions

This example makes the following assumptions:

- __Domain Root URL:__ `https://{{< sitevar name="domain" nojs="example.com" >}}`
- __Authelia Root URL:__ `https://{{< sitevar name="subdomain-authelia" nojs="auth" >}}.{{< sitevar name="domain" nojs="example.com" >}}/`
- __Authelia Account:__ `user@{{< sitevar name="domain" nojs="example.com" >}}`
- __Client ID:__ `tailscale`
- __Client Secret:__ `insecure_secret`

Some of the values presented in this guide can automatically be replaced with documentation variables.

{{< sitevar-preferences >}}

## Configuration

### Authelia

The following YAML configuration is an example __Authelia__ [client configuration] for use with [Tailscale] which will
operate with the above example:

```yaml {title="configuration.yml"}
identity_providers:
  oidc:
    ## The other portions of the mandatory OpenID Connect 1.0 configuration go here.
    ## See: https://www.authelia.com/c/oidc
    clients:
      - client_id: 'tailscale'
        client_name: 'Tailscale'
        client_secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng'  # The digest of 'insecure_secret'.
        public: false
        authorization_policy: 'two_factor'
        require_pkce: false
        pkce_challenge_method: ''
        redirect_uris:
          - 'https://login.tailscale.com/a/oauth_response'
        scopes:
          - 'openid'
          - 'email'
          - 'profile'
        response_types:
          - 'code'
        grant_types:
          - 'authorization_code'
        access_token_signed_response_alg: 'none'
        userinfo_signed_response_alg: 'none'
        token_endpoint_auth_method: 'client_secret_basic'
```

### Application

To configure [Tailscale] to utilize Authelia as a [OpenID Connect 1.0] Provider, you will need a public WebFinger reply
for your domain (see [RFC7033 Section 3.1]) and point it to Authelia. The steps necessary are outlined in the Tailscale
documentation on [Custom OIDC providers KB article]. This WebFinger reply is not generated by Authelia, so your external
web server hosted at the root of your domain will need to generate the response (Check [See also](#see-also) for example
implementations). The following steps are necessary to get Tailscale working with Authelia:

1. Your domain will need to reply to a WebFinger request for your Authelia account
2. Your domain root is `{{< sitevar name="domain" nojs="example.com" >}}` and the Authelia account in question is `user@{{< sitevar name="domain" nojs="example.com" >}}` the WebFinger request
   will be: `https://{{< sitevar name="domain" nojs="example.com" >}}/.well-known/webfinger/?resource=acct:user@{{< sitevar name="domain" nojs="example.com" >}}` the complete request is `https://{{< sitevar name="domain" nojs="example.com" >}}/.well-known/webfinger?rel=http%3A%2F%2Fopenid.net%2Fspecs%2Fconnect%2F1.0%2Fissuer&resource=acct%3Auser%40{{< sitevar name="domain" nojs="example.com" >}}`
3. The WebFinger request needs to be answered with the following example reply:
   ```json
   {
     "subject": "acct:user@{{< sitevar name="domain" nojs="example.com" >}}",
     "links": [{
       "rel": "http://openid.net/specs/connect/1.0/issuer",
       "href": "https://{{< sitevar name="subdomain-authelia" nojs="auth" >}}.{{< sitevar name="domain" nojs="example.com" >}}"
     }]
   }
   ```
4. For any other users that you want to add to Tailscale, you will need to provide similar WebFinger replies (e.g. for `user2@{{< sitevar name="domain" nojs="example.com" >}}` or `user3@{{< sitevar name="domain" nojs="example.com" >}}`)
5. Once you have the WebFinger reply set up and your [Authelia OpenID Connect Discovery endpoint](https://www.authelia.com/integration/openid-connect/introduction/#well-known-discovery-endpoints) is working (e.g. `https://{{< sitevar name="subdomain-authelia" nojs="auth" >}}.{{< sitevar name="domain" nojs="example.com" >}}/.well-known/openid-configuration`), you can sign up for a **new Tailnet** (migration can only be done if the Tailnet is associated with a custom domain) via the link: [Sign up with OIDC](https://login.tailscale.com/start/oidc) where you will see the following screen: \
   {{< figure src="tailscale_signup_1.png" alt="Tailscale Signup Screen 1" width="300" >}} \
   **Note:** Even though the WebFinger URL displayed is `https://{{< sitevar name="domain" nojs="example.com" >}}/.well-known/webfinger`, the actual GET request will be including request parameters, most importantly `resource`.
6. After clicking on **Get OIDC Issuer**, Tailscale will fetch the WebFinger reply via `https://{{< sitevar name="domain" nojs="example.com" >}}/.well-known/webfinger/?resource=acct:user@{{< sitevar name="domain" nojs="example.com" >}}` and follow the set `href` to `https://{{< sitevar name="subdomain-authelia" nojs="auth" >}}.{{< sitevar name="domain" nojs="example.com" >}}/.well-known/openid-configuration`. \
   **Note:** Make sure that the `href` URL matches the `issuer` URL returned from the Authelia OIDC discovery endpoint
7. On the next screen you will need to add your client ID & secret configured in Authelia to finish the OIDC provider registration in [Tailscale]. See the following example screenshot: \
   {{< figure src="tailscale_signup_2.png" alt="Tailscale Signup Screen 2" width="300" >}}


## See Also

- [Tailscale] [Custom OIDC providers KB article]
- [RFC7033 Section 3.1] _WebFinger: Identity Provider Discovery for OpenID Connect_
- [WebFinger example implementations](https://webfinger.net/code/)

[Authelia]: https://www.authelia.com
[Tailscale]: https://tailscale.com
[Custom OIDC providers KB article]: https://tailscale.com/kb/1240/sso-custom-oidc/
[RFC7033 Section 3.1]: https://datatracker.ietf.org/doc/html/rfc7033#section-3.1
[OpenID Connect 1.0]: ../../introduction.md
[client configuration]: ../../../../configuration/identity-providers/openid-connect/clients.md
