Skip to content

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/json

No 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

FieldDescription
KeyThe name to send, e.g. X-API-Key or key
ValueThe credential value — use a Secret, e.g. get_secret('service_api_key')
InWhere 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.com

TIP

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

FieldDescription
Client IDThe OAuth client identifier — use a Secret, e.g. get_secret('salesforce_client_id')
Client SecretThe OAuth client secret — use a Secret, e.g. get_secret('salesforce_client_secret')
Token URLThe 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

FieldDescription
Private KeyThe 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
ClaimsA 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.signature

There 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

FieldDescription
Client IDThe OAuth client identifier (used as the iss claim) — use a Secret, e.g. get_secret('salesforce_client_id')
Private KeyThe key used to sign the JWT assertion — use a Secret, e.g. get_secret('salesforce_private_key')
Token URLThe OAuth token endpoint, e.g. https://login.salesforce.com/services/oauth2/token
SubjectThe user or service account on whose behalf the token is requested, e.g. admin@example.com
AudienceThe 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.signature

The 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

Gainsight CC Developer Portal