Public security notice: This documentation is intentionally redacted. Sensitive server paths, private keys, secret tokens, and origin network details are removed.
Secure Credentials System¶
The Hodler Suite depends on many third-party APIs. The engine reads the credentials for those APIs from environment variables, and it ships a command-line helper that can also keep them in an encrypted credentials store. The desktop GUI credentials manager that earlier versions shipped was removed together with the rest of the desktop tooling.
How the engine loads provider keys¶
Provider keys reach the engine as environment variables:
- When
defi_complete_risk_assessment_clean.pyloads, it looks for a.envfile in a few locations and loads a readable one withload_dotenv(_hodler_safe_load_dotenvskips files it cannot read). Values from that file take precedence..envfiles are listed in.gitignore, so they stay out of version control. - Variables already set in the process environment, for example by the service
manager that starts the engine, are used for anything the file does not
define. When no readable
.envfile exists, the process environment is the only source. - Most keys are read with
os.getenvinto module-level constants named after their variables, such asETHERSCAN_API_KEY,ALCHEMY_API_KEYorTELEGRAM_BOT_TOKEN; a few are read withos.getenvwhere they are used.
Because most keys are read when the module loads, a changed value takes effect on the next run or after the process restarts.
Encrypted credentials store¶
The store is implemented in:
scripts/engine/credential_management/secure_credentials.py– a command-line helper that handles encryption, decryption and the file layout.
It keeps two files:
creds.meta– JSON metadata holding the salt.creds.enc– Fernet-encrypted JSON mapping of{KEY: VALUE}pairs.
From the module docstring:
```text Stores: - data/creds.meta -> JSON: {"salt": base64} - data/creds.enc -> Fernet ciphertext of JSON map {KEY: VALUE}
Usage: secure_credentials.py setup # initialize files (prompts master password) secure_credentials.py test # verify decryption secure_credentials.py list # list keys (names only) secure_credentials.py get KEY # print value for KEY secure_credentials.py set KEY VALUE # set/update a key secure_credentials.py remove KEY # delete a key secure_credentials.py import_env PATH # import from .env-like file secure_credentials.py export_env PATH # export to .env-like file secure_credentials.py rotate # change master password ```
Encryption design:
- A user-provided master password is turned into a key with
PBKDF2-HMAC-SHA256 (
derive_key) and the salt fromcreds.meta. - The derived key encrypts and decrypts the whole mapping with Fernet
(
write_store,read_store). - The helper asks for the master password unless the environment already provides it. Neither the password nor the derived key is written to disk.
rotatere-encrypts the store under a new master password and a fresh salt.
Integration with the engine¶
The engine does not decrypt the store itself. To use keys kept there, export
them to a .env-style file that the engine loads (export_env), or import an
existing file into the store (import_env). An exported file holds the values
in plain text, so keep it out of version control and readable only by the
account that runs the engine.
The goal is to ensure:
- no secrets are checked into version control,
- configuration for staging / production / personal environments can differ,
- rotating or revoking a key is a matter of updating the value where the engine
reads it (the
.envfile or the process environment) and starting a new run.
Operational recommendations¶
- Use a strong master password and share it only with the smallest set of trusted operators.
- Back up
creds.metaandcreds.encsecurely and together; the store cannot be recovered if either file is lost. - Rotate keys periodically and on any suspected compromise, then restart any long-running engine process so it picks up the new value.
- Restrict read access to
.envfiles to the account that runs the engine.
Together, environment-based key loading and the encrypted store provide a practical way to operate a complex, multi-API risk assessment engine without sacrificing security hygiene.