Skip to main content
CYPEX Documentation
Support
v2.0.0 Latest stable release View changelog ->

API Connectors

8 min read
Info
This is the conceptual / architecture reference. For the hands-on, step-by-step walkthrough with screenshots and a real sanitised request/response, see the Setup guide. For the admin-panel GUI reference (screenshots, field-by-field), see Connectors, Connector Secrets, Connector Allowlist, and Connector Enablement.

Pages in this section

  1. This page — the conceptual / architecture reference.
  2. Setup guide — the hands-on E2E walkthrough: rollout, allowlist, credentials, the guided builder, publish, execute, and audit.

A Connector is a governed, server-side definition for calling a third-party REST API and mapping its response into a typed shape a CYPEX application can render — an authenticated CYPEX user’s page can show a table backed by a live external API call, next to tables backed by CYPEX’s own PostgreSQL data.

Outbound calls are gated by platform and organization enablement, an outbound host allowlist, and org-scoped credentials. Every execution is recorded in the platform permission audit log. Connectors are designed for controlled integrations (traceable who called what, with which credential) — not ad-hoc browser-side HTTP.

Key use cases

  • Pulling live pricing, shipping, or reference data from a third-party API into a CYPEX-built application, without writing custom backend code per integration.
  • Giving each organization its own credentials and allowed hosts for the same connector definition, so a multi-tenant deployment can integrate different upstream accounts per tenant.
  • Rolling out a new integration to one organization at a time before enabling it platform-wide.

Setting up a new connector

Four admin screens work together in a fixed order — allowlist the host, add the credential, build/test/publish the connector, then enable execution. The order matters: allowlist and credential are enforced at save time, not just suggested reading order. For the full hands-on walkthrough with real screenshots, a real sanitised request/response, and a troubleshooting table, see the Setup guide.

Info
Enterprise licence required. All four screens live under Integrations, which is gated on an active enterprise licence. Without one the section does not appear in the admin sidebar, regardless of the signed-in user’s role.

What ships in v2.0.0

The administration side is complete in v2.0.0: allowlist, credentials, the guided builder, two-level enablement, and execution audit are all production surfaces. The Application Designer side is a first implementation and is deliberately narrower.

Available on connector-backed elements:

  • Connector data sources on the Table, Form, and Autocomplete elements
  • Connector-backed data renders and pages in tables
  • Forms read and write through a connector — field values resolve from literals or custom expressions on save
  • Columns are generated automatically from the connector’s response shape
  • Row selection, columns, default rows-per-page, refresh interval, and actions all work as they do on a view-backed table

Not available on connector-backed elements in v2.0.0:

ControlStatus
List element connector sourceNot available — List remains view-backed
Default sortHidden when a connector source is selected
Simple searchHidden
Fixed filter / visual filter builderHidden
Allowed filters (user-facing)Hidden
Create buttonHidden
References (linked-view configuration)Hidden
Info
These controls compile to PostgREST query parameters, which the connector runtime does not accept in this release. The editor hides them rather than offering a control that would be silently ignored — so if a knob you expect is missing after selecting a connector source, that is the reason, not a bug. A connector-backed table displays and pages its data but cannot be sorted, searched, or filtered from the designer.

Filter support, List connectors, and further element types are scheduled for v2.0.1. Plan accordingly: stand up governance and connector definitions now, build read-and-display and form-driven flows today, and hold anything that depends on designer-side filtering or List connectors until the follow-up release.

Two data sources, one governance model

It’s tempting to describe this as a single pipeline (“client → connector → PostgREST → RLS”), but the two data paths CYPEX renders from are actually siblings, not a chain:

  • PostgREST-backed views — CYPEX’s own database data, exposed as REST endpoints and filtered by Row-Level Security keyed on the caller’s org_id JWT claim. This is the REST API surface and the Capabilities vs Data Scope model.
  • Connectors — a governed outbound HTTP call to a third-party system. The connector’s own definition and credentials live in PostgreSQL and are RLS-protected by organization, but the tables themselves (cypex.t_connector, cypex.t_connector_version, cypex.t_connector_secret, cypex.t_connector_secret_version) are deliberately not exposed through PostgREST — they sit in the internal cypex schema, not cypex_generated, so there is no PostgREST route that can leak a connector definition or credential even if a view grant were misconfigured. The runtime call itself never touches PostgREST or RLS; it’s a direct, gated server-side fetch.

A single application page’s data-fetch dispatcher picks between the two per element, using a source discriminator ("view" vs "connector") on each descriptor returned by the catalogue endpoint (GET /connectors/catalogue) — from the frontend’s point of view they’re interchangeable data sources, governed by the same organization boundary, enforced by two different mechanisms.

