Add diagram proxy to route Kroki/PlantUML requests through Rails

What does this MR do and why?

Diagram rendering services like Kroki and PlantUML receive the full diagram source in the URL, which can contain sensitive data. This adds an opt-in proxy that routes diagram requests through GitLab (via Workhorse) instead of having users' browsers make direct requests.

During post-processing, DiagramProxyPostFilter stores diagram source and auth metadata in Redis with a random key and short TTL, then rewrites the img src to a new /-/diagram-proxy/:key endpoint. The endpoint authenticates the request, retrieves and deletes the key from Redis, and proxies the downstream request through Workhorse.

Two new application settings are added to a new JSONB column:

  • plantuml_diagram_proxy_enabled
  • kroki_diagram_proxy_enabled

Refactorings have been extracted to Diagram service refactorings (!224007 - merged).

References

How to set up and validate locally

  1. Check out the branch. For best results you may wish to say a blessing, burn sage, or restart your GDK.
  2. Run migrations, as this branch adds new application settings.
  3. Enable the new setting for Kroki and/or PlantUML diagrams, from /admin/application_settings/general#js-kroki-settings and/or /admin/application_settings/general#js-plantuml-settings.
    image
    Note that the PlantUML server at plantuml.com is not supported by GitLab — you'll need to run your own if you wanna test it. This invocation works and gets you one at port 5674 locally:
    docker run -d --name plantuml -p 5674:8080 plantuml/plantuml-server:jetty
  4. Go look at some existing diagrams that go through Kroki or PlantUML on your GDK, or add some! Here's some examples:
    ```wavedrom
    { signal: [
      { name: "clk",         wave: "p.....|..." },
      { name: "Data",        wave: "x.345x|=.x", data: ["head", "body", "tail", "data"] },
      { name: "Request",     wave: "0.1..0|1.0" },
      {},
      { name: "Acknowledge", wave: "1.....|01." }
    ]}
    ```
    ```plantuml
    @startuml
    Alice -> Bob: Authentication Request!
    Bob --> Alice: Authentication Response!
    @enduml
    ```
    They should render OK. Here's what they look like for me on a wiki page:
    image
  5. Check the images are not links. They should not be clickable.
  6. Open dev tools and see where the images came from — they should have loaded from your GDK!
    image
  7. Try visiting one of those URLs. You should see a 404 — they can only be loaded once. (New URLs are generated with each page load.)
  8. Try editing the content (for me, the wiki page) and use the rich-text editor. The previews are shown in-line — use dev tools to confirm these are also loaded via your GDK.
    image
  9. That's it! You're free!

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 Asherah Connor

Merge request reports

Loading