InfoThis 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.
- This page — the conceptual / architecture reference.
- 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.
- 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.
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.
InfoEnterprise 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.
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:
| Control | Status |
|---|---|
| List element connector source | Not available — List remains view-backed |
| Default sort | Hidden when a connector source is selected |
| Simple search | Hidden |
| Fixed filter / visual filter builder | Hidden |
| Allowed filters (user-facing) | Hidden |
| Create button | Hidden |
| References (linked-view configuration) | Hidden |
InfoThese 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.
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_idJWT 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 internalcypexschema, notcypex_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-sidefetch.
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.
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 --> rowsThe 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.
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_rowsConnector 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.
There is no separate OAuth-style scope string in this model — “scope” here means organization scope, applied consistently across every governance layer:
| Layer | Global option | Per-organization option |
|---|---|---|
| Allowlist entry | organization_id IS NULL — host allowed for every org | organization_id = <org> — host allowed for that org only |
| Execution enablement | Master row, platform-wide kill switch | Per-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 |
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.
WarningFor 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.
localhostand 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.
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
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.
- Glossary — the one-line Connector and External API definitions.
- Setup guide — the hands-on walkthrough: screenshots, a sanitised request/response, and a troubleshooting table.
- Connectors (admin GUI) — build and publish connector definitions.
- Connector Secrets — credential storage and rotation.
- Connector Allowlist — approved outbound hosts.
- Connector Enablement — the two-step execution kill switch.
- Connector Audit — the admin-panel execution audit screen.
- REST API — the PostgREST-backed sibling data source.
- Capabilities vs Data Scope — the access model connectors follow.
- Governance evidence — where evidence of an access decision is recorded.
- Upgrade to v2.0.0 — the operator upgrade guide, including the new Connectors governance model.