pingcap / pingcap/tidb

column masking policy: dynamic privileges (CREATE/ALTER/DROP MASKING POLICY) are not implemented

Open
#67,221 2 comments 0 reactions 0 assignees View on GitHub
component/privilege may-affects-7.1 may-affects-7.5 may-affects-8.1 may-affects-8.5 severity/major type/bug
Dominant language
Go
Stars
40.5k
Forks
6.2k
PR merge metrics
PR metrics pending

Description

## Bug Report

Dynamic privileges for masking policy management (`CREATE MASKING POLICY`, `ALTER MASKING POLICY`, `DROP MASKING POLICY`) are documented and tested but **not actually implemented** in the codebase.

## Error Message

When attempting to grant the documented dynamic privileges:

\`\`\`sql
GRANT CREATE MASKING POLICY ON *.* TO 'security_admin'@'%';
\`\`\`

**Error:**
\`\`\`
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your TiDB version for the right syntax to use near 'MASKING POLICY ON *.* TO 'security_admin'@'%'' at line 1
\`\`\`

## Expected Behavior

According to the design document (`docs/design/2026-02-27-column-level-masking.md`), these dynamic privileges should be supported:

> ### Authorization model
>
> Administrative privileges:
> - `CREATE MASKING POLICY`
> - `ALTER MASKING POLICY`
> - `DROP MASKING POLICY`

The test file (`tests/integrationtest/t/privilege/column_masking_policy.test`) includes a comprehensive test case `IT-MASK-P0-011 TestColumnMaskPolicyDynamicPrivileges` that tests these privileges:

\`\`\`sql
GRANT `CREATE MASKING POLICY` ON *.* TO cmp_mask_creator;
GRANT `ALTER MASKING POLICY` ON *.* TO cmp_mask_alter;
GRANT `DROP MASKING POLICY` ON *.* TO cmp_mask_drop;
\`\`\`

## Actual Behavior

1. The `GRANT` statement fails with a syntax error - the privilege names are not recognized
2. The privileges are not registered in the system (verified by searching for `RegisterDynamicPrivilege` calls)
3. No privilege checks exist in the DDL executor code (`pkg/ddl/executor.go`)

## Root Cause Analysis

### Missing Dynamic Privilege Registration

The following code search reveals no registration of masking policy privileges:

\`\`\`bash
$ grep -rn "RegisterDynamicPrivilege.*MASKING" pkg/
# No results found
\`\`\`

Other dynamic privileges are registered in `pkg/session/bootstrap.go` or via plugins, but masking policy privileges are missing.

### Missing Privilege Checks

In `pkg/ddl/executor.go`:

\`\`\`go
func (e *executor) CreateMaskingPolicy(ctx sessionctx.Context, stmt *ast.CreateMaskingPolicyStmt) error {
// No call to ctx.GetSessionVars().RequestDynamicVerification("CREATE MASKING POLICY")
...
}

func (e *executor) AlterTableMaskingPolicy(...) error {
// No call to ctx.GetSessionVars().RequestDynamicVerification("ALTER MASKING POLICY")
...
}

func (e *executor) DropMaskingPolicy(...) error {
// No call to ctx.GetSessionVars().RequestDynamicVerification("DROP MASKING POLICY")
...
}
\`\`\`

## Impact

1. **Security**: Anyone with table-level `ALTER` privilege can create/modify/drop masking policies, bypassing the intended administrative privilege model
2. **Documentation mismatch**: Design docs and tests indicate these privileges should exist
3. **Test effectiveness**: Test `IT-MASK-P0-011` may not actually verify the intended behavior

## Verification Steps

1. Attempt to grant the privilege:
\`\`\`sql
GRANT CREATE MASKING POLICY ON *.* TO 'test_user'@'%';
\`\`\`
Expected: Success
Actual: ERROR 1064 syntax error

2. Check if privilege exists in system:
\`\`\`sql
SHOW PRIVILEGES;
\`\`\`
Expected: Should see `CREATE MASKING POLICY`, `ALTER MASKING POLICY`, `DROP MASKING POLICY`
Actual: Not present

## What Needs to be Fixed

1. Register the three dynamic privileges during system initialization
2. Add privilege verification in `CreateMaskingPolicy`, `AlterTableMaskingPolicy`, and `DropMaskingPolicy` functions
3. Ensure the test `IT-MASK-P0-011` actually validates the privilege checks

## Component

- `component/privilege`
- `component/ddl`

## Related Files

- Design: `docs/design/2026-02-27-column-level-masking.md`
- Test: `tests/integrationtest/t/privilege/column_masking_policy.test` (IT-MASK-P0-011)
- Implementation: `pkg/ddl/executor.go` (CreateMaskingPolicy, etc.)
- Privilege system: `pkg/privilege/privileges/privileges.go`

## Related Issues

- #67217: Policy name uniqueness test coverage
- #67218: CTE test coverage
- #67219: CREATE OR REPLACE test coverage

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.