Connection secrets
If you make a secure connection to an external platform, FlexMeasures can store credentials,
API keys and tokens in the secrets JSON field of the account or asset that owns the connection.
Each secret value is encrypted separately and stored together with metadata such as its encryption
key ID and timestamps. Developers normally do not need to read or modify this
JSON structure directly.
For implementation examples, token lifecycle strategies and manually seeding a credential through the CLI, see Storing connection secrets.
The encrypted values are protected by
FLEXMEASURES_SECRETS_ENCRYPTION_KEYS, see FLEXMEASURES_SECRETS_ENCRYPTION_KEYS
This setting accepts arbitrary non-empty strings, which FlexMeasures derives into Fernet-compatible keys.
Hosts must configure this keyring before secrets can be stored - FlexMeasures will print a warning if it is not set and hints how to initialize it.
Recommended practices
Write-only API and UI
Treat secrets as write-only in API and UI flows. Accept new or replacement values, but never return plaintext secrets. Responses should contain only redacted information such as whether a value is set and when it expires.
For administrator-level maintenance, use flexmeasures edit secret to store
or replace one account or asset secret and flexmeasures delete secret to
remove one. Use --secret for dot-separated paths or --secret-path once
or twice. Prefer the edit command’s --prompt option so secret values do not
enter shell history.
Use the secret utilities
FlexMeasures provides a complete utility API in flexmeasures.utils.secrets_utils.
Use flexmeasures.utils.secrets_utils.set_secret() for individual
credentials. For token refresh flows, prefer
flexmeasures.utils.secrets_utils.TokenRefreshResult together with
flexmeasures.utils.secrets_utils.apply_token_refresh_result(). They safely
handle replacement tokens, rotated refresh tokens and providers that only
extend the expiry of an existing token.
Use flexmeasures.utils.secrets_utils.get_secret_overview() to build safe
secret listings with their paths and optional expiration times, without
exposing encrypted values or unrelated metadata.
When expires_at is stored without a timezone offset, FlexMeasures treats it
as UTC when rendering the overview.
Store secrets at one or two path levels only: a top-level namespace such as a
provider name, optionally followed by a secret name within that namespace.
String paths therefore look like provider or provider.refresh_token.
If a secret name itself contains a dot, pass the path as a tuple or list of
parts, or use --secret-path in the CLI.
Refresh early in multi-worker deployments
Store reusable access tokens and their expiry metadata in secrets so all
workers share the same token state. Refresh with time to spare before expiry to
allow for clock differences, retries and concurrent workers. In high-traffic
integrations, use database locking so only one worker performs a refresh. See
the refresh-leeway example in Initiating tokens (before app startup).