Skip to content

fix(wrangler): add safe command/args handling for telemetry#12063

Closed
petebacondarwin wants to merge 4 commits intomainfrom
pbd/safe-command-args-metrics
Closed

fix(wrangler): add safe command/args handling for telemetry#12063
petebacondarwin wants to merge 4 commits intomainfrom
pbd/safe-command-args-metrics

Conversation

@petebacondarwin
Copy link
Copy Markdown
Contributor

@petebacondarwin petebacondarwin commented Jan 23, 2026

This PR improves telemetry safety by introducing explicit control over which command arguments are included in telemetry events, preventing accidental capture of sensitive data like secrets and credentials.

Replaces #11856
Builds on top of #12069 and Builds on top of #12071

  • Renamed telemetry fields for clarity:

    • command → safeCommand (now excludes the "wrangler " prefix, e.g., "d1 list" instead of "wrangler d1 list")
    • args → safeArgs (explicitly indicates these are sanitized/safe arguments)
  • Added logArgs control:

    • New logArgs: boolean field in telemetry events and command metadata
    • Commands must explicitly opt-in via metadata.logArgs: true to have their arguments logged
    • When logArgs: false (default), safeArgs is sent as an empty object {}
  • Opted-in safe commands (~100 commands) that don't handle sensitive input:

    • List/info/get commands (d1 list, kv list, r2 bucket list, etc.)
    • Read-only operations (docs, tail, type-generation, etc.)
    • Commands with non-sensitive arguments (delete by name, deployments, etc.)
  • Intentionally excluded sensitive commands:

    • secret put, secret delete, secret bulk (handle secret values)
    • pages secret put, pages secret delete, pages secret bulk
    • hyperdrive create, hyperdrive update (contain connection strings)
  • Tests

    • Tests included/updated
    • Automated tests not possible - manual testing has been completed as follows:
    • Additional testing not necessary because:
  • Public documentation

    • Cloudflare docs PR(s):
    • Documentation not necessary because: bug fix

A picture of a cute animal (not mandatory, but encouraged)


Open with Devin

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Jan 23, 2026

🦋 Changeset detected

Latest commit: 10b86ae

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Jan 23, 2026

create-cloudflare

npm i https://pkg.pr.new/create-cloudflare@12063

@cloudflare/kv-asset-handler

npm i https://pkg.pr.new/@cloudflare/kv-asset-handler@12063

miniflare

npm i https://pkg.pr.new/miniflare@12063

@cloudflare/pages-shared

npm i https://pkg.pr.new/@cloudflare/pages-shared@12063

@cloudflare/unenv-preset

npm i https://pkg.pr.new/@cloudflare/unenv-preset@12063

@cloudflare/vite-plugin

npm i https://pkg.pr.new/@cloudflare/vite-plugin@12063

@cloudflare/vitest-pool-workers

npm i https://pkg.pr.new/@cloudflare/vitest-pool-workers@12063

@cloudflare/workers-editor-shared

npm i https://pkg.pr.new/@cloudflare/workers-editor-shared@12063

@cloudflare/workers-utils

npm i https://pkg.pr.new/@cloudflare/workers-utils@12063

wrangler

npm i https://pkg.pr.new/wrangler@12063

commit: 10b86ae

Comment thread packages/wrangler/src/index.ts Outdated
let dispatcher: ReturnType<typeof getMetricsDispatcher> | undefined;

