Skip to content

Commit 0f53ed4

Browse files
committed
feat: add collapsable list on skips
1 parent 6fcd4ea commit 0f53ed4

12 files changed

Lines changed: 101 additions & 1038 deletions

File tree

.github/workflows/release.yml

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,11 @@ jobs:
3030
- name: Check dist is up to date
3131
run: git diff --exit-code -- dist/ ':!dist/**/*.d.ts.map'
3232

33-
# Dogfood: sign dist/index.js using ourselves
34-
- name: Sign and verify dist/index.js
33+
# Dogfood: sign dist/index.js using ourselves (ephemeral, no secrets)
34+
- name: Sign dist/index.js
3535
uses: ./
3636
with:
37-
token: ${{ secrets.AUTHS_CI_TOKEN }}
3837
files: 'dist/index.js'
39-
verify: true
4038
note: 'GitHub Actions release — ${{ github.ref_name }}'
4139

4240
- name: Generate SHA256 checksums
@@ -59,16 +57,14 @@ jobs:
5957
body: |
6058
## Auths Sign GitHub Action
6159
62-
Sign build artifacts in CI using [Auths](https://github.com/auths-dev/auths) identity keys.
60+
Sign build artifacts in CI using ephemeral keys. No secrets needed.
6361
6462
### Usage
6563
6664
```yaml
6765
- uses: auths-dev/sign@v1
6866
with:
69-
token: $\{{ secrets.AUTHS_CI_TOKEN }}
7067
files: 'dist/index.js'
71-
verify: true
7268
```
7369
7470
See the [README](https://github.com/auths-dev/sign#readme) for full configuration options.

.github/workflows/sign-commits.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,4 @@ jobs:
2121

2222
- uses: ./
2323
with:
24-
token: ${{ secrets.AUTHS_CI_TOKEN }}
2524
commits: 'HEAD~1..HEAD'

README.md

Lines changed: 33 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -1,172 +1,67 @@
11
# auths-dev/sign
22

33
[![Verified with Auths](https://img.shields.io/badge/Verified%20with-Auths-4B9CD3?logo=github&logoColor=white)](https://github.com/auths-dev/verify)
4-
[![Verify Commits](https://github.com/auths-dev/sign/actions/workflows/verify-commits.yml/badge.svg)](https://github.com/auths-dev/sign/actions/workflows/verify-commits.yml?query=branch%3Amain+event%3Apush)
5-
[![Sign Commits](https://github.com/auths-dev/sign/actions/workflows/sign-commits.yml/badge.svg)](https://github.com/auths-dev/sign/actions/workflows/sign-commits.yml?query=branch%3Amain)
64

7-
Sign build artifacts in CI with [Auths](https://github.com/auths-dev/auths) identity keys. Produces `.auths.json` attestation files that anyone can verify.
5+
Sign build artifacts and commits in CI using ephemeral keys. **No secrets needed.**
86

9-
## Quick start
7+
## Quick Start
108

119
```yaml
1210
- uses: auths-dev/sign@v1
1311
with:
14-
token: ${{ secrets.AUTHS_CI_TOKEN }}
15-
files: 'dist/index.js'
16-
verify: true
12+
files: |
13+
dist/*.tar.gz
14+
dist/*.zip
1715
```
1816
19-
This signs `dist/index.js`, creates `dist/index.js.auths.json`, and verifies the signature in one step.
17+
No tokens. No secrets. The action generates a throwaway key per run, signs your artifacts, and discards the key. Trust is anchored to the commit, not to a CI credential.
2018
21-
## Setup
19+
## How It Works
2220
23-
### 1. Install the Auths CLI
21+
1. Installs the `auths` CLI
22+
2. Runs `auths artifact sign --ci --commit $GITHUB_SHA` for each matched file
23+
3. Produces `.auths.json` attestation files alongside your artifacts
24+
4. Verifiers trace: artifact ← ephemeral key ← commit SHA ← maintainer signature
2425

25-
```bash
26-
brew tap auths-dev/auths-cli
27-
brew install auths # macOS
28-
# or download from https://github.com/auths-dev/auths/releases
29-
```
30-
31-
### 2. Initialize your identity (if you haven't already)
32-
33-
```bash
34-
auths init
35-
```
36-
37-
### 3. Set up CI secrets
26+
## Usage
3827

39-
From the repo you want to sign artifacts in:
28+
### Sign release artifacts
4029

41-
```bash
42-
auths ci setup
30+
```yaml
31+
- name: Sign artifacts
32+
uses: auths-dev/sign@v1
33+
with:
34+
files: |
35+
dist/*.tar.gz
36+
dist/*.zip
37+
note: "Release ${{ github.ref_name }}"
4338
```
4439

45-
This creates a limited-capability CI device key and sets a single `AUTHS_CI_TOKEN` GitHub secret automatically.
46-
47-
### 4. Add the action to your release workflow
40+
### Sign commits
4841

4942
```yaml
50-
name: Release
51-
52-
on:
53-
push:
54-
tags: ['v*.*.*']
55-
56-
permissions:
57-
contents: write
58-
59-
jobs:
60-
release:
61-
runs-on: ubuntu-latest
62-
steps:
63-
- uses: actions/checkout@v4
64-
65-
- name: Build
66-
run: npm run build # or your build command
67-
68-
- name: Sign artifacts
69-
uses: auths-dev/sign@v1
70-
with:
71-
token: ${{ secrets.AUTHS_CI_TOKEN }}
72-
files: 'dist/*.js'
73-
verify: true
74-
note: 'Release ${{ github.ref_name }}'
75-
76-
- name: Create release
77-
uses: softprops/action-gh-release@v2
78-
with:
79-
files: |
80-
dist/*.auths.json
43+
- name: Sign commits
44+
uses: auths-dev/sign@v1
45+
with:
46+
commits: HEAD~1..HEAD
8147
```
8248

8349
## Inputs
8450

8551
| Input | Required | Default | Description |
8652
|-------|----------|---------|-------------|
87-
| `token` | No* | | `AUTHS_CI_TOKEN` JSON containing all credentials |
88-
| `files` | **Yes** | | Glob patterns for files to sign (one per line) |
89-
| `verify` | No | `false` | Verify each file immediately after signing |
90-
| `device-key` | No | `ci-release-device` | Device key alias to sign with |
53+
| `files` | No | | Glob patterns for files to sign, one per line |
54+
| `commits` | No | | Git revision range to sign |
55+
| `commit-sha` | No | `$GITHUB_SHA` | Commit SHA to anchor attestation to |
9156
| `note` | No | | Note to include in the attestation |
92-
| `auths-version` | No | latest | Pin a specific Auths CLI version |
57+
| `auths-version` | No | latest | Auths CLI version to use |
9358

94-
*`token` is the `AUTHS_CI_TOKEN` secret generated by `auths ci setup`.
59+
At least one of `files` or `commits` must be provided.
9560

9661
## Outputs
9762

9863
| Output | Description |
9964
|--------|-------------|
10065
| `signed-files` | JSON array of signed file paths |
101-
| `attestation-files` | JSON array of `.auths.json` attestation file paths |
102-
| `verified` | `true`/`false` when `verify: true`, empty otherwise |
103-
104-
### Using outputs in subsequent steps
105-
106-
```yaml
107-
- uses: auths-dev/sign@v1
108-
id: sign
109-
with:
110-
token: ${{ secrets.AUTHS_CI_TOKEN }}
111-
files: 'dist/**/*.tar.gz'
112-
113-
- name: Upload attestations
114-
uses: actions/upload-artifact@v4
115-
with:
116-
name: attestations
117-
path: ${{ fromJSON(steps.sign.outputs.attestation-files) }}
118-
```
119-
120-
## Glob patterns
121-
122-
The `files` input supports glob patterns, one per line:
123-
124-
```yaml
125-
files: |
126-
dist/*.tar.gz
127-
dist/*.zip
128-
build/output/**/*.whl
129-
```
130-
131-
Patterns follow [@actions/glob](https://github.com/actions/toolkit/tree/master/packages/glob) syntax. Symlinks are not followed. Paths outside the workspace are rejected.
132-
133-
## Verification
134-
135-
When `verify: true`, the action runs `auths artifact verify` on each signed file immediately after signing. This proves the full round-trip works and catches signing misconfigurations before they reach consumers.
136-
137-
Consumers can verify your artifacts independently:
138-
139-
```bash
140-
auths artifact verify dist/index.js --identity-bundle bundle.json
141-
```
142-
143-
Or using the [auths-dev/verify](https://github.com/auths-dev/verify) action:
144-
145-
```yaml
146-
- uses: auths-dev/verify@v1
147-
with:
148-
identity: ${{ secrets.AUTHS_CI_TOKEN }}
149-
artifact-paths: 'dist/index.js'
150-
```
151-
152-
## Security model
153-
154-
- The CI device key has **limited capabilities** (`sign_release` only) -- it cannot impersonate your root identity, link devices, or perform other privileged operations
155-
- Credentials are extracted to temp files that are **always cleaned up**, even on failure
156-
- The passphrase is **masked** from all GitHub Actions logs via `core.setSecret`
157-
- Glob results are **contained to the workspace** -- paths outside `$GITHUB_WORKSPACE` are rejected
158-
- You can **revoke CI access** at any time: `auths device revoke --device-did <DID> --key <ALIAS>`
159-
160-
## Revoking CI access
161-
162-
If the CI device key is compromised:
163-
164-
```bash
165-
auths device revoke --device-did <DEVICE_DID> --key <KEY_ALIAS>
166-
```
167-
168-
The device DID and key alias are printed by `auths ci setup` during initial setup. After revocation, existing attestations remain valid (they were legitimate when signed), but the device can no longer produce new ones.
169-
170-
## License
171-
172-
Apache-2.0
66+
| `attestation-files` | JSON array of `.auths.json` paths |
67+
| `signed-commits` | JSON array of signed commit SHAs |

action.yml

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,8 @@
11
name: 'Sign with Auths'
2-
description: 'Sign build artifacts and/or commits using Auths identity keys in CI'
2+
description: 'Sign build artifacts using ephemeral Auths keys in CI — no secrets needed'
33
author: 'auths'
44

55
inputs:
6-
token:
7-
description: 'AUTHS_CI_TOKEN JSON (preferred) — contains passphrase, keychain, identity repo, and verify bundle'
8-
required: false
9-
default: ''
10-
passphrase:
11-
description: 'Auths device key passphrase (fallback when token is not provided)'
12-
required: false
13-
default: ''
14-
keychain:
15-
description: 'Base64-encoded encrypted keychain file (fallback when token is not provided)'
16-
required: false
17-
default: ''
18-
identity-repo:
19-
description: 'Base64-encoded tar.gz of ~/.auths identity repo (fallback when token is not provided)'
20-
required: false
21-
default: ''
22-
verify-bundle:
23-
description: 'Identity bundle JSON for post-sign verification (fallback when token is not provided)'
24-
required: false
25-
default: ''
266
files:
277
description: 'Glob patterns for files to sign, one per line'
288
required: false
@@ -31,14 +11,10 @@ inputs:
3111
description: 'Git revision range to sign (e.g., HEAD~1..HEAD). Merge commits are skipped.'
3212
required: false
3313
default: ''
34-
verify:
35-
description: 'Verify each file after signing using the verify bundle from the token'
36-
required: false
37-
default: 'false'
38-
device-key:
39-
description: 'Alias of the device key to sign with'
14+
commit-sha:
15+
description: 'Commit SHA to anchor ephemeral attestation to (default: GITHUB_SHA)'
4016
required: false
41-
default: 'ci-release-device'
17+
default: ''
4218
note:
4319
description: 'Optional note to include in the attestation'
4420
required: false
@@ -55,8 +31,6 @@ outputs:
5531
description: 'JSON array of attestation file paths (.auths.json)'
5632
signed-commits:
5733
description: 'JSON array of signed commit SHAs'
58-
verified:
59-
description: 'Whether all signed artifacts/commits passed verification (empty string if verify was not requested)'
6034

6135
runs:
6236
using: 'node20'

dist/__tests__/main.test.d.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Integration tests for the sign action's run() flow.
2+
* Integration tests for the sign action's ephemeral signing flow.
33
* Since run() executes at import time, we use jest.isolateModulesAsync.
44
*/
55
declare let mockInputs: Record<string, string>;
@@ -14,7 +14,5 @@ declare let mockExecOutputResult: {
1414
stdout: string;
1515
stderr: string;
1616
};
17-
declare const mockResolveCredentials: jest.Mock<any, any, any>;
18-
declare const mockCleanupPaths: jest.Mock<any, any, any>;
1917
declare function resetMockState(): void;
2018
declare function runMain(): Promise<void>;

0 commit comments

Comments
 (0)