Data brokering
Concept
Every external call a Greenlight app makes goes through the data broker. The app authenticates as a workload identity; the broker authorizes the call against the integration grants for that app and substitutes the right upstream credential; every call lands in the audit log with the bound user attached.
The app never holds an integration credential of its own. It cannot.
Why a broker
Apps that hold their own credentials cause four ongoing problems for IT: credentials end up in source code, credentials drift between dev and prod, audit attribution is per-credential rather than per-user, and revocation requires hunting down every app that has a copy.
A broker replaces all four with one operation. Apps authenticate as themselves using a workload identity that nothing outside the cluster can mint. The broker holds upstream credentials in Key Vault and substitutes them at the edge of the request. Revoking an integration is a single dashboard action; every app that depends on it loses access immediately.
How a call flows
- The app’s code makes an HTTP call to the proxy URL it was given in its environment.
- The broker validates the pod’s workload identity and looks up the granted integration permission.
- The broker substitutes the right upstream credential (for service-account integrations) or exchanges the user’s token for an upstream user token (for user-passthrough integrations).
- The broker forwards the request to the upstream and proxies the response back.
- The broker writes an audit record: the app, the bound user, the integration, the upstream URL, the response code, the latency.
The app sees a normal HTTP response. Nothing about the credential substitution is visible from inside the app’s code.
Three kinds of integration
Greenlight integrations differ in one dimension: whose identity does the upstream system see?
| Kind | Whose identity the upstream sees | Used for |
|---|---|---|
| Service account | One IT-managed credential, shared across all app traffic to the upstream | Slack, GitHub, Google Workspace, internal REST APIs |
| User-passthrough | The actual end user, via OAuth token exchange | Snowflake External OAuth, Salesforce token exchange |
| Cache & realtime | The app itself, with a per-app isolated database | Per-app Redis-style storage |
A full breakdown lives in Integrations.
Workload identity
Workload identity is not an environment variable or a service-account JSON file the app reads at startup. It is a per-pod cryptographic credential the platform mints when the pod starts, rotated automatically, and never persisted to the control plane.
When the broker authenticates an incoming request, it verifies the workload identity against the cluster’s identity provider, looks up which app that workload belongs to, and uses that mapping to find the right integration credentials. The app’s own code does not need to know any of this is happening.
What apps see in code
The broker URL and the integration name are the only things the app needs:
const res = await fetch( `${process.env.GREENLIGHT_PROXY_URL}/slack/api/chat.postMessage`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ channel: '#general', text: 'Hello' }), });The app code is identical regardless of integration kind. The broker handles the difference.