[go: up one dir, main page]

Skip to content

Use GitLab instance as Web IDE Extension Host Domain

Issue [WebIDE] Use GitLab instance as the Web IDE's e... (#576648)

What does this MR do and why?

It implements a new mechanism to resolve CORS rules headers for HTTP requests that come from the Web IDE extension host domain origin. Before this Merge Request, the allowed origin was a static/hardcoded value set in both Workhorse and the Rack::CORS middleware : ^https://.*.web-ide.gitlab-static.net". This Merge Request replaces the Workhorse's static CORS middleware with delegating to Rails for CORS headers resolution by sending an OPTIONS request that is handled by a new middleware called WebIdeExtensionHostDomain.

In turn, the WebIdeExtensionHostDomain middleware uses an application setting introduced in Web IDE extension host domain application setting (!208978 - merged) rather than a static value.

Bigger picture

This Merge Request is part of the project to improve support for air-gapped/offline environments in the Web IDE: [WebIDE] Support Web IDE on GitLab Self-Managed... (&15146). The end goal is allowing customers to set up a custom wildcard domain that is used by the Web IDE to sandbox 3rd-party extensions. Rather than having a separate static assets server just like https://.*.web-ide.gitlab-static.net, the GitLab instance itself can serve the Web IDE static assets. Workhorse doesn't support configuring dynamic CORS headers rules for static assets therefore it delegates to the GitLab Rails Application.

sequenceDiagram
    participant Browser as Web Browser
    participant Frontend as Frontend Server<br/>(NGINX)
    participant Workhorse as GitLab Workhorse
    participant Rails as GitLab Rails<br/>Application

    Note over Browser,Rails: Code - OSS Static Asset Request Flow with CORS

    Browser->>Frontend: GET /assets/webpack/[web-ide-vscode-workbench-file-path]<br/>Origin: https://workbench-[encrypted].gitlab-static.net
    Note right of Browser: Request includes Origin header<br/>for CORS validation

    Frontend->>Workhorse: Proxy request to Workhorse<br/>(reverse proxy)
    Note right of Frontend: NGINX forwards request<br/>to internal Workhorse service

    Workhorse->>Rails: Request CORS headers<br/>for origin validation
    Note right of Workhorse: Validates if origin is allowed<br/>for this static asset

    Rails->>Rails: Validate origin against<br/>allowed domains
    Rails-->>Workhorse: Return CORS headers<br/>(Access-Control-Allow-Origin, etc.)

    Workhorse->>Workhorse: Serve static asset<br/>from filesystem

    Workhorse-->>Frontend: Static asset response<br/>+ CORS headers
    Note right of Workhorse: Includes validated CORS headers<br/>with the static content

    Frontend-->>Browser: Forward response with<br/>static asset + CORS headers
    Note right of Browser: Browser validates CORS<br/>and loads the asset

Performance considerations

This Merge Request could impact the application's performance because the Rails service is hit to fetch static assets. I think that this implementation mitigates the performance impact for the following reasons:

  1. Workhorse will only send OPTIONS HTTP requests to the Rails application for cross origin requests (a.k.a. http requests that contain the Origin header). In practice, the Web IDE only loads 10-12 static assets using cross-origin requests. These HTTP requests only happen once when the user opens the Web IDE and they only happen in the Web IDE page.

  2. The web_ide_extension_host_domain fully handles the OPTIONS HTTP requests sent by Workhorse and bypasses the rest of the middleware chain. Resolving CORS headers for an asset path is also a cheap operation that only requires evaluating obtaining an application setting and evaluating a regular expression. Given the database processing costs reported by the performance monitor, I assume that the query to obtain the application setting is cached too.

    queries_to_load_web_ide.png

References

Screenshots or screen recordings

This Merge Request doesn't introduce user-facing changes.

How to set up and validate locally

  1. You should have NGINX set up in your GDK. Follow these instructions to set it up.

  2. Use dnsmasq to set up a local DNS resolver for *.test domain using these instructions.

  3. Use mkcert to generate a TLS certificate for the domain *.web-ide.test.

  4. In your GDK, add the following configuration to the NGINX conf file located [gdk-dir]/conf/nginx.conf)

    server {
        listen *.web-ide.test:3443 ssl;
    
        ssl_certificate /Users/enrique/gitlab/gdk/web-ide-cert.pem;
        ssl_certificate_key /Users/enrique/gitlab/gdk/web-ide-cert-key.pem;
    
        proxy_set_header    Host                $http_host;
        proxy_set_header    X-Real-IP           $remote_addr;
        proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
        proxy_set_header    X-Forwarded-Proto   $scheme;
        proxy_set_header    Upgrade             $http_upgrade;
        proxy_set_header    Connection          $connection_upgrade;
    
        proxy_http_version 1.1;
        proxy_read_timeout 300;
    
        location /assets/ {
          proxy_pass https://gitlab-workhorse;
        }
      }
  5. Compile workhorse cd workhorse && make.

  6. Go to Admin -> Settings -> General -> Web IDE and set the domain + port web-ide.test:3443.

  7. Restart services gdk rails-web gitlab-workhorse nginx.

  8. Open the Web IDE. Features such as Duo Chat and Markdown preview should work as expected and all assets HTTP requests go to the domain .web-ide.test.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Enrique Alcántara

Merge request reports

Loading