feat: add denies config so object-level DENY survives a rebuild - #802
Open
Benjamin-Knight wants to merge 1 commit into
Open
feat: add denies config so object-level DENY survives a rebuild#802Benjamin-Knight wants to merge 1 commit into
denies config so object-level DENY survives a rebuild#802Benjamin-Knight wants to merge 1 commit into
Conversation
A SQL Server object-level DENY is stored against object_id, so dbt
discards it on every drop-and-recreate (every run for a view). The DENY
is the only way to carve an exception out of a schema-level GRANT, so
losing it silently leaves a fail-open posture: the broad grant persists,
its exceptions evaporate, and no run reports it.
Add a model-level `denies` config, shaped like `grants`
({privilege: [principals]}), that re-applies object-level DENYs after
each build, diffed against sys.database_permissions — mirroring how
`masks` re-applies Dynamic Data Masking. Emits DENY for
configured-not-present and REVOKE for present-not-configured; a
converged, persisted relation issues no DDL.
- Pure resolve/diff logic in sqlserver_deny.py (unit-tested), wired via
@available resolve_denies / deny_changes and a `denies` config
registered with MergeBehavior.Update.
- apply_denies macros; call sites in table/incremental/snapshot and, new
vs masks, view — a view is a valid securable and is recreated every
run, where a DENY is lost most often.
- Absent principal is warned-and-skipped; an unsupported privilege is
warned-and-skipped too (never fails the run); grant∩deny overlap warns.
- No-op on non-SQL-Server adapters. Existing grants/masks unchanged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Resolve #806
A SQL Server object-level DENY is stored against object_id, so dbt discards it on every drop-and-recreate (every run for a view). The DENY is the only way to carve an exception out of a schema-level GRANT, so losing it silently leaves a fail-open posture: the broad grant persists, its exceptions evaporate, and no run reports it.
Add a model-level
deniesconfig, shaped likegrants({privilege: [principals]}), that re-applies object-level DENYs after each build, diffed against sys.database_permissions — mirroring howmasksre-applies Dynamic Data Masking. Emits DENY for configured-not-present and REVOKE for present-not-configured; a converged, persisted relation issues no DDL.deniesconfig registered with MergeBehavior.Update.