Collaboration#
oxo-flow provides collaboration primitives for sharing and versioning pipelines across users and teams.
Overview#
| Operation | Description | Endpoint |
|---|---|---|
| Fork | Copy a pipeline to your workspace | POST /api/pipelines/{id}/fork |
| Diff | Compare two pipelines | POST /api/pipelines/diff |
| Share | Create a shareable link | POST /api/pipelines/{id}/share |
| Import | Import from share link | POST /api/pipelines/import |
Fork#
Create an independent copy of a pipeline in your workspace. The fork is a full copy — changes to the original do not affect the fork, and vice versa.
# API
curl -X POST http://localhost:8080/api/pipelines/pipeline-abc/fork \
-H "Content-Type: application/json" \
-d '{"user_id": "alice"}'
# Response
{
"forked_id": "pipeline-def",
"name": "my-analysis (fork)"
}
Forks record their lineage — the forked_from field tracks the source pipeline.
Diff#
Compare two pipelines and see what changed:
curl -X POST http://localhost:8080/api/pipelines/diff \
-H "Content-Type: application/json" \
-d '{"toml_a": "<workflow-a TOML>", "toml_b": "<workflow-b TOML>"}'
# Response
{
"diffs": [
{
"path": "rules",
"category": "rules",
"description": "rule \"align\": shell command changed",
"severity": "info"
}
]
}
Share#
Create a shareable link for a pipeline:
curl -X POST http://localhost:8080/api/pipelines/pipeline-abc/share \
-H "Content-Type: application/json" \
-d '{"visibility": "link", "expires_in_days": 30}'
# Response
{
"share_url": "oxo+https://lab.example.com:8080/share/abc123",
"access_token": "abc123",
"expires_at": "2024-02-12T00:00:00Z"
}
Visibility levels (link / workspace) are stored on the share record.
Currently the share link is consumed only through the
import API below — there is no browser page at the share URL, and
visibility/membership checks are not yet enforced on import.
Import#
Import a pipeline from an oxo+https:// share link:
curl -X POST http://localhost:8080/api/pipelines/import \
-H "Content-Type: application/json" \
-d '{"url": "oxo+https://lab.example.com:8080/share/abc123"}'
# Response
{
"pipeline_id": "pipeline-xyz"
}
The oxo+https:// protocol prefix makes share links explicit and unambiguous —
you can paste them into any tool and the intent is clear.
Import behavior:
- Creates a full copy of the shared pipeline
- Records the source via forked_from
- Sets visibility to private by default
- Checks share expiration before allowing import
Permissions Model#
A simple three-state visibility model:
| Level | Access |
|---|---|
| Private | Only the owner can view/edit (the default for imported pipelines) |
Shared (link / workspace) |
Read-only access via share/import |
| Admin | Can view all, manage users |
No nested RBAC. No group hierarchies. Simple and transparent.
Share Landing Pages#
A share link (oxo+https://host:port/share/<token>) opens a public
read-only landing page — pipeline name/version, DAG shape, the full TOML,
the owner, expiry, and the most recent terminal run as provenance. No
session is required to view it (the token is the authorization). The
Import into my workspace action copies the pipeline to the acting user's
account (login required — the API enforces it).
Visibility is now enforced server-side: private pipelines are
owner/admin-only, workspace pipelines are readable (not writable) by
every authenticated user, link pipelines are reachable only through
their share token.
Version History#
Every save/update snapshots the previous pipeline content (up to 50 revisions). In the editor's History tab you can load any snapshot into the editor or roll back — rollback preserves the current version as a new revision, so nothing is ever lost.
Audit Trail#
Forking a pipeline is recorded in the audit log:
Share and import actions are not yet logged. View audit logs via
GET /api/audit?days=7.