Build your own integration
Integrations
Greenlight does not require a vendor-specific plugin for every upstream. Most well-known services are in the integration catalog — a searchable, logo’d list (GitHub, Slack, OpenAI, Salesforce, Snowflake, Azure SQL, …) that prefills the upstream’s display name, base URL, and auth, and shows IT exactly how to obtain that provider’s credential. Build your own is the Custom path for every HTTP upstream the catalog doesn’t ship: a SaaS API, an internal microservice, a corporate gateway. It opens the same registration wizard with blank fields. (Connected databases register from their catalog entry — see Integrations.)
This page covers the conceptual flow. The step-by-step admin instructions live in Manage integrations.
What you need
Section titled “What you need”- An HTTPS base URL for the upstream service (for an HTTP integration).
- An authentication mode — a static credential, OAuth client credentials, or user-delegated token exchange.
- An idea of which apps will use it, since granting is per-app.
The auth mode
Section titled “The auth mode”A custom integration is registered with a single auth mode that tells Greenlight how to obtain the upstream credential. You pick one; a provider that supports two identity models is registered as two separate integrations — for example salesforce and salesforce-user. See Data brokering and Manage integrations for that rule.
| Auth mode | When to pick it |
|---|---|
| Service account | The upstream takes a static credential — an API key, bearer token, or basic auth. This is the common case. |
| Client credentials | The upstream issues a token via the standard OAuth client-credentials grant. |
| User-passthrough | The upstream wants the end user’s identity and enforces that user’s own permissions, via OAuth token exchange. |
Picking the right mode is usually a 30-second read of the upstream’s API documentation. For a service account, the registration form also requires one credential placement: an Authorization: Bearer header, HTTP basic auth, a custom header (e.g. X-Api-Key), or a query parameter. Basic auth lets you choose whether the API key is the username or password; the latter also collects the non-secret username. Custom-header and query-parameter choices collect the provider’s field name.
How the credential reaches apps
Section titled “How the credential reaches apps”When you register the integration you also choose how the bound credential is delivered:
- Proxied (the default for HTTP) — the app calls
GREENLIGHT_PROXY_URL, sendsGREENLIGHT_DATA_KEYwhere the upstream credential would normally go, and Greenlight swaps in the credential at the request edge. The secret never reaches the app, every call is audited, and rotation takes effect on the next request. - Injected — Greenlight injects the credential into the app as an environment variable you name (e.g.
MYSERVICE_API_KEY), and the app calls the upstream directly. Use this for anything the proxy can’t carry — for example a request-signing flow an HTTP pass-through can’t handle.
What an app sees
Section titled “What an app sees”For a proxied integration registered as, say, myservice, the app reaches it through the proxy URL with the integration name as the first path segment. For a bearer-shaped integration:
await fetch( `${process.env.GREENLIGHT_PROXY_URL}/myservice/v1/widgets`, { method: 'GET', headers: { Authorization: `Bearer ${process.env.GREENLIGHT_DATA_KEY}` }, });If the upstream expects X-Api-Key, the app sends X-Api-Key: process.env.GREENLIGHT_DATA_KEY instead; if it expects ?apikey=, the app uses that query parameter. The broker rewrites the path against the registered base URL and substitutes the credential in the same slot. The app’s code stays portable — it depends on the proxy URL env var, not on the upstream’s hostname, and never holds the credential.
For an injected integration the app reads the env var you named and calls the upstream directly:
const res = await fetch('https://api.myservice.com/v1/widgets', { headers: { Authorization: `Bearer ${process.env.MYSERVICE_API_KEY}` },});Knowledge
Section titled “Knowledge”A Custom integration starts with no Knowledge entries — its card shows an empty state inviting you to add the first one, just like a catalog registration. You, an app owner, or a builder agent during a real session authors the first entries — a connection overview, idiomatic requests, common errors — so agents building against your upstream have a head start. See Curate knowledge.
What gets audited
Section titled “What gets audited”Every call through a proxied custom integration is audited identically to a catalog integration:
- The acting user, when the call is made on behalf of a signed-in user.
- The app id.
- The integration name and the upstream URL.
- The HTTP method and response code.
- The end-to-end latency.
The audit record does not include request bodies by default. An injected integration calls the upstream directly, so Greenlight doesn’t see those calls — there’s no per-call data-access audit, which is part of the tradeoff of choosing injected over proxied.
Versioning the integration
Section titled “Versioning the integration”Greenlight does not version integration definitions. If you change the base URL, the auth mode, or the credential, the change takes effect on the next call for a proxied integration, or on the app’s next deploy for an injected one. Apps that depend on a breaking change in the upstream see the same kind of breakage they would see directly — the broker is a pass-through for semantics, not a compatibility layer.