// Register middleware to capture command info for fallback telemetry
const wranglerWithTelemetry = wranglerWithMiddleware.middleware((args) => {
// Capture command and args for potential fallback telemetry
// (used when yargs validation errors occur before handler runs)
command = `wrangler ${args._.join(" ")}`;
metricsArgs = args;
safeCommand = args._.join(" ");
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.

@MattieTK - do we want this just to be "" since we cannot guarantee that the args don't contain something sensitive?

@petebacondarwin petebacondarwin force-pushed the pbd/clean-command-metrics branch from 3fd5325 to 7e9344a Compare January 23, 2026 14:16
@petebacondarwin petebacondarwin force-pushed the pbd/safe-command-args-metrics branch 2 times, most recently from bd603d8 to 2e40a31 Compare January 23, 2026 16:27
@petebacondarwin petebacondarwin changed the base branch from pbd/clean-command-metrics to pbd/wrangler/migrate-containers-to-define-command January 23, 2026 16:27
@petebacondarwin petebacondarwin force-pushed the pbd/wrangler/migrate-containers-to-define-command branch from a073093 to db843d1 Compare January 23, 2026 18:01
@petebacondarwin petebacondarwin force-pushed the pbd/safe-command-args-metrics branch 2 times, most recently from 3ad4dd8 to 5a78386 Compare January 24, 2026 14:09
@petebacondarwin petebacondarwin marked this pull request as ready for review January 24, 2026 14:09
@petebacondarwin petebacondarwin requested review from a team January 24, 2026 14:09
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

Open in Devin Review

Comment thread packages/wrangler/src/metrics/sanitization.ts
@petebacondarwin petebacondarwin force-pushed the pbd/wrangler/migrate-containers-to-define-command branch from 7dee593 to 1360eb5 Compare January 25, 2026 08:51
@petebacondarwin petebacondarwin requested a review from a team as a code owner January 25, 2026 08:51
@petebacondarwin petebacondarwin force-pushed the pbd/safe-command-args-metrics branch from 5a78386 to 8897b68 Compare January 25, 2026 08:52
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

View issue and 5 additional flags in Devin Review.

Open in Devin Review

Comment thread packages/wrangler/src/index.ts Outdated
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

View issue and 3 additional flags in Devin Review.

Open in Devin Review

Comment thread packages/wrangler/src/metrics/sanitization.ts
@petebacondarwin petebacondarwin changed the title refactor(wrangler): add safe command/args handling for telemetry fix(wrangler): add safe command/args handling for telemetry Jan 25, 2026
Copy link
Copy Markdown
Contributor

@vicb vicb left a comment

Choose a reason for hiding this comment

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

Nice.
I added some comments.
I also see that Devin has comments, have those been addressed?

Comment thread packages/wrangler/src/metrics/types.ts Outdated
Comment on lines +86 to +87
* The command that was used, e.g. `dev`.
* Does not include the "wrangler" prefix.
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.

future proof this in case wrangler is renamed

Suggested change
* The command that was used, e.g. `dev`.
* Does not include the "wrangler" prefix.
* The command that was used, e.g. `dev` without the binary name

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.

wrangler is used throughout this file, including the names of the events; so it will need a full overhaul if we change the name. "binary" is less clear.

Comment thread packages/wrangler/src/metrics/types.ts Outdated
Comment on lines +88 to +89
* When logArgs is false, positional arguments are stripped to prevent
* accidentally capturing secrets in telemetry.
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.

It's nice to see what's stripped, could we also maybe describe what's kept?

Suggested change
* When logArgs is false, positional arguments are stripped to prevent
* accidentally capturing secrets in telemetry.
* When `logArgs` is `false`, positional arguments are stripped to prevent
* accidentally capturing secrets in telemetry.

Comment thread packages/wrangler/src/metrics/types.ts Outdated
Comment on lines +100 to +101
* Named `safeArgs` to distinguish from historical `args` field which
* may have contained sensitive data in older Wrangler versions.
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.

IMO this is noise and not needed

Suggested change
* Named `safeArgs` to distinguish from historical `args` field which
* may have contained sensitive data in older Wrangler versions.

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.

I think this is actually really useful context for why we are not just using command and args here.

Comment thread packages/wrangler/src/metrics/types.ts Outdated
Comment on lines +91 to +92
* Named `safeCommand` to distinguish from historical `command` field which
* may have contained sensitive positional arguments in older Wrangler versions.
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.

IMO this is noise and not needed

Suggested change
* Named `safeCommand` to distinguish from historical `command` field which
* may have contained sensitive positional arguments in older Wrangler versions.

Comment thread packages/wrangler/src/metrics/types.ts Outdated
* Named `safeCommand` to distinguish from historical `command` field which
* may have contained sensitive positional arguments in older Wrangler versions.
*/
safeCommand: string;
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.

Telemetry is the last thing that comes to mind about a "safe" command.
Would "sanitized" be a better prefix?

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.

I agree. I'll change the names.

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.

@MattieTK - is that OK with you?

Comment thread packages/wrangler/src/metrics/types.ts Outdated
Comment on lines +96 to +97
* The args and flags that were passed in when running the command.
* All user-inputted string values are redacted, except for some cases where there are set options.
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.

Maybe add an example to ease the understanding?

I see const safeArgs = logArgs ? args : {}; in register-yargs-command.ts

So if my understanding is correct:

  • "When logArgs is false, this is an empty object." that's true
  • WHen logArs is true, some sanitization is going on, can we add ref to the relevant code/config (@see ...)

Comment thread packages/wrangler/src/metrics/types.ts Outdated
* Named `safeArgs` to distinguish from historical `args` field which
* may have contained sensitive data in older Wrangler versions.
*/
safeArgs: Record<string, unknown>;
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.

Same comment for "safe" that for safeCommand

Comment thread packages/wrangler/src/core/types.ts Outdated
Comment on lines +80 to +83
* If true, arguments for this command will be included in telemetry.
*
* @default false - Arguments are not logged by default.
* Set to `true` to explicitly include this command's args in telemetry.
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.

Suggested change
* If true, arguments for this command will be included in telemetry.
*
* @default false - Arguments are not logged by default.
* Set to `true` to explicitly include this command's args in telemetry.
* Whether arguments for this command will be posted to telemetry.
*
* @default false - Arguments are not logged by default.

Comment thread packages/wrangler/src/metrics/metrics-dispatcher.ts
Comment on lines +133 to 150
// Truncate login commands to just "login" to avoid capturing tokens
if (properties.safeCommand?.startsWith("login")) {
properties.safeCommand = "login";
}
// Don't send metrics for telemetry/metrics disable commands
if (
properties.command === "wrangler telemetry disable" ||
properties.command === "wrangler metrics disable"
properties.safeCommand === "telemetry disable" ||
properties.safeCommand === "metrics disable"
) {
return;
}
// Show metrics banner for certain commands
if (
properties.command === "wrangler deploy" ||
properties.command === "wrangler dev" ||
properties.safeCommand === "deploy" ||
properties.safeCommand === "dev" ||
// for testing purposes
properties.command === "wrangler docs"
properties.safeCommand === "docs"
) {
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.

Note: I have created #12029 to clean that up

@github-project-automation github-project-automation Bot moved this from Untriaged to In Review in workers-sdk Jan 26, 2026
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

View issue and 8 additional flags in Devin Review.

Open in Devin Review

Comment thread packages/wrangler/src/metrics/sanitization.ts
@petebacondarwin petebacondarwin force-pushed the pbd/wrangler/migrate-containers-to-define-command branch from 1360eb5 to 8676957 Compare January 26, 2026 09:11
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 3 new potential issues.

View issues and 7 additional flags in Devin Review.

Open in Devin Review

Comment on lines 410 to 414
description: "Write a single key/value pair to the given namespace",
status: "stable",
owner: "Product: KV",
logArgs: true,
},
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.

🔴 Sensitive KV write commands now opt-in to telemetry args logging via metadata.logArgs: true

kv key put and kv bulk put are write operations that accept secret values (inline value or a JSON file containing values) and file paths. This PR’s stated goal is to avoid capturing sensitive data by requiring explicit opt-in for arg logging, but these commands are explicitly opted in.

Actual: Wrangler will include argsUsed/argsCombination and may include allowed args values depending on allow-list; at minimum it records that flags like --path, --metadata, etc. were used, and it can accidentally include values if they become allow-listed later.

Expected: write/secret-bearing commands should keep metadata.logArgs unset/false so telemetry args are always {}.

Impact: privacy/security regression—telemetry collection is re-enabled for commands that often deal with secrets and sensitive file paths.

Click to expand

Relevant opt-in additions:

  • kvKeyPutCommand sets logArgs: true in metadata: packages/wrangler/src/kv/index.ts:409-414
  • kvBulkPutCommand sets logArgs: true in metadata: packages/wrangler/src/kv/index.ts:880-885

Telemetry plumbing includes args when logArgs is true: packages/wrangler/src/core/register-yargs-command.ts:223-232

(Refers to lines 409-414)

Recommendation: Remove logArgs: true from KV write commands (at least kv key put and kv bulk put). Only opt in for read-only/non-sensitive commands, and consider adding a test asserting logArgs is false and sanitizedArgs is {} for these commands.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines 22 to 26
description: "Enable Sippy on an R2 bucket",
status: "stable",
owner: "Product: R2",
logArgs: true,
},
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.

🔴 r2 bucket sippy enable opts in to telemetry args despite taking access keys and credentials

wrangler r2 bucket sippy enable takes highly sensitive credentials (--access-key-id, --secret-access-key, --r2-access-key-id, --r2-secret-access-key, and GCS private key material). This PR intends to prevent accidental capture of secrets, but the command is explicitly opted in to arg logging.

Actual: Since metadata.logArgs is true, Wrangler will send argsUsed/argsCombination derived from the args and may include values if allow-listed later.

Expected: This command should not log args (leave logArgs unset/false).

Impact: privacy/security regression; telemetry starts recording usage of secret-bearing flags for Sippy enable.

Click to expand

Opt-in added here: packages/wrangler/src/r2/sippy.ts:21-26.
The command defines credential flags immediately below (access-key-id, secret-access-key, etc.): packages/wrangler/src/r2/sippy.ts:51-80.

(Refers to lines 21-26)

Recommendation: Remove logArgs: true from r2BucketSippyEnableCommand (and any other commands that accept credentials/secret material). Add/extend tests to ensure logArgs remains false for these commands.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines 26 to 30
owner: "Workers: Authoring and Testing",
status: "stable",
category: "Account",
logArgs: true,
},
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.

