The encrypted credential directory
Where passwords live, how they reach a form without ever passing through your shell, and the one mistake that quietly writes them in clear text.
Your credentials live in an encrypted directory you mount — a gocryptfs
volume. They sit in a plain JSON file inside it, and that file is only readable
while the volume is mounted. Diwall reads it inside the process
driving the browser, at the moment a field is filled. The value never passes
through your shell, your command history, or Diwall’s own logs.
The words matter here: a JSON file is not a safe, and calling it one promises a guarantee the file does not carry. What protects the credentials is the encryption of the directory around them, and the fact that Diwall never takes the value out of the process that needs it.
That is the whole mechanism. The rest of this page is how to set it up, and one way to get it wrong.
Create it once
diwall-monter-secrets # mount an existing encrypted directory
To create one, the repository’s setup script handles both modes — encrypted
with gocryptfs by default, or a plain directory with --sans-chiffrement. The
package does not ship it: run it from a clone of the repository, pointing it at
the package’s configuration if that is how you installed Diwall.
git clone https://github.com/RonanDavalan/diwall.git
bash diwall/scripts/configurer-repertoire-chiffre.sh --config /etc/diwall/diwall.conf # package channel
bash diwall/scripts/configurer-repertoire-chiffre.sh # Git clone channel
Encrypted mode creates the encrypted store and an empty mount point. Nothing is readable on disk until you mount it.
Put credentials in it
A plain JSON file inside the mounted directory:
{
"username": "operator",
"password": "…",
"totp_cle": "BASE32SEED",
"ntfy_topic": "…",
"origines_autorisees": ["target.local"]
}
Only the keys your scenario actually references need to exist, except
origines_autorisees — mandatory since 05/08/2026, no exceptions. It lists
the hostnames this file may be used against; a read against any other domain
is refused before the file is even opened. totp_cle is the base32 seed for
two-factor codes; ntfy_topic is for codes pushed to you.
Use it in a scenario
{"type": "remplir_som", "id": 2,
"valeur": "depuis_secrets", "secret_cle": "username"},
{"type": "remplir_som", "id": 3,
"valeur": "depuis_secrets", "secret_cle": "password"}
secret_cle is the key inside the decrypted file. The scenario stays committable
— it names a key, never a secret. That is why a scenario can live in a public
repository without anything being redacted.
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 precisely to avoid
this.
One directory per project
Two ways, depending on whether it is a one-off or a habit.
# One-shot
DIWALL_SECRETS_DIR=~/Vaults/MyProject diwall-shot --url … --guide-version 1.3
# Recurring — a config file at the project root
echo '{"secrets_dir": "../MyProject-secrets"}' > ~/git/MyProject/.diwall.conf
export DIWALL_CONF=~/git/MyProject/.diwall.conf
A relative secrets_dir resolves against the location of the config file, so the
whole thing travels with the project.
--secrets <file> designates one specific credential file for a run without
touching any configuration — useful when the same scenario serves several
tenants.
When the directory is closed
Diwall stops with an explicit failure rather than pretending:
SecretsFermesError — exit code 42
If you are an agent: do not try to mount it yourself. Ask the operator.
Diwall also protects its own writes. Its operations log detects a closed directory and redirects to a local fallback instead of writing in clear text where the encrypted store should be; proof archiving is skipped rather than duplicating authenticated screenshots outside it.
The mistake that costs the most
An unmounted directory still exists. It is simply empty — and unencrypted.
Diwall’s internal guard covers Diwall’s 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. In that case you are not writing inside it: you are writing next to it, in clear text, in a directory that looks exactly right.
Before creating or updating a credential file, confirm the directory is mounted — it must be non-empty. If in doubt, stop and check. This one has no undo.
In short
- The file is read inside the browser process, never through your shell.
- Scenarios name a key, never a secret — so they stay committable.
DIWALL_CONFor--secretsfor per-project and per-tenant directories.- Exit 42 means closed: ask the operator, do not mount it yourself.
- An unmounted directory is an empty unencrypted directory. Check before writing.