Appearance
Authentication
Each connector has an Authentication Type that controls how the platform proves your identity to the external API. Credentials are always injected server-side, so they are never exposed to the browser.
Every authentication type follows the same pattern: when a connector executes, the platform applies authentication to the outgoing HTTP request before it leaves the server. Depending on the type, this may be as simple as adding a header, or as complex as exchanging a signed token with an OAuth provider.
Authentication Types
Which type should you use?
See Choose an Authentication Type for a quick decision guide.
Each type below is documented with the same structure: a description of what it does, a sequence diagram showing the request flow, the configuration fields, an example of what the external API actually receives, and (where applicable) how tokens are managed.
None
No authentication. The platform sends the request exactly as configured, with no additional credentials.
Request flow
What the API receives
http
GET /v1/public/data HTTP/1.1
Host: api.example.com
Content-Type: application/jsonNo authentication headers or credentials are added. Use this for public APIs that require no authentication.
API Key
Injects a static key-value pair into every request. The key can be placed in either a header or a query parameter, depending on what the external API expects.
Request flow
Configuration
| Field | Description |
|---|---|
| Key | The name to send, e.g. X-API-Key or key |
| Value | The credential value — use a Secret, e.g. get_secret('service_api_key') |
| In | Where to place it: Header or Query Parameter |
All authentication fields accept Jinja2 expressions. To reference a stored secret, type the full expression into the field, for example: {{ get_secret('service_api_key') }}
What the API receives
When In is set to Header:
http
GET /v1/weather?q=Warsaw HTTP/1.1
Host: api.weatherapi.com
X-API-Key: sk-abc123...When In is set to Query Parameter:
http
GET /v1/weather?q=Warsaw&key=sk-abc123... HTTP/1.1
Host: api.weatherapi.comTIP
Use Secrets for the Value field instead of hardcoding tokens. This keeps credentials encrypted and out of connector configuration.
OAuth Client Credentials
The platform requests an access token from your OAuth server using your Client ID and Client Secret, caches it, and injects it as a Bearer token on every connector request. This is the standard OAuth 2.0 Client Credentials flow, designed for server-to-server communication where no user interaction is needed.
Request flow
Configuration
| Field | Description |
|---|---|
| Client ID | The OAuth client identifier — use a Secret, e.g. get_secret('salesforce_client_id') |
| Client Secret | The OAuth client secret — use a Secret, e.g. get_secret('salesforce_client_secret') |
| Token URL | The OAuth token endpoint, e.g. https://login.salesforce.com/services/oauth2/token |
| Scope | (optional) The OAuth scope to request, e.g. api refresh_token |
What the API receives
When the token is missing or expired, the platform first exchanges credentials at your Token URL:
http
POST /services/oauth2/token HTTP/1.1
Host: login.salesforce.com
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id=3MVG9...&client_secret=E8B1...The token endpoint responds with an access token:
json
{
"access_token": "00D5f000000XXXXX!AQcAQH...",
"token_type": "Bearer",
"expires_in": 3600
}The platform then uses this token on every connector request to your external API:
http
GET /services/data/v59.0/sobjects/Account HTTP/1.1
Host: mycompany.salesforce.com
Authorization: Bearer 00D5f000000XXXXX!AQcAQH...Subsequent requests reuse the cached token — no token exchange happens until it expires.
Token lifecycle
The platform caches the token for the duration specified by your OAuth server's expires_in response field. On every connector request the platform checks the cache: if the token is missing or expired, a new token is automatically fetched before the request proceeds.
Service-account responses are not user-scoped
OAuth Client Credentials authenticate as a service account, not as the logged-in user. The external API applies no per-user permission checks, so the response may include records the user is not entitled to see. Filter those records out in the connector definition before they reach the browser. See Filtering Sensitive Data.
JWT
Signs a JSON Web Token using your private key and injects it directly as a Bearer token on every request. Unlike OAuth flows, there is no token exchange with an external server -- the signed JWT is the credential.
Request flow
Configuration
| Field | Description |
|---|---|
| Private Key | The signing key or HMAC secret — use a Secret, e.g. get_secret('signing_private_key') |
| Algorithm | (optional) The signing algorithm. Defaults to RS256. Supported: HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512, PS256, PS384, PS512, EdDSA |
| Claims | A JSON object containing the JWT payload. All values support Jinja2 templates |
| JWT Headers | (optional) Custom JWT header fields, such as a key identifier (kid) |
Claims example
json
{
"iss": "my-service",
"sub": "{{ user.email }}",
"aud": "https://api.example.com",
"exp": "{{ now(3600) }}",
"iat": "{{ now() }}"
}Timestamp claims (exp, iat, nbf) are automatically cast to integers when their rendered values are numeric strings. See Template Variables for all available context variables and functions.
What the API receives
The platform renders your claims with current values, producing a payload like:
json
{
"iss": "my-service",
"sub": "john@example.com",
"aud": "https://api.example.com",
"exp": 1743007200,
"iat": 1743003600
}This payload is signed with your private key into a compact JWT (header.payload.signature), then sent directly as the Bearer token:
http
GET /v1/protected/resource HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im15LWtleS1pZCJ9.eyJpc3MiOiJteS1zZXJ2aWNlIiwic3ViIjoiam9obkBleGFtcGxlLmNvbSIsImF1ZCI6Imh0dHBzOi8vYXBpLmV4YW1wbGUuY29tIiwiZXhwIjoxNzQzMDA3MjAwLCJpYXQiOjE3NDMwMDM2MDB9.signatureThere is no token exchange — the signed JWT is the credential. The external API verifies the signature using your corresponding public key.
Token lifecycle
A fresh JWT is signed on every connector request. There is no caching -- each request gets a newly generated token with current claim values. This means dynamic claims like exp and iat always reflect the current time.
OAuth JWT Bearer
Combines JWT signing with an OAuth token exchange. The platform signs a JWT assertion, exchanges it for an access token at your Token URL, caches the token, and injects it as Authorization: Bearer <token> for each connector run.
This is common with services like Salesforce that use the JWT Bearer flow (RFC 7523).
Request flow
Configuration
| Field | Description |
|---|---|
| Client ID | The OAuth client identifier (used as the iss claim) — use a Secret, e.g. get_secret('salesforce_client_id') |
| Private Key | The key used to sign the JWT assertion — use a Secret, e.g. get_secret('salesforce_private_key') |
| Token URL | The OAuth token endpoint, e.g. https://login.salesforce.com/services/oauth2/token |
| Subject | The user or service account on whose behalf the token is requested, e.g. admin@example.com |
| Audience | The intended recipient of the assertion, e.g. https://login.salesforce.com |
| Token TTL | (optional) How long to cache the access token, in seconds. Defaults to 3600 |
| Algorithm | (optional) The JWT signing algorithm. Defaults to RS256. Same options as JWT above |
| Additional Claims | (optional) Extra claims merged into the JWT assertion payload, e.g. { "scope": "api refresh_token" } |
| JWT Headers | (optional) Custom JWT header fields, such as a key identifier |
What the API receives
When the token is missing or expired, the platform first builds a short-lived JWT assertion:
json
{
"iss": "3MVG9...",
"sub": "admin@example.com",
"aud": "https://login.salesforce.com",
"exp": 1743003780,
"iat": 1743003600
}This assertion is signed with your private key and sent to the Token URL:
http
POST /services/oauth2/token HTTP/1.1
Host: login.salesforce.com
Content-Type: application/x-www-form-urlencoded
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiIzTVZHOS4uLiIsInN1YiI6ImFkbWluQGV4YW1wbGUuY29tIn0.signatureThe token endpoint responds with a standard OAuth access token:
json
{
"access_token": "00D5f000000XXXXX!AQcAQH...",
"token_type": "Bearer"
}The platform then uses this token on every connector request to your external API:
http
GET /services/data/v59.0/sobjects/Account HTTP/1.1
Host: mycompany.salesforce.com
Authorization: Bearer 00D5f000000XXXXX!AQcAQH...Note that the JWT assertion is only used during the token exchange — it is never sent to the external API. Subsequent requests reuse the cached access token until it expires.
Token lifecycle
The platform caches the access token for the duration specified by Token TTL. When the cached token expires, the platform signs a new JWT assertion and exchanges it for a fresh access token automatically.
Next Steps
- Secrets -- Store credentials with
get_secret()instead of hardcoding values - Headers & Query Parameters -- Add static values alongside authentication
- Testing & Debugging -- Verify authentication is working

