Skip to content

Vault enumerates alert-method secret field names, so a new secret field is redacted on read but persisted in cleartext #85

Closed

Description

@mattmacrocket

Gap

api/config_secrets.py is fail-closed at the API boundary: every alert-method field not in ALERT_METHOD_PUBLIC_FIELDS is returned as __squirrelops_redacted__. The vault layer (config_vault.py, _ALERT_METHOD_SECRET_FIELDS) is the opposite: it enumerates the secret names it knows (webhook_url, relay_token, device_token, and since #82 signing_secret). A secret stored under any other alert-method field name is therefore hidden from GET /config and GET /config/alert-methods yet written in cleartext to config.yaml, contradicting the documented "runtime YAML contains non-secret configuration only".

#82 added signing_secret to the list, which is the symptom fix for one field. The structural fix is what this issue is for.

Proposal

  • Make the vault strip and store every alert-method field that is not in ALERT_METHOD_PUBLIC_FIELDS, mirroring the API boundary, so one allowlist governs both. _ALERT_METHOD_SECRET_FIELDS goes away or becomes a derived view.
  • Keep the vault key scheme (config.alert_methods.<sha256(method)>.<field>) so existing stored secrets keep resolving.
  • Migration: on startup, any non-public alert-method field found in config.yaml is moved into the vault and scrubbed, the same path legacy plaintext credentials already take.
  • Tests: a future field name (smtp_password) round-trips through PUT, is redacted on GET, is absent from the persisted YAML, and is restored when the client echoes the marker back. Mutation check: delete the strip and watch the YAML test fail.

Control surface. Nothing attacker-visible changes.

Activity

  1. added a commit that references this issue on Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions