Nexus
Documentation / Connectors

Built-in Workspace (Postgres)

Stage and persist intermediate results in a built-in, per-tenant Postgres workspace inside your Azure tenant — zero credentials, managed-identity access, and hard structural isolation from Nexus's own operational tables. Full read, write, and merge, with SQL pushdown.

The Nexus workspace is a built-in, per-tenant PostgreSQL database for staging tables, intermediate results, and pipeline scratch data. It ships with the platform, runs inside your own Azure tenant, and requires no connection string or stored password. This page is for engineers and analysts who need a place to land, shape, and persist data between steps without standing up a separate database — and for security reviewers who need to understand exactly how it is isolated from platform internals.

It is the same PostgreSQL adapter class as the external Postgres connector, so its read/write/discover/pushdown behavior is identical — but it is provisioned differently: no credentials, a dedicated managed identity, and a hard database boundary between it and Nexus's operational data.

What it is

Every Nexus installation includes a dedicated workspace database, exposed as a bridge named workspace alongside your external data sources. Use it to:

  • Persist the output of one pipeline step so a later step (or a saved report) can read it back.
  • Stage rows pulled from an external system before transforming, joining, or reconciling them.
  • Hold reference tables, lookups, and small derived datasets your reports query directly.

Because it is a normal SQL bridge, you query it with the same read/write surface, operator set, and pushdown you use for any other Postgres source — including $eq, $gt, $between, $in, $like, $contains, and $expr filters, plus full pushdown aggregation on reads and INSERT ... ON CONFLICT merge on writes.

No credentials to configure

There is nothing to provision. The workspace is created automatically when your tenant starts, and access is brokered through a dedicated, least-privilege Azure Managed Identity:

  • Each connection mints a short-lived Entra token — there is no password to store, rotate, or leak.
  • The workspace identity is a non-admin Postgres role scoped only to the workspace database.
  • It has no rights over the platform's operational database or any other tenant resource.

This mirrors the broader platform posture, where per-tenant Postgres uses managed-identity auth with DB passwords disabled.

Structural isolation

This is the property security reviewers care about most. The workspace is a separate database from the one that holds Nexus's own operational tables, and a workspace query connection is pinned to that database. PostgreSQL cannot query across databases on a single connection, so a workspace query structurally cannot read or modify platform internals — the isolation is enforced by the database boundary itself, not merely by a permission grant. Even a maliciously crafted query cannot reach the operational tables, because there is no SQL path across the database boundary on that connection.

Two consequences follow directly from that boundary:

  • UQL literally cannot reach operational tables from the workspace. There is no $expr or join that crosses into Nexus's own data — the connection has no visibility to it.
  • Cross-database joins are not available. You cannot join a workspace table to another bridge's database in one SQL statement. Combine data from multiple sources in a pipeline or a saved report instead, where each source is queried independently and the results are merged in the runtime.

Schema changes are admin-gated

Reading and writing rows is available to any caller with access to the bridge. Changing the shape of the workspace — creating tables, adding columns, dropping tables — is gated behind a dedicated workspace-manage admin permission. In addition:

  • Table and column names are validated against a strict identifier pattern.
  • Column types must come from an allowlist of supported types.

This keeps schema evolution deliberate and prevents malformed or injected identifiers from ever reaching the database. See Roles & RBAC for how the workspace-manage permission is granted.

Staging patterns

The workspace exists to decouple the steps of a data flow. Three patterns recur:

  • Extract → stage → serve. A scheduled pipeline reads from a slow or rate-limited source (NetSuite, QuickBooks, Monday) and lands the shaped rows in a workspace table. Reports then query the fast workspace copy instead of hammering the source on every open. This is exactly how the production nightly NetSuite sync works.
  • Multi-source reconciliation. Because you cannot cross-join two external bridges in one statement, stage each source into its own workspace table, then reconcile them with a workspace query or an in-pipeline merge.
  • Accumulate between runs. Use merge (below) to maintain a running table across scheduled runs — upserting new/changed rows on each pass rather than rebuilding from scratch.

Upsert / merge

The workspace supports the full write surface: insert, update, delete, and merge (upsert) via Postgres INSERT ... ON CONFLICT DO UPDATE. Merge is the workhorse for incremental staging — it inserts new rows and updates existing ones keyed on the conflict columns you name, so a re-run does not duplicate rows.

Safe-by-default limits

The workspace is sized for staging and reference data, with guardrails that keep casual use cheap and predictable:

Guardrail Default behavior
Row limit Reads without an explicit limit return up to 1,000 rows
Statement timeout Each statement is bounded by a 30-second timeout
Identifier validation Table/column names checked against a strict pattern
Type allowlist Column types restricted to a supported set

For heavier workloads, the underlying Postgres tier can be scaled up by your operator without changing how you use the workspace.

Example: stage in a pipeline, merge on re-run, read in a report

A scheduled pipeline pulls open orders, then upserts them into a workspace table so repeated runs keep one current copy rather than appending duplicates:

async def run(ctx):
    # Pull from an external source
    orders = await ctx.adapters.netsuite.read({
        "containers": ["NETSUITE"],
        "collection": "transaction",
        "where": {"type": {"$eq": "SalesOrd"}, "status": {"$ne": "closed"}},
        "select": ["id", "trandate", "entity", "foreignamount"],
    })

    # Upsert the shaped rows into the built-in workspace, keyed on the order id
    await ctx.workspace.upsert(
        "staged_open_orders",
        orders.rows,
        key_columns=["id"],
    )
    ctx.logger.info("staged %d open orders", len(orders.rows))

A report (or a downstream step) then reads staged_open_orders from the workspace bridge with normal filters and aggregation, all pushed down to the workspace Postgres:

{
  "bridge": "workspace",
  "collection": "staged_open_orders",
  "where": { "foreignamount": { "$gte": 1000 } },
  "order_by": [{ "field": "trandate", "direction": "desc" }],
  "limit": 500
}

Limits & behavior notes

  • Isolation is structural, not just permissioned. The database boundary is the control; there is no configuration that lets a workspace query reach operational tables.
  • No cross-bridge joins. Reconcile multiple sources in a pipeline/report, not in one SQL statement.
  • Default read cap is 1,000 rows. Always pass an explicit limit for larger staged sets.
  • 30-second statement timeout. Long-running maintenance queries may need to be broken up or run against a scaled tier.
  • Schema changes need admin permission. Row read/write is open to bridge callers; table/column DDL is gated.

See also