Skip to content

Commit c6536f3

Browse files
authored
Merge pull request #151 from auths-dev/dev-cliCiSetup
refactor: replace old 3-secret ci-setup with single AUTHS_CI_TOKEN across workflows, docs, justfiles, and templates
2 parents 042f197 + 0c307cf commit c6536f3

7 files changed

Lines changed: 52 additions & 81 deletions

File tree

crates/auths-cli/src/commands/init/helpers.rs

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,10 @@ fn set_git_config(key: &str, value: &str, scope: &str) -> Result<()> {
128128

129129
// --- GitHub Action Scaffolding ---
130130

131-
const GITHUB_ACTION_WORKFLOW_TEMPLATE: &str = r#"# Auths release workflow — signs artifacts and commits attestations to the repo.
131+
const GITHUB_ACTION_WORKFLOW_TEMPLATE: &str = r#"# Auths release workflow — signs artifacts and verifies them.
132132
# Generated by: auths init --github-action
133133
#
134-
# Required secrets (generate with `just ci-setup`):
135-
# AUTHS_CI_PASSPHRASE — passphrase for the CI keychain
136-
# AUTHS_CI_KEYCHAIN — base64-encoded keychain file
137-
# AUTHS_CI_IDENTITY_BUNDLE — base64-encoded identity bundle
134+
# Required: run `auths ci setup` to set the AUTHS_CI_TOKEN secret.
138135
139136
name: Auths Release
140137
@@ -157,22 +154,12 @@ jobs:
157154
# Replace this with your build step
158155
echo "Build your artifacts here"
159156
160-
- name: Sign artifacts and commit attestations
161-
uses: auths-dev/attest-action@v1
162-
env:
163-
# These secrets must be set in your repository settings
164-
AUTHS_PASSPHRASE: ${{ secrets.AUTHS_CI_PASSPHRASE }}
165-
AUTHS_CI_KEYCHAIN_B64: ${{ secrets.AUTHS_CI_KEYCHAIN }}
166-
AUTHS_CI_IDENTITY_BUNDLE_B64: ${{ secrets.AUTHS_CI_IDENTITY_BUNDLE }}
157+
- name: Sign and verify artifacts
158+
uses: auths-dev/sign@v1
167159
with:
168-
# Glob pattern matching your release artifacts
169-
artifacts: 'dist/*.tar.gz'
170-
171-
# Directory in your repo where attestation files are committed
172-
attestation-path: '.auths/releases'
173-
174-
# "direct" pushes to the current branch; "pr" opens a pull request
175-
commit-strategy: 'direct'
160+
token: ${{ secrets.AUTHS_CI_TOKEN }}
161+
files: 'dist/*.tar.gz'
162+
verify: true
176163
"#;
177164

178165
/// Scaffolds a GitHub Actions workflow for attestation signing.

crates/auths-cli/tests/cases/init.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ fn test_init_github_action_scaffold() {
3636

3737
let content = std::fs::read_to_string(&workflow).unwrap();
3838
assert!(
39-
content.contains("auths-dev/attest-action@v1"),
40-
"workflow should reference attest-action"
39+
content.contains("auths-dev/sign@v1"),
40+
"workflow should reference sign action"
4141
);
4242
assert!(
43-
content.contains("AUTHS_CI_PASSPHRASE"),
44-
"workflow should reference secrets"
43+
content.contains("AUTHS_CI_TOKEN"),
44+
"workflow should reference AUTHS_CI_TOKEN secret"
4545
);
4646

4747
// .auths/.gitkeep should exist

crates/xtask/src/ci_setup.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ use walkdir::WalkDir;
1515
use crate::shell::{run_capture, run_capture_env, run_with_stdin};
1616

1717
pub fn run() -> Result<()> {
18+
eprintln!(
19+
"\x1b[1;33m⚠ `cargo xt ci-setup` is deprecated. Use `auths ci setup` instead.\x1b[0m"
20+
);
21+
eprintln!(" The new command bundles all secrets into a single AUTHS_CI_TOKEN.");
22+
eprintln!(" Run `auths ci setup --help` for details.");
23+
eprintln!();
24+
1825
println!();
1926
println!("\x1b[0;36m╔════════════════════════════════════════════════════════════╗\x1b[0m");
2027
println!("\x1b[0;36m║\x1b[0m\x1b[1m CI Release Signing Setup (One-Time) \x1b[0m\x1b[0;36m║\x1b[0m");

docs/contributing/release-process.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,15 @@ This makes similar checks as the github release. It also includes properly order
4040

4141
### One-time CI signing setup
4242

43-
Before the first release, GitHub Actions needs a device key and identity bundle for artifact signing:
43+
Before the first release, GitHub Actions needs a device key and identity token for artifact signing:
4444

4545
```bash
46-
just ci-setup
46+
auths ci setup
4747
```
4848

49-
This creates a limited-capability CI device key, exports it as an encrypted keychain, and sets three GitHub secrets: `AUTHS_CI_PASSPHRASE`, `AUTHS_CI_KEYCHAIN`, and `AUTHS_CI_IDENTITY_BUNDLE`. Artifact signing is skipped gracefully if these secrets are missing.
49+
This creates a limited-capability CI device key and sets a single `AUTHS_CI_TOKEN` secret on GitHub containing everything CI needs. Artifact signing is skipped gracefully if the secret is missing.
5050

51-
Re-run `ci-setup` only if the CI device key is revoked or the identity repo changes significantly.
51+
To refresh the token without regenerating the device key, run `auths ci rotate`.
5252

5353
### Manual steps (if needed)
5454

docs/guides/platforms/ci-cd.md

Lines changed: 26 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -12,38 +12,38 @@ CI signing in Auths works through device delegation:
1212
4. In CI, the runner restores the identity bundle and signs artifacts using the CI device key.
1313
5. You can **revoke** the CI device at any time without affecting your root identity.
1414

15-
## One-time setup with `cargo xt ci-setup`
15+
## One-time setup with `auths ci setup`
1616

17-
The `ci-setup` xtask automates the entire provisioning flow. Run it from the project root:
17+
Run this from any repo with a git remote:
1818

1919
```bash
20-
cargo xt ci-setup
20+
auths ci setup
2121
```
2222

2323
This command will:
2424

25-
1. **Verify your identity exists** by running `auths status`.
26-
2. **Read your identity DID** from `auths id show` and your key alias from `auths key list`.
27-
3. **Generate a CI device key** (Ed25519, 32-byte seed) and import it into your platform keychain under the alias `ci-release-device`.
28-
4. **Prompt for a passphrase** that will protect the CI device key. This passphrase will be stored as a GitHub Secret.
29-
5. **Create an encrypted file keychain** by copying the key to a file-backed keychain using `auths key copy-backend --alias ci-release-device --dst-backend file`.
30-
6. **Derive the device DID** using `auths key export --alias ci-release-device --format pub` and `auths debug util pubkey-to-did`.
31-
7. **Link the CI device** to your identity with `auths device link --capabilities sign_release --note "GitHub Actions release signer"`.
32-
8. **Package your `~/.auths` repository** as a base64-encoded tarball (excluding `.sock` files).
33-
9. **Set three GitHub Secrets** via the `gh` CLI:
34-
- `AUTHS_CI_PASSPHRASE` -- The passphrase for the CI device key.
35-
- `AUTHS_CI_KEYCHAIN` -- The encrypted file keychain (base64).
36-
- `AUTHS_CI_IDENTITY_BUNDLE` -- The `~/.auths` repository snapshot (base64 tarball).
37-
38-
If the `gh` CLI is not authenticated, the command prints the secret values for you to add manually via **Repository > Settings > Secrets > Actions > New secret**.
25+
1. **Verify your identity exists** and read your identity DID and key alias.
26+
2. **Generate a CI device key** (Ed25519) and link it to your identity with `sign_release` capability.
27+
3. **Package everything** into a single `AUTHS_CI_TOKEN` JSON secret containing the passphrase, encrypted keychain, identity repo snapshot, and verification bundle.
28+
4. **Set the secret** on your forge automatically via the `gh` CLI (GitHub) or print the token for manual setup (other forges).
29+
30+
If the `gh` CLI is not authenticated, the command prints the token value for you to add manually via **Repository > Settings > Secrets > Actions > New secret**.
31+
32+
### Rotating the token
33+
34+
To refresh the token (new TTL, updated identity repo) without regenerating the device key:
35+
36+
```bash
37+
auths ci rotate
38+
```
3939

4040
### Re-running setup
4141

42-
If you already have a `ci-release-device` key, `cargo xt ci-setup` detects it and reuses the existing key while regenerating the file keychain and secrets.
42+
If you already have a `ci-release-device` key, `auths ci setup` detects it and reuses the existing key while regenerating the token.
4343

4444
## Signing artifacts in GitHub Actions
4545

46-
Once the secrets are set, add a signing step to your release workflow:
46+
Once `AUTHS_CI_TOKEN` is set, add a signing step to your release workflow:
4747

4848
```yaml
4949
name: Release
@@ -60,34 +60,15 @@ jobs:
6060
steps:
6161
- uses: actions/checkout@v4
6262

63-
- name: Install Auths
64-
run: cargo install auths-cli
65-
66-
- name: Restore Auths identity
67-
env:
68-
AUTHS_CI_IDENTITY_BUNDLE: ${{ secrets.AUTHS_CI_IDENTITY_BUNDLE }}
69-
AUTHS_CI_KEYCHAIN: ${{ secrets.AUTHS_CI_KEYCHAIN }}
70-
AUTHS_CI_PASSPHRASE: ${{ secrets.AUTHS_CI_PASSPHRASE }}
71-
run: |
72-
# Restore the ~/.auths identity repository
73-
mkdir -p ~/.auths
74-
echo "$AUTHS_CI_IDENTITY_BUNDLE" | base64 -d | tar xz -C ~/.auths
75-
76-
# Restore the file keychain
77-
echo "$AUTHS_CI_KEYCHAIN" | base64 -d > /tmp/ci-keychain.enc
78-
79-
# Set environment for file-backend keychain
80-
echo "AUTHS_KEYCHAIN_BACKEND=file" >> $GITHUB_ENV
81-
echo "AUTHS_KEYCHAIN_FILE=/tmp/ci-keychain.enc" >> $GITHUB_ENV
82-
echo "AUTHS_PASSPHRASE=$AUTHS_CI_PASSPHRASE" >> $GITHUB_ENV
83-
8463
- name: Build release artifact
8564
run: cargo build --release && tar czf myproject.tar.gz -C target/release myproject
8665

87-
- name: Sign release artifact
88-
run: |
89-
auths sign myproject.tar.gz \
90-
--device-key ci-release-device
66+
- name: Sign and verify artifact
67+
uses: auths-dev/sign@v1
68+
with:
69+
token: ${{ secrets.AUTHS_CI_TOKEN }}
70+
files: 'myproject.tar.gz'
71+
verify: true
9172

9273
- name: Upload release
9374
uses: softprops/action-gh-release@v2
@@ -227,4 +208,4 @@ auths device revoke \
227208
--key <your-key>
228209
```
229210

230-
The device DID and identity key alias are printed by `cargo xt ci-setup` when the device is created. After revocation, the CI device key can no longer produce valid attestations, even if the secrets remain in GitHub.
211+
The device DID and identity key alias are printed by `auths ci setup` when the device is created. After revocation, the CI device key can no longer produce valid attestations, even if the secrets remain in GitHub.

justfile

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,7 @@ release-github:
112112
release-crates:
113113
python scripts/releases/2_crates.py --publish
114114

115-
# One-time setup: create a CI release-signing device and export secrets for GitHub
116-
# Run this once locally, then add the printed values as GitHub secrets
117-
# Delegates to the xtask crate for cross-platform correctness.
115+
# One-time setup: create a CI release-signing device and set AUTHS_CI_TOKEN secret.
116+
# Run this once locally — detects forge from git remote and sets the secret automatically.
118117
ci-setup:
119-
cargo xt ci-setup
118+
auths ci setup

scripts/auths_workflows/artifact_signing.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -270,10 +270,7 @@ def main() -> None:
270270
print(f"{BOLD}{GREEN} Artifact signing workflow completed successfully!{RESET}")
271271
print(f"{BOLD}{GREEN}{'='*60}{RESET}")
272272
print(f"\n This confirms the release.yml signing step will work in CI.")
273-
print(f" Make sure these GitHub secrets are set (via 'just ci-setup'):")
274-
print(f" • AUTHS_CI_PASSPHRASE")
275-
print(f" • AUTHS_CI_KEYCHAIN")
276-
print(f" • AUTHS_CI_IDENTITY_BUNDLE\n")
273+
print(f" Make sure AUTHS_CI_TOKEN is set (via 'auths ci setup').\n")
277274

278275

279276
if __name__ == "__main__":

0 commit comments

Comments
 (0)