Skip to main content
LightShip is a stateless HTTP service backed by Postgres for its own state and a read-only connection to your ClickHouse for traces. This page explains the moving parts and what happens on each request.

Components

Control plane

lightship serve hosts REST, user and administrator MCP endpoints, and the web UI on one port.

Postgres

Stores users, roles, API keys, the access model, and the audit log. Never holds trace data.

ClickHouse

Read-only source for OTel traces. LightShip queries it with the caller’s compiled policies applied.

Web UI

Traces, Connect, guided Setup, and Audit views served from the same origin as the API.

LightShip MCP

lightship mcp runs beside a coding agent and writes bulk exports into its workspace. Its tool response contains only paths and counts.

Request flow

1

Authenticate

Browser requests use a session cookie set by POST /login. Automation uses Authorization: Bearer lsk_.... API keys always act as their creator; roles and attributes are resolved on every request.
2

Resolve access

LightShip loads the caller’s roles and user attributes, then combines their policies with an OR. Roles OR together, so a user holding both a “standard” and a “restricted” role sees the union.
3

Compile the query

The compiled policy expression is combined with the request filter (ANDed conditions) and run against the bound trace table. A trace is returned if any of its spans matches.
4

Return and audit

Authorized rows are streamed back with a next_cursor for paging. LightShip attempts to record the query with the caller identity and timestamp.

Access model cache

Every replica caches the compiled access model. Its age, including load and compile time, is bounded by LIGHTSHIP_MODEL_TTL (default 1m). If an expired model cannot refresh, new model-dependent requests fail closed. Role assignments are read on every request; queries already in flight are not cancelled by a later policy change. Postgres model reads use one repeatable-read snapshot. Writes validate a proposal and atomically check its base version before persisting it. A stale proposal returns 409 without changing state.

Fail-closed guarantees

LightShip returns no traces when:
  • The access model is missing or invalid.
  • No policy applies to the caller.
  • ClickHouse is unreachable.
  • A referenced field is unmarked or has been removed.
Invalid policies are rejected before storage, as is removing a field that a stored policy still references.

What LightShip does not do

  • LightShip does not classify or redact data itself.
  • LightShip does not hide individual spans inside an authorized trace. If any span matches, the whole trace is returned.
  • LightShip does not implement free-text search, custom sorting, or aggregate queries. Coding agents handle those ad hoc against local authorized exports.
  • LightShip does not protect direct ClickHouse credentials. See Deployment and security.