Security Audit
Automated self-assessment of the AI Harness security posture.
Live System State
!ls -la bridges/discord/.env 2>/dev/null || echo "(no .env file)"
!ls -la bridges/discord/harness.db 2>/dev/null | awk '{print $1, $5, $9}'
!git status --short 2>/dev/null | head -20
!launchctl list | grep com.aiharness 2>/dev/null || echo "(no launchd agents)"
!sqlite3 bridges/discord/harness.db "SELECT provider, expires_at FROM oauth_tokens" 2>/dev/null || echo "(no oauth tokens)"
Check Modules
Parse $ARGUMENTS to determine scope. Default is full (all checks).
Credential Safety (credentials or full)
- OAuth token expiry: Query
oauth_tokens table — check if any expires_at is within 7 days or already expired
- Encryption key present: Check if
OAUTH_ENCRYPTION_KEY is set in .env (don't print the value, just confirm presence/absence)
- Refresh token encryption: Query a token row — check if
refresh_token field looks encrypted (contains : separators for iv:tag:ciphertext format) vs plaintext
- .env file permissions: Check
bridges/discord/.env has restrictive permissions (should be 600 or 640, not world-readable)
- No secrets in logs: Grep heartbeat log files for common secret patterns (API keys, tokens, passwords):
grep -ril "sk-\|Bearer \|password=" heartbeat-tasks/logs/ 2>/dev/null
Report: token status, encryption status, file permissions, any leaked secrets in logs.
Git Hygiene (git or full)
- No .env committed:
git ls-files | grep -i '\.env' — should return nothing
- No credentials in tracked files:
git ls-files | xargs grep -l "sk-\|PRIVATE KEY\|password\s*=" 2>/dev/null — should return nothing
- Gitignore coverage: Check that
.env, harness.db, *.state.json, .bot.pid, vault-embeddings.json are in .gitignore
- No large binaries tracked:
git ls-files | xargs -I{} sh -c 'test -f "{}" && wc -c < "{}"' 2>/dev/null | sort -rn | head -5 — flag files over 1MB
- Uncommitted sensitive changes: Check
git diff --name-only for any .env, credential, or key files
Report: pass/fail for each check with file paths if issues found.
Heartbeat Health (heartbeat or full)
- All configs have plists: Compare
heartbeat-tasks/*.json (excluding .state.json, .example, projects.json) against ~/Library/LaunchAgents/com.aiharness.heartbeat.*.plist — flag any missing
- All plists loaded: Check
launchctl list | grep com.aiharness — flag any with non-zero exit codes
- Failure counts: Read all
.state.json files — flag any with consecutive_failures > 0
- Stale tasks: Flag any task whose
last_run is more than 3x its schedule interval ago
- Auto-paused tasks: Check all config JSONs for
"enabled": false — flag with reason
Report: task-by-task status table.
Configuration Drift (config or full)
- Agent tool restrictions match docs: Read
bridges/discord/agent-loader.ts and verify all agents listed in .claude/agents/ have corresponding restriction entries (or are explicitly unrestricted)
- MCP servers registered: Check
~/.claude/Config/mcp-config.json — verify vault, harness, projects, outlook, linkedin servers are registered
- Global guardrails intact: Read
task-runner.ts for GLOBAL_DISALLOWED_TOOLS — verify rm -rf, force push, DROP, DELETE FROM, kill -9 are all blocked
- Channel configs consistent: Query
channel_configs table — verify course channels have education agent, project channels have valid agents
- PID file stale: Check
.bot.pid — is the PID actually alive?
Report: pass/fail for each check.
Output Format
=== AI Harness Security Audit ===
Credentials:
OAuth tokens: OK (2 tokens, nearest expiry: 14 days)
Encryption key: OK (present in .env)
Token encryption: OK (iv:tag:ciphertext format)
.env permissions: OK (640)
Secrets in logs: OK (none found)
Git:
.env not tracked: OK
No credentials: OK
Gitignore: OK (5/5 patterns present)
Large files: OK (none over 1MB)
Heartbeat:
Plists present: OK (21/21)
All loaded: OK (21/21, exit 0)
Failures: OK (0 tasks with failures)
Stale tasks: WARN (daily-digest last ran 36h ago)
Config:
Agent restrictions: OK (9 agents, 4 restricted)
MCP servers: OK (5/5 registered)
Global guardrails: OK (6 rules intact)
Channel configs: OK (4 course channels → education)
PID file: OK (PID 12345 alive)
Overall: HEALTHY (1 warning)
For issues, list each with severity (CRITICAL/WARN/INFO) and suggested fix.
1---2name: security-audit-113description: Automated security posture check of the AI Harness system. Checks credentials, tokens, file permissions, git hygiene, heartbeat health, and configuration drift.4---5
6# Security Audit
7
8Automated self-assessment of the AI Harness security posture.
9
10## Live System State
11!`ls -la bridges/discord/.env 2>/dev/null || echo "(no .env file)"`
12!`ls -la bridges/discord/harness.db 2>/dev/null | awk '{print $1, $5, $9}'`
13!`git status --short 2>/dev/null | head -20`
14!`launchctl list | grep com.aiharness 2>/dev/null || echo "(no launchd agents)"`
15!`sqlite3 bridges/discord/harness.db "SELECT provider, expires_at FROM oauth_tokens" 2>/dev/null || echo "(no oauth tokens)"`
16
17## Check Modules
18
19Parse `$ARGUMENTS` to determine scope. Default is `full` (all checks).
20
21### Credential Safety (`credentials` or `full`)
22
231. **OAuth token expiry**: Query `oauth_tokens` table — check if any `expires_at` is within 7 days or already expired
242. **Encryption key present**: Check if `OAUTH_ENCRYPTION_KEY` is set in `.env` (don't print the value, just confirm presence/absence)
253. **Refresh token encryption**: Query a token row — check if `refresh_token` field looks encrypted (contains `:` separators for `iv:tag:ciphertext` format) vs plaintext
264. **.env file permissions**: Check `bridges/discord/.env` has restrictive permissions (should be 600 or 640, not world-readable)
275. **No secrets in logs**: Grep heartbeat log files for common secret patterns (API keys, tokens, passwords): `grep -ril "sk-\|Bearer \|password=" heartbeat-tasks/logs/ 2>/dev/null`
28
29Report: token status, encryption status, file permissions, any leaked secrets in logs.
30
31### Git Hygiene (`git` or `full`)
32
331. **No .env committed**: `git ls-files | grep -i '\.env'` — should return nothing
342. **No credentials in tracked files**: `git ls-files | xargs grep -l "sk-\|PRIVATE KEY\|password\s*=" 2>/dev/null` — should return nothing
353. **Gitignore coverage**: Check that `.env`, `harness.db`, `*.state.json`, `.bot.pid`, `vault-embeddings.json` are in `.gitignore`
364. **No large binaries tracked**: `git ls-files | xargs -I{} sh -c 'test -f "{}" && wc -c < "{}"' 2>/dev/null | sort -rn | head -5` — flag files over 1MB
375. **Uncommitted sensitive changes**: Check `git diff --name-only` for any `.env`, credential, or key files
38
39Report: pass/fail for each check with file paths if issues found.
40
41### Heartbeat Health (`heartbeat` or `full`)
42
431. **All configs have plists**: Compare `heartbeat-tasks/*.json` (excluding .state.json, .example, projects.json) against `~/Library/LaunchAgents/com.aiharness.heartbeat.*.plist` — flag any missing
442. **All plists loaded**: Check `launchctl list | grep com.aiharness` — flag any with non-zero exit codes
453. **Failure counts**: Read all `.state.json` files — flag any with `consecutive_failures > 0`
464. **Stale tasks**: Flag any task whose `last_run` is more than 3x its schedule interval ago
475. **Auto-paused tasks**: Check all config JSONs for `"enabled": false` — flag with reason
48
49Report: task-by-task status table.
50
51### Configuration Drift (`config` or `full`)
52
531. **Agent tool restrictions match docs**: Read `bridges/discord/agent-loader.ts` and verify all agents listed in `.claude/agents/` have corresponding restriction entries (or are explicitly unrestricted)
542. **MCP servers registered**: Check `~/.claude/Config/mcp-config.json` — verify vault, harness, projects, outlook, linkedin servers are registered
553. **Global guardrails intact**: Read `task-runner.ts` for `GLOBAL_DISALLOWED_TOOLS` — verify rm -rf, force push, DROP, DELETE FROM, kill -9 are all blocked
564. **Channel configs consistent**: Query `channel_configs` table — verify course channels have `education` agent, project channels have valid agents
575. **PID file stale**: Check `.bot.pid` — is the PID actually alive?
58
59Report: pass/fail for each check.
60
61## Output Format
62
63```
64=== AI Harness Security Audit ===
65
66Credentials:
67 OAuth tokens: OK (2 tokens, nearest expiry: 14 days)
68 Encryption key: OK (present in .env)
69 Token encryption: OK (iv:tag:ciphertext format)
70 .env permissions: OK (640)
71 Secrets in logs: OK (none found)
72
73Git:
74 .env not tracked: OK
75 No credentials: OK
76 Gitignore: OK (5/5 patterns present)
77 Large files: OK (none over 1MB)
78
79Heartbeat:
80 Plists present: OK (21/21)
81 All loaded: OK (21/21, exit 0)
82 Failures: OK (0 tasks with failures)
83 Stale tasks: WARN (daily-digest last ran 36h ago)
84
85Config:
86 Agent restrictions: OK (9 agents, 4 restricted)
87 MCP servers: OK (5/5 registered)
88 Global guardrails: OK (6 rules intact)
89 Channel configs: OK (4 course channels → education)
90 PID file: OK (PID 12345 alive)
91
92Overall: HEALTHY (1 warning)
93```
94
95For issues, list each with severity (CRITICAL/WARN/INFO) and suggested fix.