Skip to content

fix(integration): secret redaction and instance scope teardown hardening#593

Merged
rmyndharis merged 1 commit into
mainfrom
fix/integration-instance-secret-hygiene
Jul 2, 2026
Merged

fix(integration): secret redaction and instance scope teardown hardening#593
rmyndharis merged 1 commit into
mainfrom
fix/integration-instance-secret-hygiene

Conversation

@rmyndharis

Copy link
Copy Markdown
Owner

Summary

Config-secret hygiene and instance lifecycle fixes in the plugin/integration layer.

Changes

  • Redaction fails closed without a schema. redactSecretConfig returned config verbatim when a plugin had no configSchema, leaking any runtime-stored secret on GET /plugins. It now masks every value; restoreSecretConfig gained a symmetric sentinel-aware path so a schemaless round-trip restores stored values instead of persisting the mask.
  • Instance config redaction is recursive + reused. The integration instance view had its own top-level-only masking; it now reuses the shared recursive redactSecretConfig, so a secret nested in an object/array is masked at any depth.
  • Instance PATCH restores masked secrets. update() stored the incoming config verbatim, so a dashboard round-trip persisted the *** sentinel and corrupted the stored credential. It now restores masked secrets via restoreSecretConfig.
  • Wildcard/null scope teardown works. Disabling or deleting a */null-scope instance was a no-op, so the plugin kept firing on every session with stale config. Teardown now retires the * activation once no other enabled instance binds a wildcard, and a wildcard→concrete change tears down the old binding. applyScopeBinding is awaited; delete removes the row before teardown so the wildcard check is accurate.

Verification

npm run build ✓ · npm test ✓ (1857/1857, +5) · lint ✓. New tests: fail-closed no-schema redaction + round-trip, recursive nested masking, PATCH sentinel restore, and wildcard teardown (retires * when last wildcard removed, keeps it when another remains).

- Fail closed in redactSecretConfig when a plugin has no configSchema (mask every value instead of
  returning it verbatim), with a symmetric sentinel-aware restoreSecretConfig so a schemaless
  round-trip does not persist the mask. Previously runtime-stored secrets of a schemaless plugin
  leaked on GET /plugins.
- Redact integration-instance config through the shared recursive redactSecretConfig so a secret
  nested in an object/array is masked (not just top-level fields), and restore masked secrets on
  instance PATCH via restoreSecretConfig instead of storing the '***' sentinel verbatim (which
  corrupted the stored credential).
- Make instance scope teardown actually work for a wildcard/null sessionScope: disabling or deleting
  such an instance now retires the '*' activation once no other enabled instance still binds a
  wildcard, and a wildcard-to-concrete scope change tears the old '*' down. applyScopeBinding is now
  awaited; delete removes the row before teardown so the wildcard check is accurate.
@rmyndharis rmyndharis merged commit d2bc946 into main Jul 2, 2026
2 of 3 checks passed
@rmyndharis rmyndharis deleted the fix/integration-instance-secret-hygiene branch July 2, 2026 13:38
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.

1 participant