Skip to content

Commit 70deb81

Browse files
authored
Merge pull request #23 from UniverLab/develop
feat: improve token magement
2 parents 659a94d + b04df97 commit 70deb81

13 files changed

Lines changed: 843 additions & 193 deletions

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
name: CI
22

33
on:
4-
push:
5-
branches: [main, develop]
64
pull_request:
5+
workflow_dispatch:
76

87
jobs:
98
rust-ci:

Cargo.lock

Lines changed: 33 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ghscaff"
3-
version = "0.3.2"
3+
version = "0.4.0"
44
edition = "2021"
55
description = "Interactive CLI wizard for creating and configuring GitHub repositories"
66
license = "MIT"
@@ -28,6 +28,8 @@ urlencoding = "2"
2828
toml = "0.8"
2929
crypto_box = "0.9"
3030
blake2 = "0.10"
31+
xsalsa20poly1305 = "0.9"
32+
whoami = "1"
3133

3234
[dev-dependencies]
3335
tempfile = "3"

README.md

Lines changed: 61 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ Interactive CLI wizard for creating and configuring GitHub repositories. One bin
3131

3232
- **🪄 Interactive wizard** — Create GitHub repos with a conversational guided flow
3333
- **⚡ Zero dependencies** — Single binary, no runtime requirements
34+
- **🔒 Encrypted vault** — Tokens stored locally with XSalsa20-Poly1305, never in env vars or plain text
3435
- **🔄 Idempotent apply mode** — Configure existing repos without recreation
3536
- **👥 Team access control** — Assign repositories to organization teams with custom permissions (read, triage, write, admin)
36-
- **🏷️ Smart labels**Auto-create 6 core issue labels
37+
- **🏷️ Enforced labels**7 standard labels synced on every run (non-standard labels are removed)
3738
- **🛡️ Branch protection** — Enforce reviews, status checks, and workflow validation
3839
- **🚀 Language templates** — Rust (v1), Python/Node.js/Java coming soon
3940
- **📝 Boilerplate files** — README, Cargo.toml, CI/CD workflows, LICENSE
40-
- **🔐 Token validation** — Fail-fast authentication checks
4141
- **🔑 Template secrets** — Automatically configures required GitHub Actions secrets per template
4242
- **⬆️ Self-update** — Detects new releases on startup and offers one-command upgrade
4343

