Skip to content

[DSIP-105][Worker] Mask sensitive parameter values in task logs - #18706

Open
det101 wants to merge 13 commits into
apache:devfrom
det101:feature-18588-worker-log-mask
Open

det101 wants to merge 13 commits into
apache:devfrom
det101:feature-18588-worker-log-mask

Conversation

@det101

@det101 det101 commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Was this PR generated or assisted by AI?

YES. The code changes (sensitive field rule validation, log masking refactoring) and tests were AI-assisted; the design decisions and review were human-driven.

Purpose of the pull request

The worker server prints sensitive parameter values (e.g. passwords, API keys) in its own log output, which is a security risk. This PR:

  1. Masks sensitive parameter values in the worker's own log output, uniformly via SensitiveDataConverter (no per-log-statement handling).
  2. Adds a sensitive field rule: a sensitive value must be at least 6 characters, enforced on both the web forms and the backend create/update paths.

Related issue: #18588

Brief change log

  • Worker log masking (uniform, via SensitiveDataConverter)

    • PhysicalTaskExecutor registers the task's sensitive plaintext values via SensitiveDataConverter.registerTaskSensitiveValues(taskInstanceId, prepareParamsMap) when the task context is initialized, and clears them via clearTaskSensitiveValues in finalizeTask (success / failure / kill), so values never leak across tasks.
    • SensitiveDataConverter (logback MessageConverter) masks both the static regex patterns (e.g. datasource password) and the per-task registered values, resolving the task from MDC.
    • Values shorter than MIN_SENSITIVE_LITERAL_LENGTH (6) are skipped to avoid over-masking common log text.
    • The task process's own output (stdout / K8s pod logs) is intentionally NOT masked — it is the task's own output; only logs printed by the worker server itself are masked.
    • No point-level changes at log statements: no injection of sensitive values into shell builders, no per-statement masking of the final script content or task context dump.
  • Sensitive field rule (min length 6)

    • PropertySensitiveUtils.SENSITIVE_FIELD_RULE is defined as a regex (.{6,}, i.e. at least 6 characters) so the rule can be extended later; findInvalidSensitiveField returns the first offending prop name (empty values and the ****** keep-original placeholder are skipped).
    • Backend: SensitivePropertyUtils.requireNoPlaceholder (create) and SensitivePropertyUtils.merge (update) reject a too-short sensitive value with ServiceException, covering both workflow global params and task local params.
    • Frontend: workflow global params (dag-save-modal.tsx) and task custom/local params (use-custom-params.ts) validate the value when the sensitive checkbox is checked; the input is marked red and the submission is blocked. i18n messages sensitive_value_invalid added (zh_CN / en_US).

Verify this pull request

This change added tests and can be verified as follows:

  • PropertySensitiveUtilsTest (task-api): length boundary covered — a 5-char sensitive value is rejected, a 6-char value passes; placeholder / empty values are skipped.
  • SensitivePropertyUtilsTest (api): create and update paths reject a too-short sensitive value and accept values satisfying the rule.
  • SensitiveDataConverterTest (task-api): per-task register / mask / clear behavior.
  • BaseLinuxShellInterceptorBuilderTest (task-api): final script content is written to the shell file as-is (only the logged content is masked by the converter).
  • Frontend: vue-tsc type check passes for the changed files.

Pull Request Notice

Pull Request Notice: https://github.com/apache/dolphinscheduler/blob/dev/docs/docs/en/contribute/join/pull-request.md

Compatibility note: saving a sensitive parameter whose value is shorter than 6 characters is now rejected (web form shows an error, backend returns an error). Existing stored values are not affected; the restriction only applies to new saves / updates. If this is considered an incompatible change, docs/docs/en/guide/upgrade/incompatible.md should be updated accordingly.

@det101 det101 changed the title [Feature-18588][Worker] Mask sensitive parameter values in task logs [DSIP-105][Worker] Mask sensitive parameter values in task logs Oct 15, 2026

@ruanwenjun ruanwenjun left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should only ensure that the content printed by the worker server itself does not contain sensitive information; there is no need to encrypt the output of the shell tasks themselves, as this should be handled by the shell itself.

det101 added a commit to det101/dolphinscheduler that referenced this pull request Oct 16, 2026
Task process output (shell stdout, K8s pod logs) is produced by the
user's own program which must hold the secrets in plaintext to work;
masking it rewrites legitimate output. Per review on apache#18706, only logs
printed by the worker server itself should be masked. Revert the
taskInstanceId MDC injection in AbstractCommandExecutor so process and
pod log lines are collected without per-task literal masks, matching
dev behavior.
@det101

