Skip to content

Add bearer token authentication for agent API endpoints #86

@ColinCee

Description

@ColinCee

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

  1. 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.

  2. 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.

  3. /health and /status/* endpoints remain unauthenticated — they're monitoring-only and contain no sensitive data.

  4. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions