SpecsModelExplore
Overview
IOModel Stack
Reverse ProxyIOModel StudioYjs Realtime ServerKeycloakPostgreSQLRedis
SpecsModelExplore
Reverse Proxy
OverviewReverse Proxy GuideLinks and Communications
IDiomodel.reverse_proxy
DescriptionTLS termination and routing into the stack.
Keyreverse_proxy
Typeingress_controller
Table of contents
Reverse Proxy Guide
Why it's needed
Routing map
Deployment

Reverse Proxy Guide

The Reverse Proxy is the single front door of the stack. Every request from the outside world hits it first — it terminates TLS and forwards traffic to the right internal service over the private network.

Role in the stack

It routes HTTPS to Studio, proxies authentication to Keycloak, and upgrades WebSocket connections for the Yjs Realtime Server. Internal services never need to be exposed directly.

Why it’s needed

  • One TLS boundary — certificates and HTTPS live in one place instead of every service.
  • Routing — path/host-based routing to Studio, the Yjs server, and Keycloak.
  • WebSocket upgrades — realtime collaboration needs Upgrade/Connection headers passed through correctly.
  • Cross-cutting policy — rate limiting, request size limits, and security headers are enforced at the edge.
  • Routing map

    IncomingForwarded toNotes
    https://<host>/StudioWeb UI + API
    https://<host>/authKeycloakOIDC endpoints
    wss://<host>/collabYjs Realtime ServerWebSocket upgrade required

    Deployment

    On Kubernetes this is the Ingress controller (e.g. NGINX Ingress or Traefik), not a pod you write yourself. You declare an Ingress and the controller programs the edge:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: iomodel
      namespace: iomodel
      annotations:
        nginx.ingress.kubernetes.io/proxy-read-timeout: '3600'
        nginx.ingress.kubernetes.io/proxy-send-timeout: '3600'
    spec:
      tls:
        - hosts: ['iomodel.example.com']
          secretName: iomodel-tls
      rules:
        - host: iomodel.example.com
          http:
            paths:
              - path: /collab
                pathType: Prefix
                backend: { service: { name: yjs-server, port: { number: 3400 } } }
              - path: /
                pathType: Prefix
                backend: { service: { name: studio, port: { number: 3200 } } }

    The long proxy timeouts matter for the /collab WebSocket route — without them the Ingress will drop idle realtime connections.

    Terminate TLS here, not in the app

    Studio and the Yjs server expect to run behind this proxy. Keep TLS, HSTS, and certificate renewal at the edge so the internal services stay simple.

    Links and Communications

    5 outgoing links · 2 workflows

    Outgoing Links(5)

    Target objectLabelLink typeRelationRaw idRequiredDescription
    IOModel Studio

    deployment.iomodel.studio

    deployment
    routes HTTPS to—linksiomodel.studio——
    Keycloak

    deployment.iomodel.keycloak

    deployment
    routes auth to—linksiomodel.keycloak——
    Yjs Realtime Server

    deployment.iomodel.yjs_server

    deployment
    —defaultlinksiomodel.yjs_server——
    new_obj_9

    deployment.new_obj_9

    —
    —defaultlinksnew_obj_9——
    new_obj_11

    deployment.new_obj_11

    —
    —defaultlinksnew_obj_11——

    Related Workflows(2)

    WorkflowModelParticipant idParticipant label
    Release upgrade

    release-upgrade

    deploymentiomodel.reverse_proxyReverse Proxy
    User sign-in

    sign-in

    deploymentiomodel.reverse_proxyReverse Proxy
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: iomodel
      namespace: iomodel
      annotations:
        nginx.ingress.kubernetes.io/proxy-read-timeout: '3600'
        nginx.ingress.kubernetes.io/proxy-send-timeout: '3600'
    spec:
      tls:
        - hosts: ['iomodel.example.com']
          secretName: iomodel-tls
      rules:
        - host: iomodel.example.com
          http:
            paths:
              - path: /collab
                pathType: Prefix
                backend: { service: { name: yjs-server, port: { number: 3400 } } }
              - path: /
                pathType: Prefix
                backend: { service: { name: studio, port: { number: 3200 } } }