What's wrong
The agent API endpoints (/review, /implement) are bound to the Tailscale interface (100.100.146.119:8585) and protected by an ALLOWED_ACTORS trust check on triggered_by. However, triggered_by is a plain JSON field with no cryptographic verification — any client on the tailnet can spoof it by sending a crafted POST request.
This is low urgency since the tailnet boundary is already a strong gate, but it's cheap defense-in-depth.
What done looks like
-
A shared bearer token is validated on /review and /implement endpoints via a FastAPI dependency. Requests without a valid Authorization: Bearer <token> header get a 401 response.
-
The token is read from an environment variable (e.g., AGENT_API_KEY) in the agent service. Use Pydantic Settings to validate it's present at startup.
-
/health and /status/* endpoints remain unauthenticated — they're monitoring-only and contain no sensitive data.
-
Tests cover: valid token → 200, invalid token → 401, missing token → 401, health endpoint → 200 without token.
What the agent can't discover
- The token value will be configured in Dokploy environment variables (agent service) and GitHub Actions secrets. The agent doesn't need to set these up — just read the env var.
- Use
fastapi.security.HTTPBearer with a FastAPI dependency for clean integration. This gives automatic OpenAPI docs and a standard auth scheme.
- The current
ALLOWED_ACTORS check on triggered_by should remain as a second layer — bearer auth validates the caller is a trusted system, actor check validates the triggering user is allowed.
Out of scope (human follow-up)
The GitHub Actions workflow YAML files (.github/workflows/implement.yaml, .github/workflows/code-review.yaml) need to be updated to pass the token as Authorization: Bearer ${{ secrets.AGENT_API_KEY }} in their curl/HTTP calls. The agent cannot modify workflow files — this must be done manually after the Python changes merge.
What must not break
- Existing trust validation (
ALLOWED_ACTORS check) must remain — bearer auth is additive
/health and status endpoints must remain unauthenticated
- Worker containers don't call the API — they run as subprocesses, so no auth changes needed there
What's wrong
The agent API endpoints (
/review,/implement) are bound to the Tailscale interface (100.100.146.119:8585) and protected by anALLOWED_ACTORStrust check ontriggered_by. However,triggered_byis a plain JSON field with no cryptographic verification — any client on the tailnet can spoof it by sending a crafted POST request.This is low urgency since the tailnet boundary is already a strong gate, but it's cheap defense-in-depth.
What done looks like
A shared bearer token is validated on
/reviewand/implementendpoints via a FastAPI dependency. Requests without a validAuthorization: Bearer <token>header get a 401 response.The token is read from an environment variable (e.g.,
AGENT_API_KEY) in the agent service. Use Pydantic Settings to validate it's present at startup./healthand/status/*endpoints remain unauthenticated — they're monitoring-only and contain no sensitive data.Tests cover: valid token → 200, invalid token → 401, missing token → 401, health endpoint → 200 without token.
What the agent can't discover
fastapi.security.HTTPBearerwith a FastAPI dependency for clean integration. This gives automatic OpenAPI docs and a standard auth scheme.ALLOWED_ACTORScheck ontriggered_byshould remain as a second layer — bearer auth validates the caller is a trusted system, actor check validates the triggering user is allowed.Out of scope (human follow-up)
The GitHub Actions workflow YAML files (
.github/workflows/implement.yaml,.github/workflows/code-review.yaml) need to be updated to pass the token asAuthorization: Bearer ${{ secrets.AGENT_API_KEY }}in their curl/HTTP calls. The agent cannot modify workflow files — this must be done manually after the Python changes merge.What must not break
ALLOWED_ACTORScheck) must remain — bearer auth is additive/healthand status endpoints must remain unauthenticated