Repository navigation
fix: redact clipboard and CDP secrets in recorded steps (AIENG-228) - #52
Merged
cryptotavares merged 7 commits intoOct 16, 2026
Merged
Conversation
cryptotavares
marked this pull request as ready for review
October 15, 2026 13:22
cryptotavares
enabled auto-merge (squash)
October 15, 2026 13:43
seaona
approved these changes
Oct 16, 2026
cryptotavares
deleted the
cryptotavares/aieng-228-redact-recorded-secrets
branch
October 16, 2026 09:14
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.
Addresses the upstream fix for AIENG-228, under AIENG-128.
Problem
Onboarding sends the SRP through
clipboard.textand the password throughcdp.params.text. Neither field matches the knowledge store's sensitive-name policy. Step files retain credentials that an execute agent can read. Pool wallets are reused across runs.Errors and observations can also copy the input into the same step.
sequenceDiagram participant O as Onboarding participant T as Tool handler participant K as Knowledge store participant F as Step JSON O->>T: clipboard write SRP / CDP insert password T-->>O: Original execution result T->>K: Input, outcome, observation K->>K: Check input field names Note over K: text and params do not match K->>F: Persist plaintext input and echoed copiesSolution
Apply the recording policy before the knowledge store writes each step.
textand CDPparamswith[REDACTED]. Recurse throughrun_steps, including the mobiledevice-clipboardalias.flowchart TD A[Validated tool input] --> B[Execute tool with original input] B --> C[Collect outcome and observation] C --> P{Safe session ID and tool name?} P -->|yes| D[Redact clipboard text and CDP params] P -->|no| X[Reject recording. No filesystem operations.] D --> E[Recurse through nested batch inputs] E --> F[Scrub copied input in diagnostic content] F --> G[Keep structural metadata intact] G --> H[Write recorded step JSON] B --> I[Return original result to caller] classDef new fill:#fff3cd,stroke:#d39e00 classDef stop fill:#f8d7da,stroke:#c82333 class P,D,E,F,G new class X stopYellow boxes are new. Red boxes stop the recording.
What changes
Success and error recordings use this policy. Tools and HTTP responses retain original values.
clipboardwritetext[REDACTED],textRedacted: true, andtextLengthdevice_clipboardwritetextparamsparams: "[REDACTED]"; retains method and call metadatarun_steps2orotypeinputDecisions for reviewers
device_clipboardand its batch aliasparams.,_, and-.and..are rejected. Custom names with spaces or other punctuation now fail recording validation.Review guide
Read the files in this order:
src/knowledge-store/knowledge-store.tssrc/knowledge-store/utils/redaction.tsredactRecordedSecrets; follow the matching, observation, and prior-knowledge helpers. Check preserved metadata beside each field policy.src/server/recorded-secrets.test.ts,src/knowledge-store/utils/redaction.test.ts,src/knowledge-store/knowledge-store.test.tsREADME.mdTesting
CI=true yarn lintpasses all lint stages.CI=true yarn buildpasses.yarn tsc --project tsconfig.build.json --noEmitpasses.CI=true yarn testpasses: 48 files, 1,605 tests, coverage thresholds, build/packing, andattw --pack.CI=true yarn vitest run src/server/recorded-secrets.test.ts src/knowledge-store/utils/redaction.test.ts src/knowledge-store/knowledge-store.test.ts --coverage.enabled=falsepasses: three files, 163 cases, including existing tests.git diff --checkpasses.The acceptance regression sends synthetic onboarding inputs through real HTTP handlers and scans every generated step file. Browser/device I/O is mocked; this verifies the recording boundary, not a live wallet import.
Redaction coverage has 16 cases: seven HTTP-to-disk cases, seven pure-policy cases, and two recorder-compatibility cases. Integration cases cover onboarding, nested batches and aliases, normal errors, server exceptions, and a non-redaction control. Unit cases cover short strings, escaped matching, scoped content, metadata, idempotence, and nonmutation.
Path-validation tables check ten unsafe values against both recording components and three legitimate name combinations. Rejected values trigger neither
mkdirnorwriteFile. Direct callers receiveInvalid sessionId: expected a safe filename componentor the equivalenttoolNameerror. The server preserves tool responses when recording fails.The audit reduces feature-test source from 1,003 to 646 lines. The integration file falls to 264 lines. The subsequent merge adds one focused regression for defensive batch handling together with recursive echo scrubbing. Existing tests remain intact.
Mutation checks on the leaner suite:
2/oregression cases fail on corrupted metadata.Production mutations are restored before final verification. Production and configuration files are unchanged by the test audit. Current coverage is 96.29% statements, 91.60% branches, 94.36% functions, and 96.53% lines. The branch retains main's raised coverage thresholds.
The readability refactor reuses the existing tests. A temporary old/new comparison verifies equivalent behavior across 4,246 cases, including escaping, boundaries, optional fields, Dates, overlaps, and nonmutation.
Measured with the same ESLint complexity rule,
redactRecordedSecretsdrops from 11 to 7, and from 167 to 41 lines. No function exceeds complexity 7 or 47 lines. The file grows from 200 to 314 lines because helpers have explicit signatures and documentation.tsconfig.test.jsonhas eight pre-existing errors in mobile-driver, mock-network, and screenshot tests, reproduced against the base recorder. Production checks and the full test command pass.Independent code review confirms the revision has no remaining blocking issues.
Docs and follow-ups
README.mddocuments clipboard/CDP recording and the targeted echo policy.