Get started - it's free!
Log in
© 2025

Tailscale GitHub Action

The Tailscale GitHub Action is a GitHub Action that lets you connect your Tailscale network (known as a tailnet) to a GitHub Actions workflow.

You can access devices in your tailnet directly from your GitHub workflow, which opens up a range of possibilities:

  • Securely deploy your application to an internal server (even if you're using a GitHub-hosted runner).
  • Securely reach your self-hosted runners for specific platforms.
  • Reach your database of test data without leaving it exposed on the internet.
  • Access an internal deployment monitoring tool.

Prerequisites

Before using the Tailscale GitHub Action, ensure you have the following:

  1. A Tailscale account with Owner, Admin, or Network admin permissions.
  2. A GitHub repository that you have admin access to (required to set up the GitHub Action).
  3. At least one configured tag.
  4. An OAuth client ID and secret OR an auth key.

How it works

When you add the Tailscale GitHub Action to your workflow, subsequent steps in your GitHub Action can then access nodes in your tailnet. For example, the workflow could access a node that has a database of test data.

The Tailscale GitHub Action requires an OAuth client ID and secret OR an auth key that uses a tag identity and is reusable, ephemeral, and (if applicable) pre-approved.

We recommend that you use an OAuth client ID and secret. The OAuth client requires the auth_keys scope. You store the OAuth client ID and secret as GitHub encrypted secrets. OAuth clients are not associated with any user in your tailnet you must create tag to identify the GitHub runner. When you identify a device (such as GitHub runner) with a tag, it automatically applies the access permissions granted to that tag.

When your workflow runs, it uses the OAuth client ID and secret to create an ephemeral node. The ephemeral node can then access devices in your tailnet based on the access permissions granted to the tag you use to identify the GitHub runner.

Because the GitHub runner is ephemeral, shortly after the action completes, it's automatically removed from your tailnet. The next time the action runs, it creates a new ephemeral node, available only for the new workflow.

Any ephemeral node that the Tailscale GitHub Action creates is pre-approved on tailnets that use device approval.

Add the Tailscale GitHub Action to a workflow

  1. Create at least one tag for the ephemeral nodes that the Tailscale GitHub Action will create. For example, tag:ci, which is used for this example. The access permissions that you grant to the tags are applied to the nodes that will be created by the workflow.

  2. Set up a Tailscale OAuth client. You'll need the value of your OAuth Client ID and Client secret. If you are using an auth key instead of an OAuth client, refer to Using an auth key.

  3. Create a GitHub repository secret with the name TS_OAUTH_CLIENT_ID and assign your OAuth Client ID as the secret value.

  4. Create a GitHub repository secret with the name TS_OAUTH_SECRET and assign your OAuth Client secret as the secret value.

  5. In your GitHub Actions workflow, connect to your tailnet using the Tailscale GitHub Action. For example:

    - name: Tailscale
      uses: tailscale/github-action@v3
      with:
        oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
        oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
        tags: tag:ci
    

oauth-client-id and oauth-secret are your OAuth Client ID and Client secret, respectively. tags is a comma-separated list of the tags applied to the ephemeral nodes that the GitHub Action creates. These tags must already exist in your tailnet.

When the action runs, it creates an ephemeral node. The node can access nodes in your tailnet, subject to the access rules applied to the specified tag or tags. In the rest of your workflow, access other nodes in your tailnet as needed.

The ephemeral node is automatically cleaned up shortly after the action finishes.

Auth key considerations

If you are using an auth key instead of an OAuth client, it's best practice to ensure that the key type uses a tag identity, is reusable, and is ephemeral. If the tailnet uses device approval, ensure that the key type is also pre-approved.

To use the auth key for your workflow, create a GitHub secret with the name TAILSCALE_AUTHKEY and the value set to your auth key. Then use the authkey field to reference the secret in your workflow. For example:

- name: Tailscale
  uses: tailscale/github-action@v3
  with:
    authkey: ${{ secrets.TAILSCALE_AUTHKEY }}

Tailscale GitHub Action version

Tailscale does not update the client version for the Tailscale GitHub Action every time there is a new Tailscale client release. The default version specified in the base YAML file remains unchanged for long periods of time. It changes only when there is a meaningful reason to do so.

If you would like to set the version yourself, add a version entry to your workflow:

  - name: Tailscale
    uses: tailscale/github-action@v3
    with:
      oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
      oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
      tags: tag:ci
      version: 1.66.0

If you would like to specify the latest version, set the version to latest.

  - name: Tailscale
    uses: tailscale/github-action@v3
    with:
      oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
      oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
      tags: tag:ci
      version: latest

You can find the latest Tailscale stable version number at our stable release track.

Cache Tailscale binaries

Caching can reduce download times and download failures on runners with slower network connectivity. Although caching is not enabled by default, it is generally recommended.

You can opt in to caching Tailscale binaries by passing 'true' to the use-cache input:

  - name: Tailscale
    uses: tailscale/github-action@v3
    with:
      oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
      oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
      use-cache: 'true'

Last updated Sep 16, 2025