Skip to content

Add endpoint to proxy HTTP request to build services

This is the follow-up MR for !370 (merged). What we want to achieve in this MR, is to proxy regular HTTP requests to the services running in the build. This functionality will be used at the moment by the web IDE. Specifically the Live Preview feature.

For security reasons, mostly because we can't trust the services running in the containers (Kubernetes), we can't use the main domain to proxy requests to the runner. For that matter, we're adding a new param to Workhorse called userContentDomain. For demonstration purposes let's assume the domain is gitlabusercontent.com.

The general workflow of the whole feature will be like the following:

  • The user will start the web IDE terminal
  • The FE service will detect that the terminal job is running and will ask the backed for some information about the web IDE terminal.
    • Within this information, we will return the proxy URL, something like https://gitlab.com/namespace/project/-/jobs/123/proxy
  • When the user clicks or activates the Live preview functionality, the FE will create an iframe using the url https://gitlab.com/namespace/project/-/jobs/123/proxy with the params service and port.
  • This url will go to the JobsController where we will perform some authorizations and, if the user can access the proxy, we will redirect the user to the proper url with the param token (generated on the fly):
    • This token will store the build service info like the service, domain, build and port and a Rails token.
    • This new url will have the structure http://randomstring.gitlabusercontent.com.
    • randomstring is a random hex string generated each time the user asks for a proxy url. Why adding a subdomain instead of using the main proxy domain? Because we're going to use sessions and we don't want to store the session in the primary domain but in a subdomain.
    • The token param is a token encoded with JWT using the Workhorse secret. This way, if the token is invalid, the request will reach Workhorse and, when it tries to decode it, an error will be raised and an unnecessary request avoided to get to Rails for preauthorization.
    • The JWT token will have a very short expiration time (1 minute or even less)
  • When the request http://randomstring.gitlabusercontent.com?token=foobar reaches Workhorse, it to decode token to get the service info and also the Rails token. If the decoding fails, we stop the request and return an HTTP error.
  • With the build service info, we will build the Rails API endpoint url and make the preauthorization request.
    • If everything goes smoothly, the build runner info will be sent back to Workhorse.
    • Workhorse will store this info as well in the session to avoid, for every request to the same build, checking again the preuthorization endpoint.
  • After the preauthorization, we will redirect the user to http://randomstring.gitlabusercontent.com and, from that point, any request will be proxied to the runner

Closes #216 (closed)

Merge request reports