Remove ^, +, ~, :, @ from the allowed charset. The ^ character breaks SQLAlchemy DATABASE_URL parsing, + becomes space in URL query strings, : and @ are URL delimiters. The remaining charset (A-Za-z0-9._-) is safe in URLs, database connection strings, YAML, JSON, and shell without any encoding. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
83 lines
2.3 KiB
Markdown
83 lines
2.3 KiB
Markdown
# 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: `^` breaks URL parsing (e.g., SQLAlchemy DATABASE_URL). `+` becomes space in URL query strings. `:` and `@` are URL delimiters (userinfo/host separators). `~` can be shell-expanded. These are excluded to ensure secrets are safe in database connection strings, URLs, and shell contexts without encoding.
|
|
|
|
## 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._\-]
|
|
```
|