OpenRouter API key leaks into failed_jobs stack traces (AiSegmentSummarizer passes key as a method arg)
flower-orchestrator · submitted 4 days ago
detail
What they reported
A SegmentSession failure stores the full exception stack trace in failed_jobs.exception, and AiSegmentSummarizer::decodeJsonCompletionResponse receives the API key as a positional argument (sk-or-v1-...), so the key appears verbatim in every captured stack trace (failed_jobs, and potentially logs). #35 added Sentry payload scrubbing, but the DB failed_jobs.exception column and laravel.log are not scrubbed. Fix: don't pass the key as a method arg (inject via the client/config, or wrap so it's not in the signature), and/or scrub secrets from stored exception traces. Also consider purging existing failed_jobs rows that contain the key. Found while diagnosing docs-embed failures 2026-07-01.
context
Structured context
{
"routed": {
"target": "orchestrator",
"todo_id": 381,
"authority": "autonomous",
"routed_at": "2026-07-03T13:19:16+00:00",
"routed_by": "operator:mike",
"project_id": 16,
"solo_todo_id": "701",
"solo_project_id": "49",
"coordination_queue": {
"kind": "route_feedback",
"drain": "orchestrator_recall_signals",
"status": "pending",
"latency": "<= one orchestrator heartbeat",
"signal_id": 16
},
"default_project_id": 16,
"coordination_signal_id": 16,
"fix_spec_scratchpad_id": 372,
"orchestrator_daemon_id": 12,
"solo_fix_spec_scratchpad_id": "1063",
"orchestrator_solo_process_id": 1015
},
"promotion_ledger": [
{
"at": "2026-07-03T13:19:16+00:00",
"action": "orchestrator_routed",
"target": "orchestrator",
"todo_id": 381,
"actor_ref": "operator:mike",
"cycle_key": "2026070313",
"fix_spec_scratchpad_id": 372
}
]
}state · operator override
Lifecycle
- created
- 4d ago
- triaged
- 4d ago
- resolved
- —
- resolved by
- flower-ops
resolution
CONFIRMED LIVE SECURITY LEAK: OpenRouter key present in ALL 10 failed_jobs.exception stack traces (verified by count, key not printed). Root: key passed as positional arg to AiSegmentSummarizer::decodeJsonCompletionResponse → captured in every trace. 969-filed + owns code fix (#35 added Sentry-payload scrub; failed_jobs/logs still leak). Mitigations flagged to 969 + operator: (1) ROTATE key, (2) scrub/flush leaked rows, (3) stop passing key as positional arg. HIGH severity.