Skip to content

ddl,privilege,parser: add masking policy dynamic privileges and error codes - #69107

Open
tiancaiamao wants to merge 5 commits into
pingcap:masterfrom
tiancaiamao:pr/phase10-priv-errors
Open

tiancaiamao wants to merge 5 commits into
pingcap:masterfrom
tiancaiamao:pr/phase10-priv-errors

Conversation

@tiancaiamao

@tiancaiamao tiancaiamao commented Jun 10, 2026 •

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: ref #65744

Problem Summary: Masking policy DDL operations had no privilege checks. Any user with table-level ALTER privilege could create/drop/modify masking policies. Generic errors.Errorf were used instead of proper error codes.

What is changed and how it works?

  1. Dynamic privileges — Register CREATE MASKING POLICY, ALTER MASKING POLICY, DROP MASKING POLICY as dynamic privileges in pkg/privilege/privileges/privileges.go.

  2. Privilege enforcement — Add requireMaskingPolicyDynamicPrivilege() helper in pkg/ddl/executor.go and call it at all 6 masking policy executor entry points:

    • CreateMaskingPolicy → CREATE MASKING POLICY
    • AddMaskingPolicy → CREATE MASKING POLICY
    • AlterTableMaskingPolicyState → ALTER MASKING POLICY
    • DropMaskingPolicy → DROP MASKING POLICY
    • ModifyMaskingPolicyExpression → ALTER MASKING POLICY
    • ModifyMaskingPolicyRestrictOn → ALTER MASKING POLICY
  3. Error codes — Replace errors.Errorf("masking policy ...") with dbterror.ErrMaskingPolicyExists / dbterror.ErrMaskingPolicyNotExists in executor and worker layers.

  4. Parser — Add GRANT/REVOKE parsing rules for unquoted CREATE MASKING POLICY, ALTER MASKING POLICY, DROP MASKING POLICY in pkg/parser/parser.y.

  5. Tests — Add privilege isolation integration tests.

Check List

Tests

  • Unit test
  • Integration test

Side effects

  • SHOW PRIVILEGES output updated (3 new dynamic privilege rows)

Summary by CodeRabbit

  • New Features

    • Enforced dynamic privileges for masking policy create/alter/drop and added the corresponding privilege names to the privileges listing.
  • Bug Fixes

    • Standardized typed masking-policy “already exists” and “not exists” errors across create/alter/drop flows.
    • Improved masking-policy access checks, including required table-level privileges when available.
  • Tests

    • Added an integration test covering masking-policy dynamic privilege enforcement and updated expected outputs accordingly.

… codes

- Register CREATE/ALTER/DROP MASKING POLICY as dynamic privileges
- Add privilege checks in all masking policy executor entry points
- Replace generic errors with ErrMaskingPolicyExists/ErrMaskingPolicyNotExists
- Support unquoted masking policy dynamic privileges in GRANT/REVOKE syntax
- Add integration tests for masking policy privilege isolation
@ti-chi-bot

ti-chi-bot Bot commented Jun 10, 2026

Copy link
Copy Markdown

Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our release note process to remove it.

Details

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.

@ti-chi-bot ti-chi-bot Bot added do-not-merge/needs-triage-completed do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. labels Jun 10, 2026
@pantheon-ai

pantheon-ai Bot commented Jun 10, 2026 •

Copy link
Copy Markdown

@tiancaiamao I've received your pull request and will start the review. I'll conduct a thorough review covering code quality, potential issues, and implementation details.

⏳ This process typically takes 10-30 minutes depending on the complexity of the changes.

ℹ️ Learn more details on Pantheon AI.

@ti-chi-bot ti-chi-bot Bot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Jun 10, 2026
@tiprow

tiprow Bot commented Jun 10, 2026

Copy link
Copy Markdown

Hi @tiancaiamao. Thanks for your PR.

PRs from untrusted users cannot be marked as trusted with /ok-to-test in this repo meaning untrusted PR authors can never trigger tests themselves. Collaborators can still trigger tests on the PR using /test all.

I understand the commands that are listed here.

Details

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.

@coderabbitai

coderabbitai Bot commented Jun 10, 2026 •

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 1b39bd11-c0d2-4982-a685-6ba15c0d1f79

📥 Commits

Reviewing files that changed from the base of the PR and between e92c594 and df2264e.

📒 Files selected for processing (3)
  • pkg/ddl/executor.go
  • tests/integrationtest/r/privilege/privileges.result
  • tests/integrationtest/t/privilege/privileges.test
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/integrationtest/t/privilege/privileges.test
  • tests/integrationtest/r/privilege/privileges.result

📝 Walkthrough

Walkthrough

Registers CREATE/ALTER/DROP MASKING POLICY as dynamic privileges with typed error codes, extends the parser to recognize these privilege forms, implements dynamic privilege verification in masking-policy DDL operations via a shared helper, standardizes masking-policy existence/uniqueness error handling with typed variables, and validates enforcement through integration tests.

Changes

Masking Policy Dynamic Privilege Enforcement

