docs: add a self-hosting and private data guide - #1808
Conversation
Answers #1807: how to run GeoLibre where neither the source data nor the project can be public. New docs/self-hosting.md covers the recommended shape: host the data with GeoLens (self-hosted catalog, accounts, per-dataset permissions), host the GeoLibre web build on the same origin behind the same sign-on layer, and read it with the built-in GeoLens plugin. It documents why same-origin is the deciding factor (requests use the default same-origin credentials mode, so a session cookie reaches same-origin data and never reaches a different origin, and CORS stops being a configuration problem at all), a worked reverse-proxy config, how the plugin handles credentials (API key in memory only, project files record just the server URL and dataset id), and what does and does not work when a hosted GeoLibre reads private data elsewhere. Also documents the GeoLens plugin in the user guide, which it was missing, and cross-links the new page from Getting Started, the home page, and the embedding URL parameters, where a login-protected `?url=` silently fails cross-origin. The docblock on GeoLensRasterTiles still described API-key-only private rasters as unrenderable; registerRasterApiKey renders them through MapLibre's transformRequest hook, so the comment is updated to match.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe PR adds a self-hosting guide for private GeoLibre deployments, links it from existing documentation, documents GeoLens catalog integration and credential handling, clarifies same-origin embedding behavior, and updates raster API-key documentation. ChangesPrivate data deployment documentation
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Code reviewThis is a documentation-only PR ( Bugs: None found. Security: None found. The doc's description of how the GeoLens plugin handles credentials is accurate: the API key is only used in plain Performance: N/A (docs only). Quality: No issues. The updated CLAUDE.md: No violations. Verified against project conventions:
No findings to raise — this is a well-verified, internally consistent documentation addition. |
🔍 Cloudflare PR preview
|
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/self-hosting.md`:
- Around line 109-111: Update the authentication guidance around the dataset
access and same-origin session sections to present per-user API keys as one
available option rather than a requirement. Clarify that private requests may
also be authorized through a same-origin GeoLens session, while preserving the
existing distinction for programmatic plugin access.
- Around line 20-27: Update the “Recommended setup” tip and the corresponding
repeated claims to describe browser delivery accurately: state that data is
served from the operator-controlled origin and is not sent to third-party
services, while removing claims that data never leaves the server or VM and that
credentials never leave the authentication layer. Preserve the existing GeoLens
setup guidance.
- Around line 176-179: Update the Caddy example in the self-hosting
documentation to add a handle_path /api/* block before the existing catch-all
handle, proxying API requests to geolens-api on the documented API port; keep
the frontend reverse_proxy as the fallback for non-API routes.
- Around line 34-39: Update the Cookies section in the self-hosting
documentation to state that the SSO cookie must cover the /gis, /api, and
/projects paths, typically by setting Path=/. Preserve the existing same-origin
explanation while documenting this path requirement for private project and tile
requests.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 59649583-c4cf-4ba6-bda7-97b2c834fdc0
📒 Files selected for processing (7)
docs/getting-started.mddocs/index.mddocs/self-hosting.mddocs/user-guide/data-integrations.mddocs/user-guide/embedding.mdmkdocs.ymlpackages/plugins/src/plugins/geolens-api.ts
- Replace the "data never leaves your server / the VM" phrasing with what the architecture actually guarantees: every byte is served from your own origin to a browser your auth layer admitted, and to no third party. The app is client-side, so the bytes do reach an authenticated browser, and the old wording read as a stronger residency claim than that. - Note that same-origin is necessary but not sufficient for cookie auth: the cookie's own Path must cover the URL, so a layout spreading the app, the API, and the project files across sibling paths wants Path=/. - Present the GeoLens API key as one of two options rather than the mechanism, matching what the plugin section already said about a same-origin session authorizing private datasets with no key. - Name the Caddy catch-all upstream `geolens:8080` and say what it is: the GeoLens entry point, which routes /api to its API service internally, so one upstream covers both. Adding a separate /api route was suggested; `handle_path` would strip the prefix the API expects, so the comment explains what to do instead when a deployment does split them.
Code reviewThis is a docs-only PR (plus one comment-only code change) adding
Bugs: None found. Security: None found — the guide's security-relevant guidance (drop loopback CSP allowances before public exposure, scope Performance: N/A (docs-only change). Quality: No issues. Prose is clear, internal links resolve, and the one code comment update ( CLAUDE.md: Compliant — no code paths touched that require lockfile refreshes, catalog regeneration, or other checklist items in CLAUDE.md; this is a pure docs/comment change. No inline comments were posted; I found nothing rising to a reportable issue after verifying the claims against the source. |
🔍 GitHub Pages PR preview
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/self-hosting.md`:
- Around line 183-189: Update the self-hosting documentation around the
catch-all GeoLens reverse-proxy configuration to explicitly require verifying
that the outer SSO identity is consumed by GeoLens and that a GeoLens browser
session is created. Document the fallback requirement for same-origin session
cookies or a configured X-Api-Key so private datasets remain accessible, and
retain the existing forward_auth routing guidance.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 36797a73-7a0e-4e67-9cc9-47073a93822f
📒 Files selected for processing (1)
docs/self-hosting.md
- Say explicitly that the forward-auth layer and GeoLens are two separate authentication layers. The proxy decides who reaches the origin; it does not tell GeoLens who the visitor is, and the plugin sends only a same-origin cookie plus an optional X-Api-Key. So the visitor needs a GeoLens identity as well: either point GeoLens at the same OIDC provider so signing in yields a GeoLens session on this origin, or hand each user a per-user API key. Names the symptom (public datasets appear, private ones stay invisible) so the failure is recognizable.
Code reviewReviewed the full diff (docs-only content plus a one-line-summary-worthy comment fix in
Bugs: None found. Security: None found — the guide's security claims (same-origin cookie behavior, CORS necessity, CSP loopback warning, PostGIS host allowlisting) are accurate and, if anything, steer readers toward the safer configuration. Performance: N/A (docs-only change). Quality: No issues — the new page is well-organized, cross-linked correctly, and the supporting edits are minimal and on-topic. CLAUDE.md: No violations. This is a docs-only change (plus one doc-comment fix) with no code/test/build implications, consistent with the PR's stated "Docs only, plus one code comment" testing note. No inline comments were posted — I found nothing to flag. |
Answers discussion #1807: how to run GeoLibre where neither the source data nor the
.geolibre.jsonproject can be public (Indigenous and local community monitoring data, in that case).New page:
docs/self-hosting.mdThe recommended shape, and why:
maplibreGeoLensPluginis already registered inusePlugins.ts.fetchProjectFromUrl, the GeoLens client) use the browser defaultsame-origincredentials mode, so an SSO session cookie reaches same-origin data automatically and never reaches a different origin; CORS stops being a configuration problem; MapLibre's own tile requests follow the same rules.GEOLIBRE_SHARE_URL=off,GEOLIBRE_APP_BASE, sidecar confinement, embed origins).localStorageor the project file; a saved project records only the server URL and dataset id; public layers restore automatically while private ones stay blank until the recipient reconnects with their own key; a private raster's key is scoped to exactly that raster's tile-URL prefix.web.geolibre.appreading private data elsewhere): cookies cannot work cross-origin, CORS must allow the app origin, signed expiring URLs are the only practical mechanism, and tokens in URLs leak.Two gotchas verified against the code and written down:
?url=rejects relative paths (normalizeProjectUrlrequires an absolute http/https URL), anddocker/nginx.conf's loopbackconnect-srcallowances should be dropped before public exposure.Supporting changes
docs/user-guide/data-integrations.md: a Self-hosted catalogs section documenting the GeoLens plugin, which the user guide was missing entirely.getting-started.md(Run with Docker, Basic Auth),index.md, andembedding.md, where a login-protected?url=fails cross-origin with no obvious explanation.mkdocs.yml: nav entry under Reference.geolens-api.ts: theGeoLensRasterTilesdocblock still described API-key-only private rasters as unrenderable.registerRasterApiKeyrenders them through MapLibre'stransformRequesthook, so the comment now matches the code. Comment only, no behavior change.Testing
Docs only, plus one code comment. Internal links and anchors verified; no em dashes; mermaid fence matches the one already in
architecture.md.Summary by CodeRabbit
New Features
Documentation