Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 39 additions & 8 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
name: "Integration Tests"

permissions:
id-token: write # This is required for requesting the JWT for workload identity

on:
pull_request:
workflow_dispatch:
Expand All @@ -11,7 +14,7 @@ jobs:
# Matrix test for all supported platforms and architectures

integration-tests:
name: ${{ matrix.os }} (${{ matrix.arch }}) tailscale-${{ matrix.version }}
name: ${{ matrix.os }} (${{ matrix.arch }}) (${{ matrix.credential-type }}) tailscale-${{ matrix.version }}
strategy:
fail-fast: false
matrix:
Expand All @@ -22,63 +25,90 @@ jobs:
arch: amd64
version: latest
ping: 100.99.0.2,lax-pve.pineapplefish.ts.net,lax-pve
credential-type: oauth

# Try unstable too
- os: ubuntu-latest
runner-os: Linux
arch: amd64
version: unstable
credential-type: oauth

# Try a pinned version
- os: ubuntu-latest
runner-os: Linux
arch: amd64
credential-type: oauth
# leave version blank to fall back to default

# Linux tests (ARM64)
- os: ubuntu-24.04-arm
runner-os: Linux
arch: arm64
version: latest
credential-type: oauth

# Windows tests (AMD64)
- os: windows-latest
runner-os: Windows
arch: amd64
version: latest
ping: 100.99.0.2,lax-pve.pineapplefish.ts.net,lax-pve

- os: windows-latest
runner-os: Windows
arch: amd64
version: unstable
credential-type: oauth

# Windows tests (ARM64)
- os: windows-11-arm
runner-os: Windows
arch: arm64
version: latest
credential-type: oauth

# macOS 13 (AMD64)
- os: macos-13
runner-os: macOS
arch: amd64
version: latest
ping: 100.99.0.2,lax-pve.pineapplefish.ts.net,lax-pve
credential-type: oauth

# macOS 14 (ARM)
- os: macos-14
runner-os: macOS
arch: arm64
version: latest
ping: 100.99.0.2,lax-pve.pineapplefish.ts.net,lax-pve
credential-type: oauth

# macOS latest (ARM)
- os: macos-latest
runner-os: macOS
arch: arm64
version: latest
ping: 100.99.0.2,lax-pve.pineapplefish.ts.net,lax-pve
credential-type: oauth

# Try workload identity for each platform
- os: macos-latest
runner-os: macOS
arch: amd64
version: latest
ping: 100.99.0.2,lax-pve.pineapplefish.ts.net,lax-pve
credential-type: workload-identity

- os: windows-latest
runner-os: Windows
arch: amd64
ping: 100.99.0.2,lax-pve.pineapplefish.ts.net,lax-pve
credential-type: workload-identity
# leave version blank to fall back to default

# Try adding in an unstable
- os: ubuntu-latest
runner-os: Linux
arch: amd64
version: unstable
credential-type: workload-identity


runs-on: ${{ matrix.os }}

Expand All @@ -103,8 +133,9 @@ jobs:
id: tailscale-oauth
uses: ./
with:
oauth-client-id: ${{ secrets.TS_AUTH_KEYS_OAUTH_CLIENT_ID }}
oauth-secret: ${{ secrets.TS_AUTH_KEYS_OAUTH_CLIENT_SECRET }}
oauth-client-id: ${{ matrix.credential-type == 'oauth' && secrets.TS_AUTH_KEYS_OAUTH_CLIENT_ID || secrets.TS_WORKLOAD_IDENTITY_CLIENT_ID }}
oauth-secret: ${{ matrix.credential-type == 'oauth' && secrets.TS_AUTH_KEYS_OAUTH_CLIENT_SECRET || '' }}
audience: ${{ matrix.credential-type == 'workload-identity' && secrets.TS_AUDIENCE || ''}}
tags: "tag:ci"
version: "${{ matrix.version }}"
use-cache: false
Expand Down
74 changes: 58 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,58 @@ by adding a step to your workflow.

Subsequent steps in the Action can then access nodes in your Tailnet.