Layer / File(s) Summary
Error types, privilege registration, and parser updates
errors.toml, pkg/util/dbterror/ddl_terror.go, pkg/privilege/privileges/privileges.go, pkg/parser/parser.y, tests/integrationtest/r/executor/executor.result
Add ddl:8268/ddl:8269 error entries and export ErrMaskingPolicyExists/ErrMaskingPolicyNotExists; register CREATE MASKING POLICY, ALTER MASKING POLICY, DROP MASKING POLICY as built-in dynamic privileges; extend RoleOrPrivElem grammar production to recognize masking-policy privilege forms; update show privileges expected output with new privilege IDs 3220–3222.
Dynamic privilege verification helper
pkg/ddl/executor.go
Introduce requireMaskingPolicyDynamicPrivilege(ctx, dynamicPriv) that uses the privilege manager to run RequestDynamicVerification; returns ErrSpecificAccessDenied on denial or nil when permitted/no manager.
DDL operations with enforcement and error standardization
pkg/ddl/executor.go, pkg/ddl/masking_policy.go
Apply dynamic privilege checks (via helper) to CreateMaskingPolicy, AddMaskingPolicy, AlterTableMaskingPolicyState, DropMaskingPolicy, ModifyMaskingPolicyExpression, and ModifyMaskingPolicyRestrictOn; add table-level mysql.AlterPriv requirement in CreateMaskingPolicy; replace string-formatted "not exists" and "already exists" errors with typed dbterror variables in DDL and policy-creation flows.
Integration tests and expected outputs
tests/integrationtest/t/privilege/privileges.test, tests/integrationtest/r/privilege/privileges.result
Add TestMaskingPolicyDynamicPriv with multi-user privilege scenarios (creator, alter, drop, none, and combined roles) that verify permission failures when lacking masking-policy privileges and successes when permitted; update expected test results to reflect privilege checks and error codes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Suggested labels

release-note, size/L, sig/planner

Suggested reviewers

  • bb7133
  • qw4990
  • fzzf678

Poem

🐰 I hopped through code and checked each gate,
New CREATE, ALTER, DROP now regulate,
Typed errors tidy every case,
Dynamic checks protect the masking place,
A gentle nod from this reviewing rabbit. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main changes: adding masking policy dynamic privileges and error codes across ddl, privilege, and parser packages.
Description check ✅ Passed The description includes all required template sections: problem statement with issue reference, detailed explanation of what changed and how it works, and a completed checklist confirming integration and unit tests were added.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

Command failed


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/ddl/executor.go (1)

6478-6522: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Require ALTER MASKING POLICY for CREATE OR REPLACE.

Line 6517 switches this path to replace semantics, and Line 6810 forwards ReplaceOnExist, so this statement can overwrite an existing masking policy after only passing the CREATE MASKING POLICY check at Line 6482. That gives a create-only user a way to mutate an existing policy. Require ALTER MASKING POLICY too when stmt.OrReplace is set; doing it unconditionally avoids a TOCTOU gap between precheck and job execution.

Suggested fix
  if stmt.OrReplace && stmt.IfNotExists {
  	return dbterror.ErrWrongUsage.GenWithStackByArgs("OR REPLACE", "IF NOT EXISTS")
  }
  if err := requireMaskingPolicyDynamicPrivilege(ctx, "CREATE MASKING POLICY"); err != nil {
  	return err
  }
+ if stmt.OrReplace {
+ 	if err := requireMaskingPolicyDynamicPrivilege(ctx, "ALTER MASKING POLICY"); err != nil {
+ 		return err
+ 	}
+ }

Also applies to: 6808-6811

