Abstract secure sandbox chambers connected through narrow filtered credential conduits
Sandbox access should be explicit and minimal: pass only the named variable or credential file the task actually needs.

Pass Environment Variables and Credential Files into Hermes Sandboxes

Hermes deliberately strips sensitive environment variables from execute_code and terminal child processes. Docker terminal sessions inherit no arbitrary host variables by default, and Modal begins without host environment variables or files. This reduces the chance that LLM-generated code can read every provider key, bot token, or unrelated credential available to the parent process.

When a task genuinely needs a secret, use a narrow declaration. Pass the name of one required variable or one relative credential-file path, not the whole environment and not a broad home-directory mount.

Choose the right credential form

Use required_environment_variables for string values such as API keys and bearer tokens. Hermes stores configured secret values in its environment file and does not put the raw value into the skill text shown to the model.

Use required_credential_files when the integration produces a file: an OAuth token, client-secret document, service-account JSON, certificate, or similar artifact. File declarations are resolved relative to the active profile's HERMES_HOME.

Use ordinary skill configuration for non-secret preferences. A path, domain, output format, or feature toggle belongs in config.yaml, not in a secret passthrough list.

Prefer skill-scoped environment declarations

A skill can declare exactly what it needs in SKILL.md frontmatter:

required_environment_variables:
  - name: TENOR_API_KEY
    prompt: Tenor API key
    help: Get a key from https://developers.google.com/tenor
    required_for: GIF search functionality

When the skill is loaded through skill_view or /skill, Hermes checks whether the variable is set. Set variables are automatically registered for passthrough to execute_code, local terminal execution, Docker, and Modal. Missing variables remain in setup-needed state and are not forwarded.

In the local CLI, Hermes can request a missing declared value through secure setup. Gateway and messaging sessions do not ask a user to paste secrets into chat; they direct the operator to perform setup locally. A user can skip setup and still load the skill, but features that require the missing value remain unavailable.

Skill-scoped declarations are the best default because the requirement travels with the integration. Users do not have to maintain a separate global allowlist, and Hermes activates the passthrough only when the skill is actually loaded.

Add a manual environment allowlist when needed

For a task-specific variable that no skill declares, add only its name to terminal.env_passthrough:

terminal:
  env_passthrough:
    - MY_CUSTOM_KEY
    - ANOTHER_TOKEN

Keep the actual values out of config.yaml; place them in ~/.hermes/.env or inject them into the parent process through an approved secret manager. The config list authorizes names. It should not duplicate secret values.

Docker also has terminal.docker_forward_env. Hermes merges skill-declared variables into Docker forwarding automatically, so a skill should not require users to repeat the same name there. Any forwarded variable is visible to code running in that sandbox and can be exfiltrated by that code. An allowlist changes exposure; it does not make a secret unreadable.

Do not add Hermes infrastructure secrets such as model-provider keys, gateway tokens, or tool-service credentials to the generic passthrough list. Hermes has dedicated mechanisms for those values, and forwarding them gives task code more privilege than it needs.

Declare credential files in a skill

For file-based authentication, declare relative files in the skill frontmatter:

required_credential_files:
  - path: google_token.json
    description: Google OAuth2 token created by setup
  - path: google_client_secret.json
    description: Google OAuth2 client credentials

Hermes checks the active profile's Hermes home when the skill loads. A missing file triggers setup-needed status. An existing file is available locally without special handling, mounted read-only into Docker, and mounted into Modal at sandbox creation with a sync before each command. The Modal refresh supports credentials created during the same session.

For a credential file that is not owned by a skill, list the relative filename manually:

terminal:
  credential_files:
    - google_token.json
    - my_custom_oauth_token.json

terminal.credential_files is a valid configuration key even though it is loaded by the credential-files module and is not part of the bundled default-config snapshot. Keep each file under the active Hermes home and list the smallest set needed.

Keep MCP credentials separate

The sandbox passthrough registry does not configure MCP stdio subprocesses. MCP receives only a small safe system environment plus variables explicitly defined for that MCP server. If an MCP server needs a token, configure its own mcp_servers.<name>.env mapping. Do not assume terminal.env_passthrough will reach it.

Verify presence without revealing values

Tests should return booleans or filenames, never secret contents. Inside the intended sandbox, a skill script can check whether a variable is non-empty and whether its declared file exists. Avoid broad commands such as env, printenv, or dumping the credential document. Tool output can enter model context and logs even when later redaction is available.

Test the exact execution surface the skill uses. A successful local-shell check does not prove execute_code, Docker, or Modal received the declaration.

Pitfalls

  • Assuming everything in ~/.hermes/.env is inherited by child code.
  • Forwarding the entire host environment instead of an explicit name allowlist.
  • Putting literal secret values in config.yaml.
  • Printing a token or credential file to prove that it exists.
  • Using an environment declaration for a file-based OAuth credential, or vice versa.
  • Expecting a missing declared variable or file to be forwarded.
  • Adding provider or gateway infrastructure secrets to terminal.env_passthrough.
  • Expecting terminal passthrough settings to configure MCP subprocesses.

Verification checklist

  • Verify each secret is represented as either one environment-variable name or one relative credential-file path.
  • Verify the skill declares required_environment_variables or required_credential_files when the requirement belongs to that skill.
  • Verify missing requirements show setup-needed state and are not silently registered.
  • Verify a loaded skill can detect the required variable in the exact sandbox it uses without printing the value.
  • Verify Docker credential files are read-only from inside the container.
  • Verify Modal can see a declared credential created during the session after its pre-command sync.
  • Verify terminal.env_passthrough contains no Hermes provider, gateway, or unrelated tool credentials.
  • Verify MCP credentials are configured on the MCP server rather than assumed to inherit terminal passthrough.

Official references