apache / apache/texera

Authorize agent-service requests in the access-control-service (JWT authn + per-agent authz)

Open
#5,561 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Scala
Stars
314
Forks
187
Avg merge
1d 21h
Merged PRs (30d)
214

Description

### Feature Summary

The `agent-service` currently authenticates its own requests, and the check is both weak and incomplete:

- The only token handling is the **optional** `userToken` in `POST /api/agents`. `agent-service/src/api/auth-api.ts` base64-decodes the JWT payload and checks **only the `exp` claim** — the **signature is never verified** (`validateToken = !isTokenExpired`), so a forged-but-unexpired token passes.
- Every other endpoint — `GET /api/agents`, `GET /api/agents/models`, `PATCH …/settings`, and the `/api/agents/:id/react` WebSocket that drives LLM calls (and provider spend) — performs **no auth at all**.
- At the gateway, the ext-authz `SecurityPolicy` (`bin/k8s/templates/gateway-security-policy.yaml`) targets only the `*-dynamic-routes` HTTPRoute (wsapi / executions-stats / pve). The `*-agent-service-route` is **not** targeted, so `/api/agents` bypasses ext-authz entirely. (Single-node nginx has no ext-authz at all.)

### Proposed Solution or Design

**Authorize requests via `access-control-service`**
- Add an Envoy `SecurityPolicy` targeting the `*-agent-service-route` HTTPRoute, mirroring `gateway-security-policy.yaml`, pointing ext-auth at the access-control-service `/api/auth` and injecting `x-user-id` / `x-user-name` / `x-user-email`.
- Add a branch to `AccessControlResource.authorize()` for `/api/agents…` that verifies the JWT (`parseToken`) and requires `REGULAR`/`ADMIN` (`SessionUser.isRoleOf`) — i.e. restore the gate the old LiteLLM proxy had — returning the trusted identity headers on success and 401/403 otherwise. **Any valid REGULAR/ADMIN user is allowed on any agent path** (allow-all per-agent for now). Token extraction already supports header `Authorization: Bearer`, query `access-token` (for the WS), and body `token`.
- Frontend: attach the JWT to **all** agent-service calls. Today `agentHeaders()` only sets `X-Agent-Workflow-Id`, `fetchModelTypes()` sends nothing, and the `/react` WebSocket carries no token. REST → `Authorization: Bearer`; WS → `?access-token=…` (mirror the workflow WebSocket).
- The agent-service **keeps verifying the JWT itself** — now a real HS256 check using the shared secret read from `auth.conf` (env `AUTH_JWT_SECRET`), replacing the old non-cryptographic decode. This runs **in addition** to the gateway ext-authz, as defense-in-depth so direct / bare-metal access is authenticated too.
- Single-node (nginx, no Envoy): add an `auth_request` subrequest to `/api/auth` (Envoy and nginx both forward the original path so the same `authorize()` branch handles them).

```mermaid
sequenceDiagram
participant FE as Frontend
participant GW as Gateway (Envoy / nginx)
participant AC as access-control-service
participant AS as agent-service

FE->>GW: /api/agents/** — Bearer JWT (or ?access-token for the WS)
GW->>AC: ext_authz → /api/auth (forwards original path + token)
alt valid JWT, REGULAR/ADMIN
AC-->>GW: 200 + x-user-id / x-user-name / x-user-email
GW->>AS: forward request (JWT preserved)
Note over AS: re-verifies the JWT itself (HS256, secret from auth.conf)
AS-->>FE: response
else missing / invalid / wrong role
AC-->>GW: 401 / 403
GW-->>FE: blocked (never reaches agent-service)
end
```

Contributor guide

Open the contributing guide

Research direction

Start by reading agent-service/src/api/auth-api.ts, AccessControlResource.authorize(), and bin/k8s/templates/gateway-security-policy.yaml, then trace the frontend agentHeaders(), fetchModelTypes(), and /react WebSocket calls. Done means agent REST and WebSocket requests carry tokens, gateway and single-node routes enforce the access-control checks, and agent-service performs real HS256 verification for direct access.

Written by the indexing model from the issue text.

Assessment

Tech stack
kubernetes, nginx, scala, typescript
Domain
api, authentication, authorization, devops, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.