Add gen-secret: generate bash/YAML/JSON-safe random strings
Outputs cryptographically random strings using only characters safe for unquoted use in bash, YAML, and JSON: [A-Za-z0-9._+\-:@^~] Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
82
specs/gen-secret.spec.md
Normal file
82
specs/gen-secret.spec.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# gen-secret
|
||||
|
||||
## Purpose
|
||||
|
||||
Generate a cryptographically random string that is safe to embed unquoted in bash, YAML, and JSON without escaping.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
gen-secret [OPTIONS] [LENGTH]
|
||||
```
|
||||
|
||||
### Arguments
|
||||
|
||||
| Argument | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `LENGTH` | 32 | Number of characters in the generated secret |
|
||||
|
||||
### Flags
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `--help`, `-h` | Show usage information |
|
||||
| `--dryrun`, `-n` | Print what would happen without generating a secret |
|
||||
|
||||
## Character Set
|
||||
|
||||
The output uses only characters that need no escaping in bash (unquoted assignment), YAML (plain scalar), and JSON (string value):
|
||||
|
||||
```
|
||||
A-Z a-z 0-9 . _ + - : @ ^ ~
|
||||
```
|
||||
|
||||
**Excluded** (unsafe in at least one context): `"`, `'`, `\`, `` ` ``, `$`, `!`, `{`, `}`, `(`, `)`, `[`, `]`, `#`, `%`, `&`, `|`, `<`, `>`, `*`, `?`, `;`, `,`, `=`, space, tab, newline, `/`
|
||||
|
||||
Note: `/` is excluded because YAML plain scalars starting with `//` or containing `#` after a space can cause issues, and removing `/` keeps the set simpler without meaningful entropy loss.
|
||||
|
||||
## Behaviour
|
||||
|
||||
1. Validate that LENGTH is a positive integer.
|
||||
2. Read random bytes from `/dev/urandom`.
|
||||
3. Filter to the allowed character set.
|
||||
4. Output exactly LENGTH characters followed by a newline.
|
||||
5. Exit 0 on success.
|
||||
|
||||
## Dryrun Behaviour
|
||||
|
||||
When `--dryrun` or `-n` is passed:
|
||||
|
||||
```
|
||||
[dryrun] Would generate a 32-character secret from charset: [A-Za-z0-9._+\-:@^~]
|
||||
```
|
||||
|
||||
(Substituting the actual length if provided.)
|
||||
|
||||
No random output is produced.
|
||||
|
||||
## Edge Cases
|
||||
|
||||
| Case | Handling |
|
||||
|------|----------|
|
||||
| LENGTH is 0 | Error: "Length must be a positive integer", exit 1 |
|
||||
| LENGTH is negative | Error: "Length must be a positive integer", exit 1 |
|
||||
| LENGTH is not a number | Error: "Length must be a positive integer", exit 1 |
|
||||
| No arguments | Default to 32 |
|
||||
| Multiple arguments | Error: "Too many arguments", exit 1 |
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
# Default 32-character secret
|
||||
$ gen-secret
|
||||
xQ9.kT3+mR7:nW2@pF5^bY8~cH4_dL6a
|
||||
|
||||
# Custom length
|
||||
$ gen-secret 64
|
||||
xQ9.kT3+mR7:nW2@pF5^bY8~cH4_dL6axQ9.kT3+mR7:nW2@pF5^bY8~cH4_dL6a
|
||||
|
||||
# Dryrun
|
||||
$ gen-secret -n 16
|
||||
[dryrun] Would generate a 16-character secret from charset: [A-Za-z0-9._+\-:@^~]
|
||||
```
|
||||
Reference in New Issue
Block a user