Skip to content

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.py loads, it looks for a .env file in a few locations and loads a readable one with load_dotenv (_hodler_safe_load_dotenv skips files it cannot read). Values from that file take precedence. .env files 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 .env file exists, the process environment is the only source.
  • Most keys are read with os.getenv into module-level constants named after their variables, such as ETHERSCAN_API_KEY, ALCHEMY_API_KEY or TELEGRAM_BOT_TOKEN; a few are read with os.getenv where 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 from creds.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.
  • rotate re-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 .env file 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.meta and creds.enc securely 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 .env files 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.