Skip to content

feat: configurable ignoreDryRunFields via AUTH0_IGNORE_DRY_RUN_FIELDS#1385

Open
dotjoshrc wants to merge 1 commit into
auth0:masterfrom
dotjoshrc:feat/configurable-ignore-dry-run-fields
Open

feat: configurable ignoreDryRunFields via AUTH0_IGNORE_DRY_RUN_FIELDS#1385
dotjoshrc wants to merge 1 commit into
auth0:masterfrom
dotjoshrc:feat/configurable-ignore-dry-run-fields

Conversation

@dotjoshrc
Copy link
Copy Markdown

@dotjoshrc dotjoshrc commented May 13, 2026

🔧 Changes

Adds AUTH0_IGNORE_DRY_RUN_FIELDS, a new optional config key mapping handler type to an array of field paths to exclude from --dry-run diff comparisons. User-supplied entries are merged additively with each handler's built-in ignoreDryRunFields defaults, so the curated defaults (smtp.credentials.smtp_pass, mandrill.credentials.api_key, _clientName, etc.) cannot be accidentally dropped.

Motivation. The Management API does not echo secret values on read — client_secret on clients, options.client_secret on connections, action secrets[].value, and the email provider's credentials.api_key for non-SMTP/Mandrill providers (notably Mailgun). The corresponding local YAML fields therefore always surface as diffs in --dry-run output, drowning out signal on every run. Today the only knob is per-handler hardcoded arrays; the goal here is to let tenant configs silence the known-noisy fields for their setup without forking the CLI.

Shape. New optional config key, identical in shape to EXCLUDED_PROPS/INCLUDED_PROPS:

{
  "AUTH0_IGNORE_DRY_RUN_FIELDS": {
    "clients": ["client_secret"],
    "connections": ["options.client_secret"],
    "actions": ["secrets"],
    "emailProvider": ["credentials.api_key"]
  }
}

This only affects --dry-run reporting; a real import still sends every local field to the API as before.

Backwards compatibility. When the key is absent the handler behavior is byte-identical to today. The constructor read is wrapped in a try/catch so handlers constructed against an uninitialized configFactory() (as some unit tests do) continue to work.

Files touched. src/types.ts, src/tools/auth0/handlers/default.ts, test/tools/auth0/handlers/default.tests.ts, docs/configuring-the-deploy-cli.md, CHANGELOG.md. 119 LOC.

📚 References

N/A — no linked issue. Validated against a real tenant (Mailgun email provider, OIDC connection with client_secret, action with five secrets[] entries) where it cleanly suppresses the previously-noisy diff lines.

🔬 Testing

  • New unit tests in test/tools/auth0/handlers/default.tests.ts covering: (1) merge of user-configured fields with handler defaults, (2) dedupe of overlapping entries, (3) isolation across handler types, (4) fallback when the config provider returns undefined.
  • Full suite: npm test → 1228 passing / 1 pending (unchanged from main).
  • npm run lint, npm run format:check, npm run build, npx kacl lint all clean.

Manual verification: ran a0deploy import --dry-run --debug -c <stage.json> -i tenant.yaml against a real Auth0 tenant; before this change, every dry-run logged a found in 'localObj' but not in 'remoteObj' line for mailgun.credentials.api_key and each entry of handle-post-login.secrets. With the config set, those become Ignoring key … due to ignoreDryRunFields configuration debug lines instead, and the noise disappears at non-debug levels.

📝 Checklist

  • All new/changed/fixed functionality is covered by tests (or N/A)
  • I have added documentation for all new/changed functionality (or N/A)

@dotjoshrc dotjoshrc requested a review from a team as a code owner May 13, 2026 02:56
@dotjoshrc dotjoshrc force-pushed the feat/configurable-ignore-dry-run-fields branch from 309ee16 to 3a99d54 Compare May 13, 2026 03:55
Adds a new optional config key, AUTH0_IGNORE_DRY_RUN_FIELDS, mapping
handler type to an array of field paths to exclude from --dry-run diff
comparisons. User-supplied fields are merged additively with each
handler's built-in defaults, so users cannot accidentally drop curated
defaults like emailProvider's smtp_pass / mandrill api_key or
clientGrants' _clientName.

