From cef34ff3b418ac72ab193d96dcde34ab648fd9be Mon Sep 17 00:00:00 2001 From: Maxerns Date: Sun, 2 Aug 2026 23:44:17 +0100 Subject: [PATCH 1/3] document action adoption --- README.md | 165 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 147 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 9928e56..24bf10c 100644 --- a/README.md +++ b/README.md @@ -4,39 +4,88 @@ Installs the [Sotto](https://github.com/getsotto/sotto) CLI - end-to-end encrypt for developer teams - and puts it on `PATH`. This action **only installs the binary**. It does not decrypt, export, or otherwise touch secret -values - that stays entirely under your workflow's control via `sotto run --` / +values. Secret use stays entirely under your workflow's control via `sotto run --` or `sotto export`, using a machine token from `sotto token create` (see [the CI docs](https://github.com/getsotto/sotto#readme)). -## Usage +## Quick start + +Install an exact Sotto CLI release in a job: + +```yaml +name: CI + +on: + push: + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Install Sotto + uses: getsotto/sotto-action@v1.1.0 + with: + sotto-version: v0.4.0 + + - name: Run tests with Sotto + run: sotto run -- npm test + env: + SOTTO_TOKEN: ${{ secrets.SOTTO_TOKEN }} +``` + +`sotto-version` is **required**. There is no implicit `latest`, so a new Sotto release can never +silently change your CI's behaviour. Pin the action ref and the CLI release independently. + +## Pinning the action + +The action supports three ref styles: + +- `@v1` follows the latest validated v1 action release. +- `@v1.1.0` selects the exact numbered action release. +- `@<40-character commit SHA>` provides the strongest workflow pinning and cannot move when a tag + changes. + +For the strongest supply-chain guarantee, use a full commit SHA for the action and an exact +`sotto-version` for the CLI: ```yaml -- uses: getsotto/sotto-action@v1 +- uses: getsotto/sotto-action@ with: sotto-version: v0.4.0 +``` -- run: sotto run -- npm test - env: - SOTTO_TOKEN: ${{ secrets.SOTTO_TOKEN }} +Resolve the commit behind an exact action release before copying it into a workflow: + +```sh +git ls-remote https://github.com/getsotto/sotto-action.git 'refs/tags/v1.1.0^{}' | cut -f1 ``` -`sotto-version` is **required** - there is no implicit "latest", so a new Sotto release can never -silently change your CI's behaviour. Pin it the same way you'd pin any other tool version. +Do not use a short SHA. Keep the release tag in a comment beside the full SHA so Dependabot or a +reviewer can identify the pinned action version. + +## Security model -The action supports x86_64 and ARM64 Linux, x86_64 and ARM64 macOS, and x86_64 Windows. -Internally it downloads the archive for the selected release, verifies its checksum and Sigstore -signature, and checks that the installed binary reports the requested version. Signature -verification is mandatory: a missing or invalid bundle fails the job rather than falling back to -a checksum-only install. The verification identity is pinned to the selected tag of Sotto's -release workflow; see -[SECURITY.md](https://github.com/getsotto/sotto/blob/main/SECURITY.md) for the release model. +The action is deliberately small and fails closed: + +- It rejects missing, floating, partial, or prerelease CLI versions before downloading anything. +- It downloads the selected archive, its checksum manifest, and their Sigstore bundles. +- It verifies the bundles against Sotto's tagged release workflow, then verifies the archive checksum + and the installed binary's reported version. +- It installs cosign from a pinned action commit, rather than trusting a floating installer ref. +- It never reads, decrypts, exports, or logs secret values. Only later workflow steps use + `SOTTO_TOKEN`. + +The action supports x86_64 and ARM64 Linux, x86_64 and ARM64 macOS, and x86_64 Windows. See +[SECURITY.md](https://github.com/getsotto/sotto/blob/main/SECURITY.md) for Sotto's release and +verification model. ## Outputs Give the step an `id` to use the resolved installation details in later steps: ```yaml -- uses: getsotto/sotto-action@v1 +- uses: getsotto/sotto-action@v1.1.0 id: sotto with: sotto-version: v0.4.0 @@ -50,9 +99,88 @@ Give the step an `id` to use the resolved installation details in later steps: | `target` | Resolved release target | `aarch64-apple-darwin` | `x86_64-pc-windows-msvc` | | `binary-path` | Absolute installed binary path | `/Users/runner/work/_temp/sotto-bin/sotto` | `D:\a\_temp\sotto-bin\sotto.exe` | +## Examples + +### Linux, macOS, and Windows matrix + +```yaml +name: Sotto smoke test + +on: [push, pull_request] + +jobs: + smoke: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + runs-on: ${{ matrix.os }} + steps: + - uses: getsotto/sotto-action@v1.1.0 + with: + sotto-version: v0.4.0 + - run: sotto --version +``` + +### Windows PowerShell + +```yaml +jobs: + windows: + runs-on: windows-latest + steps: + - uses: getsotto/sotto-action@v1.1.0 + with: + sotto-version: v0.4.0 + - name: Run a command with Sotto + shell: pwsh + run: sotto run -- powershell -NoProfile -Command "Write-Output 'Sotto is ready'" +``` + +### Reusable workflow + +Define the installation once and call it from other workflows: + +```yaml +# .github/workflows/sotto.yml +name: Sotto + +on: + workflow_call: + inputs: + sotto-version: + required: true + type: string + secrets: + SOTTO_TOKEN: + required: true + +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: getsotto/sotto-action@v1.1.0 + with: + sotto-version: ${{ inputs.sotto-version }} + - run: sotto run -- npm test + env: + SOTTO_TOKEN: ${{ secrets.SOTTO_TOKEN }} +``` + +Call it from a workflow in the same repository: + +```yaml +jobs: + ci: + uses: ./.github/workflows/sotto.yml + with: + sotto-version: v0.4.0 + secrets: inherit +``` + ## Versioning -This action is tagged independently of the `sotto` CLI's own version (`v0.1.0`, `v0.2.0`, ...) - +This action is tagged independently of the `sotto` CLI's own version (`v0.1.0`, `v0.2.0`, ...). `sotto-action@v1` and `sotto-version: v0.4.0` are two unrelated version numbers. See [getsotto/sotto#67](https://github.com/getsotto/sotto/issues/67) for why. @@ -61,4 +189,5 @@ action release such as `getsotto/sotto-action@v1.1.0` for an immutable workflow `v1` convenience tag moves only after the exact release has passed the full test matrix and been published by the release workflow. `v1.1.0` is the first numbered v1 action release; the initial bootstrap release used `v1` directly, so there is no `v1.0.0` tag. Manually pushing tags bypasses -the workflow and is not a supported release path. +the workflow and is not a supported release path. Maintainers should follow +[RELEASING.md](RELEASING.md). From f33ffa6c7e39b0c81cd50990786b50994b6309c0 Mon Sep 17 00:00:00 2001 From: Maxerns Date: Mon, 3 Aug 2026 09:48:11 +0100 Subject: [PATCH 2/3] clarify action adoption --- README.md | 128 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 78 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index 24bf10c..24d6ecf 100644 --- a/README.md +++ b/README.md @@ -3,14 +3,19 @@ Installs the [Sotto](https://github.com/getsotto/sotto) CLI - end-to-end encrypted secret sync for developer teams - and puts it on `PATH`. +> [!WARNING] +> Sotto is pre-1.0 and has not had a third-party cryptographic audit. It works end to end, but +> should not yet be trusted with critical production secrets. See +> [SECURITY.md](https://github.com/getsotto/sotto/blob/main/SECURITY.md). + This action **only installs the binary**. It does not decrypt, export, or otherwise touch secret values. Secret use stays entirely under your workflow's control via `sotto run --` or `sotto export`, using a machine token from `sotto token create` (see -[the CI docs](https://github.com/getsotto/sotto#readme)). +[the Sotto README](https://github.com/getsotto/sotto#github-actions)). ## Quick start -Install an exact Sotto CLI release in a job: +Install the merged v1.1 implementation by its full commit SHA: ```yaml name: CI @@ -23,46 +28,80 @@ jobs: test: runs-on: ubuntu-latest steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 - name: Install Sotto - uses: getsotto/sotto-action@v1.1.0 + uses: getsotto/sotto-action@543d1af56ac81d1f1511d88c3d269106e8513a28 # merged v1.1 implementation with: sotto-version: v0.4.0 - name: Run tests with Sotto run: sotto run -- npm test env: + SOTTO_SERVER: ${{ vars.SOTTO_SERVER }} SOTTO_TOKEN: ${{ secrets.SOTTO_TOKEN }} ``` -`sotto-version` is **required**. There is no implicit `latest`, so a new Sotto release can never -silently change your CI's behaviour. Pin the action ref and the CLI release independently. +Set the repository variable `SOTTO_SERVER` for a self-hosted Sotto server. Leave it unset to use +the hosted instance. `sotto-version` is **required** and must be an exact release, so a new Sotto +release can never silently change your CI's behaviour. + +## Inputs and outputs + +### Inputs + +| Input | Required | Description | +| --- | --- | --- | +| `sotto-version` | Yes | Exact CLI release in `vX.Y.Z` form. Floating, partial, and prerelease values are rejected. | + +### Outputs + +Give the step an `id` to use the resolved installation details in later steps: + +```yaml +- uses: getsotto/sotto-action@543d1af56ac81d1f1511d88c3d269106e8513a28 # merged v1.1 implementation + id: sotto + with: + sotto-version: v0.4.0 + +- run: echo "installed ${{ steps.sotto.outputs.version }} for ${{ steps.sotto.outputs.target }}" +``` + +| Output | Description | macOS example | Windows example | +| --- | --- | --- | --- | +| `version` | Selected release tag | `v0.4.0` | `v0.4.0` | +| `target` | Resolved release target | `aarch64-apple-darwin` | `x86_64-pc-windows-msvc` | +| `binary-path` | Absolute installed binary path | `/Users/runner/work/_temp/sotto-bin/sotto` | `D:\a\_temp\sotto-bin\sotto.exe` | ## Pinning the action -The action supports three ref styles: +The action ref and the CLI release are independent. The available ref styles are: -- `@v1` follows the latest validated v1 action release. -- `@v1.1.0` selects the exact numbered action release. +- `@v1` is a mutable major tag. Check its target before use because a major tag can lag the + implementation documented here. +- `@vX.Y.Z` selects an exact numbered action release once that tag has been published. - `@<40-character commit SHA>` provides the strongest workflow pinning and cannot move when a tag changes. -For the strongest supply-chain guarantee, use a full commit SHA for the action and an exact -`sotto-version` for the CLI: +The examples use the full SHA `543d1af56ac81d1f1511d88c3d269106e8513a28`, which is the merged v1.1 +implementation. For the strongest supply-chain guarantee, use a reviewed full SHA for the action +and an exact `sotto-version` for the CLI: ```yaml -- uses: getsotto/sotto-action@ +- uses: getsotto/sotto-action@543d1af56ac81d1f1511d88c3d269106e8513a28 # merged v1.1 implementation with: sotto-version: v0.4.0 ``` -Resolve the commit behind an exact action release before copying it into a workflow: +To inspect the current action commit before pinning, resolve it explicitly and fail if GitHub +returns no ref: ```sh -git ls-remote https://github.com/getsotto/sotto-action.git 'refs/tags/v1.1.0^{}' | cut -f1 +action_sha="$(git ls-remote https://github.com/getsotto/sotto-action.git refs/heads/main | awk 'NF { print $1; exit }')" +test -n "$action_sha" || { echo "error: could not resolve the action commit" >&2; exit 1; } +printf '%s\n' "$action_sha" ``` -Do not use a short SHA. Keep the release tag in a comment beside the full SHA so Dependabot or a -reviewer can identify the pinned action version. +Review the resolved commit before copying it into a workflow. Do not use a short SHA. ## Security model @@ -70,35 +109,18 @@ The action is deliberately small and fails closed: - It rejects missing, floating, partial, or prerelease CLI versions before downloading anything. - It downloads the selected archive, its checksum manifest, and their Sigstore bundles. +- Signature verification is mandatory. A missing or invalid bundle fails the job rather than falling + back to a checksum-only install. - It verifies the bundles against Sotto's tagged release workflow, then verifies the archive checksum and the installed binary's reported version. - It installs cosign from a pinned action commit, rather than trusting a floating installer ref. - It never reads, decrypts, exports, or logs secret values. Only later workflow steps use - `SOTTO_TOKEN`. + `SOTTO_SERVER` and `SOTTO_TOKEN`. The action supports x86_64 and ARM64 Linux, x86_64 and ARM64 macOS, and x86_64 Windows. See [SECURITY.md](https://github.com/getsotto/sotto/blob/main/SECURITY.md) for Sotto's release and verification model. -## Outputs - -Give the step an `id` to use the resolved installation details in later steps: - -```yaml -- uses: getsotto/sotto-action@v1.1.0 - id: sotto - with: - sotto-version: v0.4.0 - -- run: echo "installed ${{ steps.sotto.outputs.version }} for ${{ steps.sotto.outputs.target }}" -``` - -| Output | Description | macOS example | Windows example | -| --- | --- | --- | --- | -| `version` | Selected release tag | `v0.4.0` | `v0.4.0` | -| `target` | Resolved release target | `aarch64-apple-darwin` | `x86_64-pc-windows-msvc` | -| `binary-path` | Absolute installed binary path | `/Users/runner/work/_temp/sotto-bin/sotto` | `D:\a\_temp\sotto-bin\sotto.exe` | - ## Examples ### Linux, macOS, and Windows matrix @@ -116,7 +138,8 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - - uses: getsotto/sotto-action@v1.1.0 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + - uses: getsotto/sotto-action@543d1af56ac81d1f1511d88c3d269106e8513a28 # merged v1.1 implementation with: sotto-version: v0.4.0 - run: sotto --version @@ -129,12 +152,16 @@ jobs: windows: runs-on: windows-latest steps: - - uses: getsotto/sotto-action@v1.1.0 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + - uses: getsotto/sotto-action@543d1af56ac81d1f1511d88c3d269106e8513a28 # merged v1.1 implementation with: sotto-version: v0.4.0 - name: Run a command with Sotto shell: pwsh run: sotto run -- powershell -NoProfile -Command "Write-Output 'Sotto is ready'" + env: + SOTTO_SERVER: ${{ vars.SOTTO_SERVER }} + SOTTO_TOKEN: ${{ secrets.SOTTO_TOKEN }} ``` ### Reusable workflow @@ -159,15 +186,17 @@ jobs: check: runs-on: ubuntu-latest steps: - - uses: getsotto/sotto-action@v1.1.0 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + - uses: getsotto/sotto-action@543d1af56ac81d1f1511d88c3d269106e8513a28 # merged v1.1 implementation with: sotto-version: ${{ inputs.sotto-version }} - run: sotto run -- npm test env: + SOTTO_SERVER: ${{ vars.SOTTO_SERVER }} SOTTO_TOKEN: ${{ secrets.SOTTO_TOKEN }} ``` -Call it from a workflow in the same repository: +Call it from a workflow in the same repository and pass only the secret the callee declares: ```yaml jobs: @@ -175,19 +204,18 @@ jobs: uses: ./.github/workflows/sotto.yml with: sotto-version: v0.4.0 - secrets: inherit + secrets: + SOTTO_TOKEN: ${{ secrets.SOTTO_TOKEN }} ``` ## Versioning This action is tagged independently of the `sotto` CLI's own version (`v0.1.0`, `v0.2.0`, ...). -`sotto-action@v1` and `sotto-version: v0.4.0` are two unrelated version numbers. See -[getsotto/sotto#67](https://github.com/getsotto/sotto/issues/67) for why. - -Use `getsotto/sotto-action@v1` to follow the latest validated v1 action release, or pin an exact -action release such as `getsotto/sotto-action@v1.1.0` for an immutable workflow dependency. The -`v1` convenience tag moves only after the exact release has passed the full test matrix and been -published by the release workflow. `v1.1.0` is the first numbered v1 action release; the initial -bootstrap release used `v1` directly, so there is no `v1.0.0` tag. Manually pushing tags bypasses -the workflow and is not a supported release path. Maintainers should follow -[RELEASING.md](RELEASING.md). +The action ref and `sotto-version: v0.4.0` are two unrelated version numbers. The moving major +tag is updated only after the exact action release has passed the full test matrix and been +published by the release workflow. Manually pushing tags bypasses the workflow and is not a +supported release path. Maintainers should follow [RELEASING.md](RELEASING.md). + +## Licence + +Licensed under the [Apache License, Version 2.0](LICENSE). From 85f1750901de832bedf7675ebb370bf039f2a31e Mon Sep 17 00:00:00 2001 From: Maxerns Date: Mon, 3 Aug 2026 09:52:49 +0100 Subject: [PATCH 3/3] scope action claims --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 24d6ecf..6a5b9b4 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,9 @@ release can never silently change your CI's behaviour. ### Outputs +The inputs and outputs below describe the merged v1.1 implementation used in these examples. A +mutable ref such as `@v1` may point to an older action until the release workflow moves it. + Give the step an `id` to use the resolved installation details in later steps: ```yaml @@ -105,7 +108,7 @@ Review the resolved commit before copying it into a workflow. Do not use a short ## Security model -The action is deliberately small and fails closed: +The merged v1.1 implementation is deliberately small and fails closed: - It rejects missing, floating, partial, or prerelease CLI versions before downloading anything. - It downloads the selected archive, its checksum manifest, and their Sigstore bundles.