🔴 wrangler login is opted in to telemetry args logging contrary to privacy requirements

This PR’s description explicitly calls out wrangler login as a command that should no longer collect telemetry on argument usage. However, loginCommand is marked with metadata.logArgs: true.

Actual: register-yargs-command will pass full parsed args as sanitizedArgs when logArgs is true (packages/wrangler/src/core/register-yargs-command.ts:223-232). While metrics-dispatcher truncates sanitizedCommand to "login", it still processes and sends sanitized args/flags usage for the login command.

Expected: wrangler login should have logArgs unset/false so sanitizedArgs is always {}.

Impact: privacy regression: argument usage telemetry is still recorded for login.

Click to expand

Opt-in added in login metadata: packages/wrangler/src/user/commands.ts:24-30.

(Refers to lines 24-30)

Recommendation: Remove logArgs: true from loginCommand metadata. Consider adding a unit test verifying sanitizedArgs is {}/argsCombination is empty for wrangler login events.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Base automatically changed from pbd/wrangler/migrate-containers-to-define-command to main January 26, 2026 14:50
- Rename 'command' to 'safeCommand' (without 'wrangler ' prefix) and 'args' to 'safeArgs' in telemetry events
- Add 'logArgs' boolean to control whether command arguments are included in telemetry
- Commands must explicitly opt-in via metadata.logArgs: true to log arguments
- Safe commands (list, info, get, etc.) that don't handle sensitive data opt-in to logging
- Sensitive commands (secret put/delete/bulk, hyperdrive create) intentionally do not opt-in
- Update fallback telemetry in index.ts to use new format with logArgs: false
… telemetry

