Repository navigation
[v3-4-test] Mask CLI secrets in the audit log by parsed argument, not argv position (#72650) - #75144
Merged
Merged
Conversation
… argv position (#72650) * Mask CLI secrets in the audit log by parsed argument, not argv position _build_metrics recorded sys.argv into the audit log and masked the variables value by position, assuming the key and value were the final two arguments. Any supported trailing option displaces them: 'airflow variables set KEY VALUE --description TEXT' ends in '--description TEXT', so the value was written to Log.extra in clear. --description is the instance found, not the class -- the same is true of --serialize-json and of any option added later. Take the key and value from the parsed Namespace instead, and redact that value wherever it appears in the recorded command. Position no longer matters. --conn-extra was not masked at all. It is the field connection secrets live in, and it accepts nested JSON. It is now redacted alongside --conn-json, and both are walked recursively -- --conn-json previously masked only top-level keys, so a secret one level down was recorded in clear. A value that cannot be parsed as JSON is redacted whole, because these options carry connection material and a value that cannot be inspected is not safe to record. Both argparse spellings are handled. --conn-json, --conn-extra and --conn-uri were matched as standalone tokens only, so the equally valid --conn-json=VALUE form skipped redaction entirely and recorded the secret. --conn-uri had that gap before this change as well. Note for operators: this prevents new disclosures only. Existing Log.extra rows and backups retain values already written and should be redacted or expired, and any credentials exposed that way rotated. The seven new cases fail against unpatched sources. * Mask long-form password options on every CLI subcommand in the audit log --password and --conn-password name a password on every subcommand, including those contributed by providers (keycloak-auth-manager ... --password), but were only masked for users and connections. Mask the long spellings everywhere; keep -p limited to users and connections, as elsewhere it means --port or --exclude-providers. Generated-by: Claude Opus 5 * Mask CLI secrets by parsed value in every argument spelling Mask secrets supplied through any supported argument spelling in the recorded command line: abbreviated and attached options, repeated options, JSON (incl. conf) and URI values, and celery flower auth. Generated-by: Claude Opus 5 following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions * Mask secrets after grouped short flags and in task-params / env-vars Mask a parsed secret wherever it appears in a recorded token, which covers grouped short flags, and add tasks test -t/--task-params and --env-vars to the JSON options. Generated-by: Claude Opus 5 following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions * Limit in-token masking to whole values and short-option clusters Mask a parsed value only where it is a whole token or ends a single-dash short-option cluster, for plain, JSON and URI options alike, so a short value is not masked wherever its text happens to appear in the recorded command line. Generated-by: Claude Opus 5 following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions * Mask clustered, repeated-empty and double-scheme URI secrets in CLI audit log Generated-by: Claude Opus 5 * Only treat a URI as double-scheme when the host carries a protocol Generated-by: Claude Opus 5 * Match Connection's double-scheme parsing when masking URIs Generated-by: Claude Opus 5 * Walk short-option clusters by option arity and fail closed on any unparsed credentials Generated-by: Claude Opus 5 * Mask the whole URI when credentials cannot be located reliably Generated-by: Claude Opus 5 * Detect percent-encoded credentials when masking URIs Generated-by: Claude Opus 5 * Match credentials across newlines when masking URIs Generated-by: Claude Opus 5 * Keep CLI commands running when audit-log masking fails The command line is masked for the audit log before the command runs, so an unexpected error in the masking aborted every CLI command. A failure now records the command fully masked instead: the command still runs, and nothing a secret could be in reaches the log. The short-option table is also checked against the real parsers, so a command definition change cannot silently change what gets masked. (cherry picked from commit 4bbe5f5) Co-authored-by: Jarek Potiuk <jarek@potiuk.com> Generated-by: Claude Opus 5
Contributor
Author
|
Hi maintainer, this PR was merged without a milestone set.
|
vatsrahul1001
pushed a commit
that referenced
this pull request
Oct 20, 2026
… argv position (#72650) (#75144) * Mask CLI secrets in the audit log by parsed argument, not argv position _build_metrics recorded sys.argv into the audit log and masked the variables value by position, assuming the key and value were the final two arguments. Any supported trailing option displaces them: 'airflow variables set KEY VALUE --description TEXT' ends in '--description TEXT', so the value was written to Log.extra in clear. --description is the instance found, not the class -- the same is true of --serialize-json and of any option added later. Take the key and value from the parsed Namespace instead, and redact that value wherever it appears in the recorded command. Position no longer matters. --conn-extra was not masked at all. It is the field connection secrets live in, and it accepts nested JSON. It is now redacted alongside --conn-json, and both are walked recursively -- --conn-json previously masked only top-level keys, so a secret one level down was recorded in clear. A value that cannot be parsed as JSON is redacted whole, because these options carry connection material and a value that cannot be inspected is not safe to record. Both argparse spellings are handled. --conn-json, --conn-extra and --conn-uri were matched as standalone tokens only, so the equally valid --conn-json=VALUE form skipped redaction entirely and recorded the secret. --conn-uri had that gap before this change as well. Note for operators: this prevents new disclosures only. Existing Log.extra rows and backups retain values already written and should be redacted or expired, and any credentials exposed that way rotated. The seven new cases fail against unpatched sources. * Mask long-form password options on every CLI subcommand in the audit log --password and --conn-password name a password on every subcommand, including those contributed by providers (keycloak-auth-manager ... --password), but were only masked for users and connections. Mask the long spellings everywhere; keep -p limited to users and connections, as elsewhere it means --port or --exclude-providers. Generated-by: Claude Opus 5 * Mask CLI secrets by parsed value in every argument spelling Mask secrets supplied through any supported argument spelling in the recorded command line: abbreviated and attached options, repeated options, JSON (incl. conf) and URI values, and celery flower auth. Generated-by: Claude Opus 5 following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions * Mask secrets after grouped short flags and in task-params / env-vars Mask a parsed secret wherever it appears in a recorded token, which covers grouped short flags, and add tasks test -t/--task-params and --env-vars to the JSON options. Generated-by: Claude Opus 5 following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions * Limit in-token masking to whole values and short-option clusters Mask a parsed value only where it is a whole token or ends a single-dash short-option cluster, for plain, JSON and URI options alike, so a short value is not masked wherever its text happens to appear in the recorded command line. Generated-by: Claude Opus 5 following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions * Mask clustered, repeated-empty and double-scheme URI secrets in CLI audit log Generated-by: Claude Opus 5 * Only treat a URI as double-scheme when the host carries a protocol Generated-by: Claude Opus 5 * Match Connection's double-scheme parsing when masking URIs Generated-by: Claude Opus 5 * Walk short-option clusters by option arity and fail closed on any unparsed credentials Generated-by: Claude Opus 5 * Mask the whole URI when credentials cannot be located reliably Generated-by: Claude Opus 5 * Detect percent-encoded credentials when masking URIs Generated-by: Claude Opus 5 * Match credentials across newlines when masking URIs Generated-by: Claude Opus 5 * Keep CLI commands running when audit-log masking fails The command line is masked for the audit log before the command runs, so an unexpected error in the masking aborted every CLI command. A failure now records the command fully masked instead: the command still runs, and nothing a secret could be in reaches the log. The short-option table is also checked against the real parsers, so a command definition change cannot silently change what gets masked. (cherry picked from commit 4bbe5f5) Generated-by: Claude Opus 5 Co-authored-by: Jarek Potiuk <jarek@potiuk.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
_build_metrics recorded sys.argv into the audit log and masked the variables
value by position, assuming the key and value were the final two arguments. Any
supported trailing option displaces them: 'airflow variables set KEY VALUE
--description TEXT' ends in '--description TEXT', so the value was written to
Log.extra in clear. --description is the instance found, not the class -- the
same is true of --serialize-json and of any option added later.
Take the key and value from the parsed Namespace instead, and redact that value
wherever it appears in the recorded command. Position no longer matters.
--conn-extra was not masked at all. It is the field connection secrets live in,
and it accepts nested JSON. It is now redacted alongside --conn-json, and both
are walked recursively -- --conn-json previously masked only top-level keys, so
a secret one level down was recorded in clear. A value that cannot be parsed as
JSON is redacted whole, because these options carry connection material and a
value that cannot be inspected is not safe to record.
Both argparse spellings are handled. --conn-json, --conn-extra and --conn-uri
were matched as standalone tokens only, so the equally valid --conn-json=VALUE
form skipped redaction entirely and recorded the secret. --conn-uri had that gap
before this change as well.
Note for operators: this prevents new disclosures only. Existing Log.extra rows
and backups retain values already written and should be redacted or expired,
and any credentials exposed that way rotated.
The seven new cases fail against unpatched sources.
--password and --conn-password name a password on every subcommand,
including those contributed by providers (keycloak-auth-manager ...
--password), but were only masked for users and connections. Mask the
long spellings everywhere; keep -p limited to users and connections, as
elsewhere it means --port or --exclude-providers.
Generated-by: Claude Opus 5
Mask secrets supplied through any supported argument spelling in the
recorded command line: abbreviated and attached options, repeated
options, JSON (incl. conf) and URI values, and celery flower auth.
Generated-by: Claude Opus 5 following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions
Mask a parsed secret wherever it appears in a recorded token, which covers grouped
short flags, and add tasks test -t/--task-params and --env-vars to the JSON options.
Generated-by: Claude Opus 5 following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions
Mask a parsed value only where it is a whole token or ends a single-dash short-option
cluster, for plain, JSON and URI options alike, so a short value is not masked wherever
its text happens to appear in the recorded command line.
Generated-by: Claude Opus 5 following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions
Generated-by: Claude Opus 5
Generated-by: Claude Opus 5
Generated-by: Claude Opus 5
Generated-by: Claude Opus 5
Generated-by: Claude Opus 5
Generated-by: Claude Opus 5
Generated-by: Claude Opus 5
The command line is masked for the audit log before the command runs, so an unexpected error in the masking aborted every CLI command. A failure now records the command fully masked instead: the command still runs, and nothing a secret could be in reaches the log. The short-option table is also checked against the real parsers, so a command definition change cannot silently change what gets masked.
(cherry picked from commit 4bbe5f5)
Co-authored-by: Jarek Potiuk jarek@potiuk.com
Generated-by: Claude Opus 5