Skip to content

fix(cdc): repair default internal principal without relaxing authorization - #29635

Merged
XuPeng-SH merged 1 commit into
4.2-devfrom
fix/42-cdc-internal-identity-20261006
Oct 5, 2026
Merged

XuPeng-SH merged 1 commit into
4.2-devfrom
fix/42-cdc-internal-identity-20261006

Conversation

@LeftHandCold

Copy link
Copy Markdown
Collaborator

Summary

Fixes #29634.

Repair the unnamed system principal produced by frontend.InternalExecutor on 4.2-dev, without weakening the current-principal authorization introduced in #29431.

CDC constructs an executor with empty session overrides and the sys account. It previously supplied numeric (account,user,role)=(0,0,0) but the synthetic username internal; the catalog's reserved user 0 is root. The new strict authorization therefore rejected both the task-definition SELECT and its failed-state UPDATE, leaving an apparently running task with no downstream data.

Change and security boundaries

  • After both override layers, normalize only unnamed sys/root/moadmin (0,0,0) to the real catalog principal.
  • Preserve explicit usernames/SQL-task definers, non-system tenants, nonzero users and nonzero selected roles. They do not borrow the default system administrator's name or privileges.
  • Leave current-user matching, account-generation/retirement checks, selected-role membership and all external authorization unchanged. Do not set Session.isInternal or bypass checks for the literal username internal.
  • Preserve default internal SQL provenance with a source-only UserInput flag. Keep isInternalInput unchanged, so SQL-mode staging, diagnostics and query-ID semantics are not altered. Carry the provenance through the existing statement copies and ANALYZE's derived query.
  • No new catalog lookup, background worker, timer, cache or retained state on the default query path.

Main currently does not exhibit the same failure because its sys/moadmin authorization differs; it still has the synthetic default name. This PR intentionally targets the 4.2 regression rather than deleting its security protections or changing Main.

Regression coverage

  • Default constructor identity, both numeric override layers, explicit definer/name precedence, non-system/nonzero-user/public/ordinary-role negatives.
  • Real catalog-validation calls: present, missing and failing lookups; a source marker or an internal/root name is not an authorization bypass.
  • Statement split/rewrite and executed ANALYZE provenance, with both internal-execution exemption flags remaining false.
  • Existing authenticated 3-CN fixture: default internal SELECT/INSERT succeeds; explicit mismatched username and public-role administrator operations are denied, with no denied-write side effects. Cleanup is registered before CREATE and has an independent 30-second bound.
  • Existing [Bug]: RESTORE ACCOUNT fails on legacy CHECK metadata and drops table privileges #29399 SQL-task definer, role-revocation, account-restore and PITR authorization regressions remain passing.

Local validation on host 50

  • RED: focused default-principal tests fail on the unmodified 4.2 head.
  • RED: freshly built unmodified 4.2 service reproduces the actual CDC task SELECT rejection and failed-state UPDATE rejection; SHOW remains running and the sink is absent.
  • GREEN: complete pkg/frontend and pkg/cdc tests.
  • GREEN: targeted frontend -race covering identity/active-role authorization and derived execution.
  • GREEN: pkg/tests/issues default-system consumer plus all existing TestIssue29399* authentication tests on the real shared 3-CN fixture.
  • GREEN: final, independently built patched binary repeats three-row MO-to-MO CDC initial sync, UPDATE/DELETE, PAUSE state persistence and RESUME followed by a new row; source/sink rows agree and checkpoint advances. This is actual CDC startup/data/state-path validation, not just mocked executor results.
  • go vet, diff/format checks and changed-line SCA are run locally; GitHub CI is reported separately and is not implied by local success.

Evidence is retained under /tmp/mo-cdc-internal-identity-20261006.UTtsLUAl and linked from the issue. No existing regression/TKE cluster was changed, and no runner/workflow changes are part of this patch.

Validation limits

The real CDC fixture exercises normal state transitions, not an injected failed-state transition; the unfixed failed UPDATE has direct server-log evidence, and the repaired default executor's read/write authorization is covered independently. Only system-account contexts used by actual CDC are exercised through SQL; no-account-context behavior is limited to constructor tests.

The standalone launch process can take longer to stop after successful CDC activity: CN lockservice may retry an already stopped TN. The harness treats SQL resource cleanup, exact PID cleanup and graceful process shutdown as separate results, and does not declare a forced stop a graceful-shutdown PASS. This PR does not alter launch/lockservice shutdown code. No test process or listener is left running.

@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@XuPeng-SH XuPeng-SH 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.

Deep review of 1bc7cb587cc2a7c9c0f615fdd15bed01a289ec01 against 4.2-dev@5c4590a55d77c93cde687ab824e9238ddce4d9c1: APPROVE — no verified blocking findings.

The fix belongs at the existing internal-session producer. Both override layers are applied before normalizing only the unnamed final (account,user,role)=(0,0,0) to the catalog's reserved sys/root/moadmin principal. Explicit SQL-task definers, mismatched names and other selected roles continue through the existing binding and current-catalog authorization. This closes the common cause of CDC's task-definition read and failed-state write rejection; neither Session.isInternal nor internal-AST authorization is enabled.

The separate request-local SQL-source flag is justified: authenticated identity and statement origin are different contracts, and explicit root execution must remain distinguishable from the default internal producer. Statement copies/rewrite preserve the flag, ANALYZE carries it into its derived query, and the existing SQL-mode/diagnostic/query-ID execution flags retain their semantics. No source marker provides an authorization exemption. No new catalog lookup, worker, cache or persistent state is added; the extra work is bounded identity checks and assignments. No production performance improvement is claimed.

Independent reviewer QA passed on this exact head using a temporary overlay and the existing authenticated 3-CN fixture, with Go 1.26.4 darwin/arm64, freshly built branch-native artifacts, GOMAXPROCS=2 and serial package/test execution:

  • A conditional running-to-failed UPDATE through public ExecWithStatus changes exactly one row; retry changes zero rows, with literal stored-state/error checks.
  • Explicit root with the public role is denied both SELECT and UPDATE. This challenges role enforcement with a valid catalog username, beyond denial of the synthetic internal name.
  • Numeric command overrides cannot replace an explicit mismatched base username; denied writes have no side effects.
  • A cancelled write has no side effects, and a subsequent call through the same executor successfully updates the row.

The probe completed with zero failures/skips (one parent and three subtests; package 15.361s, exit 0). It validates the failed-state SQL/authorization pattern, not an injected failure inside the CDC startup state machine. The author's issue evidence supplies the actual CDC RED/GREEN initial copy, incremental DML, PAUSE/RESUME and advancing-checkpoint validation, plus full frontend/CDC and retained #29399 security checks. Exact-head required CI, UT, SCA, coverage and BVT are successful. The tracked review worktree is clean and git diff --check passes.

All six changed files and their ownership/consumer paths were reviewed. The tests extend existing fixtures and cover different identity, authorization, provenance and cleanup contracts. Separate increments are implementation +30/-4 (net +26), tests +342/-2 (net +340), documentation unchanged. There are no prior human review comments/change requests on this PR left unresolved; the linked issue's evidence and declared limitations were accounted for. No subagents were used.

CI exception: Iceberg E2E Local failed while Docker was pulling MinIO: unauthorized: access to the requested resource is not authorized. dev-up-minio-local failed before E2E setup completed. No workflow/container setup changes are in this patch, and this job is not counted as a passing E2E result. The separate CI Required check is green.

This branch was successfully deployed

1 active deployment
ci — 1bc7cb58 Deployed Oct 6, 2026 by XuPeng-SH
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/M Denotes a PR that changes [100,499] lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants