Cloudflare Worker that holds a single Linear OAuth token and proxies GraphQL requests to Linear. Avoids PAT attribution and the need for a robot seat.
npx wrangler secret put SECRET # shared secret callers must present
npx wrangler secret put LINEAR_CLIENT_ID
npx wrangler secret put LINEAR_CLIENT_SECRET
npx wrangler deployOpen the authorization URL in a browser:
https://linear.app/oauth/authorize?client_id=<YOUR_CLIENT_ID>&redirect_uri=http://localhost&response_type=code&scope=issues:create&actor=app
After approving, the browser will redirect to http://localhost/?code=<CODE>. Copy the code parameter, then exchange it:
curl -X POST https://api.linear.app/oauth/token \
-d "code=<CODE>&client_id=<CLIENT_ID>&client_secret=<CLIENT_SECRET>&redirect_uri=http://localhost&grant_type=authorization_code"curl -X POST https://<your-worker-name>.workers.dev/setup \
-H "Authorization: Bearer <SECRET>" \
-H "Content-Type: application/json" \
-d '{"access_token":"...","refresh_token":"...","expires_in":3600}'The worker stores and refreshes the token automatically from here on.
curl -X POST https://<your-worker-name>.workers.dev/linear \
-H "Authorization: Bearer <SECRET>" \
-H "Content-Type: application/json" \
-d '{"query":"mutation { issueCreate(input: { title: \"Test\", teamId: \"...\" }) { success } }"}'All GraphQL requests are forwarded to https://api.linear.app/graphql with the managed token injected.