Skip to content

RFC: on-boot materialization of _-prefixed SSM secrets into $HERMES_HOME/.env - #24

Closed
capotej wants to merge 1 commit into
mainfrom
rfc/underscore-ssm-secrets-to-hermes-env
Closed

RFC: on-boot materialization of _-prefixed SSM secrets into $HERMES_HOME/.env#24
capotej wants to merge 1 commit into
mainfrom
rfc/underscore-ssm-secrets-to-hermes-env

Conversation

@capotej

@capotej capotej commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Proposes a template-free escape hatch for forwarding operator-specific env vars into the running claw: any SSM SecureString under /bclaw/ whose leaf name starts with _ (e.g. /bclaw/_MY_API_KEY) is fetched inside the container via the task role, decrypted, and written to $HERMES_HOME/.env on every boot. Hermes already sources that file (env_loader.load_hermes_dotenv), so the values reach the gateway with no task-def secrets[] entry, no template.yaml edit, and no per-secret redeploy. Editing the SSM param + restarting the task auto-rotates the value.

This is Status: Proposed — doc-only (a new RFC under rfcs/). No template/ or src/ changes in this PR.

Why in-container (not deployer-side)

An earlier draft materialized .env from the deployer shell during setup-bclaw. That design was rejected because it routes secret plaintext through the deployer host and the agent's context: get-parameters --with-decryption --query '...Value]' prints values the agent captures, and the manage-bclaw transfer transport (CHUNK=$(cat "$f") + --command embedding) would flow the base64 of a secret-laden .env through the agent's tool calls. Decoding base64 is trivial, so that's plaintext-in-context in practice.

Doing the fetch inside the container under the task role removes that exposure entirely — the agent only ever sees exit codes. As a bonus, running it on every boot makes rotation automatic.

⚠️ Blocking dependency: harness image must ship aws

The boot Command calls aws ssm inside the container, but ghcr.io/boldblackai/harness does not ship the aws CLI today (it ships gh and hermes; every aws call in the shipped skills runs on the deployer host or the EC2 instance, never in the container). The Command guards on command -v aws and degrades gracefully (non-fatal no-op), so the gateway never crashes — but the feature is inert on every claw until aws is added to the image.

That image change is a blocking upstream prerequisite, called out as the RFC's first ## Dependencies bullet, the first Edge cases & risks bullet, the first implementation-checklist item, and the first integration-cycle gate. If shipping aws proves undesirable, the RFC lists fallbacks (root-stage image fixup, boto3, or revert to the deployer-side design) — none chosen; in-image aws is preferred.

Decisions worth a glance on review

  • Flat /bclaw/_* only — deeper nesting (/bclaw/sub/_BAR) is ignored (path filter is non-recursive /bclaw).
  • DescribeParameters on Resource: "*". List-style SSM actions can't be ARN-scoped; mirrors the deployer policy's existing grant. Values stay pinned to parameter/bclaw/*.
  • Authoritative-overwrite .env on every boot$HERMES_HOME/.env is no longer operator-editable inside the container (a hand-edit is clobbered on restart). Merge semantics deferred pending confirmation of the hermes config / .env write interaction in cloud mode.
  • Non-fatal (mirrors the gh-auth block) — operator extras must never take down the Slack bot.

See rfcs/2026-07-16_underscore-ssm-secrets-to-hermes-env.md for the full design, the IAM grant shape, the boot Command sketch, alternatives considered, and the integration-cycle plan.

…ES_HOME/.env

Propose an on-boot, in-container mechanism: any SSM SecureString under /bclaw/
whose leaf starts with _ (e.g. /bclaw/_MY_API_KEY) is fetched inside the
container via the task role, decrypted, and written to $HERMES_HOME/.env on
every boot. Hermes' existing env_loader.load_hermes_dotenv already sources that
file, so the values reach the gateway with no task-def secrets[] entry, no
template edit, and no per-secret redeploy. SSM edit + task restart auto-rotates.

Doing the fetch in-container (vs. deployer-side) keeps secret plaintext off the
deployer host and out of the agent's context -- the agent only ever sees exit
codes. Adds a scoped task-role ssm:GetParameter(s)+kms:Decrypt grant and a
non-fatal boot-time SSM step (mirrors the gh-auth block posture).

BLOCKING DEPENDENCY: the harness image (ghcr.io/boldblackai/harness) does not
ship the aws CLI today, and the boot Command calls aws ssm inside the container.
The Command guards on 'command -v aws' and silently no-ops without it, so this
RFC cannot land until aws is added to the image. Flagged as the first checklist
item and the first integration-cycle gate.
@capotej capotej closed this Jul 17, 2026
@capotej

capotej commented Jul 17, 2026

Copy link
Copy Markdown
Contributor Author

closing in favor of a native hermes aws ssm plugin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant