sem: drive Starter SQL restrictions through SEM v2 config#67945
sem: drive Starter SQL restrictions through SEM v2 config#67945AmoebaProtozoa wants to merge 1 commit into
Conversation
|
Skipping CI for Draft Pull Request. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds a concurrency-safe strict SEM flag, implements strict Starter Edition Mode checks for statements and optimizer hints, integrates strict checks into planner and session (pipelined DML), wires strict enabling at server startup, and adds unit/integration tests and BUILD dependency updates. ChangesStrict SEM Feature Implementation
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Hi @AmoebaProtozoa. Thanks for your PR. PRs from untrusted users cannot be marked as trusted with I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
Review failed due to infrastructure/execution failure after retries. Please re-trigger review. ℹ️ Learn more details on Pantheon AI. |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
pkg/planner/optimize.go (1)
233-244:⚠️ Potential issue | 🟡 MinorStripped-hint warnings may suppress the later "hints ignored, using bindSQL" notice.
originStmtHintsis now parsed from the already-filtered hint list. If strict SEM strips every user hint,hint.ParseStmtHintswill seelen(hints) == 0and setQueryHasHints = false, so the check at line 351 (if originStmtHints.QueryHasHints { ... "The system ignores the hints in the current query ..." }) will silently skip that note for queries whose only hints happened to be restricted. The user still gets a per-hint restricted warning, so this is minor, but worth a conscious decision: either computeQueryHasHintsfrom the pre-filter slice, or accept the reduced note.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/planner/optimize.go` around lines 233 - 244, The current code parses originStmtHints from the already-filtered tableHints so QueryHasHints can become false if all user hints were stripped; to fix, preserve or inspect the pre-filter hint slice when computing QueryHasHints: call hint.ParseStmtHints using the original extracted hints (before filterRestrictedHints) or, after parsing the filtered originStmtHints, explicitly set originStmtHints.QueryHasHints = len(originalExtractedHints) > 0 (where originalExtractedHints is the slice returned by hint.ExtractTableHintsFromStmtNode before filterRestrictedHints). Ensure you still append restrictedHintWarns to sessVars.StmtCtx and then assign sessVars.StmtCtx.StmtHints = originStmtHints so downstream checks (e.g., the QueryHasHints check) reflect whether the user actually provided hints before filtering.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@cmd/tidb-server/main.go`:
- Around line 1165-1191: The current setupSEM enables classic sem (sem.Enable())
when SEMConfig is empty which leaves semv2 global state nil and makes
EnableStrictSEM ineffective; change setupSEM so EnableStrictSEM requires
cfg.Security.SEMConfig to be non-empty: if cfg.Security.SEMConfig == "" and
cfg.Security.EnableStrictSEM is true, log a clear warning (via
logutil.BgLogger().Warn) that strict SEM requires a semv2 config and
ignore/disable strict mode, then continue with classic sem; only call
semv2.EnableStrict() after successfully calling
semv2.Enable(cfg.Security.SEMConfig) (i.e., ensure semv2.Enable returned no
error and global semv2 state is initialized before calling semv2.EnableStrict())
and do not call semv2.EnableStrict() when semv2 was not enabled.
In `@pkg/planner/core/planbuilder.go`:
- Around line 6382-6389: The strict SEM check (semv2.IsStrictEnabled()) is being
executed before verifying SEM is enabled, causing strict mode to apply even when
SEM is disabled; update the logic so strict checks only run when
semv2.IsEnabled() is true (e.g., wrap the semv2.IsStrictEnabled() /
semv2.IsRestrictedStatement(stmt) block inside an if semv2.IsEnabled() { ... }
or change it to if semv2.IsEnabled() && semv2.IsStrictEnabled() { if err :=
semv2.IsRestrictedStatement(stmt); err != nil { return err } }).
In `@pkg/session/session.go`:
- Around line 5521-5524: Add a SQL-level test that enables strict SEM via
semv2.EnableStrict(), sets tidb_dml_type='bulk', executes a DML (e.g.,
INSERT/UPDATE) and asserts the presence of the warning text "Pipelined DML is
not supported in this deployment. Fallback to standard mode" using SHOW
WARNINGS; the test should exercise the usePipelinedDmlOrWarn code path (which
calls semv2.IsStrictEnabled()) and then disable strict mode after the test to
avoid global state leakage. Ensure the test file mirrors existing pipelined-DML
tests (e.g., pipelineddml_test.go) for setup/teardown and uses the same
assertion pattern for SHOW WARNINGS.
In `@pkg/util/sem/v2/restricted_hint.go`:
- Around line 30-31: The "resource_group" branch currently unconditionally
returns an error referencing strict SEM; update the branch in restricted_hint.go
(the case for "resource_group" in the switch handling hints) to follow the same
SEM-aware pattern as the other cases: either check IsStrictEnabled() (or the
same sysvar visibility helper used by
memory_quota/read_consistent_replica/max_execution_time) and only return the
"not supported when strict SEM is enabled" error when strict SEM is active, or
change the error text to a SEM-agnostic message that does not mention strict
SEM; pick one approach and apply it in the "resource_group" case so behavior and
messaging match the other hint checks.
---
Outside diff comments:
In `@pkg/planner/optimize.go`:
- Around line 233-244: The current code parses originStmtHints from the
already-filtered tableHints so QueryHasHints can become false if all user hints
were stripped; to fix, preserve or inspect the pre-filter hint slice when
computing QueryHasHints: call hint.ParseStmtHints using the original extracted
hints (before filterRestrictedHints) or, after parsing the filtered
originStmtHints, explicitly set originStmtHints.QueryHasHints =
len(originalExtractedHints) > 0 (where originalExtractedHints is the slice
returned by hint.ExtractTableHintsFromStmtNode before filterRestrictedHints).
Ensure you still append restrictedHintWarns to sessVars.StmtCtx and then assign
sessVars.StmtCtx.StmtHints = originStmtHints so downstream checks (e.g., the
QueryHasHints check) reflect whether the user actually provided hints before
filtering.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: eded8646-e4a3-40db-a5f7-b6b1b77d1b34
📒 Files selected for processing (13)
cmd/tidb-server/main.gopkg/config/config.gopkg/planner/BUILD.bazelpkg/planner/core/planbuilder.gopkg/planner/optimize.gopkg/session/BUILD.bazelpkg/session/session.gopkg/util/sem/v2/BUILD.bazelpkg/util/sem/v2/restricted_hint.gopkg/util/sem/v2/restricted_hint_test.gopkg/util/sem/v2/restricted_statement.gopkg/util/sem/v2/restricted_statement_test.gopkg/util/sem/v2/strict.go
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #67945 +/- ##
================================================
- Coverage 76.3152% 75.2368% -1.0784%
================================================
Files 2041 2028 -13
Lines 563114 568087 +4973
================================================
- Hits 429742 427411 -2331
- Misses 132456 140633 +8177
+ Partials 916 43 -873
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
/retest |
|
@AmoebaProtozoa: PRs from untrusted users cannot be marked as trusted with DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
pkg/util/sem/v2/restricted_statement.go (1)
186-186: 💤 Low valueDead code:
AdminStmtcase is unreachable.
AdminStmtis already handled directly inIsRestrictedStatement(line 94-95) before reachingverifySimple. SinceAdminStmtis not in the case list at lines 102-108, this allowlist entry will never match.♻️ Remove unreachable case
case *ast.FlushStmt, *ast.BeginStmt, *ast.CommitStmt, *ast.SavepointStmt, *ast.ReleaseSavepointStmt, *ast.RollbackStmt, *ast.CreateUserStmt, *ast.AlterUserStmt, *ast.SetPwdStmt, *ast.SetSessionStatesStmt, *ast.KillStmt, *ast.BinlogStmt, *ast.DropStatsStmt, - *ast.AdminStmt, *ast.GrantStmt, *ast.RevokeStmt, *ast.NonTransactionalDMLStmt, *ast.UseStmt: return nil🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/util/sem/v2/restricted_statement.go` at line 186, The switch in verifySimple contains an unreachable AdminStmt case because IsRestrictedStatement already handles *ast.AdminStmt earlier; remove the AdminStmt entry from the case list in verifySimple (or from the allowlist used there) so the unreachable branch is deleted, leaving only the actually reachable statement types referenced in verifySimple and ensuring no dead-case remains.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@pkg/util/sem/v2/restricted_statement.go`:
- Around line 206-219: GrantRoleStmt and RevokeRoleStmt currently only check
Roles but must also block operations that target restricted users similar to
SetDefaultRoleStmt; update the handlers for GrantRoleStmt and RevokeRoleStmt to
iterate over s.Users and call isRestrictedUser on each entry, returning
notSupported with an appropriate message if any target user is restricted. Use
the existing symbols GrantRoleStmt, RevokeRoleStmt, Users, Roles and
isRestrictedUser to locate the code and implement the additional check so
GRANT/REVOKE cannot modify restricted accounts' role sets.
---
Nitpick comments:
In `@pkg/util/sem/v2/restricted_statement.go`:
- Line 186: The switch in verifySimple contains an unreachable AdminStmt case
because IsRestrictedStatement already handles *ast.AdminStmt earlier; remove the
AdminStmt entry from the case list in verifySimple (or from the allowlist used
there) so the unreachable branch is deleted, leaving only the actually reachable
statement types referenced in verifySimple and ensuring no dead-case remains.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 04cdc6d4-3420-4138-9a0a-66f7a686f0a3
📒 Files selected for processing (3)
pkg/util/sem/v2/restricted_statement.gopkg/util/sem/v2/restricted_statement_test.gotests/realtikvtest/pipelineddmltest/pipelineddml_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
- tests/realtikvtest/pipelineddmltest/pipelineddml_test.go
|
/rerun |
|
/retest |
|
@AmoebaProtozoa: PRs from untrusted users cannot be marked as trusted with DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
979019c to
7c5722d
Compare
Express the next-gen Starter SQL restrictions through the existing config-driven semv2 mechanism rather than a separate strict-mode layer. - Statement restrictions reuse the semv2 deny-list (restricted_sql.sql / restricted_sql.rule); add the exchange_partition rule for the only case ast.SEMCommand cannot tell apart from a plain ALTER TABLE. - restricted_users / restricted_roles protect managed identities from DROP USER, RENAME USER and role changes, ahead of the RESTRICTED_SQL_ADMIN bypass. - restricted_hints strips configured optimizer hints with a warning, optionally only while a guard variable is hidden or read-only. - Pipelined DML falls back to standard mode under the Starter deploy mode. Every semv2 addition is inert unless the SEM config enables it, so existing deployments keep their current behavior.
7c5722d to
be14e46
Compare
|
[FORMAT CHECKER NOTIFICATION] Notice: To remove the For example:
📖 For more info, you can check the "Contribute Code" section in the development guide. |
|
/retest |
|
@AmoebaProtozoa: PRs from untrusted users cannot be marked as trusted with DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
What problem does this PR solve?
Issue Number: ref #67765
Problem Summary:
The Starter deploy mode needs tighter SQL restrictions than stock TiDB: a set of
dangerous statements rejected outright, optimizer hints that would otherwise
sidestep SEM-hidden sysvars stripped, the managed admin accounts protected from
account/role changes, and pipelined DML disabled. Most of this is already
expressible through the existing config-driven SEM v2 mechanism, so this PR
extends SEM v2 with the few capabilities it was missing instead of adding a
parallel "strict" subsystem.
What changed and how does it work?
Every restriction is driven by the SEM v2 config (
security.sem-config) and isinert unless the config opts into it, so existing deployments are unaffected.
restricted_sqldeny-list (sqlmatched on
ast.SEMCommand(), plus namedrules).ast.SEMCommand()alreadydistinguishes every dangerous statement (BACKUP/RESTORE, placement policy,
resource group, FLASHBACK CLUSTER, SET CONFIG, SPLIT REGION, the SHOW/ADMIN
subtypes, ...), so the only new rule is
exchange_partitionforALTER TABLE ... EXCHANGE PARTITION, which shares the genericALTER TABLEcommand and cannot be matched by command string.
restricted_users/restricted_rolesprotect managed identities fromDROP/RENAME USERand role changes (CheckRestrictedUserStmt), enforcedin the planner ahead of the
RESTRICTED_SQL_ADMINbypass.restricted_hintsis a list of optimizer hint names stripped with a warning;a hint that overrides a system variable (e.g.
memory_quota) is stripped onlywhile that variable is SEM-hidden or read-only.
(
deploymode.IsStarter()), independent of SEM.Enforcement is gated by
semv2.IsEnabled()(anddeploymode.IsStarter()for thepipelined-DML fallback), so classic builds and non-Starter deployments keep their
current behavior.
Check List
Tests
Side effects
Documentation
Release note