Sparround

Secrets and data flow

There are two separate questions, and they must not be conflated:

  • How are secrets protected inside the agent? — which process receives a key and which does not
  • Where does data go? — which external service sees conversation content, file contents and log fragments

The first is answered by technical controls; the second is an architectural decision, and in a company it often has a legal dimension too.

EnvironmentDefault secret filterHow to pass something through
The `execute_code` sandboxVariables whose name contains KEY, TOKEN, SECRET, PASSWORD, AUTH are blockedAn explicit passthrough declaration
`terminal` (local)Hermes infrastructure variables are blocked`terminal.env_passthrough`
`terminal` (Docker)No host environment is passed`docker_forward_env`
MCP serversOnly safe system variables (PATH, HOME, LANG…)The MCP server's `env` block

Skills have a separate, tidier mechanism: a skill declares required_environment_variables and required_credential_files in its frontmatter. When the skill loads, only those variables and files reach the execution environment — and under Docker the credential files are mounted read-only. So a key is opened up for a specific procedure's need, not for everything.

Also: MCP tool errors are sanitised (GitHub PATs, sk- keys, Bearer tokens, password= and secret= parameters), and secrets are redacted automatically in logs.

The honest answer on data flow: everything sent to the model provider is subject to that provider's policy. File contents, log fragments and customer names that enter the conversation all travel as part of the request. In a corporate setting that usually forces one of three choices: an approved corporate provider, a local model, or simply not giving sensitive data to the agent at all.

This is not a configuration decision — it is a policy decision to be agreed with information security and legal.

Practice. Write a skill that declares exactly one key through required_environment_variables. Then print the environment variables with execute_code and check what is visible. Done means: the declared key is there and the other keys are not.

📚 Sources and documentation