Skip to content

Commit 3eb78c1

Browse files
authored
Docs: Linear Auth Provider (#351)
1 parent 92f8be2 commit 3eb78c1

6 files changed

Lines changed: 250 additions & 0 deletions

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
auth:
2+
providers:
3+
- id: default-linear
4+
description: "The default Linear provider"
5+
enabled: true
6+
type: oauth2
7+
provider_id: linear
8+
client_id: ${env:LINEAR_CLIENT_ID}
9+
client_secret: ${env:LINEAR_CLIENT_SECRET}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Arcade } from "@arcadeai/arcadejs";
2+
3+
const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable
4+
5+
const userId = "{arcade_user_id}";
6+
7+
// Start the authorization process
8+
let authResponse = await client.auth.start(userId, "linear", {
9+
scopes: ["read"],
10+
});
11+
12+
if (authResponse.status !== "completed") {
13+
console.log("Please complete the authorization challenge in your browser:");
14+
console.log(authResponse.url);
15+
}
16+
17+
// Wait for the authorization to complete
18+
authResponse = await client.auth.waitForCompletion(authResponse);
19+
20+
const token = authResponse.context.token;
21+
// Do something interesting with the token...
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from arcadepy import Arcade
2+
3+
client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable
4+
5+
user_id = "{arcade_user_id}"
6+
7+
# Start the authorization process
8+
auth_response = client.auth.start(
9+
user_id=user_id,
10+
provider="linear",
11+
scopes=[
12+
"read"
13+
],
14+
)
15+
16+
if auth_response.status != "completed":
17+
print("Please complete the authorization challenge in your browser:")
18+
print(auth_response.url)
19+
20+
# Wait for the authorization to complete
21+
auth_response = client.auth.wait_for_completion(auth_response)
22+
23+
token = auth_response.context.token
24+
# Do something interesting with the token...
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from typing import Annotated, Any
2+
3+
from arcade_tdk import ToolContext, tool
4+
from arcade_tdk.auth import Linear
5+
6+
import httpx
7+
8+
9+
@tool(requires_auth=Linear(scopes=["read"]))
10+
async def get_teams(context: ToolContext) -> Annotated[dict[str, Any], "Teams in the workspace with member information"]:
11+
"""Get Linear teams and team information including team members"""
12+
token = context.get_auth_token_or_empty()
13+
url = "https://api.linear.app/graphql"
14+
headers = {
15+
"Authorization": f"Bearer {token}",
16+
"Content-Type": "application/json",
17+
"Accept": "application/json",
18+
}
19+
20+
query = """
21+
query Teams {
22+
teams {
23+
nodes {
24+
id
25+
name
26+
key
27+
}
28+
}
29+
}
30+
"""
31+
32+
async with httpx.AsyncClient() as client:
33+
resp = await client.post(url, json={"query": query}, headers=headers)
34+
resp.raise_for_status()
35+
data = resp.json()
36+
teams = data["data"]["teams"]["nodes"]
37+
return teams

