You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Vault enumerates alert-method secret field names, so a new secret field is redacted on read but persisted in cleartext #85
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 #82signing_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
Merge pull request #87 from rocketweb/fix/vault-nonpublic-alert-fields