# 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._+\-:@^~] ```