What this module does #
Almost every service on your instance needs a secret: the database password, the passphrase for an integrity tool, an API key… Storing them by hand — or worse, leaving them at their defaults — is one of the most common ways for a machine to end up compromised.
The secrets module handles that lifecycle locally: it generates each secret with a cryptographically secure generator (CSPRNG), stores it with 0600 permissions (only root can read it), returns it with clean output ready to chain in a pipe, and rotates it when you need to. Everything is organized by domains (for example mariadb or tripwire), and each domain can have several fields.
generate is idempotent: if a domain's secret already exists, it doesn't touch it. That way a single image can create its secrets on each instance's first boot without two machines sharing the same password. The values are never logged or shown in list.
Common tasks #
Pick what you want to do. Each recipe comes with the command already written — just swap the domain for your own and hit Copy.
1
Generate a service's secret
Create a strong password for a domain, only if it doesn't exist yet.
Connect to your server over SSH with the ubuntu user.
Generate the secret for the mariadb domain. Since it's idempotent, you can run it as many times as you like without any fear of overwriting:
$ sudo imaxe secrets generate mariadbNeed a long passphrase for another tool and in a specific field? Adjust --format, --len and --field:
$ sudo imaxe secrets generate tripwire --field local.passphrase --format passphrase --len 400600 permissions. If it already existed, nothing has changed — the command still ends in success.2
Read a secret to use it
Get the raw value, ready to chain into another command.
get prints only the value, with no decoration or extra line breaks, so you can pass it to another process via pipe:
$ sudo imaxe secrets get mariadbIs the secret in a specific field of the domain? Point to it with --field:
$ sudo imaxe secrets get tripwire --field local.passphrasePASS="$(sudo imaxe secrets get mariadb)" and use it directly in your script.3
Rotate a secret
Replace the value with a new one and mark the domain as rotated.
Generate a new value for the domain. Unlike generate, rotate does replace the existing secret:
$ sudo imaxe secrets rotate mariadblist). Remember to update the service that uses that secret with the new value from get.4
See which domains exist
Query the metadata without exposing any value.
List the domains with their metadata (when they were created and when they were rotated). It never shows the secret itself:
$ sudo imaxe secrets listNeed it for a script or an automated check? Ask for the output in JSON:
$ sudo imaxe secrets list --jsonThe secret is only readable by root while it lives on disk. As soon as you read it with get it passes into your terminal and your shell: avoid leaving it in the history (history), in over-exported environment variables or in logs. Prefer one-off command substitutions like "$(sudo imaxe secrets get mariadb)".
Synopsis #
imaxe secrets <subcomando> [<dominio>] [--field CLAVE] [flags]All subcommands require root privileges (use sudo) because they read and write 0600 files under /etc/imaxe/. Add --json to list to get machine-readable output, suitable for scripting. Remember: get emits the raw value, with no decoration, ready for a pipe.
Subcommands #
| Subcommand | What it does | Relevant flags |
|---|---|---|
| generate | Creates a domain's secret if it doesn't exist (idempotent, CSPRNG). Without a domain, it generates the ones in generate_on_first_boot. | --len, --format, --field |
| get | Returns a secret's value with clean output, suitable for a pipe. | --field |
| rotate | Generates a new secret and marks the domain as rotated. | --field |
| list | Lists the domains and metadata (created, rotated). Never shows values. | --json |
Arguments and flags #
| Flag | Type | Default | Description |
|---|---|---|---|
| <dominio> | string | — | Secret domain (e.g. mariadb, tripwire). Required in get and rotate. In generate, empty = the domains in generate_on_first_boot. |
| --field | string | value | Field within the domain. Lets you store several secrets per domain (e.g. local.passphrase). |
| --len | int | 32 | In generate: length of the secret in characters. |
| --format | enum | password | In generate: format of the value — password, passphrase or hex. |
| --json | bool | false | In list, emits the metadata as structured JSON on stdout. |
Files and paths #
| Path | Contents |
|---|---|
| /etc/imaxe/secrets.yml | Module configuration: default values (length, format), domains and the generate_on_first_boot list. Stored with 0600 permissions. |
Example secrets.yml:
defaults:
length: 32
format: password
domains: {}
generate_on_first_boot:
- mariadb
- tripwireWith that configuration, a sudo imaxe secrets generate without a domain on the first boot creates the secrets for mariadb and tripwire with the default length and format.
Exit codes and logs #
Each run returns a code you can check with echo $? — handy for chaining in scripts:
get without a domain).Typical use in a script, taking advantage of the clean output of get:
$ sudo imaxe secrets generate mariadb \
&& sudo imaxe secrets get mariadb | some-tool --stdin-password \
|| echo "falló con código $?"Troubleshooting #
| Symptom | Likely cause | Fix |
|---|---|---|
| NOTFOUND appears (code 3) | The domain or the --field hasn't been generated yet. | Create it first with secrets generate <dominio> (and the same --field). |
| USAGE appears (code 2) | get or rotate run without specifying the domain. | Pass the domain as an argument; it's required in those subcommands. |
generate doesn't change the value | The secret already existed: generate is idempotent by design. | If you want a new value, use secrets rotate <dominio>. |
Permission denied when reading | The file is 0600 and you ran it without privileges. | Run the command with sudo; only root can access the secret. |
Stuck with the Secrets module?
Write to us with the output of «imaxe <module> status --json» and we'll get back to you fast.