diff --git a/.github/workflows/tailscale.yml b/.github/workflows/tailscale.yml index 9872d13..21a5d0d 100644 --- a/.github/workflows/tailscale.yml +++ b/.github/workflows/tailscale.yml @@ -18,8 +18,10 @@ jobs: - name: Tailscale Action uses: ./ with: - authkey: ${{ secrets.TAILSCALE_AUTHKEY }} + oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }} + oauth-secret: ${{ secrets.TS_OAUTH_SECRET }} + tags: tag:ci - - name: check for hello.ipn.dev in netmap + - name: check for hello.ts.net in netmap run: tailscale status | grep -q hello diff --git a/README.md b/README.md index 2bc3030..61a0a40 100644 --- a/README.md +++ b/README.md @@ -5,22 +5,24 @@ by adding a step to your workflow. ```yaml - name: Tailscale - uses: tailscale/github-action@v1 + uses: tailscale/github-action@v2 with: - authkey: ${{ secrets.TAILSCALE_AUTHKEY }} + oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }} + oauth-secret: ${{ secrets.TS_OAUTH_SECRET }} + tags: tag:ci ``` Subsequent steps in the Action can then access nodes in your Tailnet. -TAILSCALE\_AUTHKEY is an [authkey](https://tailscale.com/kb/1085/auth-keys/) -for the Tailnet to be accessed, and needs to be populated in the Secrets for -your workflow. [Ephemeral authkeys](https://tailscale.com/kb/1111/ephemeral-nodes/) tend -to be a good fit for GitHub runners, as they clean up their state automatically shortly -after the runner finishes. +oauth-client-id and oauth-secret are an [OAuth client](https://tailscale.com/s/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) ----- +tags is a comma-separated list of one or more [ACL Tags](https://tailscale.com/kb/1068/acl-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. -### Maintainer's Notes -This repository is provided and maintained by Tailscale. The CI script in this -repository uses an ephemeral authkey generated for the Tailnet owned by -TailscaleGitHubActionBot.github and stored as a Secret as described above. +Nodes created by this Action are [marked as Ephemeral](https://tailscale.com/s/ephemeral-nodes) to +be automatically removed by the coordination server a short time after they +finish their run. 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/) diff --git a/action.yml b/action.yml index e9768ab..cc5c862 100644 --- a/action.yml +++ b/action.yml @@ -1,6 +1,6 @@ -# Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. +# Copyright (c) Tailscale Inc & AUTHORS +# SPDX-License-Identifier: BSD-3-Clause +# name: 'Connect Tailscale' description: 'Connect your GitHub Action workflow to Tailscale' branding: @@ -9,11 +9,21 @@ branding: inputs: authkey: description: 'Your Tailscale authentication key, from the admin panel.' - required: true + 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.' + required: false + oauth-secret: + description: 'Your Tailscale OAuth Client Secret.' + required: false + tags: + description: 'Comma separated list of Tags to be applied to nodes. The OAuth client must have permission to apply these tags.' + required: false version: description: 'Tailscale version to use.' required: true - default: '1.32.1' + default: '1.42.0' args: description: 'Optional additional arguments to `tailscale up`' required: false @@ -35,11 +45,11 @@ runs: run: | echo "::error title=⛔ error hint::Support Linux Only" exit 1 - - name: Check Auth Key Empty - if: ${{ inputs.authkey == '' }} + - name: Check Auth Info Empty + if: ${{ inputs.authkey == '' && (inputs['oauth-secret'] == '' || inputs.tags == '') }} shell: bash run: | - echo "::error title=⛔ error hint::Auth key empty, Maybe you need to populate it in the Secrets for your workflow, see more in https://docs.github.com/en/actions/security-guides/encrypted-secrets" + echo "::error title=⛔ error hint::OAuth identity empty, Maybe you need to populate it in the Secrets for your workflow, see more in https://docs.github.com/en/actions/security-guides/encrypted-secrets and https://tailscale.com/s/oauth-clients" exit 1 - name: Download Tailscale shell: bash @@ -63,7 +73,7 @@ runs: env: ADDITIONAL_DAEMON_ARGS: ${{ inputs.tailscaled-args }} run: | - sudo -E tailscaled ${ADDITIONAL_DAEMON_ARGS} 2>~/tailscaled.log & + sudo -E tailscaled --state=mem: ${ADDITIONAL_DAEMON_ARGS} 2>~/tailscaled.log & # And check that tailscaled came up. The CLI will block for a bit waiting # for it. And --json will make it exit with status 0 even if we're logged # out (as we will be). Without --json it returns an error if we're not up. @@ -74,8 +84,13 @@ runs: TAILSCALE_AUTHKEY: ${{ inputs.authkey }} ADDITIONAL_ARGS: ${{ inputs.args }} HOSTNAME: ${{ inputs.hostname }} + TS_EXPERIMENT_OAUTH_AUTHKEY: true run: | if [ -z "${HOSTNAME}" ]; then HOSTNAME="github-$(cat /etc/hostname)" fi - sudo -E tailscale up --authkey ${TAILSCALE_AUTHKEY} --hostname=${HOSTNAME} --accept-routes ${ADDITIONAL_ARGS} + if [ -n "${{ inputs['oauth-secret'] }}" ]; then + TAILSCALE_AUTHKEY="${{ inputs['oauth-secret'] }}?preauthorized=true&ephemeral=true" + TAGS_ARG="--advertise-tags=${{ inputs.tags }}" + fi + sudo -E tailscale up ${TAGS_ARG} --authkey=${TAILSCALE_AUTHKEY} --hostname=${HOSTNAME} --accept-routes ${ADDITIONAL_ARGS}