oauth-client-id and oauth-secret are an [OAuth client](https://tailscale.com/s/oauth-clients/)
oauth-client-id and oauth-secret are an [OAuth client][kb-oauth-clients]
for the tailnet to be accessed. We recommend storing these as
[GitHub Encrypted Secrets.](https://docs.github.com/en/actions/security-guides/encrypted-secrets)
OAuth clients used for this purpose must have the
[`auth_keys` scope.](https://tailscale.com/kb/1215/oauth-clients#scopes)
[`auth_keys` scope.][kb-trust-credentials-scopes]

tags is a comma-separated list of one or more [ACL Tags](https://tailscale.com/kb/1068/acl-tags/)
tags is a comma-separated list of one or more [Tags][kb-tags]
for the node. At least one tag is required: an OAuth client is not associated
with any of the Users on the tailnet, it has to Tag its nodes.

Nodes created by this Action are [marked as Ephemeral](https://tailscale.com/s/ephemeral-nodes) to
Nodes created by this Action are [marked as Ephemeral][kb-ephemeral-nodes] to
and log out immediately after finishing their CI run, at which point they are automatically removed
by the coordination server. The nodes are also [marked Preapproved](https://tailscale.com/kb/1085/auth-keys/)
on tailnets which use [Device Approval](https://tailscale.com/kb/1099/device-approval/)
by the coordination server. The nodes are also [marked Preapproved][kb-auth-keys]
on tailnets which use [Device Approval][kb-device-approval]


### Workload identity federation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we mark this as the preferred method? Potentially even use it for the default example starting on l.6?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call! Had been thinking that we might want to leave this as-is for beta, but I feel like there's no harm in swapping this now given the improved UX / security posture.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine either way, I see your point that for the Beta phase there could be bugs or rough edges that make authkeys the preferable default for a little longer.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will leave it as-is for now, can adjust later

[Workload identity federation][kb-workload-identity-federation] can also be used for authenticating nodes with your tailnet:

```yaml
- name: Tailscale
uses: tailscale/github-action@v4
with:
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
audience: ${{ secrets.TS_AUDIENCE }}
tags: tag:ci
```

Workload identity federation requires the `id-token: write` [permission setting](https://docs.github.com/en/actions/how-tos/secure-your-work/security-harden-deployments/oidc-in-cloud-providers#adding-permissions-settings) for the workflow:

```yaml
permissions:
id-token: write # This is required for the tailscale action to request a JWT from GitHub
```

OIDC federated identity credentials used for this purpose must have the [`auth_keys` scope.][kb-trust-credentials-scopes]

tags is a comma-separated list of one or more [Tags][kb-tags]
for the node. At least one tag is required: a federated identity is not associated
with any of the Users on the tailnet, it has to Tag its nodes.

> [!IMPORTANT]
> Tailscale version `1.90.1` or later is required for workload identity federation.

## Prerequisites

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

1. A Tailscale account with <Role>Owner, Admin, or Network admin</Role> permissions.
1. A Tailscale account with Owner, Admin, or Network admin permissions.
1. A GitHub repository that you have admin access to (required to set up the GitHub Action).
1. At least one configured [tag][kb-tags].
1. An [OAuth client][kb-oauth-clients] ID and secret OR an [auth key][kb-auth-keys].
1. At least one configured [tag][kb-tags] if using OAuth or workload identity federation.
1. An [OAuth client][kb-oauth-clients] ID and secret, [federated identity][kb-workload-identity-federation] client ID and audience, OR an [auth key][kb-auth-keys].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will the KB have a section tailored to setup a federated client compatible with GitHub? If not how will people know what issuer URL, subject and audience they should use?

1. A runner image version >= 2.237.1 (required to support running Node.js 24).

## Eventual consistency
Expand All @@ -55,22 +84,21 @@ You can do this by adding a list of hosts to ping to the action configuration:
ping: 100.x.y.z,my-machine.my-tailnet.ts.net
```

or with the [tailscale ping](https://tailscale.com/kb/1080/cli#ping) command if you do not know the peers at the time of installing Tailscale in the workflow:
or with the [tailscale ping][kb-cli-ping] command if you do not know the peers at the time of installing Tailscale in the workflow:

```bash
tailscale ping my-target.my-tailnet.ts.net
```

The `ping` option will wait up to to 3 minutes for a connection (direct or relayed).
The `ping` option will wait up to 3 minutes for a connection (direct or relayed).

## Tailnet Lock

If you are using this Action in a [Tailnet
Lock](https://tailscale.com/kb/1226/tailnet-lock) enabled network, you need to:
If you are using this Action in a [Tailnet Lock][kb-tailnet-lock] enabled network, you need to:

- Authenticate using an ephemeral reusable [pre-signed auth key](https://tailscale.com/kb/1226/tailnet-lock#add-a-node-using-a-pre-signed-auth-key)
- Authenticate using an ephemeral reusable [pre-signed auth key][kb-tailnet-lock-pre-signed]
rather than an OAuth client.
- Specify a [state directory](https://tailscale.com/kb/1278/tailscaled#flags-to-tailscaled) for the
- Specify a [state directory][kb-tailscaled-flags] for the
client to store the Tailnet Key Authority data in.

```yaml
Expand Down Expand Up @@ -139,4 +167,18 @@ the GitHub Action leaves tailscale binaries installed but stops the tailscale ba

### requested tags [tag:mytag] are invalid or not permitted

You may encounter this error when using an OAuth client. OAuth clients must have the [`auth_keys` scope](https://tailscale.com/kb/1215/oauth-clients#scopes) with one or more [tags](https://tailscale.com/kb/1068/acl-tags/), and the tags specified with `tags` must match all tags on the OAuth client.
You may encounter this error when using a trust credential (OAuth client or OIDC federated identity).
Trust credentials must have the writable [`auth_keys` scope][kb-trust-credentials-scopes] with one or more [tags][kb-tags],
and the tags specified with `tags` must match all tags on the trust credential or be tags owned by the tags on the trust credential.

[kb-auth-keys]: https://tailscale.com/kb/1085/auth-keys
[kb-cli-ping]: https://tailscale.com/kb/1080/cli#ping
[kb-device-approval]: https://tailscale.com/kb/1099/device-approval
[kb-ephemeral-nodes]: https://tailscale.com/kb/1111/ephemeral-nodes
[kb-oauth-clients]: https://tailscale.com/kb/1215/oauth-clients
[kb-tags]: https://tailscale.com/kb/1068/tags
[kb-tailnet-lock]: https://tailscale.com/kb/1226/tailnet-lock
[kb-tailnet-lock-pre-signed]: https://tailscale.com/kb/1226/tailnet-lock#add-a-node-using-a-pre-signed-auth-key
[kb-tailscaled-flags]: https://tailscale.com/kb/1278/tailscaled#flags-to-tailscaled
[kb-trust-credentials-scopes]: https://tailscale.com/kb/1623/trust-credentials#scopes
[kb-workload-identity-federation]: https://tailscale.com/kb/1581/workload-identity-federation
8 changes: 5 additions & 3 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ inputs:
required: false
deprecationMessage: 'An OAuth API client https://tailscale.com/s/oauth-clients is recommended instead of an authkey'
oauth-client-id:
description: 'Your Tailscale OAuth Client ID.'
description: 'Your Tailscale OAuth or OIDC Federated Identity clientID.'
required: false
audience:
description: 'Your Tailscale OIDC Federated Identity Audience'
required: false
oauth-secret:
description: 'Your Tailscale OAuth Client Secret.'
Expand All @@ -24,7 +27,7 @@ inputs:
version:
description: 'Tailscale version to use. Specify `latest` to use the latest stable version, and `unstable` to use the latest development version.'
required: true
default: '1.88.3'
default: '1.90.4'
args:
description: 'Optional additional arguments to `tailscale up`.'
required: false
Expand Down Expand Up @@ -66,4 +69,3 @@ runs:
using: 'node24'
main: 'dist/index.js'
post: 'dist/logout/index.js'

46 changes: 36 additions & 10 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading