R2-D2
Dashboard
Node Red
Restreaming
The Force
UpdatedNever
v1.0.0

Overview

Loading…
R2-D2
Dashboard
Node Red
Restreaming
The Force
UpdatedNever
v1.0.0

COP SitaWare

Connection

Where the dashboard will reach the SitaWare HQ REST API.

Embed URL
https://sw.r2d2.office.ilab.zone/sw/
API base
https://sw.r2d2.office.ilab.zone/sw/rest
Auth mode
Keycloak bearer (rotates)
Token source (Phase 1)
User's GUI login at /the-force/cop
Token source (Phase 2)
MQTT middleware → in-memory cache

Iframe embedding — header overrides

The /the-force/cop iframe is blocked today by X-Frame-Options: DENY (SitaWare) + frame-ancestors 'self' (Keycloak). Paste one of the snippets below into whatever reverse proxy we control to unblock it.

Observed redirect chain (curl https://sw.r2d2.office.ilab.zone/sw/):
Diagnosis
GET https://sw.r2d2.office.ilab.zone/sw/
  -> 302  Location: /oauth2/authorization/SitaWare_SessionService
          x-frame-options: DENY            <-- iframe blocked here
  -> 302  Location: https://login.sw.r2d2.office.ilab.zone/realms/SitaWare/...
          x-frame-options: DENY
  -> 200  Keycloak login page
          content-security-policy: frame-src 'self'; frame-ancestors 'self'; ...
Caddyfile — sw.r2d2 + login.sw.r2d2 (if Caddy becomes ours)
# /etc/caddy/Caddyfile (or import file) — applied at the edge.
# We don't own Caddy today; hand this to whoever does.

sw.r2d2.office.ilab.zone {
    reverse_proxy https://SITAWARE_UPSTREAM {
        header_down -X-Frame-Options
        header_down -Content-Security-Policy
    }
    header Content-Security-Policy "frame-ancestors 'self' http://localhost:3210 https://r2d2.office.ilab.zone" always
    header -X-Frame-Options
}

login.sw.r2d2.office.ilab.zone {
    reverse_proxy https://KEYCLOAK_UPSTREAM {
        header_down -X-Frame-Options
        header_down -Content-Security-Policy
    }
    # Merge — keep Keycloak's own frame-src / object-src protections
    header Content-Security-Policy "frame-src 'self'; frame-ancestors 'self' http://localhost:3210 https://r2d2.office.ilab.zone; object-src 'none'" always
    header -X-Frame-Options
}
nginx — sidecar in front of our SitaWare/Keycloak instance
# /etc/nginx/conf.d/sitaware-iframe.conf
# Deploy as a sidecar in front of our SitaWare + Keycloak instance.
# Replace SITAWARE_UPSTREAM / KEYCLOAK_UPSTREAM with the real backends.

server {
    listen 8080;
    server_name sw.r2d2.office.ilab.zone;

    location / {
        proxy_pass         https://SITAWARE_UPSTREAM;
        proxy_set_header   Host              $host;
        proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto https;

        # Strip upstream framing blocks. Applied on 3xx too — the iframe's
        # FIRST response is a 302 to /oauth2/authorization/..., so the headers
        # on the redirect itself must be clean.
        proxy_hide_header  X-Frame-Options;
        proxy_hide_header  Content-Security-Policy;
        add_header         Content-Security-Policy
            "frame-ancestors 'self' http://localhost:3210 https://r2d2.office.ilab.zone" always;

        # SitaWare's SW_SESSION cookie is SameSite=Lax by default — iframe needs None+Secure.
        proxy_cookie_flags SW_SESSION samesite=none secure;
    }
}

server {
    listen 8080;
    server_name login.sw.r2d2.office.ilab.zone;

    location / {
        proxy_pass         https://KEYCLOAK_UPSTREAM;
        proxy_set_header   Host              $host;
        proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto https;

        proxy_hide_header  X-Frame-Options;
        proxy_hide_header  Content-Security-Policy;
        # Merge — keep Keycloak's own frame-src / object-src protections.
        add_header         Content-Security-Policy
            "frame-src 'self'; frame-ancestors 'self' http://localhost:3210 https://r2d2.office.ilab.zone; object-src 'none'" always;

        # Keycloak sets KC_* cookies SameSite=None already; AUTH_SESSION_ID needs the same.
        proxy_cookie_flags AUTH_SESSION_ID samesite=none secure;
    }
}
Keycloak realm — kcadm.sh (alternative to nginx for the login.* host)
# Alternative to the login.sw.r2d2 nginx block: configure the realm directly.
# Requires keycloak admin access on the SitaWare realm.

# 1) Authenticate
kcadm.sh config credentials \
    --server https://login.sw.r2d2.office.ilab.zone \
    --realm master --user admin

# 2) Relax X-Frame-Options + CSP frame-ancestors on the SitaWare realm
kcadm.sh update realms/SitaWare \
    -s 'browserSecurityHeaders.xFrameOptions=' \
    -s "browserSecurityHeaders.contentSecurityPolicy=frame-src 'self'; frame-ancestors 'self' http://localhost:3210 https://r2d2.office.ilab.zone; object-src 'none'"

# 3) Add the fleet origin to the SitaWare_SessionService client's web origins
kcadm.sh update clients/$(kcadm.sh get clients -r SitaWare -q clientId=SitaWare_SessionService --fields id --format csv --noquotes | tail -n1) \
    -r SitaWare \
    -s 'webOrigins=["https://r2d2.office.ilab.zone","http://localhost:3210"]'
Cookie gotcha: SW_SESSION is set with SameSite=Lax. Inside a cross-site iframe the OAuth redirect chain drops it and loops back to Keycloak. The nginx snippet rewrites it to SameSite=None; Secure. Note: Secure cookies require an HTTPS frame parent, so embedding from http://localhost:3210 may still fail — only the deployed https://r2d2.office.ilab.zone parent will work.

Latency

Round-trip timing against a cheap authenticated endpoint.

Health probe
GET /v2/licensing/currentUsers
Last check
— (awaiting C-3 / C-4)
Last latency
—
Last status
—

Track Layers

Mirror of the SitaWare admin view. Built from /v1/layerCatalogue + per-layer detail calls.

Planned columns:
  • Path/NameLayer display namelayerCatalogue → layer.name
  • TypeNVG, OTH Gold, C2, …layerCatalogue bucket + layer.type
  • Obj. CountSymbols on the layerGET /v5/layers/{id}/symbols (length)
  • Source LayersUpstream sources feeding the layerlayerCatalogue → layer.sources
  • RecordingWhether recording is activelayerCatalogue → layer.recording
  • Timespan (days)Retention windowlayerCatalogue → layer.timespanDays
  • UsageWhere the layer is referencedGET /v1/layerCatalogue/layers/{id}/usage
Empty state — Phase 2 swaps this card for a DataView backed by /api/cop/layers.

Advanced — developer references

OpenAPI, dev docs, and the SHC matrix deep link.

OpenAPI spec
src/app/data/cop-sitaware/openapi.json
Integration plan
.settings/features/nr-fleet_feature-cop-sitaware.md
Vendor docs
src/app/data/cop-sitaware/cop-sitaware{,-intro,-symbology}.md
Management (SHC matrix)
https://sw.r2d2.office.ilab.zone/sw/connection?mode=smt&connection_view=shc-matrix
REST API
https://sw.r2d2.office.ilab.zone/sw/documentation/api-rest/index.html
Javadoc
https://sw.r2d2.office.ilab.zone/sw/documentation/api-javadoc/index.html
NanoMap REST
https://sw.r2d2.office.ilab.zone/sw/documentation/api-nanomapRest/index.html