det101 commented Oct 16, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @ruanwenjun, addressed. Reverted the taskInstanceId MDC injection in AbstractCommandExecutor — task process stdout and K8s pod logs are now collected unmasked, same as dev. Masking now applies only to logs printed by the worker server itself (task context dumps, plugin logs on the executor thread), where sensitive prepareParams plaintext would otherwise leak into worker logs.

@det101

det101 commented Oct 16, 2026

Copy link
Copy Markdown
Contributor Author

Verified end-to-end on a standalone instance (official 3.4.3 image + this branch's jars + rebuilt UI), with a SHELL task carrying secret_token (sensitive) and normal_msg (normal) prepareParams:

Log location Result
Task log: localParams JSON / Final Script Content value: "******" ✅
Task log: process output plaintext SuperSecretToken123 kept, per review intent ✅
Worker log: Initialized Task Context{...} dump (taskParams + prepareParamsMap) ******, MDC [TI-1] ✅
Normal params never masked, no over-masking ✅

During this E2E run I also found a pre-existing leak unrelated to this PR's changes: PhysicalTaskExecutorOperatorImpl (introduced in #16790) logged the whole TaskExecutorDispatchRequest on the RPC dispatch thread — before per-task masks are registered and without taskInstanceId MDC, so both masking mechanisms missed it. Fixed in 48c469e by logging only taskInstanceId and taskName; after the fix the worker log contains no sensitive plaintext outside the process-output forwarding.

Register per-task sensitive prepareParams at PhysicalTaskExecutor start and
clear on finalize; apply literal masks via SensitiveDataConverter using
taskInstanceId MDC on process and K8s pod log collection.
… literals

Register per-task sensitive values before super.initializeTaskContext so
worker logs of prepareParams are masked. Skip literals shorter than 3 and
apply longest-first replacement to reduce over-masking.
Task process output (shell stdout, K8s pod logs) is produced by the
user's own program which must hold the secrets in plaintext to work;
masking it rewrites legitimate output. Per review on apache#18706, only logs
printed by the worker server itself should be masked. Revert the
taskInstanceId MDC injection in AbstractCommandExecutor so process and
pod log lines are collected without per-task literal masks, matching
dev behavior.
Literals as short as 3 characters collide with common log text such as
timestamps and numeric IDs, over-masking unrelated worker log lines.
Raise the threshold to 6 to keep masking meaningful while preserving
log readability.
…logs

The Receive/Handle logs in PhysicalTaskExecutorOperatorImpl printed the
whole TaskExecutorDispatchRequest, whose TaskExecutionContext carries
sensitive prepareParams plaintext. These lines are logged on the RPC
dispatch thread before per-task masks are registered and without
taskInstanceId MDC, so they escaped both masking mechanisms. Log only
taskInstanceId and taskName instead, verified by standalone E2E.
@det101
det101 force-pushed the feature-18588-worker-log-mask branch from 48c469e to 3bcc56d Compare October 20, 2026 02:07
@det101
det101 requested a review from ruanwenjun October 20, 2026 02:07
det101 and others added 4 commits October 20, 2026 13:51
…rce sensitive field rule

- Mask sensitive prepareParams plaintext only at worker log points: the task
  context dump and the logged final shell script content; the shell file written
  to disk keeps the real values so the task can run
- Restore SensitiveDataConverter to static-regex only, drop the per-task value
  registry and MDC-based resolution
- Introduce SENSITIVE_FIELD_RULE as a regex (currently at least 6 characters) and
  enforce it on the web forms (task custom params and workflow global params,
  red + block submit) and on the backend save/update paths; empty values and the
  keep-original placeholder are not affected
@det101
det101 marked this pull request as draft October 21, 2026 07:44
@github-actions github-actions Bot added the UI ui and front end related label Oct 21, 2026
det101 and others added 4 commits October 21, 2026 15:55
…g, drop point-level masking

Log masking is now handled uniformly by SensitiveDataConverter (per-task
sensitive values registered and matched when logs are written), so the
point-level changes at log output sites are reverted:

- AbstractCommandExecutor: drop sensitiveValues injection into shell builders
- Shell builders: drop sensitiveValues plumbing and final-script log masking
- PhysicalTaskExecutor: restore SensitiveDataConverter register/clear, drop the
  point-masked task context dump helper
- PropertySensitiveUtils: keep only the sensitive field rule helpers, drop the
  log-only extract/mask string functions and their tests
@det101
det101 marked this pull request as ready for review October 22, 2026 03:37

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

backend test UI ui and front end related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants