runtimeProxyForOrgAndProject proxies a request to the runtime service for a specific project. This provides a way to directly query a project's runtime on a stable URL without needing to call GetProject or GetDeploymentCredentials to discover the runtime URL. If the request is made using an Authoriz
(w http.ResponseWriter, r *http.Request)
| 24 | // the proxied request is made with a newly minted JWT similar to the one that could be obtained by calling GetProject. |
| 25 | // If the Authorization header of the request is not recognized by the admin service, it is proxied through to the runtime service. |
| 26 | func (s *Server) runtimeProxyForOrgAndProject(w http.ResponseWriter, r *http.Request) error { |
| 27 | // Get args from URL path components |
| 28 | org := r.PathValue("org") |
| 29 | project := r.PathValue("project") |
| 30 | proxyPath := r.PathValue("path") |
| 31 | proxyRawQuery := r.URL.RawQuery |
| 32 | |
| 33 | // Find the production deployment for the project we're proxying to |
| 34 | proj, err := s.admin.DB.FindProjectByName(r.Context(), org, project) |
| 35 | if err != nil { |
| 36 | return httputil.Error(http.StatusBadRequest, err) |
| 37 | } |
| 38 | if proj.PrimaryDeploymentID == nil { |
| 39 | return httputil.Errorf(http.StatusBadRequest, "no prod deployment for project") |
| 40 | } |
| 41 | depl, err := s.admin.DB.FindDeployment(r.Context(), *proj.PrimaryDeploymentID) |
| 42 | if err != nil { |
| 43 | return httputil.Error(http.StatusBadRequest, err) |
| 44 | } |
| 45 | |
| 46 | // Prepare a JWT to use for the proxied request. |
| 47 | // We support three scenarios: |
| 48 | // 1. Passing a runtime JWT directly. |
| 49 | // 2. Using admin service authentication, which requires us to issue a new ephemeral runtime JWT for the proxied request. |
| 50 | // 3. Accessing public projects anonymously, which also requires us to issue a new ephemeral runtime JWT for the proxied request. |
| 51 | var jwt string |
| 52 | |
| 53 | // We support passing a runtime JWT directly. |
| 54 | // Since we use HTTPMiddlewareLenient for this handler, it's invoked even if the Authorization header contains a token that is not valid for the admin service. |
| 55 | claims := auth.GetClaims(r.Context()) |
| 56 | if claims.OwnerType() == auth.OwnerTypeAnon { |
| 57 | authorizationHeader := r.Header.Get("Authorization") |
| 58 | if len(authorizationHeader) >= 6 && strings.EqualFold(authorizationHeader[0:6], "bearer") { |
| 59 | jwt = strings.TrimSpace(authorizationHeader[6:]) |
| 60 | } |
| 61 | } |
| 62 | // If a direct JWT was not provided, issue a new ephemeral runtime JWT for the proxied request. |
| 63 | if jwt == "" { |
| 64 | permissions := claims.ProjectPermissions(r.Context(), proj.OrganizationID, depl.ProjectID) |
| 65 | if proj.Public { |
| 66 | permissions.ReadProject = true |
| 67 | permissions.ReadProd = true |
| 68 | } |
| 69 | if !permissions.ReadProd { |
| 70 | if claims.OwnerType() == auth.OwnerTypeAnon { |
| 71 | // This means no token was provided, so return instructions for how to initiate an OAuth flow. |
| 72 | // This is currently used by MCP clients that authenticate with OAuth. |
| 73 | w.Header().Set("WWW-Authenticate", fmt.Sprintf("Bearer resource_metadata=%q", s.admin.URLs.OAuthProtectedResourceMetadata(r))) |
| 74 | } |
| 75 | return httputil.Errorf(http.StatusUnauthorized, "does not have permission to access the production deployment") |
| 76 | } |
| 77 | |
| 78 | jwt, err = s.issueRuntimeToken(r.Context(), &issueRuntimeTokenOptions{ |
| 79 | project: proj, |
| 80 | deployment: depl, |
| 81 | projectPermissions: permissions, |
| 82 | forOwner: true, |
| 83 | ttl: runtimeProxyAccessTokenTTL, |
nothing calls this directly
no test coverage detected