Repository navigation
Vault every non-public alert-method field instead of a named list (#85) - #87
Merged
Merged
Conversation
The API boundary was fail-closed: any alert-method field not on the public allow-list came back redacted. The vault enumerated the secret names it knew, so a secret under any other field name was hidden on read yet written in cleartext to config.yaml. The two layers now share one allow-list (config_fields.ALERT_METHOD_PUBLIC_FIELDS, re-exported by config_secrets): every string field not on it is a credential to both. The persisted YAML keeps a marker in place of each vaulted value so startup hydration knows which fields to fetch without the vault holding an index. Installs written by older releases, which popped the known field names outright, still hydrate because those names are probed as before. A marker with nothing behind it is dropped rather than handed to a handler. Non-string unknown fields are settings and stay in the YAML. Red first: five new vault tests (marker on strip, round trip through the vault, legacy YAML hydration, marker never stored, shared allow-list). Full sensor suite 2614 passed.
chrissyrocket
approved these changes
Oct 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #85.
Problem
api/config_secrets.pyis fail-closed: every alert-method field not onALERT_METHOD_PUBLIC_FIELDSis redacted onGET.config_vault.pywas the opposite: it enumerated the secret field names it knew (webhook_url,relay_token,device_token, and since #82signing_secret). A secret stored under any other name was hidden from the API and written in cleartext toconfig.yaml.Fix
config_fields.ALERT_METHOD_PUBLIC_FIELDS(enabled,include_device_info,min_severity,relay_url), re-exported fromconfig_secretsso existing imports keep working. A test asserts both modules reference the same object.PUT, and stripped from the persisted YAML.__squirrelops_vaulted__in place of each vaulted value so hydration knows which fields to fetch without the vault keeping an index. The marker is never stored as a secret; a marker with nothing behind it is dropped rather than passed to a handler.retries: 3) are settings, not credentials, and stay in the YAML. The API boundary's redaction of them is unchanged.Tests
Red first, then green: marker on strip and nothing secret left in the clean copy; a future
smtp_passwordround-trips through hydrate, strip, reload; legacy YAML without the field still hydrateswebhook_url; the marker itself is never stored; shared allow-list identity. Two existing strip assertions moved from "key absent" to "key holds the marker". Full sensor suite: 2614 passed, 6 skipped; ruff clean.SECURITY_MODEL "Stored secrets" updated. Control surface only.