feat(aliases): encrypt component alias values at rest#152
Open
uittenbroekrobbert wants to merge 1 commit into
Open
feat(aliases): encrypt component alias values at rest#152uittenbroekrobbert wants to merge 1 commit into
uittenbroekrobbert wants to merge 1 commit into
Conversation
…t AGE key Alias values can hold secrets (e.g. a password) but were stored in plaintext. Mirror the user-env-vars mechanism, per alias value: - read: decrypt alias values at deploy time in _collect_deployment_aliases and in the KeyValueConverter editor path. Plaintext values pass through unchanged, so existing files keep working with no schema migration. - write: encrypt each value on save via a new ComponentAliasesEncryptGenerator, the KeyValueConverter dict mode, and build_component_config. Already-encrypted values are skipped (idempotent, no ciphertext churn on unchanged aliases). Alias names stay readable; only values are encrypted. Existing plaintext aliases encrypt lazily on the next save. Decrypting before the cross-component conflict check also fixes a latent false-conflict on identical aliases (AGE ciphertext is non-deterministic).
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.
Why
Component
aliasesare stored in the project YAML, but their values were kept in plaintext. Aliases are meant to be\$VARtemplates, yet users paste literal secrets (e.g. database passwords) into them, so those secrets sat unencrypted in thezad-projectsrepo.This makes alias values behave exactly like
user-env-vars: encrypted at rest with the project AGE key, decrypted on use, with a plaintext fallback so nothing breaks.What
Read (decrypt, with plaintext fallback)
_collect_deployment_aliasesdecrypts each alias value at deploy time before categorization/substitution. Gated onis_age_encrypted, so plaintext passes through unchanged; the project key is decoded lazily (only when an encrypted value is present).KeyValueConverter._maybe_decryptnow recurses into the alias dict so the editor shows decrypted values.Write (encrypt on save — the three places
user-env-varsalready encrypts)ComponentAliasesEncryptGenerator(catch-all on save), registered after the AGE keypair generator.KeyValueConverter.writedict mode encrypts each value.build_component_config(create / add-component API) encrypts alias values.router_wizard._apply_literal_scalarsliteralizes alias AGE blocks for clean YAML block-scalar output.Alias names stay readable; only values are encrypted. Already-encrypted values are skipped (idempotent, no ciphertext churn).
No schema migration
Existing plaintext aliases keep resolving via the read fallback and encrypt lazily on the next save, exactly like
user-env-vars. Nothing to migrate.Behavioural notes
zad-projects— a one-time diff per project.Verification
ruff check/ruff format/pyrightclean; full pre-push unit suite green (3971 passed).