pages/home/auth-providers/index.mdx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ For more information on how to customize your auth provider, select an auth prov
7777
link="/home/auth-providers/hubspot"
7878
category="Auth"
7979
/>
80+
<ToolCard
81+
name="Linear"
82+
image="linear.svg"
83+
summary="Authorize tools and agents with Linear"
84+
link="/home/auth-providers/linear"
85+
category="Auth"
86+
/>
8087
<ToolCard
8188
name="LinkedIn"
8289
image="linkedin"
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import { Tabs } from "nextra/components";
2+
3+
# Linear auth provider
4+
5+
The Linear auth provider enables tools and agents to call [Linear APIs](https://linear.app/developers/graphql) on behalf of a user. Behind the scenes, the Arcade Engine and the Linear auth provider seamlessly manage Linear OAuth 2.0 authorization for your users.
6+
7+
### What's documented here
8+
9+
This page describes how to use and configure Linear auth with Arcade.
10+
11+
This auth provider is used by:
12+
13+
- Your [app code](#using-linear-auth-in-app-code) that needs to call the Linear API
14+
- Or, your [custom tools](#using-Linear-auth-in-custom-tools) that need to call the Linear API
15+
16+
## Configuring Linear auth
17+
18+
In a production environment, you will most likely want to use your own Linear app credentials. This way, your users will see your application's name requesting permission.
19+
20+
You can use your own Linear credentials in both the Arcade Cloud and in a [self-hosted Arcade Engine](/home/local-deployment/install/local) instance.
21+
22+
Before showing how to configure your Linear app credentials, let's go through the steps to create a Linear app.
23+
24+
### Create a Linear app
25+
26+
- It is **highly recommended** to first [create a new Linear workspace](https://linear.app/join) for the purpose of managing the OAuth2 Application.
27+
- Create a new public OAuth2 Application in your [integration's settings page](https://linear.app/settings/api/applications/new).
28+
- Fill out your application specific information such as application name and description.
29+
- Set the Callback URL to: `https://cloud.arcade.dev/api/v1/oauth/callback`
30+
- Toggle the **Public** switch to enable public access to the application if you want other workspaces to be able to use your application.
31+
- Once you complete creating your integration, copy the client ID and client secret to use below.
32+
33+
Next, add the Linear app to your Arcade Engine configuration. You can do this in the Arcade Dashboard, or by editing the `engine.yaml` file directly (for a self-hosted instance).
34+
35+
## Configuring your own Linear Auth Provider in Arcade
36+
37+
There are two ways to configure your Linear app credentials in Arcade:
38+
39+
1. From the Arcade Dashboard GUI
40+
2. By editing the `engine.yaml` file directly (for a self-hosted Arcade Engine)
41+
42+
We show both options step-by-step below.
43+
44+
<Tabs items={["Dashboard GUI", "Engine Configuration YAML"]}>
45+
<Tabs.Tab>
46+
47+
### Configure Linear Auth Using the Arcade Dashboard GUI
48+
49+
<Steps>
50+
51+
#### Access the Arcade Dashboard
52+
53+
To access the Arcade Cloud dashboard, go to [api.arcade.dev/dashboard](https://api.arcade.dev/dashboard). If you are self-hosting, by default the dashboard will be available at `http://localhost:9099/dashboard`. Adjust the host and port number to match your environment.
54+
55+
#### Navigate to the OAuth Providers page
56+
57+
- Under the **OAuth** section of the Arcade Dashboard left-side menu, click **Providers**.
58+
- Click **Add OAuth Provider** in the top right corner.
59+
- Select the **Included Providers** tab at the top.
60+
- In the **Provider** dropdown, select **Linear**.
61+
62+
#### Enter the provider details
63+
64+
- Choose a unique **ID** for your provider (e.g. "my-linear-provider").
65+
- Optionally enter a **Description**.
66+
- Enter the **Client ID** and **Client Secret** from your Linear app.
67+
68+
#### Create the provider
69+
70+
Hit the **Create** button and the provider will be ready to be used in the Arcade Engine.
71+
72+
</Steps>
73+
74+
When you use tools that require Linear auth using your Arcade account credentials, the Arcade Engine will automatically use this Linear OAuth provider. If you have multiple Linear providers, see [using multiple auth providers of the same type](/home/auth-providers#using-multiple-providers-of-the-same-type) for more information.
75+
76+
</Tabs.Tab>
77+
<Tabs.Tab>
78+
79+
### Configuring Linear auth in self-hosted Arcade Engine configuration
80+
81+
<Steps>
82+
83+
### Set environment variables
84+
85+
Set the following environment variables:
86+
87+
```bash
88+
export LINEAR_CLIENT_ID="<your client ID>"
89+
export LINEAR_CLIENT_SECRET="<your client secret>"
90+
```
91+
92+
Or, you can set these values in a `.env` file:
93+
94+
```bash
95+
LINEAR_CLIENT_ID="<your client ID>"
96+
LINEAR_CLIENT_SECRET="<your client secret>"
97+
```
98+
99+
<Tip>
100+
See [Engine configuration](/home/local-deployment/configure/engine) for more information on how
101+
to set environment variables and configure the Arcade Engine.
102+
</Tip>
103+
104+
### Edit the Engine configuration
105+
106+
Edit the `engine.yaml` file and add a `Linear` item to the `auth.providers` section:
107+
108+
```yaml file=<rootDir>/examples/code/integrations/linear/config_provider.engine.yaml {3-9}
109+
110+
```
111+
112+
</Steps>
113+
114+
</Tabs.Tab>
115+
</Tabs>
116+
117+
## Using Linear auth in app code
118+
119+
Use the Linear auth provider in your own agents and AI apps to get a user token for the Linear API. See [authorizing agents with Arcade](/home/auth/how-arcade-helps) to understand how this works.
120+
121+
Use `client.auth.start()` to get a user token for the Linear API:
122+
123+
<Tabs items={["Python", "JavaScript"]} storageKey="preferredLanguage">
124+
<Tabs.Tab>
125+
126+
```python file=<rootDir>/examples/code/integrations/linear/custom_auth.py {8-14}
127+
128+
```
129+
130+
</Tabs.Tab>
131+
132+
<Tabs.Tab>
133+
134+
```javascript file=<rootDir>/examples/code/integrations/linear/custom_auth.js {8-10}
135+
136+
```
137+
138+
</Tabs.Tab>
139+
140+
</Tabs>
141+
142+
## Using Linear auth in custom tools
143+
144+
You can use the pre-built [Arcade Linear toolkit](/toolkits/productivity/linear) to quickly build agents and AI apps that interact with Linear.
145+
146+
If the pre-built tools in the Linear toolkit don't meet your needs, you can author your own [custom tools](/home/build-tools/create-a-toolkit) that interact with the Linear API.
147+
148+
Use the `Linear()` auth class to specify that a tool requires authorization with Linear. The `context.authorization.token` field will be automatically populated with the user's Linear token:
149+
150+
```python file=<rootDir>/examples/code/integrations/linear/custom_tool.py
151+
152+
```

0 commit comments

Comments
 (0)