Deployed 697eff74 to development with ProperDocs 1.6.7 and mike 2.2.0

This commit is contained in:
github-actions committed 2026-11-02 18:16:33 +00:00
1 parent 088340f173
commit fba2d78143
8 files changed
+42 -42

No files matched your search

+2 -2
View File
@@ -8,8 +8,8 @@
</span></code></pre></div> </div> <div class=tabbed-block> <div class="language-console highlight"><pre><span></span><code><span id=__span-5-1><a id=__codelineno-5-1 name=__codelineno-5-1 href=#__codelineno-5-1></a><span class=go>curl -H "Authorization: Bearer &lt;API_KEY&gt;" \</span>
</span><span id=__span-5-2><a id=__codelineno-5-2 name=__codelineno-5-2 href=#__codelineno-5-2></a><span class=go> --json '{"user": "&lt;USER&gt;", "authId": "&lt;AUTH_ID&gt;"}' \</span>
</span><span id=__span-5-3><a id=__codelineno-5-3 name=__codelineno-5-3 href=#__codelineno-5-3></a><span class=go> https://headscale.example.com/api/v1/auth/register</span>
</span></code></pre></div> </div> </div> </div> <h2 id=join-nodes-with-an-oauth-client>Join nodes with an OAuth client<a class=headerlink href=#join-nodes-with-an-oauth-client title="Permanent link">&para;</a></h2> <p>Headscale also serves a subset of the Tailscale-compatible API at <code>/api/v2</code>, which accepts <strong>OAuth 2.0 client-credentials</strong> in addition to API keys. The Tailscale client can use an OAuth client secret in place of an auth key: it exchanges the secret for an access token, mints a single-use tagged auth key and registers with it. This works anywhere the client takes an auth key: <code>tailscale up</code>, the container image, <code>tsnet</code> and the <a href=https://github.com/tailscale/github-action><code>tailscale/github-action</code></a>. One long-lived secret joins any number of nodes.</p> <p>Create an OAuth client with the <code>auth_keys</code> scope and the tags its nodes get. The secret is shown once:</p> <div class="language-shell highlight"><pre><span></span><code><span id=__span-6-1><a id=__codelineno-6-1 name=__codelineno-6-1 href=#__codelineno-6-1></a>headscale<span class=w> </span>oauth-clients<span class=w> </span>create<span class=w> </span>--scope<span class=w> </span>auth_keys<span class=w> </span>--tag<span class=w> </span>tag:ci
</span></code></pre></div> <p>Build the auth key from the secret:</p> <ol> <li>Swap the prefix: <code>hskey-client-…</code> becomes <code>tskey-client-…</code>. The client only runs the exchange for <code>tskey-client-</code>; Headscale accepts both.</li> <li>Append <code>?baseURL=&lt;your Headscale URL&gt;</code>.</li> <li>Set <code>--advertise-tags</code>. Each tag must exist in the policy's <code>tagOwners</code> and be one of the OAuth client's tags, or owned by one of them.</li> </ol> <div class="language-text highlight"><pre><span></span><code><span id=__span-7-1><a id=__codelineno-7-1 name=__codelineno-7-1 href=#__codelineno-7-1></a>tskey-client-&lt;id&gt;-&lt;secret&gt;?baseURL=https://headscale.example.com
</span></code></pre></div> </div> </div> </div> <h2 id=join-nodes-with-an-oauth-client>Join nodes with an OAuth client<a class=headerlink href=#join-nodes-with-an-oauth-client title="Permanent link">&para;</a></h2> <p>Headscale also serves a subset of the Tailscale-compatible API at <code>/api/v2</code>, which accepts <strong>OAuth 2.0 client-credentials</strong> in addition to API keys. The Tailscale client can use an OAuth client secret in place of an auth key: it exchanges the secret for an access token, mints a single-use tagged auth key and registers with it. This works anywhere the client takes an auth key: <code>tailscale up</code>, the container image, <code>tsnet</code> and the <a href=https://github.com/tailscale/github-action><code>tailscale/github-action</code></a>. One long-lived secret joins any number of nodes. A client keeps its newest 1000 access tokens and minting more ends the oldest, so give a long-lived integration its own client.</p> <p>Create an OAuth client with the <code>auth_keys</code> scope and the tags its nodes get. The secret is shown once:</p> <div class="language-shell highlight"><pre><span></span><code><span id=__span-6-1><a id=__codelineno-6-1 name=__codelineno-6-1 href=#__codelineno-6-1></a>headscale<span class=w> </span>oauth-clients<span class=w> </span>create<span class=w> </span>--scope<span class=w> </span>auth_keys<span class=w> </span>--tag<span class=w> </span>tag:ci
</span></code></pre></div> <p>Scopes apply to the whole tailnet, as in Tailscale: an <code>auth_keys</code> token can read and revoke auth keys of any tag, an <code>oauth_keys</code> token every OAuth client, and a <code>devices:core:read</code> token reads every device, routes included with <code>fields=all</code>. Keep the secret as safe as any credential that can revoke keys. Without <code>all=true</code>, a token lists only the auth keys made through a token, whatever their tags; with it, every valid auth key. No listing holds a spent, expired or revoked key. Tags limit only the tags a token puts on keys, clients and devices, and which tagged devices it may retag. Deleting an OAuth client revokes its secret and its access tokens; auth keys, clients and nodes created with it stay until you remove them.</p> <p>Build the auth key from the secret:</p> <ol> <li>Swap the prefix: <code>hskey-client-…</code> becomes <code>tskey-client-…</code>. The client only runs the exchange for <code>tskey-client-</code>; Headscale accepts both.</li> <li>Append <code>?baseURL=&lt;your Headscale URL&gt;</code>.</li> <li>Set <code>--advertise-tags</code>. Each tag must exist in the policy's <code>tagOwners</code> and be one of the OAuth client's tags, or owned by one of them.</li> </ol> <div class="language-text highlight"><pre><span></span><code><span id=__span-7-1><a id=__codelineno-7-1 name=__codelineno-7-1 href=#__codelineno-7-1></a>tskey-client-&lt;id&gt;-&lt;secret&gt;?baseURL=https://headscale.example.com
</span></code></pre></div> <div class="admonition warning"> <p class=admonition-title>Warning</p> <p>Without <code>baseURL</code> the client sends the secret to <code>https://api.tailscale.com</code>.</p> </div> <h3 id=attributes>Attributes<a class=headerlink href=#attributes title="Permanent link">&para;</a></h3> <p>These are all the attributes the client understands; any other is an error. Order does not matter and an empty value means the default.</p> <table> <thead> <tr> <th>Attribute</th> <th>Default</th> <th>Effect</th> </tr> </thead> <tbody> <tr> <td><code>baseURL</code></td> <td><code>https://api.tailscale.com</code></td> <td>Where the exchange and key creation go. Your Headscale URL, no trailing slash.</td> </tr> <tr> <td><code>ephemeral</code></td> <td><code>true</code></td> <td>Node is removed after it goes offline (<code>node.ephemeral.inactivity_timeout</code>). <code>false</code> to keep it.</td> </tr> <tr> <td><code>preauthorized</code></td> <td><code>false</code></td> <td>Accepted, no effect: Headscale always authorizes pre-auth-key nodes.</td> </tr> </tbody> </table> <p>Booleans take any Go <code>strconv.ParseBool</code> value (<code>true</code>, <code>false</code>, <code>1</code>, <code>0</code>, …).</p> <h3 id=examples>Examples<a class=headerlink href=#examples title="Permanent link">&para;</a></h3> <p><code>tailscale up</code>, either as the auth key or via <code>--client-secret</code> (which also takes <code>file:/path/to/secret</code>):</p> <div class="language-shell highlight"><pre><span></span><code><span id=__span-8-1><a id=__codelineno-8-1 name=__codelineno-8-1 href=#__codelineno-8-1></a>tailscale<span class=w> </span>up<span class=w> </span>--login-server<span class=w> </span>https://headscale.example.com<span class=w> </span>--advertise-tags<span class=w> </span>tag:ci<span class=w> </span><span class=se>\</span>
</span><span id=__span-8-2><a id=__codelineno-8-2 name=__codelineno-8-2 href=#__codelineno-8-2></a><span class=w> </span>--auth-key<span class=w> </span><span class=s1>'tskey-client-&lt;id&gt;-&lt;secret&gt;?baseURL=https://headscale.example.com&amp;ephemeral=false'</span>
</span></code></pre></div> <p>Container image:</p> <div class="language-shell highlight"><pre><span></span><code><span id=__span-9-1><a id=__codelineno-9-1 name=__codelineno-9-1 href=#__codelineno-9-1></a>docker<span class=w> </span>run<span class=w> </span>-d<span class=w> </span>--name<span class=w> </span>tailscale<span class=w> </span><span class=se>\</span>