The encrypted credential directory
Where passwords live, how they reach a form without passing through your shell, and the mistake that writes them in clear text.
Your credentials live in an encrypted directory that you mount, a
gocryptfs volume. Inside it they sit in plain JSON files, readable only
while the volume is mounted. Dinoer reads them inside the process that
drives the browser, at the moment a field is filled. The value never passes
through your shell, your command history or Dinoer’s logs.
Create it, then mount it
On a Git-clone installation, the setup script creates the encrypted store and
an empty mount point, at the paths set by secrets_crypt_dir and
secrets_dir in dinoer.conf. --sans-chiffrement creates a plain
directory instead (mode 700), for a machine without gocryptfs:
bash scripts/configurer-repertoire-chiffre.sh # from the clone
The .deb package does not ship this script: create the gocryptfs volume
yourself and set secrets_dir to its mount point. Then, on either channel,
mount it before a run that needs it:
dinoer-monter-secrets # .deb package
bash /opt/dinoer/scripts/monter-repertoire-chiffre.sh # Git clone
Nothing can be read on disk until the volume is mounted.
Put credentials in it
One JSON file per site, named after its domain (target.local.json, or
target.local_8443.json for a specific port), anywhere under the mounted
directory:
{
"username": "operator",
"password": "…",
"totp_cle": "BASE32SEED",
"ntfy_topic": "…",
"origines_autorisees": ["target.local"]
}
Only the keys your scenarios use need to exist. totp_cle is the base32 seed
for two-factor codes; ntfy_topic is the channel on which a code sent to you
can be passed on. Without --secrets, Dinoer picks the file from the domain of
the page actually loaded, so a redirect to another site finds no credential.
With --secrets, the file is named explicitly: it must then list the domains
it may be used on in origines_autorisees, and be readable by its owner only
(chmod 600), otherwise Dinoer refuses it.
Use it in a scenario
{"type": "remplir", "selecteur": "input[name=\"username\"]",
"valeur": "depuis_secrets", "secret_cle": "username"},
{"type": "remplir", "selecteur": "input[name=\"password\"]",
"valeur": "depuis_secrets", "secret_cle": "password"}
secret_cle is the key inside the file. The scenario names a key, never a
secret, so it can live in a public repository without anything to redact.
Never do this
PASS=$(jq -r ‘.password’ ~/Vaults/…/creds.json): a credential in
a shell variable is in your process environment, in /proc, and
possibly in your history. The encrypted directory exists to avoid exactly
this.
One directory per project
Two ways, for a one-off run or for a habit.
# One-off
DINOER_SECRETS_DIR=~/Vaults/MyProject /opt/dinoer/venv/bin/python3 /opt/dinoer/shot.py \
--url … --guide-version 1.6
# Recurring: a configuration file at the root of the project
echo '{"secrets_dir": "../MyProject-secrets"}' > ~/git/MyProject/.dinoer.conf
export DINOER_CONF=~/git/MyProject/.dinoer.conf
A relative secrets_dir is resolved from the location of the configuration
file, so the setting travels with the project.
--secrets <file> names one credential file for a single run without
changing any configuration, for example when the same scenario serves several
accounts.
When the directory is closed
Dinoer stops with an explicit error:
SecretsFermesError — exit code 42 (encrypted directory not mounted)
SecretsNonConfigureError — exit code 43 (no credential directory configured)
If you are an agent: do not try to mount it yourself. Ask the operator.
Dinoer also protects its own writes: when its operations journal is set up inside the encrypted directory and that directory is closed, it writes to a local fallback file instead of writing in clear where the encrypted store should be.
The mistake that costs the most
An unmounted directory still exists. It is simply empty, and unencrypted.
Dinoer’s guard covers its own writes. It does not cover a credential file you create yourself, with a shell command or an editor, while the directory happens to be unmounted. You are then writing next to the encrypted store, in clear, in a directory that looks exactly right.
Before creating or changing a credential file, check that the directory is mounted: it must not be empty. This mistake cannot be undone.
In short
- The file is read inside the browser process, never through your shell.
- Scenarios name a key, never a secret, so they can be committed.
DINOER_CONF,DINOER_SECRETS_DIRor--secretsfor per-project and per-account credentials.- Exit 42 means closed, exit 43 means never configured: ask the operator, do not mount it yourself.
- An unmounted directory is an empty, unencrypted directory. Check before writing.