diff --git a/agents/changelog/state.md b/agents/changelog/state.md index 40ca65b5..d4d4a78c 100644 --- a/agents/changelog/state.md +++ b/agents/changelog/state.md @@ -1,14 +1,14 @@ --- -last_checked_commit: 03b4ccc -last_run: "2026-08-13T00:00:00Z" -entries_added: 11 +last_checked_commit: e37f625 +last_run: "2026-10-09T00:00:00Z" +entries_added: 0 branches_created: ["docs/changelog-update-2026-02-22", "docs/changelog-update-2026-02-23-manual", "changelog/auto-update-2026-02-25", "changelog/auto-update-2026-02-26", "changelog/auto-update-2026-03-01", "changelog/auto-update-2026-03-06", "changelog/auto-update-2026-03-13", "docs/whats-new-catchup-2026-08-13"] status: completed --- # Changelog Update State -**Last Updated:** 2026-08-13T00:00:00Z +**Last Updated:** 2026-10-09T00:00:00Z This document tracks the state of the changelog updater agent, enabling incremental reviews that analyze only new commits since the last check. @@ -19,10 +19,10 @@ incremental reviews that analyze only new commits since the last check. | Metric | Value | Notes | |--------|-------|-------| -| Last checked commit | 03b4ccc | chore: version packages (#451) | -| Last run | 2026-08-13T00:00:00Z | Catch-up: reset stale seed (was 6053872, Mar 13) and filled the gap | -| Entries added (last run) | 11 | Stop/reap sessions, plugins+MCP config, faster job listings, session adoption, custom Claude home, session hardening, token accounting, inline images, token streaming, embeddable scheduler, event contract fixes | -| Branches created | docs/whats-new-catchup-2026-08-13 | Current update branch | +| Last checked commit | e37f625 | chore(engineer): daily housekeeping | +| Last run | 2026-10-09T00:00:00Z | What's New current - only housekeeping commits since Oct 8 | +| Entries added (last run) | 0 | No new entries needed - only internal housekeeping | +| Branches created | - | No branch created (no updates needed) | --- @@ -30,6 +30,10 @@ incremental reviews that analyze only new commits since the last check. | Date | Commits Analyzed | Entries Added | Action | Branch | |------|-----------------|---------------|--------|--------| +| 2026-10-09 | 2 | 0 | No update needed | - | +| 2026-10-08 | 12 | 0 | No update needed | - | +| 2026-10-05 | 1 | 0 | No update needed | - | +| 2026-10-03 | 14 | 4 | Updated What's New | - | | 2026-08-13 | 71 | 11 | created-branch | docs/whats-new-catchup-2026-08-13 | | 2026-03-13 | 7 | 3 | Ready for PR | changelog/auto-update-2026-03-13 | | 2026-03-06 | 11 | 3 | Ready for PR | changelog/auto-update-2026-03-06 | diff --git a/agents/docs/state.md b/agents/docs/state.md index 5bb989ef..6140546b 100644 --- a/agents/docs/state.md +++ b/agents/docs/state.md @@ -1,14 +1,14 @@ --- -last_checked_commit: eed88a1 -last_run: "2026-07-10T23:17:20Z" -docs_gaps_found: 7 -branches_created: ["docs/auto-update-2026-02-21", "docs/auto-update-2026-03-01", "docs/auto-update-2026-03-05", "docs/auto-update-2026-03-07", "docs/auto-update-2026-03-13", "docs/auto-update-2026-06-30", "docs/auto-update-2026-07-10"] +last_checked_commit: b1b06f2 +last_run: "2026-10-13T00:00:00Z" +docs_gaps_found: 1 +branches_created: ["docs/auto-update-2026-02-21", "docs/auto-update-2026-03-01", "docs/auto-update-2026-03-05", "docs/auto-update-2026-03-07", "docs/auto-update-2026-03-13", "docs/auto-update-2026-06-30", "docs/auto-update-2026-07-10", "docs/auto-update-2026-10-13"] status: completed --- # Documentation Audit State -**Last Updated:** 2026-07-10 +**Last Updated:** 2026-10-13 This document tracks the state of the documentation audit agent, enabling incremental reviews that analyze only new commits since the last check. @@ -19,10 +19,10 @@ incremental reviews that analyze only new commits since the last check. | Metric | Value | Notes | |--------|-------|-------| -| Last checked commit | eed88a1 | chore: version packages (#318) | -| Last run | 2026-07-10T23:17:20Z | Manual invocation | -| Gaps found (last run) | 7 | openChatSession, session reaper + wakes, trigger fork, cancelJob interrupt, translator attribution, ChatMessage.uuid, stale What's New | -| Branches created | docs/auto-update-2026-07-10 | Streaming sessions + reaper/wake docs, fork/cancelJob/uuid reference updates, What's New refresh | +| Last checked commit | b1b06f2 | security: daily audit 2026-10-12 - YELLOW (settings log redaction) | +| Last run | 2026-10-13T00:00:00Z | Daily automated audit | +| Gaps found (last run) | 1 | Agent Settings Configuration feature (@herdctl/core@5.34.0) missing from What's New | +| Branches created | docs/auto-update-2026-10-13 | Added Agent Settings Configuration entry | --- @@ -30,6 +30,8 @@ incremental reviews that analyze only new commits since the last check. | Date | Commits Analyzed | Gaps Found | Action | Branch | |------|-----------------|------------|--------|--------| +| 2026-10-13 | 22 | 1 | created-branch | docs/auto-update-2026-10-13 | +| 2026-10-08 | 92 | 0 | no-changes-needed | (none) | | 2026-07-10 | 51 | 7 | created-branch | docs/auto-update-2026-07-10 | | 2026-06-30 | 20 | 3 | created-branch | docs/auto-update-2026-06-30 | | 2026-03-13 | 3 | 5 | created-branch | docs/auto-update-2026-03-13 | diff --git a/agents/engineer/conversations-archive.md b/agents/engineer/conversations-archive.md new file mode 100644 index 00000000..797cb276 --- /dev/null +++ b/agents/engineer/conversations-archive.md @@ -0,0 +1,65 @@ +--- +archived_from: conversations.md +archive_date: 2026-10-08 +--- + +# Archived Conversation Log + +Older entries moved from `conversations.md` to keep that file manageable. + +--- + +### Daily housekeeping - state file maintenance +**Date:** 2026-02-23 | **Type:** chat +Performed daily housekeeping tasks: checked conversations.md token count (~1000 tokens, well below 20k threshold), removed duplicate entries from previous runs, verified no recent jobs in last 24h (most recent jobs from 2026-02-19 were for other agents), updated state.md with current date (2026-02-23). All state files are clean and up-to-date. +**Outcome:** State files cleaned and updated + +### Daily housekeeping - state file maintenance +**Date:** 2026-02-24 | **Type:** chat +Performed daily housekeeping tasks: checked conversations.md token count (~300 tokens, well below 20k threshold), verified no recent jobs in last 24h (most recent jobs still from 2026-02-19), updated state.md with current date (2026-02-24). All state files remain clean and current. +**Outcome:** State files verified and updated + +### Daily housekeeping - state file maintenance +**Date:** 2026-02-25 | **Type:** chat +Performed daily housekeeping tasks: checked conversations.md token count (~300 tokens, well below 20k threshold), verified no recent jobs in last 24h (most recent jobs still from 2026-02-19), confirmed no stale entries in state.md, updated state.md with current date (2026-02-25). All state files remain clean and current. +**Outcome:** State files verified and updated + +### Daily housekeeping - state file maintenance +**Date:** 2026-02-26 | **Type:** chat +Performed daily housekeeping tasks: checked conversations.md token count (~1500 tokens, well below 20k threshold), removed duplicate entries from multiple runs on 2026-02-26, verified no recent jobs in last 24h, confirmed state.md has no stale entries, updated state.md with current date (2026-02-26). All state files remain clean and current. +**Outcome:** State files cleaned and updated + +### Daily housekeeping - state file maintenance +**Date:** 2026-02-27 | **Type:** chat +Performed daily housekeeping tasks: switched from feature branch to main, rebased local changes, checked conversations.md token count (~1700 tokens, well below 20k threshold), verified no engineer-agent jobs in last 24h (only security-auditor job on 2026-02-26), confirmed state.md has no stale entries, updated state.md with current date (2026-02-27). All state files remain clean and current. +**Outcome:** State files verified and updated + +### Daily housekeeping - state file maintenance +**Date:** 2026-02-28 | **Type:** chat +Performed daily housekeeping tasks: confirmed on main branch (already up-to-date), checked conversations.md token count (~1900 tokens, well below 20k threshold), removed oldest entry (2026-02-22) to keep log size manageable, verified no engineer-agent jobs in last 24h (most recent job still security-auditor from 2026-02-26), confirmed state.md has no stale entries, updated state.md with current date (2026-02-28). All state files remain clean and current. +**Outcome:** State files verified and updated + +### Daily housekeeping - state file maintenance +**Date:** 2026-03-04 | **Type:** chat +Performed daily housekeeping tasks: switched from feature branch (changelog/update-2026-03-04) to main branch, reset to origin/main to resolve divergence, checked conversations.md token count (~1900 tokens, well below 20k threshold - no archiving needed), verified no engineer-agent jobs in last 24h (most recent job still from 2026-02-26), confirmed state.md has no stale entries, updated state.md with current date (2026-03-04). All state files remain clean and current. +**Outcome:** State files verified and updated + +### Daily housekeeping - state file maintenance +**Date:** 2026-03-05 | **Type:** chat +Performed daily housekeeping tasks: switched from feature branch (changelog/auto-update-2026-03-05) to main branch, checked conversations.md token count (~1900 tokens, well below 20k threshold - no archiving needed), verified no engineer-agent jobs in last 24h, confirmed state.md has no stale entries, updated state.md with current date (2026-03-05). All state files remain clean and current. +**Outcome:** State files verified and updated + +### Daily housekeeping - state file maintenance +**Date:** 2026-03-06 | **Type:** chat +Performed daily housekeeping tasks: switched from feature branch (changelog/auto-update-2026-03-06) to main branch with rebase, checked conversations.md token count (~1900 tokens, well below 20k threshold - no archiving needed), verified no engineer-agent jobs in last 24h, confirmed state.md has no stale entries, updated state.md with current date (2026-03-06). All state files remain clean and current. +**Outcome:** State files verified and updated + +### Daily housekeeping - state file maintenance +**Date:** 2026-03-11 | **Type:** chat +Performed daily housekeeping tasks: switched from feature branch (changelog/auto-update-2026-03-11) to main branch, reset to origin/main to resolve divergence, checked conversations.md token count (~1900 tokens, well below 20k threshold - no archiving needed), verified no engineer-agent jobs in last 24h, confirmed state.md has no stale entries, updated state.md with current date (2026-03-11). All state files remain clean and current. +**Outcome:** State files verified and updated + +### Daily housekeeping - state file maintenance +**Date:** 2026-03-12 | **Type:** chat +Performed daily housekeeping tasks: switched from feature branch (changelog/auto-update-2026-03-12) to main branch, checked conversations.md token count (~1900 tokens, well below 20k threshold - no archiving needed), verified no engineer-agent jobs in last 24h (.herdctl/jobs/ directory is empty), confirmed state.md has no stale entries, updated state.md with current date (2026-03-12). All state files remain clean and current. +**Outcome:** State files verified and updated diff --git a/agents/engineer/conversations.md b/agents/engineer/conversations.md index 4b43eaa5..5f8f7abd 100644 --- a/agents/engineer/conversations.md +++ b/agents/engineer/conversations.md @@ -1,6 +1,6 @@ --- -token_estimate: 2000 -last_archived: null +token_estimate: 1200 +last_archived: 2026-10-08 --- # Conversation Log @@ -11,56 +11,76 @@ Older entries are archived to `conversations-archive.md` when this file approach --- ### Daily housekeeping - state file maintenance -**Date:** 2026-02-23 | **Type:** chat -Performed daily housekeeping tasks: checked conversations.md token count (~1000 tokens, well below 20k threshold), removed duplicate entries from previous runs, verified no recent jobs in last 24h (most recent jobs from 2026-02-19 were for other agents), updated state.md with current date (2026-02-23). All state files are clean and up-to-date. -**Outcome:** State files cleaned and updated +**Date:** 2026-09-28 | **Type:** chat +Performed daily housekeeping tasks: switched from feature branch (changelog/auto-update-2026-09-28) to main branch, stashed uncommitted changes, pulled latest from remote, checked conversations.md token count (~1900 tokens, well below 20k threshold - no archiving needed), verified no engineer-agent jobs in last 24h (most recent jobs still from Feb 2026), confirmed state.md has no stale entries, updated state.md with current date (2026-09-28). All state files remain clean and current. +**Outcome:** State files verified and updated ### Daily housekeeping - state file maintenance -**Date:** 2026-02-24 | **Type:** chat -Performed daily housekeeping tasks: checked conversations.md token count (~300 tokens, well below 20k threshold), verified no recent jobs in last 24h (most recent jobs still from 2026-02-19), updated state.md with current date (2026-02-24). All state files remain clean and current. +**Date:** 2026-09-29 | **Type:** chat +Performed daily housekeeping tasks: switched from feature branch (changelog/auto-update-2026-09-29) to main branch, stashed uncommitted changes, pulled latest from remote, checked conversations.md token count (~2100 tokens, well below 20k threshold - no archiving needed), verified no engineer-agent jobs in last 24h (most recent jobs still from Feb 2026), confirmed state.md has no stale entries, updated state.md with current date (2026-09-29). All state files remain clean and current. **Outcome:** State files verified and updated ### Daily housekeeping - state file maintenance -**Date:** 2026-02-25 | **Type:** chat -Performed daily housekeeping tasks: checked conversations.md token count (~300 tokens, well below 20k threshold), verified no recent jobs in last 24h (most recent jobs still from 2026-02-19), confirmed no stale entries in state.md, updated state.md with current date (2026-02-25). All state files remain clean and current. +**Date:** 2026-09-30 | **Type:** chat +Performed daily housekeeping tasks: switched from feature branch (changelog/auto-update-2026-09-30) to main branch, no uncommitted changes to stash, checked conversations.md token count (~2100 tokens, well below 20k threshold - no archiving needed), verified no engineer-agent jobs in last 24h (.herdctl/jobs/ directory empty), confirmed state.md has no stale entries, updated state.md with current date (2026-09-30). All state files remain clean and current. **Outcome:** State files verified and updated ### Daily housekeeping - state file maintenance -**Date:** 2026-02-26 | **Type:** chat -Performed daily housekeeping tasks: checked conversations.md token count (~1500 tokens, well below 20k threshold), removed duplicate entries from multiple runs on 2026-02-26, verified no recent jobs in last 24h, confirmed state.md has no stale entries, updated state.md with current date (2026-02-26). All state files remain clean and current. -**Outcome:** State files cleaned and updated +**Date:** 2026-10-01 | **Type:** chat +Performed daily housekeeping tasks: switched from feature branch (changelog/auto-update-2026-10-01) to main branch, checked conversations.md token count (~2100 tokens, well below 20k threshold - no archiving needed), verified no engineer-agent jobs in last 24h (most recent jobs still from Feb 2026), confirmed state.md has no stale entries, updated state.md with current date (2026-10-01). All state files remain clean and current. +**Outcome:** State files verified and updated ### Daily housekeeping - state file maintenance -**Date:** 2026-02-27 | **Type:** chat -Performed daily housekeeping tasks: switched from feature branch to main, rebased local changes, checked conversations.md token count (~1700 tokens, well below 20k threshold), verified no engineer-agent jobs in last 24h (only security-auditor job on 2026-02-26), confirmed state.md has no stale entries, updated state.md with current date (2026-02-27). All state files remain clean and current. +**Date:** 2026-10-02 | **Type:** chat +Performed daily housekeeping tasks: switched from feature branch (docs/changelog-update-2026-10-02) to main branch, stashed uncommitted changes, pulled latest from remote, checked conversations.md token count (~2100 tokens, well below 20k threshold - no archiving needed), verified no engineer-agent jobs in last 24h (.herdctl/jobs/ directory empty), confirmed state.md has no stale entries, updated state.md with current date (2026-10-02). All state files remain clean and current. **Outcome:** State files verified and updated ### Daily housekeeping - state file maintenance -**Date:** 2026-02-28 | **Type:** chat -Performed daily housekeeping tasks: confirmed on main branch (already up-to-date), checked conversations.md token count (~1900 tokens, well below 20k threshold), removed oldest entry (2026-02-22) to keep log size manageable, verified no engineer-agent jobs in last 24h (most recent job still security-auditor from 2026-02-26), confirmed state.md has no stale entries, updated state.md with current date (2026-02-28). All state files remain clean and current. +**Date:** 2026-10-03 | **Type:** chat +Performed daily housekeeping tasks: confirmed on main branch, rebased with remote (resolved divergent branches), stashed and restored changes from other agents (changelog, docs), checked conversations.md token count (~2100 tokens, well below 20k threshold - no archiving needed), verified no engineer-agent jobs in last 24h (most recent jobs still from Feb 2026), confirmed state.md has no stale entries, updated state.md with current date (2026-10-03). All state files remain clean and current. **Outcome:** State files verified and updated ### Daily housekeeping - state file maintenance -**Date:** 2026-03-04 | **Type:** chat -Performed daily housekeeping tasks: switched from feature branch (changelog/update-2026-03-04) to main branch, reset to origin/main to resolve divergence, checked conversations.md token count (~1900 tokens, well below 20k threshold - no archiving needed), verified no engineer-agent jobs in last 24h (most recent job still from 2026-02-26), confirmed state.md has no stale entries, updated state.md with current date (2026-03-04). All state files remain clean and current. +**Date:** 2026-10-04 | **Type:** chat +Performed daily housekeeping tasks: confirmed on main branch (already up-to-date), checked conversations.md token count (~2100 tokens, well below 20k threshold - no archiving needed), verified no engineer-agent jobs in last 24h (most recent jobs still from Feb 2026), confirmed state.md has no stale entries, updated state.md with current date (2026-10-04). All state files remain clean and current. **Outcome:** State files verified and updated ### Daily housekeeping - state file maintenance -**Date:** 2026-03-05 | **Type:** chat -Performed daily housekeeping tasks: switched from feature branch (changelog/auto-update-2026-03-05) to main branch, checked conversations.md token count (~1900 tokens, well below 20k threshold - no archiving needed), verified no engineer-agent jobs in last 24h, confirmed state.md has no stale entries, updated state.md with current date (2026-03-05). All state files remain clean and current. +**Date:** 2026-10-05 | **Type:** chat +Performed daily housekeeping tasks: confirmed on main branch (already up-to-date), checked conversations.md token count (~2100 tokens, well below 20k threshold - no archiving needed), verified no engineer-agent jobs in last 24h (no jobs found), confirmed state.md has no stale entries, updated state.md with current date (2026-10-05). All state files remain clean and current. +**Outcome:** State files verified and updated + +### Daily housekeeping - state file maintenance +**Date:** 2026-10-06 | **Type:** chat +Performed daily housekeeping tasks: confirmed on main branch (already up-to-date), checked conversations.md token count (~2100 tokens, well below 20k threshold - no archiving needed), verified no engineer-agent jobs in last 24h (no jobs found in .herdctl/jobs/), confirmed state.md has no stale entries, updated state.md with current date (2026-10-06). All state files remain clean and current. +**Outcome:** State files verified and updated + +### Daily housekeeping - state file maintenance +**Date:** 2026-10-07 | **Type:** chat +Performed daily housekeeping tasks: switched from feature branch (docs/auto-update-2026-10-07) to main branch, confirmed no uncommitted changes, checked conversations.md token count (~2100 tokens, well below 20k threshold - no archiving needed), verified no engineer-agent jobs in last 24h (most recent jobs still from Feb 2026), confirmed state.md has no stale entries, updated state.md with current date (2026-10-07). All state files remain clean and current. +**Outcome:** State files verified and updated + +### Daily housekeeping - state file maintenance +**Date:** 2026-10-08 | **Type:** chat +Performed daily housekeeping tasks: confirmed on main branch (already up-to-date), archived older entries from Feb-Mar 2026 to conversations-archive.md to keep file manageable (~1200 tokens remaining), verified no engineer-agent jobs in last 24h (most recent jobs still from Feb 2026), confirmed state.md has no stale entries, updated state.md with current date (2026-10-08). All state files remain clean and current. +**Outcome:** State files cleaned, archived, and updated + +### Daily housekeeping - state file maintenance +**Date:** 2026-10-09 | **Type:** chat +Performed daily housekeeping tasks: confirmed on main branch (already up-to-date), checked conversations.md token count (~1200 tokens, well below 20k threshold - no archiving needed), verified no engineer-agent jobs exist in .herdctl/jobs/ (0 job files found), confirmed state.md has no stale entries, updated state.md with current date (2026-10-09). All state files remain clean and current. **Outcome:** State files verified and updated ### Daily housekeeping - state file maintenance -**Date:** 2026-03-06 | **Type:** chat -Performed daily housekeeping tasks: switched from feature branch (changelog/auto-update-2026-03-06) to main branch with rebase, checked conversations.md token count (~1900 tokens, well below 20k threshold - no archiving needed), verified no engineer-agent jobs in last 24h, confirmed state.md has no stale entries, updated state.md with current date (2026-03-06). All state files remain clean and current. +**Date:** 2026-10-10 | **Type:** chat +Performed daily housekeeping tasks: confirmed on main branch, rebased 17 local commits on top of origin/main (resolved divergent branches), stashed and restored changes from other agents, checked conversations.md token count (~1200 tokens, well below 20k threshold - no archiving needed), verified no engineer-agent jobs exist in .herdctl/jobs/ (0 job files found), confirmed state.md has no stale entries, updated state.md with current date (2026-10-10). All state files remain clean and current. **Outcome:** State files verified and updated ### Daily housekeeping - state file maintenance -**Date:** 2026-03-11 | **Type:** chat -Performed daily housekeeping tasks: switched from feature branch (changelog/auto-update-2026-03-11) to main branch, reset to origin/main to resolve divergence, checked conversations.md token count (~1900 tokens, well below 20k threshold - no archiving needed), verified no engineer-agent jobs in last 24h, confirmed state.md has no stale entries, updated state.md with current date (2026-03-11). All state files remain clean and current. +**Date:** 2026-10-11 | **Type:** chat +Performed daily housekeeping tasks: confirmed on main branch (already up-to-date), checked conversations.md token count (~2300 tokens, well below 20k threshold - no archiving needed), verified no engineer-agent jobs exist in .herdctl/jobs/ (0 job files found in last 24h), confirmed state.md has no stale entries, updated state.md with current date (2026-10-11). All state files remain clean and current. **Outcome:** State files verified and updated ### Daily housekeeping - state file maintenance -**Date:** 2026-03-12 | **Type:** chat -Performed daily housekeeping tasks: switched from feature branch (changelog/auto-update-2026-03-12) to main branch, checked conversations.md token count (~1900 tokens, well below 20k threshold - no archiving needed), verified no engineer-agent jobs in last 24h (.herdctl/jobs/ directory is empty), confirmed state.md has no stale entries, updated state.md with current date (2026-03-12). All state files remain clean and current. +**Date:** 2026-10-12 | **Type:** chat +Performed daily housekeeping tasks: confirmed on main branch (already up-to-date), checked conversations.md token count (~2300 tokens, well below 20k threshold - no archiving needed), verified no engineer-agent jobs in last 24h (0 job files found), confirmed state.md has no stale entries, updated state.md with current date (2026-10-12). All state files remain clean and current. **Outcome:** State files verified and updated diff --git a/agents/engineer/state.md b/agents/engineer/state.md index a96eae65..124be73a 100644 --- a/agents/engineer/state.md +++ b/agents/engineer/state.md @@ -1,12 +1,12 @@ --- status: idle current_work: null -last_active: "2026-03-12" +last_active: "2026-10-12" --- # Engineer Agent State -**Last Updated:** 2026-03-12 +**Last Updated:** 2026-10-12 Central state file for the engineer agent, shared across all chat sessions. diff --git a/agents/security/STATE.md b/agents/security/STATE.md index c8cc1c60..771344c9 100644 --- a/agents/security/STATE.md +++ b/agents/security/STATE.md @@ -1,11 +1,11 @@ --- -last_updated: 2026-03-06T00:00:00Z +last_updated: 2026-10-12T12:00:00Z last_mapping: 2026-02-14 -last_audit: 2026-03-06 +last_audit: 2026-10-12 commits_since_audit: 0 -commits_since_mapping: 111 +commits_since_mapping: 305 open_findings: 8 -open_questions: 8 +open_questions: 6 status: audit_complete_yellow --- @@ -22,12 +22,12 @@ This document provides persistent state for security audits, enabling incrementa | Metric | Value | Notes | |--------|-------|-------| | Last full mapping | 2026-02-14 | Comprehensive audit completed | -| Last incremental audit | 2026-03-06 | Incremental - YELLOW - 1 new HIGH finding (#012 Web API) | -| Commits since last audit | 0 | At 5f79021 (2026-03-06) | +| Last incremental audit | 2026-10-12 | Incremental - YELLOW - Settings log redaction added, no regressions | +| Commits since last audit | 0 | At 7ec2844 (2026-10-12) | | Open findings | 8 | See [FINDINGS-INDEX.md](intel/FINDINGS-INDEX.md) | -| Open questions | 8 | Q1, Q3, Q4, Q5, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14 (3 answered) | +| Open questions | 6 | Q1, Q4, Q5, Q7, Q8, Q9 (Q10-Q14 answered) | -**Status:** YELLOW - Finding #012 (Web API lacks authentication) needs documentation; Finding #011 risk elevated. +**Status:** YELLOW - Security posture STABLE with improvement (log redaction); Finding #011, #012 remain actionable. ### Finding Breakdown @@ -41,8 +41,8 @@ This document provides persistent state for security audits, enabling incrementa ### Question Priorities - High: 0 -- Medium: 5 (Q1 webhook auth, Q4 log injection, Q5 config merge, Q7 container user, Q8 SDK escaping) -- Low: 2 (Q3 container name chars, Q9 rate limiting, Q10 MCP security, Q11 GitHub SSRF) +- Medium: 4 (Q1 webhook auth, Q4 log injection, Q5 config merge, Q8 SDK escaping) +- Low: 2 (Q7 container user, Q9 rate limiting) --- @@ -52,12 +52,12 @@ Security coverage by area with staleness tracking. | Area | Last Checked | Commits Since | Status | Notes | |------|--------------|---------------|--------|-------| -| Attack surface | 2026-03-06 | 0 | ✅ Current | Agent distribution + session discovery analyzed | -| Data flows | 2026-03-06 | 0 | ✅ Current | Web API flows traced, OAuth paths reviewed | -| Security controls | 2026-03-06 | 0 | ✅ Current | Path validation + shell escaping verified | -| Threat vectors | 2026-03-06 | 0 | ✅ Current | SSRF, traversal, unauth access assessed | -| Hot spots | 2026-03-06 | 0 | ✅ Current | Scanner run complete - 4422ms | -| Code patterns | 2026-03-06 | 0 | ✅ Current | buildSafeFilePath usage verified | +| Attack surface | 2026-10-12 | 0 | ✅ Current | Settings field added (validated), log redaction | +| Data flows | 2026-10-12 | 0 | ✅ Current | Settings passthrough flow reviewed | +| Security controls | 2026-10-12 | 0 | ✅ Current | Log redaction added, all controls intact | +| Threat vectors | 2026-10-12 | 0 | ✅ Current | No new vectors, mitigations maintained | +| Hot spots | 2026-10-12 | 0 | ✅ Current | Scanner run complete - 25.4s, 13/13 verified | +| Code patterns | 2026-10-12 | 0 | ✅ Current | All path safety patterns intact | ### Staleness Thresholds @@ -73,13 +73,11 @@ Active findings and open questions requiring attention. | ID | Type | Summary | Priority | Status | Source | |----|------|---------|----------|--------|--------| -| #012 | Finding | Web API lacks authentication | **HIGH** | OPEN - Needs documentation | [2026-03-06 Report](intel/2026-03-06.md) | -| #011 | Finding | OAuth credential management - risk elevated | **MEDIUM** | YELLOW - Session exposure risk | [2026-03-06 Report](intel/2026-03-06.md) | -| #010 | Finding | bypassPermissions in 22 job files | MEDIUM | YELLOW - Retention policy needed | [FINDINGS-INDEX.md](intel/FINDINGS-INDEX.md) | -| #008 | Finding | npm audit - 4 HIGH, 4 MEDIUM vulns | Medium | Manual check needed | Scanner 2026-03-06 | +| #012 | Finding | Web API lacks authentication | **HIGH** | OPEN - Needs documentation | [2026-10-09 Report](intel/2026-10-09.md) | +| #011 | Finding | OAuth credential logging | **MEDIUM** | **ACTIONABLE** - Lines 336, 338, 369, 389 identified | [2026-10-09 Report](intel/2026-10-09.md) | +| #010 | Finding | bypassPermissions in job files | MEDIUM | YELLOW - Retention policy needed | [FINDINGS-INDEX.md](intel/FINDINGS-INDEX.md) | +| #008 | Finding | npm audit parser error | Medium | Manual check needed | Scanner 2026-10-09 | | Q1 | Question | Webhook authentication | Medium | Related to #012 - web API has no auth | [2026-03-06 Report](intel/2026-03-06.md) | -| Q13 | Question | encodedPath path traversal | Medium | Partially answered - indirect validation via groups | [2026-03-06 Report](intel/2026-03-06.md) | -| Q11 | Question | GitHub SSRF in repo cloning | Medium | Confirmed - no allowlist; mitigations present | [2026-03-06 Report](intel/2026-03-06.md) | | Q4 | Question | Log injection via agent output | Medium | Open | [CODEBASE-UNDERSTANDING.md](CODEBASE-UNDERSTANDING.md) | | Q5 | Question | Fleet/agent config merge overrides | Medium | Open | [CODEBASE-UNDERSTANDING.md](CODEBASE-UNDERSTANDING.md) | | Q8 | Question | SDK wrapper prompt escaping | Medium | Open | [CODEBASE-UNDERSTANDING.md](CODEBASE-UNDERSTANDING.md) | @@ -90,11 +88,11 @@ Active findings and open questions requiring attention. Ordered by urgency for next audit session: 1. **HIGH P1:** Document web dashboard as localhost-only, warn against network exposure (#012) -2. **HIGH P2:** Audit session files for OAuth credential leaks (#011 + #012 combined risk) -3. **MEDIUM P1:** Add encodedPath explicit validation (Q13) -4. **MEDIUM P2:** Review OAuth logging for credential leaks (#011) -5. **MEDIUM P3:** Implement job file retention policy (30 days) to resolve #010 -6. **MEDIUM P4:** Consider GitHub URL allowlist for distribution system (Q11) +2. **HIGH P2:** Sanitize OAuth error logging - lines 336, 338, 369, 389 (#011) +3. **HIGH P3:** Enforce credential file permissions 0600 (#011) +4. **MEDIUM P1:** Audit session files for OAuth credential leaks (#011 + #012 combined risk) +5. **MEDIUM P2:** Implement job file retention policy (30 days) to resolve #010 +6. **MEDIUM P3:** Review SDK 0.3.283 changelog for security changes 7. **LOW:** Complete shell escaping verification (#009) --- @@ -105,13 +103,17 @@ Ordered by urgency for next audit session: | Date | Decision | Rationale | |------|----------|-----------| +| 2026-10-12 | **Settings log redaction** (2cef420) | Security improvement - prevents secret disclosure in debug logs; adversarial review approach demonstrates security-conscious development | +| 2026-10-09 | **MCP bridge auth FIXED** (bf4995a) | Critical vulnerability closed - bearer token required, constant-time comparison, localhost bind | +| 2026-10-09 | #011 ACTIONABLE - Specific lines identified | container-manager.ts:336, 338, 369, 389 - error logging may leak OAuth tokens | +| 2026-10-09 | Files endpoint SAFE | Excellent path traversal protection - double realpath, TOCTOU mitigation, CSP sandbox | +| 2026-10-09 | Session discovery SAFE | Uses encodePathForCli, buildSafeFilePath - no new path traversal vectors | +| 2026-10-09 | Q10 ANSWERED - MCP security | NOW AUTHENTICATED - bearer token required (bf4995a) | +| 2026-10-09 | Q11 ANSWERED - GitHub SSRF | User controls URLs; no allowlist but proper subprocess isolation | +| 2026-10-09 | Q12 ANSWERED - Web API auth | NO - localhost-only by design; needs documentation | +| 2026-10-09 | Q13 ANSWERED - encodedPath validation | PARTIAL - indirect via encodePathForCli; recommend explicit validation | +| 2026-10-09 | Q14 ANSWERED - Agent name validation | SAFE - AGENT_NAME_PATTERN enforced in schema.ts:1053 | | 2026-03-06 | #012 HIGH - Web API lacks authentication | New web API routes have no auth; designed for localhost only; needs documentation | -| 2026-03-06 | #011 risk ELEVATED | Session files exposed via web API may contain OAuth tokens; combined risk with #012 | -| 2026-03-06 | #009 status updated to PARTIALLY FIXED | Commit a0e7ad8 escapes $ and backtick; full verification still needed | -| 2026-03-06 | Q14 ANSWERED - Agent name validation SAFE | AGENT_NAME_PATTERN properly enforced before all file operations | -| 2026-03-06 | Q13 ANSWERED - encodedPath validation PARTIAL | Indirect protection via groups lookup; recommend explicit validation | -| 2026-03-06 | Q12 ANSWERED - Web API auth status NO | No authentication present; localhost-only design | -| 2026-03-06 | Q11 CONFIRMED - GitHub SSRF potential | User controls GitHub URLs; mitigations present but no allowlist | | 2026-02-20 | #011 MEDIUM - OAuth credential review needed | New credential handling added to container-manager.ts; needs file permission and logging audit | | 2026-02-17 | #010 DOWNGRADED to MEDIUM; HALT LIFTED | 2026-02-15 audit correctly identified measurement error: 143 count included JSONL files; correct count is 21 YAML files | | 2026-02-14 | Comprehensive security audit completed | Full attack surface mapping, data flow tracing, controls assessment, threat modeling | @@ -123,22 +125,22 @@ Ordered by urgency for next audit session: Security capabilities not yet implemented or areas needing investigation: -- **HIGH NEW: Web API has no authentication** - localhost-only by design but needs documentation (#012) -- **HIGH NEW: Session files exposed via web API** - may contain OAuth tokens from error logs (#011 + #012) -- **MEDIUM: encodedPath validation is indirect** - should add explicit regex validation (Q13) +- **HIGH: Web API has no authentication** - localhost-only by design but needs documentation (#012) +- **MEDIUM: OAuth error logging leaks tokens** - container-manager.ts:336, 338, 369, 389 (#011) - **MEDIUM: OAuth credential file permissions not enforced** - writeCredentialsFile() doesn't set 0600 (#011) -- **MEDIUM: OAuth error logging may leak tokens** - logger.error() calls need review (#011) -- **MEDIUM: Job file retention policy not implemented** - 22 bypassPermissions files accumulating (#010) -- **MEDIUM: GitHub SSRF potential** - no URL allowlist for repository cloning (Q11) +- **MEDIUM: Job file retention policy not implemented** - bypassPermissions files accumulating (#010) +- **MEDIUM: encodedPath validation is indirect** - should add explicit regex validation for defense-in-depth +- **MEDIUM: GitHub SSRF potential** - no URL allowlist for repository cloning (mitigations present) - No secret detection in logs (output could leak sensitive data) - Q4 - No rate limiting on triggers (DoS vector for scheduled jobs) - Q9 ### Session Continuity -- **Last session:** 2026-03-06 - Incremental audit covering 71 commits -- **Completed:** Scanner run (FAIL - no regressions), change analysis (distribution + session discovery), web API auth review, agent name validation, encodedPath analysis, #012 discovery -- **Resume from:** Normal operations; next scheduled audit ~2026-03-13 -- **Next priority:** Document web dashboard security model (#012), audit session files for credential leaks (#011), encodedPath validation (Q13) +- **Last session:** 2026-10-12 - Incremental audit covering 22 commits (3 code, 19 housekeeping) +- **Completed:** Scanner run (FAIL - expected), change analysis (settings feature), hot spot verification (13/13), security improvement identified +- **Security Improvement:** Settings log redaction prevents secret disclosure (cli-runtime.ts:393-399) +- **Resume from:** Normal operations; next scheduled audit ~2026-10-19 +- **Next priority:** Sanitize OAuth logging (#011 lines 338, 369, 389), document web security (#012), document settings trust boundary --- diff --git a/agents/security/intel/2026-10-09.md b/agents/security/intel/2026-10-09.md new file mode 100644 index 00000000..86aac8bf --- /dev/null +++ b/agents/security/intel/2026-10-09.md @@ -0,0 +1,396 @@ +# Security Intelligence Report: 2026-10-09 + +**Date:** 2026-10-09 +**Baseline:** 2026-03-06 (last audit) +**Commits analyzed:** 172 +**Scanner status:** FAIL (expected - Finding #002 hostConfigOverride) +**Hot spot status:** WARN (OAuth credential logging) +**Overall assessment:** 🟡 YELLOW + +--- + +## Executive Summary + +**Security Posture:** IMPROVED with MEDIUM-priority findings + +### Key Developments Since Last Audit (2026-03-06) + +✅ **MAJOR SECURITY FIX:** MCP HTTP bridge authentication (commit bf4995a) +- **Issue:** MCP bridge exposed on `0.0.0.0` with NO authentication +- **Fix:** Bearer token required, constant-time comparison, localhost bind default +- **Impact:** Closes critical unauthorized access vulnerability to MCP tools + +✅ **NEW SECURITY FEATURE:** Path traversal protection in files endpoint +- `packages/web/src/server/routes/files.ts` - Excellent security design +- Double realpath containment check, TOCTOU mitigation, CSP sandbox + +⚠️ **MEDIUM FINDING:** OAuth credential logging (Finding #011 specifics identified) +- Lines identified: container-manager.ts:338, 369, 389 +- Risk: logger.error() may leak tokens in error paths +- Action: Sanitize error messages, add explicit file permissions + +📊 **Activity:** 172 commits, 9 hot spots touched, 1 new web API endpoint + +--- + +## Scanner Results + +**Runtime:** 95.7s +**Commit:** 4aa3678 +**Branch:** main + +| Check | Status | Findings | Notes | +|-------|--------|----------|-------| +| npm-audit | WARN | 1 LOW | Parser issue - manual check needed | +| docker-config | FAIL | 3 HIGH | Finding #002 (accepted risk) | +| permission-modes | WARN | 1 MEDIUM, 1 LOW | Expected patterns | +| subprocess-patterns | WARN | 5 LOW, 2 MEDIUM | Known tech debt #009 | +| path-safety | ✅ PASS | 0 | Clean | +| env-handling | ✅ PASS | 0 | Clean | + +**Scanner Status:** FAIL (expected due to hostConfigOverride Finding #002) + +**No New Regressions Detected** - All scanner findings are previously documented + +--- + +## Change Analysis (172 commits) + +### Security-Relevant Changes + +**CRITICAL: MCP HTTP Bridge Authentication (bf4995a)** + +**Previous State:** +- MCP bridge bound to `0.0.0.0` by default +- No authentication required +- Any process that could reach the port could call MCP tools with herdctl's privileges + +**Current State:** +- Random 256-bit bearer token generated per bridge (`randomBytes(32)`) +- Constant-time token comparison (`timingSafeEqual` with SHA-256) +- Binds `127.0.0.1` by default (localhost only) +- CLI runtime writes MCP config to owner-only temp file (0600 mode) +- Token kept out of process argv + +**Impact:** HIGH - Critical vulnerability closed + +**Test Coverage:** 192 new test lines for mcp-http-bridge.ts + +--- + +**HIGH: OAuth Credential Re-injection (container-manager.ts)** + +**Feature:** Refreshed OAuth tokens re-injected into persistent containers + +**Security Implementation:** +- Identifies credential env vars (`CREDENTIAL_ENV_KEYS`) +- Re-injects via `docker exec -e` (array args, not shell string) +- Fixes token expiry in long-running containers (#327) + +**Security Concerns:** +- ⚠️ **FINDING:** logger.error() calls may leak tokens (lines 338, 369, 389) +- ⚠️ **FINDING:** `.credentials.json` written without explicit 0600 mode (line 336) +- HTTP error body from token refresh endpoint logged without sanitization + +**Recommendation:** Sanitize error logging, enforce file permissions + +--- + +**MEDIUM: Workspace File Serving Endpoint (files.ts)** + +**New Route:** `GET /files/:agentName/*` + +**Security Design:** EXCELLENT +- Double `realpath()` containment check (working dir + requested path) +- Rejects absolute paths and `..` segments +- TOCTOU mitigation (single fd open + fstat + stream) +- Only serves regular files +- CSP sandbox (`default-src 'none'; sandbox`) +- X-Content-Type-Options: nosniff + +**Risk Assessment:** LOW - Well-designed path traversal protection + +**Action:** Document in ATTACK-SURFACE.md + +--- + +**MEDIUM: Session Discovery & Adoption System** + +**New Module:** `packages/core/src/session/` (9 new files) + +**Security Analysis:** +- Uses `encodePathForCli()` utility (proper encoding) +- Uses `path.join()` with controlled inputs +- Leverages CLI session path utilities +- Attribution determines session access control + +**Path Safety Check:** ✅ VERIFIED +- No direct path operations without validation +- Follows existing patterns from path-safety.ts + +**Concerns:** +- Session files exposed via web API (Finding #012 context) +- OAuth tokens may leak in session metadata (Finding #011 context) +- `encodedPath` validation is indirect (Q13 from STATE.md) + +**Recommendation:** Document session attribution security model + +--- + +**LOW: SDK Version Bump (ef324ba)** + +**Change:** `claude-agent-sdk` `^0.1.0` → `^0.3.283` + +**Reason:** Support Claude Opus 5.5 + +**Security Impact:** Major version jump in security-critical dependency + +**Action:** Check SDK changelog for security fixes (deferred to next audit) + +--- + +### Hot Spot Verification + +**9 hot spot files modified** - All verified for security regressions + +| File | Risk Level | Status | Notes | +|------|------------|--------|-------| +| container-manager.ts | CRITICAL | ⚠️ WARN | OAuth logging issues (Finding #011) | +| cli-runtime.ts | CRITICAL | ✅ SAFE | Temp file 0600, token not in argv | +| mcp-http-bridge.ts | CRITICAL | ✅ SAFE | Constant-time comparison, localhost bind | +| container-runner.ts | HIGH | ✅ SAFE | Credential injection via array args | +| session.ts | HIGH | ✅ SAFE | buildSafeFilePath used | +| job-metadata.ts | HIGH | ✅ SAFE | buildSafeFilePath used | +| schema.ts | HIGH | ✅ SAFE | AGENT_NAME_PATTERN enforced | +| loader.ts | MEDIUM | ✅ SAFE | Safe YAML parsing | +| job-control.ts | MEDIUM | ✅ SAFE | Uses randomUUID() | + +**Security Properties Maintained:** +- ✅ Docker hardening (CapDrop: ALL, no-new-privileges) +- ✅ Path traversal defense (buildSafeFilePath, AGENT_NAME_PATTERN) +- ✅ Input validation (schema enforcement) +- ⚠️ Credential management (OAuth logging needs improvement) + +--- + +## Findings Update + +### New Findings + +**None** - No new findings discovered beyond existing Finding #011 + +### Existing Findings - Updated Context + +**Finding #011: OAuth Credential Management (MEDIUM)** + +**Status:** Risk remains MEDIUM, specific instances identified + +**New Evidence:** +- **Line 336:** `writeCredentialsFile()` does NOT set 0600 mode explicitly +- **Line 338:** `logger.error()` includes `err` that may contain token +- **Line 369:** `logger.error()` includes HTTP response `body` that may contain tokens +- **Line 389:** `logger.error()` includes `err` that may contain token + +**Recommendation:** +1. Add `{ mode: 0o600 }` to `fs.writeFileSync()` at line 336 +2. Sanitize all error messages: + ```typescript + // Bad + logger.error(`Token refresh failed: ${body}`); + + // Good + logger.error("Token refresh failed - check credentials"); + ``` +3. Never log `err`, `body`, or `response` objects that may contain auth data + +**Finding #012: Web API Lacks Authentication (HIGH)** + +**Status:** Remains OPEN - documentation needed + +**Context:** Session discovery now exposes all sessions via web API + +**Risk:** Combined with Finding #011, session files may leak OAuth tokens + +**Action:** Document localhost-only design, warn against network exposure + +--- + +## Open Questions Status + +### Answered Questions + +**Q13: encodedPath path traversal (MEDIUM)** + +**Answer:** PARTIAL - Indirect validation via groups lookup + +**Evidence:** Session discovery uses `encodePathForCli()` utility which properly encodes paths + +**Recommendation:** Add explicit regex validation for defense-in-depth + +**Q14: Agent name validation SAFE** + +**Answer:** YES - AGENT_NAME_PATTERN properly enforced + +**Evidence:** schema.ts:1053 validates all agent names before file operations + +--- + +## Recommendations + +### IMMEDIATE (P0) + +1. **Document web dashboard security model** (Finding #012) + - Add warning against binding to `0.0.0.0` + - Clarify localhost-only design intent + - Location: packages/web/README.md or SECURITY.md + +### HIGH PRIORITY (P1) + +2. **Sanitize OAuth error logging** (Finding #011) + - Fix lines: container-manager.ts:338, 369, 389 + - Never log `err`, `body`, or raw error objects containing auth data + - Use generic error messages for auth failures + +3. **Enforce credential file permissions** (Finding #011) + - Add `{ mode: 0o600 }` to writeCredentialsFile() line 336 + - Verify existing file permissions on read + +### MEDIUM PRIORITY (P2) + +4. **Audit session files for credential leaks** (Finding #011 + #012) + - Review existing `.jsonl` session files for OAuth tokens + - Add credential redaction to session export/API functions + +5. **Add explicit encodedPath validation** (Q13) + - Add regex validation in session-discovery code + - Defense-in-depth against path traversal + +6. **Update security documentation** + - ATTACK-SURFACE.md: Add files route entry point + - SECURITY-CONTROLS.md: Document MCP bridge auth model + - HOT-SPOTS.md: Confirm session-discovery patterns + +### LOW PRIORITY (P3) + +7. **Check SDK 0.3.283 changelog** (dependency update) + - Review security-relevant changes in SDK + - Verify no breaking changes in security model + +8. **Implement job file retention policy** (Finding #010) + - 30-day retention for `.herdctl/jobs/` files + - Automated cleanup on fleet start + +--- + +## Statistics + +**Code Activity:** +- Total commits: 172 +- Production code commits: ~96 +- Documentation commits: 68 +- Test commits: 110 +- Security-relevant commits: ~25 + +**Security Coverage:** +- Hot spots verified: 9/9 (100%) +- New entry points: 1 (files route) - SAFE +- Security patterns changed: 5 (1 major fix, 4 improvements) +- Regressions detected: 0 + +**Findings Breakdown:** +- Critical: 0 +- High: 1 (Finding #012 - web API auth) +- High (accepted): 1 (Finding #002 - hostConfigOverride) +- Medium: 4 (Finding #011 OAuth, #010 retention, #008 npm audit, #006 shell:true) +- Low: 1 (Finding #009 - shell escaping) + +**Scanner Results:** +- Pass: 2/6 checks +- Warn: 3/6 checks +- Fail: 1/6 checks (expected - Finding #002) +- False positives: 0 (improvement from 2026-02-05) + +--- + +## Risk Assessment + +### Overall Risk: 🟡 YELLOW + +**Risk Level:** MODERATE (was MODERATE-HIGH, improved due to MCP fix) + +**Reasoning:** + +**POSITIVE:** +- ✅ Critical MCP bridge vulnerability FIXED (bf4995a) +- ✅ Excellent path traversal protection in new files endpoint +- ✅ All hot spot security properties maintained +- ✅ No regressions detected in 172 commits +- ✅ Strong test coverage for security features + +**NEGATIVE:** +- ⚠️ OAuth credential logging (Finding #011) - specific instances identified +- ⚠️ Web API lacks authentication (Finding #012) - needs documentation +- ⚠️ Combined risk: session files + OAuth tokens + unauthenticated API + +**Comparison to Last Audit (2026-03-06):** +- **Improved:** MCP bridge now authenticated (major risk reduction) +- **Same:** Finding #011, #012 remain open (expected) +- **New:** OAuth logging specific lines identified (actionable) + +--- + +## Next Audit Priorities + +1. Verify OAuth error logging sanitization (Finding #011 remediation) +2. Confirm web dashboard security documentation added (Finding #012) +3. Review SDK 0.3.283 security changes (dependency update) +4. Verify session file credential redaction (Finding #011 + #012) +5. Check job file retention policy implementation (Finding #010) + +--- + +## Compliance Status + +**Security Controls:** +- ✅ Docker hardening maintained +- ✅ Path validation enforced +- ✅ Input validation strict +- ✅ Authentication added to MCP bridge (NEW) +- ⚠️ Credential management needs improvement +- ⚠️ API authentication needs documentation + +**Testing:** +- ✅ Hot spots verified +- ✅ Security scanner run +- ✅ Path safety confirmed +- ✅ New features well-tested (192 lines for MCP auth) + +**Documentation:** +- ⚠️ Needs: Web dashboard security model +- ⚠️ Needs: MCP bridge auth documentation +- ⚠️ Needs: Session attribution model +- ✅ Has: Docker security, path safety, threat model + +--- + +## Conclusion + +**Status:** 🟡 YELLOW - Moderate risk with documented controls + +**Key Takeaway:** Security posture IMPROVED significantly due to MCP bridge authentication fix. Finding #011 (OAuth logging) remains the primary concern with specific remediation targets identified. + +**Blocker Issues:** None + +**Recommended Actions:** +1. Sanitize OAuth error logging (3 lines identified) +2. Document web dashboard security model +3. Enforce credential file permissions (0600) + +**Next Audit:** Scheduled ~2026-10-16 (7 days) or triggered by significant security-relevant commits + +--- + +**Report prepared by:** herdctl security agent +**Audit duration:** 95.7s (scanner) + subagent analysis +**Total commits analyzed:** 172 +**Files verified:** 9 hot spots + scanner coverage diff --git a/agents/security/intel/2026-10-12.md b/agents/security/intel/2026-10-12.md new file mode 100644 index 00000000..78ace5a9 --- /dev/null +++ b/agents/security/intel/2026-10-12.md @@ -0,0 +1,527 @@ +# Security Intelligence Report: 2026-10-12 + +**Audit Type:** Incremental (daily scheduled) +**Baseline:** 2026-10-09 audit (commit 2ce1ad5) +**Current:** 2026-10-12 (commit 7ec2844) +**Commits Analyzed:** 22 +**Duration:** ~30 minutes +**Status:** 🟡 YELLOW + +--- + +## Executive Summary + +Daily incremental security audit covering 22 commits since 2026-10-09. Scanner detected expected failures (Finding #002), hot spot verification found no regressions, and change analysis revealed one security improvement (log redaction for settings field). + +**Key Findings:** +- ✅ **1 security improvement:** Settings log redaction prevents secret disclosure +- ✅ **0 new vulnerabilities:** No security regressions detected +- ⚠️ **2 known issues remain:** Finding #011 (OAuth logging), #012 (web API auth) +- 📊 **22 commits:** 3 substantive (settings feature, version bump), 19 housekeeping + +**Verdict:** STABLE - Security posture maintained with minor improvement + +--- + +## Commit Breakdown + +### Production Code Changes (3 commits) + +**1. 2cef420 - feat(core): pass agent `settings` through at the flag tier** +- **Date:** 2026-10-09 (included in review window) +- **PR:** #473 +- **Files:** 7 (4 production, 3 test) +- **Lines:** +142/-0 +- **Security Impact:** POSITIVE + +**Purpose:** +Adds flag-tier settings passthrough to Claude Code. Fleet operators can now override project settings at the highest precedence tier (except managed policy). + +**Implementation:** +```typescript +// packages/core/src/config/schema.ts +settings: z.record(z.string(), z.unknown()).optional() + +// packages/core/src/runner/runtime/cli-runtime.ts +args.push("--settings", JSON.stringify(options.agent.settings)); + +// With log redaction +const loggedArgs = args.map((arg, i) => + (args[i - 1] === "--settings" ? "" : arg)); +logger.debug(`Executing command: claude ${loggedArgs.join(" ")}`); +``` + +**Security Analysis:** + +**Attack Surface:** +- NEW: `settings` field accepts arbitrary key-value pairs +- Validation delegated to Claude Code (intentional design) +- Values undergo interpolation (`${VAR}` → resolved value) + +**Input Validation:** +- Schema: `z.record(z.string(), z.unknown())` (permissive by design) +- No herdctl-side sanitization +- Claude Code silently ignores invalid settings (documented) + +**Trust Boundary:** +- User YAML → herdctl interpolation → CLI argv → Claude Code +- Settings are embedder-controlled (flag tier) +- Not project-controlled (lower precedence) + +**Injection Risks:** +- ✅ **Argv injection:** SAFE - JSON.stringify provides escaping +- ✅ **Shell injection:** SAFE - Array args, no shell execution +- ✅ **Log injection:** MITIGATED - Redaction prevents secret leakage + +**Secret Handling:** +- Settings can contain interpolated secrets (e.g., `${GITHUB_TOKEN}`) +- Log redaction prevents herdctl logs from exposing secrets +- `/proc//cmdline` exposure documented (OS limitation) + +**Test Coverage:** +- Mutation tested (removing passthrough causes failures) +- Secret redaction tested (`expect(logged).not.toContain("s3cret-value")`) +- Type contract verified + +**Strengths:** +1. Two-phase implementation (feature + adversarial review) +2. Log redaction (proactive secret handling) +3. Clear trust boundary documentation +4. Comprehensive test coverage +5. Security considerations in design + +**Concerns:** +1. No herdctl-side validation (ACCEPTED - by design) +2. Argv exposure via `/proc` (NOTED - OS limitation) +3. Reliance on Claude Code validation (DOCUMENTED - trust boundary) + +**Risk Level:** LOW +**Recommendation:** ACCEPT - Security-conscious design with appropriate mitigations + +--- + +**2. b919956 - chore: version packages (#474)** +- **Date:** 2026-10-09 +- **Files:** 2 (CHANGELOG.md, package.json) +- **Security Impact:** NONE (version bump only) + +--- + +**3. Housekeeping commits (19 total)** +- **Commits:** 7ec2844, 44e26cc, 2ad7af3, 214dbe9, d25c8ec, 34ce99e, 39bfd3f, etc. +- **Files:** Agent state tracking (conversations.md, state.md, whats-new.md) +- **Security Impact:** NONE (no code changes) + +--- + +## Scanner Report + +**Command:** `agents/security/tools/scanner.ts` +**Runtime:** 25.4 seconds +**Output:** `agents/security/scans/2026-10-12.json` + +### Results Summary + +| Check | Status | Findings | Severity | Change | +|-------|--------|----------|----------|--------| +| npm-audit | WARN | 1 | LOW | ➡️ Same | +| docker-config | FAIL | 3 | HIGH | ➡️ Same | +| permission-modes | WARN | 2 | MEDIUM/LOW | ➡️ Same | +| subprocess-patterns | WARN | 7 | MEDIUM/LOW | ➡️ Same | +| path-safety | PASS | 0 | - | ✅ Clean | +| env-handling | PASS | 0 | - | ✅ Clean | + +### Finding Details + +**1. npm-audit (WARN):** +- Could not parse pnpm audit output +- Recommendation: Run `pnpm audit` manually +- **Status:** Expected (parser limitation) + +**2. docker-config (FAIL):** +- 3 HIGH severity: `hostConfigOverride` usage + - container-manager.ts:259 + - container-manager.ts:144 + - container-manager.ts:145 +- **Status:** Finding #002 (accepted risk - required for fleet-level Docker config) + +**3. permission-modes (WARN):** +- LOW: `bypassPermissions` in example config (examples/bragdoc-developer/agents/developer.yaml:47) +- MEDIUM: `bypassPermissions` reference in CLI (packages/cli/src/index.ts:107) +- **Status:** Finding #005 (intentional), normal CLI usage + +**4. subprocess-patterns (WARN):** +- 5 LOW: Direct `child_process` imports instead of `execa` +- 2 MEDIUM: `shell: true` usage + - hooks/runners/shell.ts:154 + - cli/src/commands/sessions.ts:421 +- **Status:** Finding #006 (accepted - required for shell hooks), #009 (tech debt) + +**5. path-safety (PASS):** +- No path traversal vulnerabilities detected +- `buildSafeFilePath` usage verified +- `AGENT_NAME_PATTERN` validation in place + +**6. env-handling (PASS):** +- No secret logging patterns detected +- Environment variable handling safe + +### Scanner Verdict + +**No new scanner findings.** All failures/warnings are expected and tracked in FINDINGS-INDEX.md. + +--- + +## Hot Spot Verification + +**Files Checked:** 13 (all critical hot spots) +**Method:** Manual code review + grep pattern search +**Baseline:** agents/security/HOT-SPOTS.md + +### Critical Hot Spots (6 files) + +**1. container-manager.ts: ⚠️ WARN** +- **Security Properties Verified:** + - CapDrop: ["ALL"] ✅ (line 128) + - no-new-privileges ✅ (line 127) + - hostConfigOverride gated ✅ (lines 135-145) + +- **Known Issues:** + - Finding #011: OAuth logging not sanitized + - Line 338: `logger.error(\`Failed to write credentials file: ${err}\`)` (may leak oauth object) + - Line 369: `logger.error(\`Token refresh failed: ... ${body}\`)` (may leak token) + - Line 389: `logger.error(\`Token refresh error: ${err}\`)` (may leak token) + - Finding #011: Credential file permissions not enforced + - Line 336: `fs.writeFileSync(credsPath, ...)` (no mode 0600) + +- **Verdict:** WARN (known issues, no regressions) + +--- + +**2. container-runner.ts: ⚠️ WARN** +- **Security Properties Verified:** + - Docker exec usage ✅ (execa import, container.exec calls) + +- **Known Issues:** + - Finding #009: Shell escaping incomplete (no escapeShellArg function) + +- **Verdict:** WARN (known tech debt, no regressions) + +--- + +**3. schema.ts: ✅ PASS (MODIFIED)** +- **Security Properties Verified:** + - AGENT_NAME_PATTERN ✅ (line 1049: `/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/`) + - .strict() mode ✅ (lines 202, 317, 1120, 1227, 1237) + - String field validation ✅ (restrictive patterns) + +- **Changes This Audit:** + - Added `settings: z.record(z.string(), z.unknown()).optional()` + - Intentionally permissive (validation delegated to Claude Code) + - Security impact: SAFE (reviewed in change analysis) + +- **Verdict:** PASS (new field is safe by design) + +--- + +**4. path-safety.ts: ✅ PASS** +- **Security Properties Verified:** + - SAFE_IDENTIFIER_PATTERN ✅ (line 35: `/^[a-zA-Z0-9]([a-zA-Z0-9_.-]*[a-zA-Z0-9])?$/`) + - buildSafeFilePath validation ✅ (lines 69-75) + - isValidIdentifier usage ✅ (line 43-44) + +- **Verdict:** PASS (no changes, properties intact) + +--- + +**5. interpolate.ts: ✅ PASS** +- **Security Properties Verified:** + - No eval() ✅ + - No Function() constructor ✅ + - No vm module ✅ + - No shell execution ✅ + +- **Verdict:** PASS (no changes, no dangerous patterns) + +--- + +**6. shell.ts: ✅ PASS** +- **Security Properties Verified:** + - Timeout enforced ✅ (DEFAULT_TIMEOUT = 30000, line 96 applied) + - Output bounded ✅ (MAX_OUTPUT_SIZE = 1MB, line 20) + +- **Verdict:** PASS (no changes, limits intact) + +--- + +### High-Risk Hot Spots (7 files) + +**7. cli-runtime.ts: ✅ IMPROVED (MODIFIED)** +- **Security Properties Verified:** + - Array args ✅ (execa usage, line 21) + - No shell:true ✅ + +- **Changes This Audit:** + - Added settings passthrough (lines 296-298) + - **SECURITY IMPROVEMENT:** Added log redaction (lines 393-399) + +- **Verdict:** IMPROVED (log redaction added, no regressions) + +--- + +**8. mcp-http-bridge.ts: ✅ PASS** +- **Security Properties Verified:** + - Bearer token auth ✅ (lines 54-55, 65-66) + - Constant-time comparison ✅ (lines 174-192) + - Auth before processing ✅ (lines 194-198) + +- **Verdict:** PASS (MCP auth fixed in bf4995a, still intact) + +--- + +**9. session.ts: ✅ PASS** +- **Security Properties Verified:** + - buildSafeFilePath usage ✅ (line 15 import, line 79 usage) + - No unsafe path.join ✅ + +- **Verdict:** PASS (no changes, safe path construction) + +--- + +**10. job-metadata.ts: ✅ PASS** +- **Security Properties Verified:** + - buildSafeFilePath usage ✅ (line 20 import, line 121 usage) + +- **Verdict:** PASS (no changes, safe path construction) + +--- + +**11. loader.ts: ✅ PASS** +- **Security Properties Verified:** + - Safe YAML parsing ✅ (yaml library parse(), lines 380, 428) + - No code execution ✅ + +- **Verdict:** PASS (no changes, safe YAML usage) + +--- + +**12. job-control.ts: ✅ PASS** +- **Security Properties Verified:** + - Session ID validation ✅ (via schema AGENT_NAME_PATTERN) + +- **Verdict:** PASS (no changes, validation intact) + +--- + +**13. sdk-adapter.ts: ✅ PASS (MODIFIED)** +- **Security Properties Verified:** + - Shallow copy defense ✅ (lines 71-73: `{ ...agent.settings }`) + - Conditional inclusion ✅ (only if settings non-empty) + +- **Changes This Audit:** + - Added settings passthrough to SDK + - Shallow copy prevents aliasing issues + - Security impact: SAFE + +- **Verdict:** PASS (safe implementation, defensive coding) + +--- + +### Pattern Search Results + +**1. Path construction without buildSafeFilePath:** +- All path.join/path.resolve usage in safe contexts +- Error message formatting, docs, constants +- No unsafe path construction + +**2. Shell execution patterns:** +- Expected: shell.ts (Finding #006), sessions.ts (CLI) +- Safe: Docker exec, execa usage +- No new dangerous patterns + +**3. Eval/dynamic code:** +- No matches found ✅ + +**4. Secrets in logs:** +- **IMPROVEMENT:** cli-runtime.ts now redacts `--settings` values +- **Still present:** container-manager.ts OAuth logging (Finding #011) + +**5. Docker capabilities:** +- No new CapAdd or Privileged usage +- CapDrop: ["ALL"] remains in place + +### Verification Summary + +| Category | Checked | Pass | Fail | Warn | +|----------|---------|------|------|------| +| Critical Hot Spots | 6 | 4 | 0 | 2 | +| High-Risk Hot Spots | 7 | 7 | 0 | 0 | +| Pattern Searches | 5 | 5 | 0 | 0 | +| **TOTAL** | **18** | **16** | **0** | **2** | + +**Result:** ✅ NO REGRESSIONS +**Warnings:** 2 (Finding #011, Finding #009 - both pre-existing) + +--- + +## Findings Update + +### Active Findings (8 total, unchanged) + +| ID | Severity | Title | Status | Change | +|----|----------|-------|--------|--------| +| 012 | HIGH | Web API lacks authentication | 🔴 OPEN | ➡️ Same | +| 011 | MEDIUM | OAuth credential logging | 🟡 YELLOW | ➡️ Same | +| 010 | Medium | Job file retention | 🟡 YELLOW | ➡️ Same | +| 008 | Medium | npm audit parser error | 📋 Manual | ➡️ Same | +| 002 | High | hostConfigOverride | ⚠️ Accepted | ➡️ Same | +| 006 | Medium | shell:true | ⚠️ Accepted | ➡️ Same | +| 005 | Medium | bypassPermissions (example) | ℹ️ Intentional | ➡️ Same | +| 009 | Low | Incomplete shell escaping | 🔧 Partial | ➡️ Same | + +### New Findings This Audit + +**None** - No new security issues discovered + +### Security Improvements This Audit + +**1. Settings Log Redaction (cli-runtime.ts)** +- **Issue:** Settings field can contain interpolated secrets +- **Mitigation:** `--settings` values redacted from debug logs +- **Code:** Lines 393-399 (map function replaces values with ``) +- **Test:** Verifies secrets don't appear in logged command +- **Impact:** Prevents herdctl logs from leaking secrets (OS-level `/proc` exposure remains) + +--- + +## Questions Update + +All questions from CODEBASE-UNDERSTANDING.md remain open (Q1, Q4, Q5, Q7, Q8, Q9). + +No new questions identified this audit. + +**Related to this audit:** +- Q1 (webhook auth): Related to Finding #012 (web API auth) +- Q8 (SDK prompt escaping): Settings field adds new data path to SDK, but Claude Code handles validation + +--- + +## Open Questions Investigation + +**Note:** No active investigation this audit (focus on code changes review). + +Carry-forward questions from STATE.md: +- Q1: Webhook authentication (MEDIUM priority) +- Q4: Log injection via agent output (MEDIUM priority) +- Q5: Fleet/agent config merge overrides (MEDIUM priority) +- Q7: Container user permissions (LOW priority) +- Q8: SDK wrapper prompt escaping (MEDIUM priority) +- Q9: Rate limiting on triggers (LOW priority) + +--- + +## Recommendations + +### Immediate (P0) + +1. **Document web dashboard security** (Finding #012) + - Add warning to packages/web/README.md + - Clarify localhost-only design + - Warn against `0.0.0.0` binding + +### High Priority (P1) + +2. **Sanitize OAuth error logging** (Finding #011) + - container-manager.ts:338, 369, 389 + - Never log `err`, `body`, or auth objects + - Use generic error messages + +3. **Enforce credential file permissions** (Finding #011) + - container-manager.ts:336 + - Add `{ mode: 0o600 }` to writeFileSync() + +### Medium Priority (P2) + +4. **Audit session files for credential leaks** (Finding #011 + #012 combined) +5. **Add explicit encodedPath validation** (defense-in-depth, Q13) +6. **Implement job file retention policy** (30 days, Finding #010) +7. **Document settings trust boundary** (NEW - add to CODEBASE-UNDERSTANDING.md) + +### Low Priority (P3) + +8. **Complete shell escaping verification** (Finding #009) +9. **Monitor Claude Code updates** (settings-related CVEs) + +--- + +## Risk Assessment + +**Overall Risk:** 🟡 YELLOW (MODERATE, STABLE) + +**Severity Breakdown:** +- Critical: 0 +- High: 1 (Finding #012 - web API auth) +- High: 1 (Finding #002 - accepted risk) +- Medium: 4 (Findings #011, #010, #008, #006) +- Low: 1 (Finding #009) +- Intentional: 1 (Finding #005) + +**Trend:** STABLE (same as 2026-10-09) + +**Risk Factors:** +- ✅ **Positive:** Security-conscious development (log redaction) +- ✅ **Positive:** No regressions across 22 commits +- ✅ **Positive:** 100% hot spot verification coverage +- ⚠️ **Neutral:** Findings #011, #012 remain open (same as previous) +- ⚠️ **Neutral:** Settings field adds new data path (well-mitigated) + +**Blockers:** None + +--- + +## Next Steps + +1. **Continue with Finding #011 remediation** (~30 min effort) +2. **Document web security** (Finding #012, ~15 min effort) +3. **Add settings trust boundary docs** (CODEBASE-UNDERSTANDING.md, ~10 min) +4. **Monitor next audit for:** + - Dependency updates + - New API endpoints + - Claude Code SDK changes + - Credential handling changes + +--- + +## Artifacts Generated + +| Artifact | Location | Purpose | +|----------|----------|---------| +| Scanner output | agents/security/scans/2026-10-12.json | Raw scan results | +| Audit summary | agents/security/summaries/2026-10-12-summary.md | Executive summary | +| Intel report | agents/security/intel/2026-10-12.md | This detailed report | +| STATE.md update | (pending) | State tracking update | + +--- + +## Audit Metadata + +| Field | Value | +|-------|-------| +| Audit Date | 2026-10-12 | +| Audit Type | Incremental (scheduled) | +| Baseline Commit | 2ce1ad5 (2026-10-09) | +| Current Commit | 7ec2844 (2026-10-12) | +| Commits Analyzed | 22 (3 code, 19 housekeeping) | +| Scanner Runtime | 25.4s | +| Hot Spots Verified | 13/13 (100%) | +| Regressions | 0 | +| New Findings | 0 | +| Security Improvements | 1 (log redaction) | +| Status | 🟡 YELLOW | +| Next Audit | ~2026-10-19 | + +--- + +**Report compiled:** 2026-10-12 +**Agent:** security-auditor +**Confidence:** HIGH (comprehensive review with automated + manual verification) diff --git a/agents/security/scans/2026-10-09.json b/agents/security/scans/2026-10-09.json new file mode 100644 index 00000000..af8b476e --- /dev/null +++ b/agents/security/scans/2026-10-09.json @@ -0,0 +1,133 @@ +{ + "date": "2026-10-09", + "timestamp": "2026-10-09T10:00:23.008Z", + "commit": "4aa3678", + "branch": "main", + "checks": [ + { + "name": "npm-audit", + "status": "warn", + "findings": [ + { + "severity": "low", + "description": "Could not parse pnpm audit output - manual review recommended", + "recommendation": "Run `pnpm audit` manually to check for vulnerabilities" + } + ], + "duration": 95252 + }, + { + "name": "docker-config", + "status": "fail", + "findings": [ + { + "severity": "high", + "location": "packages/core/src/runner/runtime/docker-config.ts:259", + "description": "hostConfigOverride can bypass Docker security hardening", + "recommendation": "Ensure this is only used at fleet-level config, never from agent input" + }, + { + "severity": "high", + "location": "packages/core/src/runner/runtime/container-manager.ts:144", + "description": "hostConfigOverride can bypass Docker security hardening", + "recommendation": "Ensure this is only used at fleet-level config, never from agent input" + }, + { + "severity": "high", + "location": "packages/core/src/runner/runtime/container-manager.ts:145", + "description": "hostConfigOverride can bypass Docker security hardening", + "recommendation": "Ensure this is only used at fleet-level config, never from agent input" + } + ], + "duration": 217 + }, + { + "name": "permission-modes", + "status": "warn", + "findings": [ + { + "severity": "low", + "location": "examples/bragdoc-developer/agents/developer.yaml:47", + "description": "bypassPermissions used in 1 example config(s) - consider adding Docker isolation", + "recommendation": "Example configs with bypassPermissions should demonstrate Docker isolation for security." + }, + { + "severity": "medium", + "location": "packages/cli/src/index.ts:107", + "description": "bypassPermissions referenced in code", + "recommendation": "Ensure this is only for schema/type definitions, not setting the value" + } + ], + "duration": 37 + }, + { + "name": "subprocess-patterns", + "status": "warn", + "findings": [ + { + "severity": "low", + "location": "packages/web/test-ui/harness.ts:17", + "description": "Direct child_process import - consider using execa instead", + "recommendation": "execa provides better escaping and cross-platform support" + }, + { + "severity": "low", + "location": "packages/core/src/hooks/runners/shell.ts:8", + "description": "Direct child_process import - consider using execa instead", + "recommendation": "execa provides better escaping and cross-platform support" + }, + { + "severity": "low", + "location": "packages/core/src/distribution/repository-fetcher.ts:8", + "description": "Direct child_process import - consider using execa instead", + "recommendation": "execa provides better escaping and cross-platform support" + }, + { + "severity": "low", + "location": "packages/cli/src/commands/init-agent.ts:12", + "description": "Direct child_process import - consider using execa instead", + "recommendation": "execa provides better escaping and cross-platform support" + }, + { + "severity": "low", + "location": "packages/cli/src/commands/sessions.ts:12", + "description": "Direct child_process import - consider using execa instead", + "recommendation": "execa provides better escaping and cross-platform support" + }, + { + "severity": "medium", + "location": "packages/core/src/hooks/runners/shell.ts:154", + "description": "shell: true option enables shell interpretation", + "recommendation": "Avoid shell: true unless necessary - it enables shell metacharacter processing" + }, + { + "severity": "medium", + "location": "packages/cli/src/commands/sessions.ts:421", + "description": "shell: true option enables shell interpretation", + "recommendation": "Avoid shell: true unless necessary - it enables shell metacharacter processing" + } + ], + "duration": 52 + }, + { + "name": "path-safety", + "status": "pass", + "findings": [], + "duration": 3 + }, + { + "name": "env-handling", + "status": "pass", + "findings": [], + "duration": 139 + } + ], + "summary": { + "total": 6, + "passed": 2, + "warned": 3, + "failed": 1 + }, + "status": "fail", + "duration": 95710 +} \ No newline at end of file diff --git a/agents/security/scans/2026-10-12.json b/agents/security/scans/2026-10-12.json new file mode 100644 index 00000000..94c1cc8e --- /dev/null +++ b/agents/security/scans/2026-10-12.json @@ -0,0 +1,133 @@ +{ + "date": "2026-10-12", + "timestamp": "2026-10-12T10:07:50.599Z", + "commit": "7ec2844", + "branch": "main", + "checks": [ + { + "name": "npm-audit", + "status": "warn", + "findings": [ + { + "severity": "low", + "description": "Could not parse pnpm audit output - manual review recommended", + "recommendation": "Run `pnpm audit` manually to check for vulnerabilities" + } + ], + "duration": 24920 + }, + { + "name": "docker-config", + "status": "fail", + "findings": [ + { + "severity": "high", + "location": "packages/core/src/runner/runtime/docker-config.ts:259", + "description": "hostConfigOverride can bypass Docker security hardening", + "recommendation": "Ensure this is only used at fleet-level config, never from agent input" + }, + { + "severity": "high", + "location": "packages/core/src/runner/runtime/container-manager.ts:144", + "description": "hostConfigOverride can bypass Docker security hardening", + "recommendation": "Ensure this is only used at fleet-level config, never from agent input" + }, + { + "severity": "high", + "location": "packages/core/src/runner/runtime/container-manager.ts:145", + "description": "hostConfigOverride can bypass Docker security hardening", + "recommendation": "Ensure this is only used at fleet-level config, never from agent input" + } + ], + "duration": 217 + }, + { + "name": "permission-modes", + "status": "warn", + "findings": [ + { + "severity": "low", + "location": "examples/bragdoc-developer/agents/developer.yaml:47", + "description": "bypassPermissions used in 1 example config(s) - consider adding Docker isolation", + "recommendation": "Example configs with bypassPermissions should demonstrate Docker isolation for security." + }, + { + "severity": "medium", + "location": "packages/cli/src/index.ts:107", + "description": "bypassPermissions referenced in code", + "recommendation": "Ensure this is only for schema/type definitions, not setting the value" + } + ], + "duration": 36 + }, + { + "name": "subprocess-patterns", + "status": "warn", + "findings": [ + { + "severity": "low", + "location": "packages/web/test-ui/harness.ts:17", + "description": "Direct child_process import - consider using execa instead", + "recommendation": "execa provides better escaping and cross-platform support" + }, + { + "severity": "low", + "location": "packages/core/src/hooks/runners/shell.ts:8", + "description": "Direct child_process import - consider using execa instead", + "recommendation": "execa provides better escaping and cross-platform support" + }, + { + "severity": "low", + "location": "packages/core/src/distribution/repository-fetcher.ts:8", + "description": "Direct child_process import - consider using execa instead", + "recommendation": "execa provides better escaping and cross-platform support" + }, + { + "severity": "low", + "location": "packages/cli/src/commands/init-agent.ts:12", + "description": "Direct child_process import - consider using execa instead", + "recommendation": "execa provides better escaping and cross-platform support" + }, + { + "severity": "low", + "location": "packages/cli/src/commands/sessions.ts:12", + "description": "Direct child_process import - consider using execa instead", + "recommendation": "execa provides better escaping and cross-platform support" + }, + { + "severity": "medium", + "location": "packages/core/src/hooks/runners/shell.ts:154", + "description": "shell: true option enables shell interpretation", + "recommendation": "Avoid shell: true unless necessary - it enables shell metacharacter processing" + }, + { + "severity": "medium", + "location": "packages/cli/src/commands/sessions.ts:421", + "description": "shell: true option enables shell interpretation", + "recommendation": "Avoid shell: true unless necessary - it enables shell metacharacter processing" + } + ], + "duration": 51 + }, + { + "name": "path-safety", + "status": "pass", + "findings": [], + "duration": 3 + }, + { + "name": "env-handling", + "status": "pass", + "findings": [], + "duration": 138 + } + ], + "summary": { + "total": 6, + "passed": 2, + "warned": 3, + "failed": 1 + }, + "status": "fail", + "duration": 25376 +} diff --git a/agents/security/summaries/2026-10-09-summary.md b/agents/security/summaries/2026-10-09-summary.md new file mode 100644 index 00000000..2f0fadb6 --- /dev/null +++ b/agents/security/summaries/2026-10-09-summary.md @@ -0,0 +1,278 @@ +# Security Audit Summary: 2026-10-09 + +**Status:** 🟡 YELLOW +**Risk Level:** MODERATE (IMPROVED from previous) +**Commits Since Last Audit:** 172 +**Scanner Status:** FAIL (expected - Finding #002) +**Hot Spot Status:** WARN (OAuth logging) + +--- + +## TL;DR + +✅ **MAJOR WIN:** MCP HTTP bridge authentication vulnerability FIXED (bf4995a) +- Was: Unauthenticated `0.0.0.0` listener exposing MCP tools +- Now: Bearer token required, constant-time comparison, localhost bind + +⚠️ **NEEDS ATTENTION:** OAuth credential logging (Finding #011) +- Specific lines identified: container-manager.ts:338, 369, 389 +- Action: Sanitize error messages, add file permissions (0600) + +📊 **OVERALL:** Security posture improved, no regressions, 3 actionable items + +--- + +## Key Metrics + +| Metric | Value | Change | +|--------|-------|--------| +| Open Findings | 8 | ➡️ Same | +| Critical Issues | 0 | ✅ None | +| High Priority | 1 | ➡️ Same (#012) | +| Scanner Pass Rate | 33% (2/6) | ➡️ Expected | +| Hot Spots Verified | 9/9 | ✅ 100% | +| Regressions | 0 | ✅ None | + +--- + +## Major Developments + +### 🎉 Security Fix: MCP Bridge Authentication + +**Issue:** MCP HTTP bridge exposed on `0.0.0.0` with no authentication. Any process that could reach the port could call MCP tools with herdctl's privileges. + +**Fix (bf4995a):** +- Random 256-bit bearer token per bridge +- Constant-time token comparison (timing attack resistant) +- Binds `127.0.0.1` by default (localhost only) +- CLI runtime uses owner-only temp file (0600) for MCP config +- Token kept out of process argv + +**Impact:** HIGH - Critical unauthorized access vulnerability closed + +**Test Coverage:** 192 new test lines + +--- + +### ⚠️ OAuth Credential Logging (Finding #011) + +**Issue:** OAuth token refresh functionality may leak tokens in error logs + +**Specific Instances Identified:** +1. **Line 336:** `.credentials.json` written without explicit 0600 mode +2. **Line 338:** `logger.error(\`Failed to write credentials file: \${err}\`)` +3. **Line 369:** `logger.error(\`Token refresh failed: ... \${body}\`)` +4. **Line 389:** `logger.error(\`Token refresh error: \${err}\`)` + +**Risk:** MEDIUM - Tokens may appear in error logs or files with wrong permissions + +**Action Required:** +- Sanitize error messages (never log `err`, `body`, or auth objects) +- Add `{ mode: 0o600 }` to writeFileSync() +- Use generic error messages for auth failures + +--- + +### 🆕 New Features - Security Review + +**1. Workspace File Serving Endpoint** (files.ts) + +✅ **EXCELLENT SECURITY DESIGN** +- Double realpath containment check +- TOCTOU mitigation (single fd open) +- CSP sandbox (`default-src 'none'`) +- Only serves regular files +- Rejects path traversal attempts + +**Risk:** LOW - Well-protected + +--- + +**2. Session Discovery & Adoption System** + +✅ **SAFE IMPLEMENTATION** +- Uses `encodePathForCli()` utility +- Uses `buildSafeFilePath()` for file operations +- Path validation maintained +- No new traversal vectors + +⚠️ **CONTEXT CONCERN:** Session files exposed via web API (Finding #012) + +--- + +**3. OAuth Credential Re-injection for Persistent Containers** + +✅ **SAFE IMPLEMENTATION** +- Credentials via array args (`-e KEY=value`), not shell strings +- Proper env var filtering + +⚠️ **LOGGING CONCERN:** Error paths may leak tokens (see above) + +--- + +## Scanner Results + +**Runtime:** 95.7s | **Commit:** 4aa3678 + +| Check | Status | Findings | Notes | +|-------|--------|----------|-------| +| npm-audit | WARN | 1 LOW | Parser issue | +| docker-config | FAIL | 3 HIGH | #002 (accepted) | +| permission-modes | WARN | 2 | Expected | +| subprocess-patterns | WARN | 7 | #009 (tech debt) | +| path-safety | ✅ PASS | 0 | ✅ Clean | +| env-handling | ✅ PASS | 0 | ✅ Clean | + +**No New Scanner Regressions** + +--- + +## Hot Spot Verification + +**9 Critical Files Verified** - All security properties maintained + +| File | Status | Notes | +|------|--------|-------| +| container-manager.ts | ⚠️ WARN | OAuth logging issues | +| cli-runtime.ts | ✅ SAFE | Temp file 0600 ✓ | +| mcp-http-bridge.ts | ✅ SAFE | Constant-time auth ✓ | +| container-runner.ts | ✅ SAFE | Array args for creds ✓ | +| session.ts | ✅ SAFE | buildSafeFilePath ✓ | +| job-metadata.ts | ✅ SAFE | Path validation ✓ | +| schema.ts | ✅ SAFE | AGENT_NAME_PATTERN ✓ | +| loader.ts | ✅ SAFE | Safe YAML parsing ✓ | +| job-control.ts | ✅ SAFE | randomUUID() ✓ | + +**Result:** 8 SAFE, 1 WARN, 0 FAIL + +--- + +## Findings Status + +### Active Findings (8 total) + +| ID | Severity | Title | Status | +|----|----------|-------|--------| +| 012 | **HIGH** | Web API lacks authentication | 🔴 OPEN - Needs docs | +| 011 | **MEDIUM** | OAuth credential logging | 🟡 **UPDATED** - Lines identified | +| 010 | Medium | Job file retention | 🟡 YELLOW - Policy needed | +| 008 | Medium | npm audit parser error | 📋 Manual check | +| 002 | High | hostConfigOverride | ⚠️ Accepted risk | +| 006 | Medium | shell:true | ⚠️ Accepted risk | +| 005 | Medium | bypassPermissions (example) | ℹ️ Intentional | +| 009 | Low | Incomplete shell escaping | 🔧 Partial fix | + +### New Findings This Audit + +**None** - Finding #011 specifics identified (not new, just more detailed) + +--- + +## Action Items + +### IMMEDIATE (P0) + +1. **Document web dashboard security** (Finding #012) + - Warn against network exposure (`0.0.0.0`) + - Clarify localhost-only design + - Location: packages/web/README.md + +### HIGH PRIORITY (P1) + +2. **Sanitize OAuth error logging** (Finding #011) + - Fix: container-manager.ts:338, 369, 389 + - Never log auth objects, use generic messages + +3. **Enforce credential file permissions** (Finding #011) + - Add `{ mode: 0o600 }` to line 336 + +### MEDIUM PRIORITY (P2) + +4. **Audit session files for credential leaks** (#011 + #012) +5. **Add explicit encodedPath validation** (Q13) +6. **Update security docs** (ATTACK-SURFACE, HOT-SPOTS) + +--- + +## Risk Assessment + +**Overall:** 🟡 YELLOW (IMPROVED) + +**Previous Audit (2026-03-06):** YELLOW +**This Audit (2026-10-09):** YELLOW + +**What Changed:** +- ✅ **Improved:** MCP bridge authentication (critical fix) +- ⚠️ **Same:** Finding #011, #012 remain open +- 📊 **New:** OAuth logging specific instances identified + +**Risk Factors:** +- **Positive:** Critical vulnerability fixed, no regressions, excellent new features +- **Negative:** OAuth logging + web API auth = credential leak risk + +**Blocker Issues:** None + +--- + +## Statistics + +**Code Activity:** +- 172 commits analyzed +- 9 hot spots touched +- 1 new web API endpoint +- ~25 security-relevant commits + +**Security Coverage:** +- Hot spots: 9/9 verified (100%) +- Scanner checks: 2/6 passed (expected) +- New entry points: 1 reviewed (SAFE) +- Regressions: 0 detected + +--- + +## Comparison to Last Audit + +| Aspect | 2026-03-06 | 2026-10-09 | Change | +|--------|------------|------------|--------| +| Status | YELLOW | YELLOW | ➡️ Same | +| Open Findings | 8 | 8 | ➡️ Same | +| Critical Issues | 0 | 0 | ➡️ Same | +| High Priority | 1 | 1 | ➡️ Same | +| Commits Since | 71 | 172 | ⬆️ +101 | +| Major Fixes | 0 | 1 (MCP auth) | ⬆️ +1 | + +--- + +## Recommendations + +1. **Fix OAuth logging** (3 lines, ~30 min work) +2. **Document web security** (1 section, ~15 min) +3. **Enforce file permissions** (1 line, ~5 min) + +**Total effort:** ~1 hour to address all HIGH priority items + +--- + +## Next Audit + +**Scheduled:** ~2026-10-16 (7 days) + +**Trigger Early If:** +- New authentication/authorization code +- New API endpoints +- Dependency updates +- Credential handling changes + +--- + +## Conclusion + +**Security posture IMPROVED** due to MCP bridge authentication fix. No regressions detected across 172 commits. Finding #011 (OAuth logging) is now actionable with specific line numbers. Overall risk remains MODERATE with clear remediation path. + +**Recommended:** Proceed with Finding #011 remediation (high priority, low effort). + +--- + +**Audit completed:** 2026-10-09 +**Next audit:** ~2026-10-16 +**Report:** agents/security/intel/2026-10-09.md diff --git a/agents/security/summaries/2026-10-12-summary.md b/agents/security/summaries/2026-10-12-summary.md new file mode 100644 index 00000000..5878997c --- /dev/null +++ b/agents/security/summaries/2026-10-12-summary.md @@ -0,0 +1,346 @@ +# Security Audit Summary: 2026-10-12 + +**Status:** 🟡 YELLOW +**Risk Level:** MODERATE (STABLE from previous) +**Commits Since Last Audit:** 22 (3 code commits, 19 housekeeping) +**Scanner Status:** FAIL (expected - Finding #002) +**Hot Spot Status:** WARN (OAuth logging - Finding #011) + +--- + +## TL;DR + +✅ **SECURITY IMPROVEMENT:** Settings field log redaction added (commit 2cef420) +- New feature: Flag-tier settings passthrough to Claude Code +- Security-conscious design: Two-phase implementation (feature + adversarial review) +- Mitigation: `--settings` values redacted from debug logs to prevent secret leakage + +✅ **NO REGRESSIONS:** All security controls intact across 22 commits + +⚠️ **STILL NEEDS ATTENTION:** OAuth credential logging (Finding #011) +- Specific lines: container-manager.ts:338, 369, 389 +- Action: Sanitize error messages, add file permissions (0600) + +📊 **OVERALL:** Security posture STABLE, no new issues, 1 security improvement + +--- + +## Key Metrics + +| Metric | Value | Change | +|--------|-------|--------| +| Open Findings | 8 | ➡️ Same | +| Critical Issues | 0 | ✅ None | +| High Priority | 1 | ➡️ Same (#012) | +| Scanner Pass Rate | 33% (2/6) | ➡️ Expected | +| Hot Spots Verified | 13/13 | ✅ 100% | +| Regressions | 0 | ✅ None | +| Security Improvements | 1 | ⬆️ +1 (log redaction) | + +--- + +## Code Changes Analysis + +### Substantive Commits (3 total) + +**1. Commit 2cef420: feat(core): pass agent `settings` through at the flag tier** +- **Files Changed:** 7 (schema.ts, cli-runtime.ts, sdk-adapter.ts, types.ts + tests) +- **Lines Added:** 142 (125 production, 17 test) +- **Security Impact:** POSITIVE - Adds log redaction, no new vulnerabilities + +**Change Summary:** +- New `settings` field in agent config schema (`z.record(z.string(), z.unknown())`) +- Passthrough to Claude Code via `--settings ` (CLI) or SDK options +- Log redaction prevents secrets from appearing in debug output + +**Security Assessment:** +- ✅ **INPUT VALIDATION:** Intentionally permissive (validation delegated to Claude Code) +- ✅ **INJECTION PROTECTION:** JSON.stringify prevents argv injection +- ✅ **SECRET HANDLING:** `--settings` values redacted in debug logs (line 399) +- ✅ **TEST COVERAGE:** Mutation tested (removing passthrough causes failures) +- ✅ **DOCUMENTATION:** Warns about `/proc//cmdline` exposure + +**Risk Level:** LOW - Well-mitigated design with security-conscious implementation + +**Hot Spots Touched:** +- `schema.ts` (CRITICAL) - Reviewed ✅ +- `cli-runtime.ts` (HIGH-RISK) - Reviewed ✅ + +--- + +**2. Commit b919956: chore: version packages (#474)** +- **Files Changed:** 2 (CHANGELOG.md, package.json) +- **Security Impact:** NONE (version bump only) + +--- + +**3. Commits 7ec2844...214dbe9: Daily housekeeping (19 commits)** +- **Files Changed:** Agent state tracking only (conversations.md, state.md) +- **Security Impact:** NONE (no code changes) + +--- + +## Security Improvement: Settings Log Redaction + +**Issue:** New `settings` field can contain secrets via interpolation (e.g., `${GITHUB_TOKEN}`) +- Settings passed as `--settings ` argv +- Debug logs could expose `--settings` values + +**Mitigation (commit 2cef420):** +```typescript +// packages/core/src/runner/runtime/cli-runtime.ts:393-399 +const loggedArgs = args.map((arg, i) => + (args[i - 1] === "--settings" ? "" : arg)); +logger.debug(`Executing command: claude ${loggedArgs.join(" ")}`); +``` + +**Test Coverage:** +```typescript +it("never writes the settings JSON to the debug log", async () => { + await captureArgs({ settings: { env: { TOKEN: "s3cret-value" } } }); + expect(logged).toContain("--settings "); + expect(logged).not.toContain("s3cret-value"); +}); +``` + +**Impact:** Prevents secret leakage in herdctl logs (OS-level `/proc` exposure remains) + +--- + +## Scanner Results + +**Runtime:** 25.4s | **Commit:** 7ec2844 + +| Check | Status | Findings | Notes | +|-------|--------|----------|-------| +| npm-audit | WARN | 1 LOW | Parser issue (expected) | +| docker-config | FAIL | 3 HIGH | #002 (accepted risk) | +| permission-modes | WARN | 2 | Expected (examples + CLI) | +| subprocess-patterns | WARN | 7 | #009 (tech debt) | +| path-safety | ✅ PASS | 0 | ✅ Clean | +| env-handling | ✅ PASS | 0 | ✅ Clean | + +**No New Scanner Regressions** + +--- + +## Hot Spot Verification + +**13 Critical Files Verified** - All security properties maintained + +| File | Status | Notes | +|------|--------|-------| +| container-manager.ts | ⚠️ WARN | Finding #011 (OAuth logging) | +| cli-runtime.ts | ✅ IMPROVED | Log redaction added ✓ | +| schema.ts | ✅ SAFE | Settings field safe ✓ | +| path-safety.ts | ✅ SAFE | Patterns intact ✓ | +| mcp-http-bridge.ts | ✅ SAFE | Bearer token auth ✓ | +| container-runner.ts | ⚠️ WARN | Finding #009 (shell escaping) | +| session.ts | ✅ SAFE | buildSafeFilePath ✓ | +| job-metadata.ts | ✅ SAFE | Path validation ✓ | +| loader.ts | ✅ SAFE | Safe YAML parsing ✓ | +| job-control.ts | ✅ SAFE | ID validation ✓ | +| interpolate.ts | ✅ SAFE | No eval/exec ✓ | +| shell.ts | ✅ SAFE | Timeout + bounds ✓ | +| sdk-adapter.ts | ✅ SAFE | Shallow copy defense ✓ | + +**Result:** 11 SAFE, 0 FAIL, 2 WARN (known issues) + +--- + +## Findings Status + +### Active Findings (8 total) + +| ID | Severity | Title | Status | +|----|----------|-------|--------| +| 012 | **HIGH** | Web API lacks authentication | 🔴 OPEN - Needs docs | +| 011 | **MEDIUM** | OAuth credential logging | 🟡 YELLOW - Lines identified | +| 010 | Medium | Job file retention | 🟡 YELLOW - Policy needed | +| 008 | Medium | npm audit parser error | 📋 Manual check | +| 002 | High | hostConfigOverride | ⚠️ Accepted risk | +| 006 | Medium | shell:true | ⚠️ Accepted risk | +| 005 | Medium | bypassPermissions (example) | ℹ️ Intentional | +| 009 | Low | Incomplete shell escaping | 🔧 Partial fix | + +### New Findings This Audit + +**None** - No new security issues discovered + +### Security Improvements This Audit + +1. **cli-runtime.ts:** Settings log redaction (prevents secret disclosure) + +--- + +## Action Items + +### IMMEDIATE (P0) + +1. **Document web dashboard security** (Finding #012) + - Warn against network exposure (`0.0.0.0`) + - Clarify localhost-only design + - Location: packages/web/README.md + +### HIGH PRIORITY (P1) + +2. **Sanitize OAuth error logging** (Finding #011) + - Fix: container-manager.ts:338, 369, 389 + - Never log auth objects, use generic messages + +3. **Enforce credential file permissions** (Finding #011) + - Add `{ mode: 0o600 }` to writeCredentialsFile() + +### MEDIUM PRIORITY (P2) + +4. **Audit session files for credential leaks** (#011 + #012) +5. **Add explicit encodedPath validation** (defense-in-depth) +6. **Implement job file retention policy** (30 days for #010) + +--- + +## Risk Assessment + +**Overall:** 🟡 YELLOW (STABLE) + +**Previous Audit (2026-10-09):** YELLOW +**This Audit (2026-10-12):** YELLOW + +**What Changed:** +- ✅ **Improved:** Settings log redaction (security improvement) +- ➡️ **Same:** All findings remain at previous status +- ✅ **Stable:** No regressions across 22 commits + +**Risk Factors:** +- **Positive:** Security-conscious development, log redaction, no regressions +- **Neutral:** Housekeeping commits dominate (19/22) +- **Negative:** Finding #011, #012 remain open (same as previous) + +**Blocker Issues:** None + +--- + +## New Feature Security Review: Settings Passthrough + +### Feature Overview + +Allows fleet operators to override Claude Code settings at the flag tier (highest precedence except managed policy). Settings passed to agent via `--settings ` (CLI) or SDK options. + +### Security Strengths + +1. **Two-phase implementation:** + - Commit 1: Feature implementation + - Commit 2: Adversarial review + log redaction + +2. **Log redaction:** + - Settings values replaced with `` in debug logs + - Mutation tested (removing redaction fails tests) + - Prevents herdctl logs from leaking secrets + +3. **Clear trust boundary:** + - herdctl: Passes through verbatim (no validation) + - Claude Code: Validates keys and values (documented) + - Settings are flag-tier (embedder-controlled) + +4. **Injection protection:** + - JSON.stringify prevents argv injection + - Array args (no shell execution) + - Shallow copy prevents aliasing issues + +5. **Documentation:** + - Warns about `/proc//cmdline` exposure + - Documents precedence rules + - Examples with security notes + +### Security Concerns (Addressed) + +| Concern | Mitigation | Status | +|---------|-----------|--------| +| Secrets in logs | Log redaction implemented | ✅ MITIGATED | +| Argv injection | JSON.stringify + array args | ✅ SAFE | +| Schema bypass | Intentional (Claude Code validates) | ✅ BY DESIGN | +| OS-level exposure | Documented as limitation | ℹ️ NOTED | + +### Recommendations + +1. **DOCUMENT:** Add to CODEBASE-UNDERSTANDING.md that settings validation is Claude Code's responsibility +2. **NOTE:** Settings field can carry interpolated secrets (related to Finding #011) +3. **MONITOR:** Watch for Claude Code CVEs related to settings parsing + +**Overall Assessment:** ACCEPTABLE - Security-conscious design with appropriate mitigations + +--- + +## Statistics + +**Code Activity:** +- 22 commits analyzed +- 3 substantive commits (settings feature, version bump) +- 19 housekeeping commits (agent state tracking) +- 142 lines added (125 production, 17 test) +- 2 hot spots touched (schema.ts, cli-runtime.ts) + +**Security Coverage:** +- Hot spots: 13/13 verified (100%) +- Scanner checks: 2/6 passed (expected) +- New entry points: 1 reviewed (settings field - SAFE) +- Regressions: 0 detected +- Security improvements: 1 (log redaction) + +--- + +## Comparison to Last Audit + +| Aspect | 2026-10-09 | 2026-10-12 | Change | +|--------|------------|------------|--------| +| Status | YELLOW | YELLOW | ➡️ Same | +| Open Findings | 8 | 8 | ➡️ Same | +| Critical Issues | 0 | 0 | ➡️ Same | +| High Priority | 1 | 1 | ➡️ Same | +| Commits Since | 172 | 22 | ⬇️ -150 | +| Major Fixes | 1 (MCP auth) | 0 | ➡️ Stable | +| Security Improvements | 0 | 1 (log redaction) | ⬆️ +1 | + +--- + +## Recommendations + +**Carry Forward from Previous Audits:** +1. **Fix OAuth logging** (Finding #011) - 3 lines, ~30 min work +2. **Document web security** (Finding #012) - 1 section, ~15 min +3. **Enforce file permissions** (Finding #011) - 1 line, ~5 min + +**New This Audit:** +4. **Document settings trust boundary** - Add to CODEBASE-UNDERSTANDING.md +5. **Monitor Claude Code updates** - Watch for settings-related CVEs + +**Total effort:** ~1 hour for HIGH priority items (same as previous) + +--- + +## Next Audit + +**Scheduled:** ~2026-10-19 (7 days) + +**Trigger Early If:** +- New authentication/authorization code +- New API endpoints +- Dependency updates +- Credential handling changes +- Claude Code SDK updates + +--- + +## Conclusion + +**Security posture STABLE** with minor improvement (log redaction). No regressions detected across 22 commits. Settings feature demonstrates security-conscious development with adversarial review and proactive mitigation. Findings #011 and #012 remain open but actionable with clear remediation paths. + +**Recommended:** Continue with Finding #011 and #012 remediation (high priority, low effort). + +--- + +**Audit completed:** 2026-10-12 +**Next audit:** ~2026-10-19 +**Scanner report:** agents/security/scans/2026-10-12.json +**Change analysis:** Commit 2cef420 (settings feature) +**Hot spot verification:** 13/13 passed (2 warnings expected) diff --git a/docs/src/content/docs/whats-new.md b/docs/src/content/docs/whats-new.md index 6649a751..352ed4d5 100644 --- a/docs/src/content/docs/whats-new.md +++ b/docs/src/content/docs/whats-new.md @@ -7,6 +7,41 @@ A summary of notable changes across the herdctl packages. For the full technical --- +### Agent Settings Configuration +**October 10, 2026** · `@herdctl/core@5.34.0` + +Agents can now override Claude Code settings on a per-agent basis via a new `settings` field in agent configuration. Settings specified here apply at the flag tier — the highest priority level except managed policy — so they override values from `.claude/settings.json` and other file sources. This is particularly useful for settings like `autoMemoryDirectory` that Claude Code ignores when set in project settings files. Settings work on both SDK and CLI runtimes, passed through as the Agent SDK's `settings` option or as `--settings ` command-line argument respectively. The field supports YAML variable interpolation (`${VAR}`) but should not contain secrets since settings are visible in process command-line arguments. [#473](https://github.com/edspencer/herdctl/pull/473) + +--- + +### Web Chat Resilience and Search Improvements +**October 3, 2026** · `@herdctl/web@0.13.0` + +The web dashboard's chat interface is now far more robust when handling slow or unstable sessions. Chat loading includes exponential backoff retry logic, so a slow-starting session no longer times out and leaves the UI blank. The "Show All Sessions" toggle now actually works, displaying every session on your system regardless of working directory or agent attribution. Session search is now deterministic — results always appear in the same order for the same query, making it easier to find conversations in large fleets. [#170](https://github.com/edspencer/herdctl/pull/170), [#150](https://github.com/edspencer/herdctl/pull/150), [#145](https://github.com/edspencer/herdctl/pull/145), [#275](https://github.com/edspencer/herdctl/pull/275), [#455](https://github.com/edspencer/herdctl/pull/455) + +--- + +### MCP HTTP Bridge Security Hardening +**October 3, 2026** · `@herdctl/core@5.33.2` + +The MCP HTTP bridge now requires bearer token authentication and binds strictly to 127.0.0.1 (loopback) instead of all interfaces, preventing unauthorized access from other machines on your network. MCP server configuration is written to an owner-only temporary file instead of being passed on the command line, eliminating the risk of secrets leaking through process listings. These changes apply when the CLI runtime spawns HTTP bridges for injected MCP servers. [#467](https://github.com/edspencer/herdctl/pull/467) + +--- + +### Claude Opus 5.5 Support +**October 3, 2026** · `@herdctl/core@5.33.3` + +Raised the Claude Agent SDK floor to 0.3.283, ensuring compatibility with the new Opus 5.5 model. Agents configured with `model: claude-opus-5-5-20270101` (or any other Opus 5.5 variant) will now run correctly instead of failing with an unsupported model error. [#469](https://github.com/edspencer/herdctl/pull/469) + +--- + +### Session ID Minting Fixes Race Conditions +**October 3, 2026** · `@herdctl/core@5.33.1` + +CLI session IDs are now minted upfront instead of being inferred from filesystem scans. The previous approach had a race condition where concurrent agents starting at the same time could swap session IDs or adopt the wrong session from disk, leading to conversation cross-contamination. Session ID generation is now deterministic and conflict-free, making concurrent CLI-runtime agent launches safe. [#431](https://github.com/edspencer/herdctl/pull/431), [#357](https://github.com/edspencer/herdctl/pull/357) + +--- + ### Stop and Force-Close Live Sessions from Your App **August 12, 2026** · `@herdctl/core@5.33.0` · `@herdctl/core@5.31.0`