Motivation: the Management API does not return secret values
(client_secret on clients, options.client_secret on connections, action
secrets[].value, emailProvider credentials.api_key for non-SMTP/Mandrill
providers, etc.). The corresponding local YAML fields therefore always
appear as differences in dry-run output, drowning out signal. This
option lets a tenant config silence those known-noisy fields without
forking the CLI.

Implementation: the merge is computed lazily by a new
getEffectiveIgnoreDryRunFields() method, called from calcChanges and
dryRunChanges where ignoreDryRunFields is actually consumed. The
constructor remains byte-identical to upstream, so handler construction
has no new side effects and any unrelated tests that exercise handler
construction continue to behave exactly as before.

The change is fully backwards compatible: when the new key is absent,
the method returns the handler's existing ignoreDryRunFields unchanged.

Includes unit tests covering merge, dedupe, type-isolation, the
no-config fallback, and the throwing-config-provider path. All existing
tests continue to pass.
@dotjoshrc dotjoshrc force-pushed the feat/configurable-ignore-dry-run-fields branch from 3a99d54 to cc5d021 Compare May 13, 2026 04:00
@dotjoshrc
Copy link
Copy Markdown
Author

The E2E tests as Node module check is failing, but the failure is unrelated to this PR. Surfacing the analysis here so reviewers don't have to re-derive it:

Failure pattern (4 tests, identical across re-runs):

  • #end-to-end deploy: should deploy without throwing an error
  • #end-to-end deploy: should deploy without deleting resources if AUTH0_ALLOW_DELETE is false
  • #end-to-end deploy: should deploy while deleting resources if AUTH0_ALLOW_DELETE is true
  • #end-to-end dump and deploy cycle: should dump and deploy without throwing an error

All four fail with the same nock mismatch — PATCH / DELETE on the Deploy CLI client (client_id: Vp0gMRF8PtMzekil38qWoj4Fjw2VjRZE, the client used to authenticate the test itself). That client is supposed to be filtered out of changesets by clients.ts:589:

item.client_id !== currentClient

…where currentClient = this.config('AUTH0_CLIENT_ID'). The nock recordings (test/e2e/recordings/should-deploy-without-throwing-an-error.json and siblings) contain zero requests against Vp0gMRF8…, confirming the test was recorded with the auth-client filter active.

Why this isn't from this PR:

  1. src/tools/auth0/handlers/default.ts constructor is byte-identical to upstream master in the current revision of this branch — git diff upstream/master -- src/tools/auth0/handlers/default.ts shows only an added getEffectiveIgnoreDryRunFields() method plus two call-site swaps inside the existing if (AUTH0_DRY_RUN) and dryRunChanges branches.
  2. The four failing tests invoke deploy() with configs that contain only AUTH0_DOMAIN/AUTH0_CLIENT_ID/AUTH0_CLIENT_SECRET/AUTH0_ACCESS_TOKEN — no AUTH0_DRY_RUN. So getEffectiveIgnoreDryRunFields() is never called on any code path exercised by these tests.
  3. The other e2e tests in the same suite that do exercise deploy() but with AUTH0_INCLUDED_ONLY: ['tenant'] (skipping the clients handler entirely) all pass.

What I'd suggest: treat the four failing tests as a pre-existing CI flake on the auth-client filter and re-run, or point me at the right place to look if there's something more I can do from this PR. Happy to debug further if you'd like.

@kushalshit27
Copy link
Copy Markdown
Contributor

Thank you for submitting this PR! Your contribution is greatly appreciated. We'll review it shortly

@kushalshit27 kushalshit27 self-assigned this May 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants