nvflare.fuel.utils.secret_utils module

Helpers for keeping secret values out of job definitions.

Job parameters (training script args, per-site config, extra config dicts) are written in clear text into the generated job configuration files, which are exported, logged, and shared. They must therefore never contain actual secret values. This module provides two complementary tools to support that contract:

  • Secret references: secret_ref() and secret_file_ref() build placeholders that can be used at supported runtime boundaries instead of actual secret values. Only placeholders are stored in generated job configuration; supported consumers call resolve_secret_refs() with values from the executing site’s environment or mounted secret files at runtime.

  • Secret detection: find_potential_secrets() and warn_on_potential_secrets() scan user-supplied parameter values for things that look like actual secrets (well-known token formats, password-like flags or keys, high-entropy strings) so mistakes can be flagged before the values end up in exported job configs and logs.

Messages produced by this module report only the flagged value’s length, never any of its characters, so warning text is safe to log and share.

exception PotentialSecretWarning[source]

Bases: UserWarning

Warning category emitted when a job parameter looks like it contains an actual secret value.

class SecretFinding(location: str, reason: str, preview: str)[source]

Bases: NamedTuple

One potential secret found by find_potential_secrets().

location

where the value was found, e.g. "train_args (secret-named flag)".

Type:

str

reason

why it was flagged, e.g. "GitHub token".

Type:

str

preview

masked preview of the value, safe to log and share.

Type:

str

Create new instance of SecretFinding(location, reason, preview)

location: str

Alias for field number 0

preview: str

Alias for field number 2

reason: str

Alias for field number 1

exception UnsupportedSecretRefWarning[source]

Bases: UserWarning

Warning emitted when a secret reference appears outside a supported runtime boundary.

find_potential_secrets(value: Any, location: str = 'value') List[SecretFinding][source]

Scan a parameter value for anything that looks like an actual secret.

Strings are checked for well-known credential formats, secret-named command-line flags with inline values, credentials embedded in URLs, and high-entropy tokens. Dicts and lists are scanned recursively; dict entries whose key names suggest a credential (password, token, api_key, …) are flagged when their value looks like actual secret material. Stand-alone, valid secret references (${secret:NAME}), env-var/config placeholders, and file paths are not flagged – those are the recommended ways to hand secrets to a job.

This is a heuristic intended to catch mistakes, not a guarantee: absence of findings does not prove a value is safe.

Parameters:
  • value – the parameter value to scan (str, dict, list, or any nesting of them).

  • location – human-readable description of where the value came from; used in findings.

Returns:

List of SecretFinding, deduplicated by location and preview. Findings contain only masked previews and are safe to log.

has_secret_refs(value: Any) bool[source]

Return whether a string contains an environment or mounted-file secret reference.

resolve_secret_refs(value: Any, env: Mapping[str, str] | None = None) Any[source]

Resolve secret references recursively without changing mapping keys.

Intended to be called at runtime on the executing site, as late as possible and only on the in-memory value handed to user code. Environment references use ${secret:NAME}; mounted-file references use ${secret:file:/path/to/key}. Resolved values must never be logged or written back into config files.

Parameters:
  • value – string or nested mapping/list/tuple whose string values should be resolved.

  • env – source of secret values; defaults to os.environ.

Returns:

A resolved value. Containers are copied; mapping keys are preserved unchanged.

Raises:

ValueError – if reference syntax is invalid, a referenced environment variable is not set, or a referenced file cannot be read. Errors never include a resolved value, so they are safe to log.

secret_file_ref(path: str) str[source]

Build a reference to a secret stored in a mounted text file on the executing site.

This is intended for secrets projected as files, including Kubernetes Secret volume keys. The path itself is stored in the generated job config; the file content is read only on the executing site at runtime. One trailing newline commonly added by secret-file tooling is removed before injection.

Parameters:

path – runtime path of the mounted secret file. Absolute paths are strongly recommended; whitespace and brace characters are not supported.

Returns:

The placeholder string ${secret:file:<path>}.

secret_ref(env_var: str) str[source]

Build a secret reference placeholder for use in job parameters.

The returned string carries no secret value and is safe to store in job configs. A supported runtime consumer on the executing site replaces it with the value of the named environment variable. See nvflare.recipe.secrets for supported parameter locations.

Parameters:

env_var – name of the environment variable that holds the secret on the executing site.

Returns:

The placeholder string ${secret:<env_var>}.

Example

train_args=f”–api-key {secret_ref(‘MY_API_KEY’)}”

split_command_preserving_secret_refs(command: str, posix: bool, group_secret_ref_quotes: bool = False) List[str][source]

Tokenize a command without interpreting characters inside secret reference markers.

Valid and malformed markers are temporarily replaced with inert tokens. Restoring them after tokenization ensures the runtime resolver sees exactly what the recipe supplied, including quote and backslash characters in mounted-file paths. posix=False retains the task script runner’s legacy whitespace-only splitting; posix=True uses shlex.split(). With group_secret_ref_quotes=True, only quoted spans containing references are grouped and unquoted; unrelated arguments retain the legacy behavior.

warn_on_potential_secrets(value: Any, context: str) List[SecretFinding][source]

Scan a parameter value and emit a PotentialSecretWarning for each finding.

Warning messages contain only masked previews, never the flagged values, so they are safe to appear in logs that get shared.

Parameters:
  • value – the parameter value to scan.

  • context – where the value came from, e.g. "recipe parameter 'train_args'".

Returns:

The list of findings (empty if nothing was flagged).

warn_on_unsupported_secret_ref_keys(value: Any, context: str) bool[source]

Warn when nested mapping keys contain references, since keys are never resolved.

warn_on_unsupported_secret_refs(value: Any, context: str) bool[source]

Warn when a value contains references that its runtime consumer will not resolve.

warn_on_unsupported_secret_refs_outside_keys(value: Any, supported_value_keys: set[str], context: str, supported_value_depth: int = 1) bool[source]

Warn when references occur outside explicitly supported mapping values.

supported_value_depth controls the mapping depth at which supported keys are exempted. Per-site configuration uses depth 2 for its site key and immediate field values.