Skip to main content
The auth type determines how user credentials are collected, stored, and injected into the service context at call time.

Auth types

TypeDescriptionUse case
oauth2Full OAuth 2.0 flow with authorization, token exchange, and refreshGitHub, Google, Slack, Shopify
customUser-provided credentials with a configurable settings schemaAPI keys, tokens, basic auth
noneNo authentication requiredPublic APIs, data processing

OAuth2

const SERVICE_CONFIG = {
  displayName: "GitHub",
  description: "GitHub API integration",
  category: "Developer Tools",
  authType: "oauth2",
  authorizationUrl: "https://github.com/login/oauth/authorize",
  tokenUrl: "https://github.com/login/oauth/access_token",
  scopes: "repo user read:org",
  additionalAuthorizationParams: {},
  tokenResponseToCredentials: (response: any) => ({
    accessToken: response.access_token,
    refreshToken: response.refresh_token,
    expiresAt: response.expires_in
      ? Date.now() + response.expires_in * 1000
      : undefined,
    tokenType: response.token_type,
  }),
} as const;
FieldRequiredDescription
authorizationUrlYesOAuth authorization endpoint
tokenUrlYesToken exchange endpoint
scopesYesSpace-separated OAuth scopes to request
additionalAuthorizationParamsNoExtra query parameters for the authorization URL (e.g., { access_type: "offline" })
tokenResponseToCredentialsNoMaps the provider’s token response to the standard credential format

Custom

const SERVICE_CONFIG = {
  displayName: "OpenAI",
  description: "OpenAI API integration",
  category: "AI & ML",
  authType: "custom",
} as const;

const CUSTOM_AUTH_SETTINGS = [
  {
    key: "apiKey",
    description: "Your OpenAI API key",
    type: "password",
    required: true,
  },
  {
    key: "organization",
    description: "OpenAI organization ID (optional)",
    type: "text",
    required: false,
  },
] as const;

Custom auth setting fields

FieldDescription
keyUnique identifier for the setting
descriptionLabel shown to the user
typeInput type: text, password, url, or select
requiredWhether the field is required
defaultValueDefault value (optional)
optionsJSON-stringified array of { value, label } for select type

Accessing custom credentials

createClient(context: AuthenticatedServiceContext<Settings, CustomAuth>) {
  return new OpenAI({
    apiKey: context.userCredentials.customData?.apiKey,
    organization: context.userCredentials.customData?.organization,
  });
}

None

const SERVICE_CONFIG = {
  displayName: "CSV Parser",
  description: "Parse and transform CSV files",
  category: "Data Processing",
  authType: "none",
} as const;
No credentials are collected or injected. The service context still includes the user ID and workspace directory.