feat(kiloclaw): add @kilocode/kiloclaw-secret-catalog package#857
Merged
feat(kiloclaw): add @kilocode/kiloclaw-secret-catalog package#857
Conversation
7817c3b to
587cb73
Compare
Contributor
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Files Reviewed (10 files)
|
pandemicsyn
reviewed
Mar 6, 2026
- Add Zod schemas for runtime validation of catalog structure - Derive TypeScript types via z.infer<> (single source of truth) - Validate catalog at module load with z.array().parse() - Use as const satisfies for literal type preservation - Export schemas for reuse in downstream PR mutations - Add typecheck + test CI steps for secret-catalog package - Strengthen ReDoS test with near-match inputs
pandemicsyn
approved these changes
Mar 6, 2026
St0rmz1
added a commit
that referenced
this pull request
Mar 9, 2026
…g lookups (#907) <!-- PR title format: type(scope): description — e.g., feat(auth): add SSO login --> <!-- Keep the title under 72 characters, use imperative mood, no trailing period. --> ## Summary Replace hardcoded channel-to-env-var mappings in the CF Worker with catalog-derived lookups from @kilocode/kiloclaw-secret-catalog (PR1, #857). Behavior is identical — only the source of truth changes. - Replace CHANNEL_ENV_MAP in encryption.ts with FIELD_KEY_TO_ENV_VAR from catalog - Replace hardcoded SENSITIVE_KEYS in env.ts with catalog-derived ALL_SECRET_ENV_VARS - Unknown channel keys in DO state are gracefully skipped (warn + continue) instead of silently ignored - Add ALL_SECRET_ENV_VARS export to the secret catalog package <!-- What changed and why? Keep this brief and outcome-focused. --> <!-- Include any architectural changes and enough context for a reviewer unfamiliar with this code area. --> ## Verification <!-- List the checks you ran and what passed. Add command output notes when useful. --> - [x] - pnpm --filter kiloclaw run test — 505 tests pass (504 existing + 1 new) - [x] - pnpm --filter @kilocode/kiloclaw-secret-catalog run test — 30 tests pass - [x] - pnpm --filter kiloclaw run typecheck — clean - [x] - New buildEnvVars equivalence test confirms catalog-derived SENSITIVE_KEYS classifies - [x] all 4 channel env vars identically to the old hardcoded set - [x] - New test confirms unknown channel keys are skipped gracefully without blocking - [x] machine startup ## Visual Changes <!-- If UI/visual behavior changed, add before/after screenshots in the table below. --> <!-- If there are no visual changes, replace the table with: N/A --> N/A | Before | After | | ------ | ----- | | | | ## Reviewer Notes - Depends on #857 (already merged) - Non-breaking: catalog contains the exact same 4 field→env-var mappings that were hardcoded (TELEGRAM_BOT_TOKEN, DISCORD_BOT_TOKEN, SLACK_BOT_TOKEN, SLACK_APP_TOKEN) - One subtle behavioral change: decryptChannelTokens now iterates over input channels keys instead of the old map keys. Unknown keys produce a console.warn + skip rather than being silently ignored — same outcome (key not in result) but with observability This doesn't touch storage. It only changes how the worker reads stored data: - DO state format is unchanged — channels field still holds EncryptedChannelTokens - Decryption logic (decryptWithPrivateKey) is unchanged - Only the key→env-var mapping source changed (hardcoded map → catalog map with identical values) <!-- Optional: reviewer focus areas, edge cases, or context that helps review quickly. -->
St0rmz1
added a commit
that referenced
this pull request
Mar 9, 2026
… validation (#947) <!-- PR title format: type(scope): description — e.g., feat(auth): add SSO login --> <!-- Keep the title under 72 characters, use imperative mood, no trailing period. --> ## Summary feat(kiloclaw): add generic patchSecrets endpoint with catalog-driven validation <!-- What changed and why? Keep this brief and outcome-focused. --> <!-- Include any architectural changes and enough context for a reviewer unfamiliar with this code area. --> Adds patchSecrets tRPC mutation and PATCH /api/platform/secrets worker endpoint alongside existing patchChannels. Uses secret catalog for key validation, pattern matching, maxLength enforcement, and allFieldsRequired enforcement. Makes updateChannels delegate to updateSecrets internally so both storage fields (channels + encryptedSecrets) stay in sync regardless of which endpoint is called. Eliminates interleave drift risk. Key design decisions: - Key remapping at storage boundary: encryptedSecrets stores env var names (e.g., TELEGRAM_BOT_TOKEN) so the existing buildEnvVars/mergeEnvVarsWithSecrets pipeline works unchanged. A reverse map (ENV_VAR_TO_FIELD_KEY) converts back to field keys when reading into the working set. - allFieldsRequired enforced at DO level: The DO validates post-merge state (existing secrets + patch), not just the incoming patch. This allows single-field rotations (e.g., rotating slackBotToken when slackAppToken is already stored) while still rejecting invalid partial clears. - secretCount excludes channel env vars: Channel tokens are dual-written into encryptedSecrets but excluded from secretCount (via CHANNEL_ENV_VARS filter) since they're already counted by channelCount. Applied in getStatus(), getDebugState(), and /api/kiloclaw/config. - Validation errors return 400: DO validation errors carry status: 400 and an Invalid secret patch: prefix so the route handler returns the actual message instead of a generic 500. ## Verification - Catalog package tests pass (37 tests) — includes new allFieldsRequired contract, maxLength contract, and unknown key rejection tests - DO updateSecrets tests pass (8 tests) — set, remove, merge, legacy migration, Slack dual-token set/clear, channel-only filtering - DO updateChannels tests pass (8 tests) — all 6 existing tests pass through delegation path, plus 2 new interleave consistency tests - updateChannels delegation produces identical boolean return shape as original implementation - Worker builds without errors (wrangler types + wrangler deploy --dry-run) - Integration: provision instance via patchChannels, update via patchSecrets, verify both endpoints see consistent state ## Visual Changes N/A ## Reviewer Notes - Dual-write strategy: updateSecrets writes to both channels (legacy, field-keyed) and encryptedSecrets (new, env-var-keyed). Channel-category keys go to both; future non-channel secrets (tools, providers) only go to encryptedSecrets. - updateChannels delegation: The old method now delegates to updateSecrets. This is the fix for the interleave drift edge case; there's now a single write path. Existing updateChannels callers see no behavior change. - tRPC defers allFieldsRequired to DO: The tRPC layer validates key membership, patterns, and maxLength, but does not check allFieldsRequired — only the DO can see existing state to validate post-merge correctness. - configured response filtered: The configured array returned by updateSecrets is filtered to ALL_SECRET_FIELD_KEYS only, preventing non-catalog env var names from leaking into the response. - Rate limiting: Not yet applied to patchSecrets. Should match whatever strategy patchChannels uses. Can be added as a follow-up. - tRPC-level integration tests: Validation logic is tested via catalog contract tests and DO-level tests rather than full tRPC caller tests, since the router test infrastructure requires real DB + user setup + worker client mocking. - Depends on: PR #857 (@kilocode/kiloclaw-secret-catalog package)
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.
Summary
Adds a new shared workspace package (
@kilocode/kiloclaw-secret-catalog) that provides a declarative registry of secret types for KiloClaw. Migrates channel definitions (Telegram, Discord, Slack) from hardcoded config inchannel-config.tsxinto a serializable catalog with types, validation patterns, lookup helpers, and env var mappings.Verification
pnpm test— 27 unit tests pass (uniqueness, regex safety, backtracking, env var mappings, validation)channel-config.tsxregex exactlymaxLengthset on all fields (100 Telegram, 200 Discord, 300 Slack)Visual Changes
N/A
Reviewer Notes
validationPatternis stored as a string (not RegExp) for JSON serializability across Next.js and CF Worker boundaries.maxLengthenforcement happens at the zod/input layer in PR 3, not invalidateFieldValue()— documented in JSDoc.{24,}?) is preserved from the originalchannel-config.tsx; comment explains why.