@@ -96,18 +96,16 @@ Check the [Releases](https://github.com/UniverLab/ghscaff/releases) page for pre
9696

9797
```bash
9898
rm -f ~/.local/bin/ghscaff # ghscaff binary
99-
rm -rf ~/.ghscaff/ # boilerplate cache
99+
rm -rf ~/.ghscaff/ # boilerplate cache + encrypted vault
100100
```
101101

102102
---
103103

104104
## Quick Start
105105

106106
```bash
107-
# Set your GitHub token
108-
export GITHUB_TOKEN=ghp_xxxxxxxxxxxx
109-
110107
# Interactive wizard — create a new repo
108+
# (token is requested on first run and stored in the encrypted vault)
111109
ghscaff
112110

113111
# Or directly with a subcommand
@@ -118,10 +116,52 @@ ghscaff apply owner/repo
118116

119117
# Preview changes without API calls
120118
ghscaff --dry-run
119+
120+
# Reconfigure credentials
121+
ghscaff config
121122
```
122123

123124
---
124125

126+
## Authentication
127+
128+
ghscaff resolves the GitHub token in this order:
129+
130+
1. **`GITHUB_TOKEN` env var** — for CI/CD and backward compatibility
131+
2. **Encrypted vault** (`~/.ghscaff/vault.enc`) — for secure local usage
132+
3. **Interactive prompt** — on first run, asks for the token and saves it to the vault
133+
134+
### Encrypted Vault
135+
136+
Tokens are encrypted with **XSalsa20-Poly1305** and a key derived from:
137+
138+
| Factor | Purpose |
139+
|--------|---------|
140+
| Username | Only your OS user can decrypt |
141+
| Hostname | Copying the vault to another machine won't work |
142+
| Binary path | Other programs can't derive the same key |
143+
| Passphrase (optional) | Extra protection if desired |
144+
145+
The vault file (`~/.ghscaff/vault.enc`) has `0600` permissions and the directory has `0700`. Writes are atomic (temp file + rename) to prevent corruption.
146+
147+
### Reconfiguring
148+
149+
```bash
150+
ghscaff config
151+
```
152+
153+
This wipes the vault (with confirmation) and starts fresh — new token, optional passphrase. Template secrets will be requested on the next run.
154+
155+
### Required token scopes
156+
157+
- `repo` — Repository access
158+
- `workflow` — GitHub Actions access
159+
- `read:org` — (Optional) Organization and team access
160+
161+
**Note on team access:** If your token lacks the `read:org` scope, the wizard will skip the team selection step with a warning, but the rest of the repository setup will continue normally.
162+
163+
---
164+
125165
## Wizard Flow
126166

127167
The wizard guides you through **7 interactive steps**:
@@ -139,8 +179,8 @@ Then **automatically**:
139179
- Commits all boilerplate files in a single atomic commit (`chore: init repository`)
140180
- Applies branch protection to main (and develop if created)
141181
- Adds selected teams with their assigned permissions
142-
- Syncs labels, topics, and CI/CD workflows
143-
- Configures required GitHub Actions secrets from `secrets.toml`
182+
- Enforces standard labels (creates missing, updates changed, removes non-standard)
183+
- Configures required GitHub Actions secrets (from vault, env, or interactive prompt)
144184

145185
---
146186

@@ -158,10 +198,10 @@ ghscaff apply
158198

159199
Applies:
160200
- ✅ Atomic single commit with all boilerplate files (no individual file commits)
161-
- ✅ Labels (creates missing, updates existing)
201+
- ✅ Labels enforced (creates missing, updates changed, **removes non-standard**)
162202
- ✅ Branch protection on `main` and `develop` (if created)
163203
- ✅ Topics (merges with existing)
164-
- ✅ GitHub Actions secrets (from template's `secrets.toml`)
204+
- ✅ GitHub Actions secrets (from vault, env, or interactive prompt)
165205
- ✅ CI/CD workflows (included in boilerplate)
166206
-`develop` branch (creates if absent)
167207

@@ -182,28 +222,6 @@ ghscaff apply owner/repo --dry-run
182222

183223
---
184224

185-
## Authentication
186-
187-
`ghscaff` reads the GitHub token exclusively from the `GITHUB_TOKEN` environment variable:
188-
189-
```bash
190-
export GITHUB_TOKEN=ghp_xxxxxxxxxxxx
191-
ghscaff
192-
```
193-
194-
**Required token scopes:**
195-
- `repo` — Repository access
196-
- `workflow` — GitHub Actions access
197-
- `read:org` — (Optional, for team access feature) Organization and team access
198-
199-
If the token is missing or invalid, ghscaff fails immediately with a clear error message before prompting anything else.
200-
201-
**Note on team access:** If your token lacks the `read:org` scope, the wizard will skip the team selection step with a warning, but the rest of the repository setup will continue normally.
202-
203-
**Security note:** Never hardcode tokens. Use environment variables or secret managers.
204-
205-
---
206-
207225
## Boilerplate Templates
208226

209227
Each language template includes:
@@ -221,15 +239,16 @@ All files are merged into a single atomic `chore: init repository` commit.
221239

222240
## Standard Label Set
223241

224-
6 core labels are auto-created with every new repo:
242+
7 labels are enforced on every repo. Non-standard labels are removed.
225243

226244
| Label | Color | Description |
227245
|-------|-------|-------------|
228246
| `bug` | `#d73a4a` | Something isn't working |
229247
| `feature` | `#a2eeef` | New feature or request |
230248
| `documentation` | `#0075ca` | Improvements to docs |
231249
| `breaking-change` | `#e4e669` | Introduces breaking changes |
232-
| `good first issue` | `#7057ff` | Good for newcomers |
250+
| `target:main` | `#1d76db` | Targets the main branch |
251+
| `target:develop` | `#0e8a16` | Targets the develop branch |
233252
| `help wanted` | `#008672` | Extra attention needed |
234253

235254
---
@@ -242,15 +261,18 @@ When enabled, applies to the default branch:
242261
- ✅ Dismiss stale reviews
243262
- ✅ Disallow force-push
244263

245-
--
264+
---
246265

247266
### Secrets Configuration
248267

249-
If you're extending `ghscaff` with new templates or modifying the release workflow, you may need to set up GitHub Actions secrets for your development fork:
268+
Templates can declare required secrets in `secrets.toml`. ghscaff resolves them in order:
269+
270+
1. **Encrypted vault** — previously saved secrets
271+
2. **Environment variable** — e.g. `CARGO_REGISTRY_TOKEN`
272+
3. **Interactive prompt** — with option to save to vault for future use
250273

251-
- **`CARGO_REGISTRY_TOKEN`** — Required for publishing Rust crates to crates.io
252-
- Get your token from [crates.io/me](https://crates.io/me)
253-
- Add it as a repository secret in GitHub (`Settings > Secrets and variables > Actions`)
274+
For the Rust template:
275+
- **`CARGO_REGISTRY_TOKEN`** — Required for publishing to crates.io ([get one here](https://crates.io/me))
254276

255277
---
256278

0 commit comments

Comments
 (0)