Skip to main content

Authentication

Use kittl.auth to run OAuth from a sandboxed app without exposing secrets in the client.

Setup your auth provider

Setup an auth client with your provider and get the client ID, scopes, and auth/token URLs needed to configure the app manifest. You will need to use

https://app.kittl.com/auth/callback/:appId

as your callback (where :appId is your app's ID)

Setup

Declare your OAuth provider in the app manifest.

Add an oauthProviders object under config in manifest.json. Keys are camelCase. For example:

{
"config": {
"oauthProviders": {
"myProvider": {
"clientId": "client_id_from_provider",
"scope": "example:read,example:write",
"authorizationUrl": "https://myAuthProvider.com/oauth2/authorize",
"accessType": "offline",
"tokenUrl": "https://myAuthProvider.com/oauth2/token"
}
}
}
}

Trigger the auth flow

const provider = 'myProvider';

const startResp = await kittl.auth.startAuth({
provider,
// Recommended when your provider supports OAuth 2.1 / PKCE
generatePKCE: true,
});

if (!startResp.isOk) {
// Handle startResp.error
return;
}

const { code, code_verifier } = startResp.result;

// Exchange the auth code for tokens
const exchangeResp = await kittl.auth.exchangeCode({
code,
provider,
code_verifier,
});

if (!exchangeResp.isOk) {
// Handle exchangeResp.error
return;
}

// exchangeResp.result contains the provider token response payload

Restore token on reload

When the app loads, check if a token is already stored:

const provider = 'myProvider';
const tokenResp = await kittl.auth.getAuthToken({ provider });

if (tokenResp.isOk && tokenResp.result) {
// Already authenticated
}

Logout

await kittl.auth.logout({ provider: 'myProvider' });

Omit provider to clear all provider tokens for the app.

Backend proxy and provider limitations

If your provider does not support PKCE, run a backend proxy for token exchange so your client secret stays server-side.

In general:

  • Prefer OAuth with PKCE (generatePKCE: true)
  • Keep secrets off the app client
  • Use your backend for provider-specific token handling when needed

Custom field mappings

If your auth provider does not follow the spec exactly, you can map the field names to custom values, for example you can map redirect_uri to be sent as redirect_url using the following config:

{
oauthProviders: {
myProvider: {
// ...
customFieldMappings: {
redirect_uri: 'redirect_url',
},
},
},
}