Programmatic Auth Configs

Guide to creating auth configs programmatically

Auth configs are created once and reused many times. However when dealing with many toolkits, you may want to create auth configs programmatically.

  • When creating and destroying auth configs multiple times in your app’s lifecycle.
  • When creating auth configs for your users’ users.

Using Composio Default Auth

For certain apps, you can optionally use Composio’s managed auth. This means you don’t have to provide your own OAuth credentials, Bearer tokens, API keys, etc.

1import { Composio } from "@composio/core";
2
3const composio = new Composio();
4
5const authConfig = await composio.authConfigs.create("LINEAR", {
6 name: "Linear",
7 type: "use_composio_managed_auth",
8});
9
10console.log(authConfig);

The auth_config_id should be stored securely in your database for future use to be created and destroyed multiple times.

You can also provide your own authentication details. The required credentials and authScheme depend on the auth type.

Using Custom Auth

Create the auth config

If you know the required authentication fields for your toolkit, you can directly create the auth config. OAuth2 is the most common auth type for apps. When using your own OAuth developer app, you must ensure to set the authorized redirect URI in the OAuth configuration to https://backend.composio.dev/api/v3/toolkits/callback.

This is the URI that captures the OAuth code that is returned to the app.

In this case, we’re using our own OAuth2 client ID and secret to create the auth config for Notion:

1const authConfig = await composio.authConfigs.create("NOTION", {
2 name: "Notion",
3 type: "use_custom_auth",
4 credentials: {
5 client_id: "1234567890",
6 client_secret: "1234567890",
7 oauth_redirect_uri: "https://backend.composio.dev/api/v3/toolkits/callback",
8 },
9 authScheme: "OAUTH2",
10});
11
12console.log(authConfig);

Fetching the fields

For more complex cases where you need to dynamically discover the exact field names and handle different auth schemes programmatically, you can inspect the auth config details first.

Inspect the auth config details

1const toolkits = await composio.toolkits.get("NOTION");
2
3// Extract field names from authConfigDetails
4const authFields = toolkits.authConfigDetails?.flatMap(
5 detail => [
6 ...detail.fields.authConfigCreation.required.map(field => field.name),
7 ...detail.fields.authConfigCreation.optional.map(field => field.name)
8 ]
9) || [];
10
11console.log("Required auth config fields:", authFields);

In this example, assuming you have the following environment variables set:

$NOTION_CLIENT_ID=your_client_id
>NOTION_CLIENT_SECRET=your_client_secret

This makes it easy to create the auth config programmatically by reading required fields from the environment variables.

1import { Composio } from "@composio/core";
2
3const composio = new Composio({
4 apiKey: process.env.COMPOSIO_API_KEY,
5});
6
7const toolkits = await composio.toolkits.get("NOTION");
8
9// Extract field names from authConfigDetails
10const requiredAuthFields =
11 toolkits.authConfigDetails?.flatMap((detail) =>
12 detail.fields.authConfigCreation.required.map((field) => field.name)
13 ) || [];
14
15console.log("Required auth config fields:", requiredAuthFields);
16
17const authConfig = await composio.authConfigs.create("NOTION", {
18 name: "Notion",
19 type: "use_custom_auth",
20 authScheme: "OAUTH2", // Replace with the correct scheme for your toolkit if different
21 credentials: Object.fromEntries(
22 requiredAuthFields.map((fieldName) => [
23 fieldName,
24 process.env[`NOTION_${fieldName.toUpperCase()}`] || "",
25 ])
26 ),
27});