ServeHTTP is the entrypoint for requests which will be intercepted by AI Bridge. This function will validate that the given API key may be used to perform the request. An [aibridge.RequestBridge] instance is acquired from a pool based on the API key's owner (referred to as the "initiator"); this in
(rw http.ResponseWriter, r *http.Request)
| 33 | // A [DRPCClient] is provided to the [aibridge.RequestBridge] instance so that data can |
| 34 | // be passed up to a [DRPCServer] for persistence. |
| 35 | func (s *Server) ServeHTTP(rw http.ResponseWriter, r *http.Request) { |
| 36 | ctx := r.Context() |
| 37 | |
| 38 | logger := s.logger.With( |
| 39 | slog.F("method", r.Method), |
| 40 | slog.F("path", r.URL.Path), |
| 41 | ) |
| 42 | |
| 43 | // Extract and strip proxy request ID for cross-service log |
| 44 | // correlation. Absent for direct requests not routed through |
| 45 | // aibridgeproxyd. |
| 46 | if proxyReqID := r.Header.Get(agplaibridge.HeaderCoderRequestID); proxyReqID != "" { |
| 47 | // Inject into context so downstream loggers include it. |
| 48 | ctx = slog.With(ctx, slog.F("aibridgeproxy_id", proxyReqID)) |
| 49 | logger = logger.With(slog.F("aibridgeproxy_id", proxyReqID)) |
| 50 | } |
| 51 | r.Header.Del(agplaibridge.HeaderCoderRequestID) |
| 52 | |
| 53 | byok := agplaibridge.IsBYOK(r.Header) |
| 54 | authMode := "centralized" |
| 55 | if byok { |
| 56 | authMode = "byok" |
| 57 | } |
| 58 | |
| 59 | // When the request arrived via the in-process transport, the caller |
| 60 | // has placed a delegated API key ID on the context. We trust that the |
| 61 | // caller already established the user's identity and only validate |
| 62 | // liveness; the caller does not have (and cannot send) the key secret. |
| 63 | // Delegation is orthogonal to BYOK: a delegated request still carries |
| 64 | // the user's own LLM credentials in Authorization/X-Api-Key when BYOK |
| 65 | // is in effect. |
| 66 | var ( |
| 67 | authReq *proto.IsAuthorizedRequest |
| 68 | ) |
| 69 | |
| 70 | delegatedID, delegated := agplaibridge.DelegatedAPIKeyIDFromContext(ctx) |
| 71 | |
| 72 | key := strings.TrimSpace(agplaibridge.ExtractAuthToken(r.Header)) |
| 73 | |
| 74 | // When a BYOK header is present, a key is ALWAYS required. |
| 75 | // Delegated auth only requires a key when using BYOK. |
| 76 | if key == "" && !delegated { |
| 77 | // Some clients (e.g. Claude) send a HEAD request |
| 78 | // without credentials to check connectivity. |
| 79 | if r.Method == http.MethodHead { |
| 80 | logger.Info(ctx, "unauthenticated HEAD request") |
| 81 | } else { |
| 82 | logger.Warn(ctx, "no auth key provided") |
| 83 | } |
| 84 | http.Error(rw, ErrNoAuthKey.Error(), http.StatusBadRequest) |
| 85 | return |
| 86 | } |
| 87 | |
| 88 | if delegated { |
| 89 | authReq = &proto.IsAuthorizedRequest{KeyId: delegatedID} |
| 90 | } else { |
| 91 | authReq = &proto.IsAuthorizedRequest{Key: key} |
| 92 | } |