Both paths are reachable from the same rendered application page — the frontend dispatcher picks between them per element via the source discriminator described above. They don’t feed into each other; the two diagrams below are independent routes to the same page, not a single pipeline.

Connector execution

flowchart TB
    user["Authenticated user<br/>JWT: org_id, role"]
    execute["POST /connectors/:id/execute"]
    gate{"Enablement gate"}
    allow{"Allowlist check"}
    secret["Fetch credential<br/>RLS org-scoped, not in PostgREST"]
    apicall["Outbound HTTP call"]
    map["Response mapping"]
    rows["Mapped rows returned"]
    deny["402/403 problem+json"]

    user --> execute --> gate
    gate -->|disabled| deny
    gate -->|enabled| allow
    allow -->|not approved| deny
    allow -->|approved| secret --> apicall --> map --> rows

The enablement gate is the platform-wide + org rollout switch (Connector Enablement); the allowlist check is whether the connector’s Base URL host is approved (Connector Allowlist); the credential fetch is versioned and org-scoped (Connector Secrets); a denied request returns a problem+json body such as connector_disabled or ip_not_allowed.

PostgREST view (sibling data source)

flowchart TB
    view_user["Same authenticated user"]
    view_call["PostgREST request"]
    rls["RLS policy on org_id"]
    view_rows["Rows visible to that org"]

    view_user --> view_call --> rls --> view_rows

Security model

Credential management

Connector credentials (Integrations → Credentials) are write-only and envelope-encrypted: each version stores a per-version data key wrapped by the master key, plus payload ciphertext encrypted by that data key. The plaintext value is never shown again after saving, and rotating a credential adds a new version without changing the name a connector references — no connector definition needs to change when a credential rotates. See Connector Secrets for the GUI.

Scopes

There is no separate OAuth-style scope string in this model — “scope” here means organization scope, applied consistently across every governance layer:

LayerGlobal optionPer-organization option
Allowlist entryorganization_id IS NULL — host allowed for every orgorganization_id = <org> — host allowed for that org only
Execution enablementMaster row, platform-wide kill switchPer-org row — which orgs are included in the rollout
Credentials— (always org-scoped)Every credential belongs to exactly one organization
Connector definition— (always org-scoped)Every connector belongs to exactly one organization, fixed after first save

Organization context

Every execution request resolves an organizationId (explicit in the request body, or the caller’s own organization) and validates the calling user actually has access to it before the enablement gate or allowlist check runs. A user cannot execute a connector, or read another organization’s connector-execution audit trail, outside organizations they belong to — the one exception being the system-admin-only audit view described below.

Explicit security boundaries

Warning

For review: the boundaries below are the ones that matter when auditing this feature. See Governance evidence for where the evidence of an access decision is recorded.

  • Connector definitions and credentials are RLS-scoped by organization and structurally unreachable via PostgREST — two independent barriers, not one.
  • localhost and private/loopback Base URLs are blocked at runtime (ip_not_allowed) even if they were saved; reaching an internal/local target additionally requires a platform-wide Configuration switch, on top of an allowlist entry marked “Internal / local network target.”
  • A connector only executes when both the platform-wide switch and that organization’s rollout inclusion are on (Connector Enablement) — everything is off by default.
  • The connector-execution audit view (GET /admin/audit/connector-executions) is system-admin only when queried without an organization filter, since an unfiltered query spans every tenant.

Security hardening history

The connector platform was built up in stages, each adding one layer of the governance model described above:

  • Tenant-scoped, envelope-encrypted secrets-at-rest for connector credentials (t_connector_secret, t_connector_secret_version), RLS-isolated, not PostgREST-exposed.
  • The typed, versioned connector schema itself (t_connector, t_connector_version) — immutable JSONB definitions with a pre-compiled response-mapping AST.
  • The hardened outbound runtime: the host allowlist table, SSRF-via-redirect protections, and blocking of https→http downgrade to stop credential leakage.
  • Hardened connector execution audit — correlation IDs, org-filter indexing, and locking the unfiltered view to super-admins.
  • The two-level rollout model: a platform-wide kill switch plus per-organization inclusion, replacing a single global enable flag.

Every connector execution is written to cypex_log.t_permission_audit_log as an EXECUTE_* action — the same table documented in Capabilities vs Data Scope — Permission audit cross-link. Connector executions aren’t a separate audit system; they’re filtered rows in the platform’s one permission-audit log, exposed through a dedicated endpoint:

GET /admin/audit/connector-executions

Organizations data scoping

Connectors follow the same two-dimension access model as everything else in the admin panel: a role’s capabilities decide whether a user can manage or execute connectors at all, and data scope (organization membership) decides which connectors, credentials, and allowlist entries they can see. See Capabilities vs Data Scope for the full model and Organizations for the tenancy contract it’s built on.

See also