Research Collaborra interation #486
Labels
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: Cordy/Cairn#486
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
can we implement this?
what is the benefit?
what would the User/customer gain?
is it free for us to use or is there some license agreements/pitfalls?
Research findings (September 2026), sources at the bottom. Answers in the order the issue asks them, then the competitor comparison, the licensing map, and a proposed design.
1. Can we implement this?
Yes, and the integration surface is small and well-documented. Collabora Online (COOL) integrates through WOPI — a plain HTTP protocol where Cairn acts as the "WOPI host". Per Collabora's own SDK, COOL depends on only three file operations, all of which map directly onto what Cairn already has:
CheckFileInfo(GET/wopi/files/<id>)Store.Stat+ our locks/holds/read-only →UserCanWriteGetFile(GET/wopi/files/<id>/contents)Store.Openthrough the normal (decrypting) stackPutFile(POST.../contents)Store.Write— quota, holds and read-only enforcement come freePlus: fetch
/hosting/discoveryfrom the COOL server once (it lists which formats it edits and the iframe URL per format), mint a short-lived access token per user+file (signed HMAC — stateless, no new state file, fits the no-DB architecture), and serve an editor page that embeds the COOL iframe. The web UI side is one "Open in <editor>" entry (kebab + preview panel) behind a boot-probe feature flag, exactly the converter (#297) pattern.Anything Cairn must get right beyond the minimum: the external-change detection handshake (
LastModifiedTimein CheckFileInfo/PutFile + answering 409 withCOOLStatusCode: 1010whenX-COOL-WOPI-Timestampmismatches) — this is what protects against a WebDAV/sync client writing the file mid-editing-session; and bypassing download marking (#423) on WOPI GetFile — a marked file saved back through PutFile would bake the forensic mark into the stored original permanently. Both are handler-level details, not architecture.2. What is the benefit / what does the user gain?
3. Is it free? Licensing map (as of 2026)
For us (Swiss Cairn): completely free and clean. The WOPI host is our own code; we ship zero Collabora code. Collabora Online is MPL 2.0, fully open source, "inbound == outbound" — integrating against it via HTTP creates no obligations on Cairn's codebase. Their FAQ explicitly frames integration as the point of the product ("implement WOPI support… we have the documentation to help you"). There's a partner programme if we ever want to resell subscriptions — optional, not required.
For the customer, two editions of the same software:
So the customer decides free-vs-supported; nothing in the integration changes. That's the cleanest licensing story available in this space.
The alternatives, for contrast:
Key architectural fact: all three of the above speak WOPI on the same host-side surface. Build the WOPI host once for Collabora, and ONLYOFFICE (or anything else) becomes a config value later, not a new subsystem.
4. How the competitors implemented it
collaborationservice (Go) implementing WOPI, plus an app-registry mapping MIME types to registered apps ("Open with…" menu, which is what the #488 reference screenshot showed). Config per app:APP_NAME(display name, admin-chosen),APP_PRODUCT(Collabora/OnlyOffice/Microsoft365 — behavioural quirks per product),APP_ADDR(the document server URL),WOPI_SRC(the externally reachable address of the WOPI endpoints — the document server must be able to call back). Their service is off by default because it needs the external document server. Also relevant: they need a token store (NATS/Redis) for short-token support — Cairn's stateless signed-token approach avoids that dependency entirely.richdocumentsapp + Collabora ("Nextcloud Office" is white-labelled Collabora), including a "built-in CODE server" appimage for zero-config small installs. The built-in-server trick is not for us (a gigabyte-plus appimage inside a single Go binary is the opposite of our deployment story); our equivalent convenience is Helm/compose packaging of thecollabora/codecontainer, like the preview converter.5. What we have to take into account (pitfalls)
frame-src/frame-ancestorsCSP both ways, coolwsd's alias-group allowlist (so the COOL server only serves our WOPI host), and awopiBaseconfig override for split-horizon DNS.UserCanWrite: false); PutFile re-enforces server-side regardless. COOL handles concurrent editors internally — our lock is for the WebDAV/desktop world, and the timestamp handshake (above) bridges the two.appName, like OpenCloud) and our UI copy generic ("Open in Collabora Online" when that's the configured name). Referential use of the name is fine per their trademark policy.collabora/codeships multi-arch — dogfoodable on the Pi cluster, though a small x86 LXC would perform better.6. Recommended path
Implement a generic WOPI host with Collabora as the first-class target. Config block
office.url(+appName,wopiBase, optional format list), boot-time discovery fetch →feat.officeprobe → UI entries only when configured — the proven #297 pattern. Phases: (1) backend WOPI host TDD'd against synthetic WOPI calls + token round-trip; (2) editor page + UI entries (mockup first); (3) packaging (Helm optional service, default off, loud docs) + dogfood on the cluster + handbook page. ONLYOFFICE support later = mostly testing + anappProductswitch, if ever needed.Cairn licence gating — options, decision Nikola's:
(a) available in every licensed tier (drives adoption; customer pays Collabora only if they want the supported edition), or
(b) Business-tier feature (it's a collaboration/enterprise capability, and the enforcement hook exists via
feat.lic), or(c) core open in all tiers, with admin-side controls (per-space edit policy, watermarking) as Business features later.
Sources: Collabora SDK — How to integrate (WOPI) · Collabora FAQ (editions, licensing, MPL, subscriptions) · OpenCloud collaboration service docs · ONLYOFFICE 9.4 removes community connection limit · Collabora vs OnlyOffice after the Euro-Office fork (2026) · oCIS app-registry/app-provider docs
Researched by Claude on behalf of @Cordy.
Decisions (Nikola, 2026-09-13):
Issue stays open as the implementation tracker with the research above as the decision record.
Deployment + legal posture addendum (2026-09-13):
Dogfood networking plan (Nikola handles DNS):
code.c0rdyceps.ch→ A84.234.21.80(VPS, standard chain: Caddy → WireGuard → LAN).frame_ancestors= the Cairn origins (files-bao, files), and its alias-group allowlist restricted to our WOPI hosts.Licensing posture (settled):
appNamekeeps UI copy generic); Helm/compose may reference the publiccollabora/codeimage (customer pulls it — same asgotenberg/gotenberg:8today); if Swiss Cairn ever resells Collabora subscriptions or operates it as a managed service, we join their partner programme first — that is the vehicle for it, and an opportunity rather than a risk.Shipped in v0.6.178 (PR #516), live on both dogfoods. Built exactly to the approved office-editor mockup rev 2.
Deployed infrastructure
k3s/collabora/: MetalLB 192.168.10.250, Service 80→9980,ssl.enable=false+ssl.termination=truebehind your Caddy route, aliasgroups for files.c0rdyceps.ch / files-bao.c0rdyceps.ch / 192.168.10.249 (these also feed coolwsd's frame-ancestors, so the iframe is permitted). Discovery verified end-to-end through code.c0rdyceps.ch: 74 edit actions, all six target formats.Backend (witnessed-red TDD,
internal/office+internal/api)/wopi/files/{id}(+/contents) mounted on the OUTER mux beside /login and /s/: CheckFileInfo (UserCanNotWriteRelative— no Save As), GetFile, PutFile. The verified token's user is injected into the request context, so the scoped storage stack resolves paths, per-user encryption keys, quota, holds, locks and read-only spaces exactly as for that user's own session.X-COOL-WOPI-Timestamphandshake (mismatch → 409 +COOLStatusCode: 1010, so external WebDAV/sync changes become an overwrite-or-reload prompt instead of a silent clobber), and GetFile runs undermarks.ContextSkipMarkingso an edit round-trip can never bake a #423 download mark into the stored file./api/v1/office/opendecides write access up front (read-only space / covering lock with owner / legal hold) and states the reason; Recents +office-openaudit on open.POST /api/v1/files/newcreates from templates embedded in the binary (minimal ODF and OOXML built at release; md/txt empty) through the scoped store.office{url, appName, wopiBase}; envCAIRN_OFFICE_URL/CAIRN_OFFICE_WOPI_BASEwin, which is how the dogfoods are configured (GitOps env, config Secrets untouched).Frontend (mockup rev 2, all four variants)
Docs/legal: handbook
document-editing.md(+ index row), EULA "Third-party document servers" clause with the agreed wording, compose + chart notes (default off, browser-facing warning), CHANGELOG v0.6.178.Live verification: both dogfoods report
office editor enabled endpoint=https://code.c0rdyceps.ch app="Collabora Online"at v0.6.178;/wopi/files/*answers 401 on a bad token through the public route (the exact path COOL calls); office probe correctly session-gated.The one check only a signed-in human can do: open a docx on files-bao, watch it render in the editor, type, and confirm the save round-trip. That's yours, champ.