Move addBreadcrumb call into the command handler where we have access to
the safe commandName from the command definition, rather than deriving it
from args._ which may contain sensitive user-supplied positional arguments.

Remove safeCommand variable from fallback telemetry since we cannot safely
derive it from args._. The dispatchGenericCommandErrorEvent now uses empty
string for safeCommand.
@petebacondarwin petebacondarwin force-pushed the pbd/safe-command-args-metrics branch from f99030b to 10b86ae Compare January 26, 2026 15:53
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 2 new potential issues.

View issues and 12 additional flags in Devin Review.

Open in Devin Review

Comment on lines 26 to 30
owner: "Workers: Authoring and Testing",
status: "stable",
category: "Account",
logArgs: true,
},
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.

🔴 Sensitive wrangler login command is incorrectly opted-in to argument telemetry via logArgs: true

wrangler login was intended (per PR description/changeset) to not collect any argument usage telemetry, but it is explicitly opted-in by setting metadata.logArgs: true.

Actual behavior: when wrangler login runs, createHandler() will set logArgs = true and pass the full args object to telemetry (sanitizedArgs = args) (packages/wrangler/src/core/register-yargs-command.ts:223-232). The metrics dispatcher then derives argsUsed/argsCombination from the sanitized arg keys, meaning argument usage is still collected (even if values are later dropped/redacted).

