An incident-investigation agent that won't do things it wasn't told it's allowed to do
driftwood-custodian is an AI agent built for Maya, the on-call engineer at Driftwood Goods — a 25-person B2B SaaS startup. When production breaks, Maya can ask the agent to investigate automatically through Dynatrace, diagnose the root cause, and propose remediation with human approval required before execution.
But here's the catch: anyone on the internet can write to the logs the agent reads. This project demonstrates a two-altitude security model where the agent's instructions and the underlying sandbox work independently to prevent injection attacks.
An attacker can write to HTTP headers, logs, or event streams that the agent reads. The agent's job is parsing logs — so it's parsing whatever an attacker types into a request header.
Single merged sandbox: Agent + MCP server compiled into one Docker policy from a capability manifest, ensuring both components operate under the same egress constraints.
aiplatform.googleapis.com:443 — Gemini API (Vertex AI)egc32068.apps.dynatrace.com:443 — Tenant queriessso.dynatrace.com:443 — Authenticationhost.docker.internal:3000 — Rollback tool (demo app)assert: capabilities for auditability.
${VAR} interpolation).
Candidate for v0.1.
gcloud auth application-default login
# Install dependencies
npm install
uv sync
# Configure credentials (.env, gitignored)
cat > .env <<EOF
DT_ENVIRONMENT=your-env-id
DT_PLATFORM_TOKEN=your-token
GOOGLE_CLOUD_PROJECT=your-project
GOOGLE_CLOUD_LOCATION=global
EOF
# Start ADK server
adk api_server --host 127.0.0.1 --port 8123 driftwood-agent
# Run agent (separate terminal)
node scripts/agent-session.mjs http://127.0.0.1:8123
[maya] > Investigate the driftwood-inventory service
# Full two-path rehearsal (bad deploy → poison → investigation → HITL → rollback)
node scripts/rehearsal.mjs
Watch the two-path demo (investigation + injection detection) in action:
What happens in the agent run: investigates via Dynatrace MCP (~0:50) → flags the prompt injection in the request headers → operator approves the rollback (HITL) → rollback executes and the Davis problem closes.
See the full source code, architecture, and findings.