Skip to main content

Proxying Requests

Vectra acts as a reverse proxy gateway. Any HTTP request prefixed with /proxy/ is intercepted, evaluated, and either forwarded to the upstream service or blocked/held.


URL Format

GET /proxy/<full-upstream-url>

The full absolute URL of the upstream target is embedded in the path:

GET /proxy/https://api.example.com/users/123
Authorization: Bearer <agent-jwt>

Vectra will:

  1. Extract https://api.example.com/users/123 as the target.
  2. Set context.Request.Path to /users/123 and forward to api.example.com.
info

Query strings embedded in the target URL are preserved and forwarded correctly.


Request Pipeline

Every proxied request goes through the following stages in order:

1. Agent Authentication

AgentAuthMiddleware validates the Authorization: Bearer <token> header.

  • Missing or invalid token → the request continues unauthenticated (no AgentId in context).
  • ProxyMiddleware then requires AgentId → returns 401 Unauthorized if absent.

2. Agent Status Check

The agent is loaded from the repository. If the agent does not exist or has Status = Revoked, the request is rejected with 403 Forbidden.

3. Rate Limiting

IAgentRateLimiter.IsAllowedAsync() is called. If the agent has exceeded its configured RequestsPerMinute, the gateway returns:

HTTP/1.1 429 Too Many Requests
Retry-After: 60

4. Circuit Breaker

ICircuitBreaker.IsAllowed(upstreamHost) is checked. If the circuit for the target host is open, the gateway returns 503 Service Unavailable.

5. Decision Engine

A RequestContext is constructed and passed to IDecisionEngine.EvaluateAsync(). The engine runs three evaluations in sequence:

StageDescriptionShort-circuits if…
PolicyEvaluates the agent's assigned policy rulesRule matches Deny or Hitl
Risk ScoringComputes a weighted risk scoreScore exceeds HITL threshold
SemanticLLM/ONNX intent classification (if enabled)Model verdict is negative

6. Decision Outcome

OutcomeHTTP ResponseDescription
AllowForward to upstreamRequest is forwarded
Deny403 ForbiddenRequest body contains the denial reason
Hitl202 AcceptedLocation header set to /hitl/status/{id}

Request Forwarding

When a request is allowed, Vectra constructs a new HttpRequestMessage and forwards it using an IHttpClientFactory-managed client.

Headers forwarded:

  • All headers from the original request, except: Authorization, Host, Connection, Content-Length

Headers NOT forwarded:

  • Authorization — This is Vectra's internal JWT, not intended for the upstream.

RequestContext Model

The following data is available during policy/risk/semantic evaluation:

FieldTypeDescription
MethodstringHTTP method
PathstringPath and query string
TargetUrlstringFull upstream URL
HeadersDictionary<string, string>Sanitised request headers
AgentIdGuidAuthenticated agent ID
PolicyNamestring?Assigned policy name
TrustScoredoubleAgent's current trust score
Bodystring?Raw request body

Example: Proxying a GET Request

GET /proxy/https://jsonplaceholder.typicode.com/todos/1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5...

If the agent is active, not rate-limited, and the decision engine allows it, Vectra forwards the request and returns the upstream response unchanged.


Example: HITL Interception

DELETE /proxy/https://api.example.com/users/all
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5...

HTTP/1.1 202 Accepted
Location: /hitl/status/abc-123

Request pending approval. Poll /hitl/status/abc-123

The operator can then approve or deny this request via the HITL endpoints.