Expected behavior: wrangler login should have metadata.logArgs unset/false so that sanitizedArgs is {} and no argument usage is collected.

Impact: privacy/telemetry policy regression for a security-sensitive auth command; could leak presence of particular flags/options and violates the explicit policy described in the PR.

Click to expand

Relevant code:

  • loginCommand opts in: packages/wrangler/src/user/commands.ts:25-30
  • Opt-in causes args to be sent into telemetry pipeline: packages/wrangler/src/core/register-yargs-command.ts:223-232

(Refers to lines 25-30)

Recommendation: Remove logArgs: true from loginCommand metadata (or explicitly set logArgs: false) so wrangler login sends empty sanitizedArgs and collects no argument usage.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines 16 to 20
description: "Upload an mTLS certificate",
owner: "Product: SSL",
status: "stable",
logArgs: true,
},
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.

🔴 wrangler mtls-certificate upload is incorrectly opted-in to argument telemetry (captures file-path flag usage)

mTlsCertificateUploadCommand sets metadata.logArgs: true even though it takes certificate/private-key file paths (--cert, --key). The changeset states that commands with file paths that could reveal sensitive structure should not collect argument usage telemetry.

Actual behavior: with logArgs enabled, Wrangler will include argsUsed/argsCombination for this command, indicating the use of file path flags. While values may be redacted/dropped later, the command is still opted into argument usage telemetry.

Expected behavior: logArgs should be false so telemetry does not capture argument usage for file-path-bearing commands.

Impact: privacy regression (argument usage telemetry for filesystem-path-bearing commands).

Click to expand

Relevant code:

  • Opt-in: packages/wrangler/src/mtls-certificate/cli.ts:14-20

(Refers to lines 14-20)

Recommendation: Remove logArgs: true from mTlsCertificateUploadCommand metadata so it does not collect argument usage telemetry.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@petebacondarwin
Copy link
Copy Markdown
Contributor Author

Looking at this code after the refactorings, we don't actually need the logArgs:false behaviour any more. The metrics command events never send unsanitized command strings any more, and the logic to only allow approved args already ensure that unsanitized/unapproved args are never sent either.
Closing this PR in favour of a simpler improvement at #12153

@github-project-automation github-project-automation Bot moved this from In Review to Done in workers-sdk Jan 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants