Repository navigation
Refuse a schema default that holds a password, and never print one (BL-209) - #98
Merged
Merged
Conversation
…rint one (BL-209) Loading a schema now raises CredentialDefaultError when a defaultValue holds a credential (a password in a URL or connection string), whatever `secret` says: the same gate as BL-001's, at the same load points, also for an inherited default and a per-service override. The error names the field and the fix, never the value. value_embeds_credential moves to schema_types so the importer and the gate share one rule. Two leaks of the same invariant, fixed here: - `scan --staged` (the pre-commit hook) skipped a schema that failed to load and passed; it now fails closed when the schema holds a secret, and still skips an unrelated broken schema. - `schema diff` and `check --since` printed both values of a changed default from history; a secret's or a credential's default change is now reported without values. Fixes #96. Marks #94 (BL-208) merged.
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.
Fixes #96
In one line: a schema whose
defaultValueholds a password (one written by a pre-#94init, or by hand) now fails to load with a message naming the field. The pre-commit check blocks it, andschema diffnever prints it.Problem (BL-209, P1)
#94 stopped
initfrom writing credentials into the schema, but projects that already ran it may have one committed. A schema withdefaultValue = "redis://:password@cache"passedscan, the pre-commit hook andcheck.Design (maintainer decision on #96: option 1)
CredentialDefaultErroris raised at the same two full-schema load points as BL-001's secret-default gate, whateversecretsays. It also covers an inherited (extends) default and a per-service override (schema_scope). The message names the field, how to fix it (remove the default,secret = true) and to rotate the password if it was committed. It never includes the value.value_embeds_credentialmoves from the importer toschema_types, so the importer (init writes a password from a URL into the committed schema as a defaultValue (BL-208) #94) and the gate share it..env.example,explain) viaschema_types.default_must_not_render.Found and fixed in the same change (same invariant)
scan --stagedskipped any schema that failed to load and passed, so a schema refused for holding a secret was committable. It now fails closed onCredentialDefaultErrorandSecretDefaultConflictError. An unrelated broken schema is still skipped as before, so a half-edited schema in one service doesn't block commits in another.schema diffandcheck --sinceprinted both values of a changed default from history.detail: {before: null, after: null, redacted: true}.Alternatives
doctor/checkwarning without failing the load (option 2): rejected.scanrule (option 3): left to Gitleaks and GitHub push protection (§14).Security
Invariant: a secret value must never enter an output representation (an error, JSON, a diff, a generated file). The tests exercise the class.
Compatibility
default_changedaddsredacted: trueand nullsbefore/after.Tests
envshield/tests/test_credential_default_gate.py(58), covering every credential form from init writes a password from a URL into the committed schema as a defaultValue (BL-208) #94's tests through:secret = falseand absent),extends, a per-service override;check(human,--json,--code-only),doctor,schema sync(writes no.env.example),explain,generate,scan --staged;schema diff(library, and the CLI on the fixing commit).ruff checkandruff format --checkclean.On a real repository
The cal.com trial clone, with a pre-fix leak committed (
DATABASE_URLholding a password):check,doctor,schema sync,explainandscan --stagedall exit 1 namingDATABASE_URL, and none prints the password.check --since HEAD --code-onlypasses.Product / market impact
Table stakes: "secret values never leave the place they belong" (§1). It closes the gap #94 left for existing projects.
🤖 Generated with Claude Code
https://claude.ai/code/session_01376EvgPvifpHL8LP5BYoPc