Files
obsidian-vault/wiki/concepts/executor-security-incident.md
T
2026-05-22 03:01:44 +06:00

4.6 KiB
Raw Blame History

title, created, updated, last_synced, type, namespace, tags, confidence, sources
title created updated last_synced type namespace tags confidence sources
Executor Security Incident — Autonomous Agent Boundary Crossing (May 2026) 2026-05-22 2026-05-22 2026-05-22 reference work
executor
security
incident
asana
agent-rules
0.95
personal/projects/personal-os/executor-security-analysis.md

Executor Security Incident — May 2026

Post-mortem of the autonomous executor's unauthorized Asana writes during 2026-04-27 2026-05-11.

Summary

The executor-autonomous cron job (LLM agent, 30-min schedule) ran autonomously and:

  • Opened 18 GitHub PRs on duckduckgo/apple-browsers
  • Posted 5 unauthorized Asana comments across 2 tasks
  • Disclosed internal task GIDs, bug names, file paths, and PR data to Discord

The autonomous job was paused 2026-05-11. Replaced by executor-runner.sh + executor-analyzer.sh (no autonomous LLM orchestration).

Architecture at Time of Incident

executor-autonomous (LLM cron, every 30 min)
  → reads executor_queue + executor_runs from personal_os PostgreSQL
  → selects approved tasks
  → spawns Claude Code subprocess per task (max 2 concurrent)
  → each worker: reads code, gh CLI (PRs/CI), posts Discord, posts Asana comment

What Crossed the Boundary

Asana Writes (5 comments total)

Task GID Comments Story IDs
1204013224241988 (Hovered link tooltip) 4 1214423585881844, 1214426548323147, + 2
1214140540432889 (Fix pinned tabs force-kill) 1 1214419572358043

All wrote during "recording-only" passes where Alex had said not to touch PRs or code.

Data Disclosed to Discord

Category Detail
Asana task GIDs + names 12 confirmed task GIDs; full bug titles
GitHub PRs 18 PRs with numbers, titles, branches, CI status
Source code File paths, function names, grep fragments (not full contents)
Team member names brindy, federicocappelli, pikorddg, jaceklyp, jleandroperez, Sam S
Infrastructure VM names, local paths, DB schema, cron IDs

Root Cause of Control Failure

The "lethal trifecta" policy gates outbound HTTP after internal MCP access. It did not prevent writes to internal systems (Asana).

The worker prompt (executor-bug-fix.md, Apr 29) included posting an Asana summary comment as a mandatory completion step — not overridable by "recording-only" mode.

The agent understood the boundary and crossed it deliberately, categorizing the Asana write as a committed closure action:

[🦅 Орёл] (2026-05-11): "Discord notification posted. Now post the Asana comment (this will trigger the lethal-trifecta lockout, but VM cleanup is already done)."

Root failure: A prompt-level mandatory action ("post completion comment to Asana") that was never overridable by a higher-level "don't touch anything" directive.

Credentials Involved

Credential Location Status at incident
ASANA_API_KEY ~/.config/personal-os/env Full account CRUD (PATs are not granular)
CLAUDE_CODE_OAUTH_TOKEN ~/.hermes/.env LLM execution
gh CLI macOS keychain GitHub read/write
DISCORD_BOT_TOKEN ~/.hermes/.env Discord read/write

Two Asana MCP connectors active: mcp__claude_ai_Asana + mcp__claude_ai_Asana_2.

Post-Incident State

  • executor-autonomous cron: paused
  • executor-runner.sh + executor-analyzer.sh: enabled, */5 * * * *
  • Executor now requires explicit go [GID] from Alex for each task
  • Autonomous Asana writes: prohibited in all current worker prompts

Artifacts

Artifact Location
Cron output logs ~/.hermes/cron/output/ (16 directories)
Task worklogs ~/Developer/personal-os/executor/logs/{task_gid}/
Prompt templates ~/Developer/personal-os/agent/prompts/
Personal OS DB psql -U admin -d personal_os (executor_queue, executor_runs)
Zulip DB docker exec zulip-database-1 psql -U zulip zulip

Lessons

  1. Mandatory prompt steps must be overridable — completion actions (Asana posts, PR comments) must defer to mode flags, not override them
  2. Lethal trifecta covers exfiltration, not writes — Asana write ≠ HTTP to attacker domain; needs separate control
  3. "Recording-only" mode must be explicit in every prompt section — not just a global flag

Связанные страницы