🤖 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/ddl/executor.go` around lines 6478 - 6522, The CreateMaskingPolicy path
currently only calls requireMaskingPolicyDynamicPrivilege("CREATE MASKING
POLICY") which allows a user with create-only rights to use stmt.OrReplace to
overwrite existing policies; update CreateMaskingPolicy so that when
stmt.OrReplace is true it also requires the ALTER MASKING POLICY privilege (call
requireMaskingPolicyDynamicPrivilege with "ALTER MASKING POLICY") before
proceeding, and perform this check unconditionally in the pre-check section
(before calling createMaskingPolicyWithInfo and before determining
onExist/OnExistReplace) to avoid any TOCTOU gap between privilege verification
and job execution.
🤖 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.

Outside diff comments:
In `@pkg/ddl/executor.go`:
- Around line 6478-6522: The CreateMaskingPolicy path currently only calls
requireMaskingPolicyDynamicPrivilege("CREATE MASKING POLICY") which allows a
user with create-only rights to use stmt.OrReplace to overwrite existing
policies; update CreateMaskingPolicy so that when stmt.OrReplace is true it also
requires the ALTER MASKING POLICY privilege (call
requireMaskingPolicyDynamicPrivilege with "ALTER MASKING POLICY") before
proceeding, and perform this check unconditionally in the pre-check section
(before calling createMaskingPolicyWithInfo and before determining
onExist/OnExistReplace) to avoid any TOCTOU gap between privilege verification
and job execution.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 3e354e14-556a-4213-aebf-c0e44784f622

📥 Commits

Reviewing files that changed from the base of the PR and between e370684 and a0fdfd5.

📒 Files selected for processing (8)
  • pkg/ddl/executor.go
  • pkg/ddl/masking_policy.go
  • pkg/parser/parser.go
  • pkg/parser/parser.y
  • pkg/privilege/privileges/privileges.go
  • pkg/util/dbterror/ddl_terror.go
  • tests/integrationtest/r/executor/executor.result
  • tests/integrationtest/t/privilege/privileges.test

@ti-chi-bot

ti-chi-bot Bot commented Jun 10, 2026

Copy link
Copy Markdown

Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our release note process to remove it.

Details

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.

@ti-chi-bot ti-chi-bot Bot added do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. do-not-merge/needs-tests-checked labels Jun 10, 2026
@codecov

codecov Bot commented Jun 10, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 54.16667% with 22 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.4523%. Comparing base (e370684) to head (df2264e).
⚠️ Report is 272 commits behind head on master.

Additional details and impacted files
@@               Coverage Diff                @@
##             master     #69107        +/-   ##
================================================
+ Coverage   76.3235%   76.4523%   +0.1287%     
================================================
  Files          2041       2059        +18     
  Lines        562593     580729     +18136     
================================================
+ Hits         429391     443981     +14590     
- Misses       132291     134319      +2028     
- Partials        911       2429      +1518     
Flag Coverage Δ
integration 46.1616% <54.1666%> (+6.4418%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
dumpling 60.4610% <ø> (ø)
parser ∅ <ø> (∅)
br 65.0613% <ø> (+2.2714%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread pkg/ddl/executor.go
if stmt.OrReplace && stmt.IfNotExists {
return dbterror.ErrWrongUsage.GenWithStackByArgs("OR REPLACE", "IF NOT EXISTS")
}
if err := requireMaskingPolicyDynamicPrivilege(ctx, "CREATE MASKING POLICY"); err != nil {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CREATE OR REPLACE only checks CREATE MASKING POLICY. It should also require ALTER MASKING POLICY for replacement.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is by design.
ALTER MASKING POLICY is not used for alter the masking policy's name.
It's changing the value of a masking policy (enable or disable, set a new expression, change RESTRICT ON etc)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename a masking policy becomes recreate one, and it requires CREATE MASKING POLICY

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. That make sense.

drop table if exists privilege__privileges.mask_t;
create table privilege__privileges.mask_t (c char(10));
CREATE USER mask_creator, mask_alter, mask_drop, mask_none;
GRANT ALTER ON privilege__privileges.mask_t TO mask_creator;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CREATE MASKING POLICY still misses table ALTER permission. A user can add a policy without table ALTER.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@ti-chi-bot

ti-chi-bot Bot commented Jun 15, 2026

Copy link
Copy Markdown

[FORMAT CHECKER NOTIFICATION]

Notice: To remove the do-not-merge/needs-tests-checked label, please finished the tests then check the finished items in description.

For example:

Tests <!-- At least one of them must be included. -->

- [x] Unit test
- [ ] Integration test
- [ ] Manual test (add detailed scripts or steps below)
- [ ] No code

‼️ Must keep the HTML comments <!-- At least one of them must be included. -->

📖 For more info, you can check the "Contribute Code" section in the development guide.

@tiancaiamao

Copy link
Copy Markdown
Contributor Author

/retest

@tiprow

tiprow Bot commented Jun 15, 2026

Copy link
Copy Markdown

@tiancaiamao: PRs from untrusted users cannot be marked as trusted with /ok-to-test in this repo meaning untrusted PR authors can never trigger tests themselves. Collaborators can still trigger tests on the PR using /test.

Details

In response to this:

/retest

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.

@tiancaiamao
tiancaiamao requested a review from expxiaoli June 16, 2026 01:28

@expxiaoli expxiaoli left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@ti-chi-bot

ti-chi-bot Bot commented Jun 16, 2026

Copy link
Copy Markdown

@expxiaoli: adding LGTM is restricted to approvers and reviewers in OWNERS files.

Details

In response to this:

LGTM

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.

@expxiaoli expxiaoli left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@ti-chi-bot

ti-chi-bot Bot commented Aug 17, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: expxiaoli
Once this PR has been reviewed and has the lgtm label, please assign benjamin2037, terry1purcell for approval. For more information see the Code Review Process.
Please ensure that each of them provides their approval before proceeding.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@ti-chi-bot ti-chi-bot Bot added the needs-1-more-lgtm Indicates a PR needs 1 more LGTM. label Aug 17, 2026
@ti-chi-bot

ti-chi-bot Bot commented Aug 17, 2026

Copy link
Copy Markdown

[LGTM Timeline notifier]

Timeline:

  • 2026-08-17 06:42:57.480689389 +0000 UTC m=+3633563.516784455: ☑️ agreed by expxiaoli.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do-not-merge/needs-tests-checked do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. needs-1-more-lgtm Indicates a PR needs 1 more LGTM. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants