Skip to content

Re-apply lost v2026.3.1/v2026.3.2 security improvements (4 findings) #2201

@alexey-pelykh

Description

@alexey-pelykh

Context

PR #2191 wholesale-restored 20 files from pre-v2026.3.1 (fdcbc3bd86~1) to remediate sync regressions. This discarded legitimate upstream security improvements from v2026.3.1/v2026.3.2 that are NOT tied to gutted subsystems.

Audit report: hq/engineering/notes/post-remediation-audit-b3b4.md

Findings

1. src/commands/agent.ts — Ingress senderIsOwner enforcement (v2026.3.2)

v2026.3.2 split agentCommand into agentCommandInternal + agentCommandFromIngress. The ingress entry point throws if senderIsOwner is not explicitly set to a boolean, preventing privilege escalation where channel ingress could default to owner permissions.

What to do: Extract the agentCommandFromIngress wrapper that validates senderIsOwner is explicitly boolean. Wire ingress callers through it.

2. src/acp/client.ts — Scoped read-tool auto-approval (v2026.3.1)

~90 LoC of new functions: extractPathFromToolTitle, resolveToolPathCandidate, resolveAbsoluteScopedPath, isPathWithinRoot, isReadToolCallScopedToCwd. Adds "read" to SAFE_AUTO_APPROVE_TOOL_IDS but only auto-approves when the target path is within cwd.

What to do: Re-apply the scoped read auto-approval system. Strip memory_search (gutted). Keep read + web_search entries. Add READ_TOOL_PATH_KEYS constant. Expand shouldAutoApproveToolCall signature to accept params/toolTitle/cwd.

3. src/commands/doctor-config-flow.ts — Allowlist policy detection + repair (v2026.3.1)

detectEmptyAllowlistPolicy warns when an empty allowlist silently blocks all DMs/group messages. maybeRepairAllowlistPolicyAllowFrom auto-repairs from pairing store. Both use readChannelAllowFromStore from ../pairing/pairing-store.js (exists in fork).

What to do: Re-apply hasAllowFromEntries, maybeRepairAllowlistPolicyAllowFrom, detectEmptyAllowlistPolicy. Wire into doctor repair and diagnostic flows.

4. src/config/defaults.tshasConfiguredSecretInput (v2026.3.2)

Replaces naive string-based API key check with hasConfiguredSecretInput() which properly handles secret references ($ENV_VAR, op://vault/item) rather than just checking emptiness. Prevents false negatives.

What to do: Import hasConfiguredSecretInput from its module (exists in fork). Replace the string check in applyProviderDefaults.

Exit Criterion

All 4 security improvements re-applied. No new @ts-expect-error suppressions introduced.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions