plugins/linear-orchestrator/skills/linear-webhooks/SKILL.md
This skill should be used when registering, verifying, or processing Linear webhooks — HMAC signatures, replay protection, idempotency, dead-letter queues. Activates on "linear webhook", "webhook signature", "Linear-Signature", "webhook secret".
npx skillsauth add markus41/claude Linear Webhooks (Verify, Replay, DLQ)Install this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Reference: https://linear.app/developers/webhooks
Linear signs every delivery with HMAC-SHA256:
Linear-Signature: <hex digest>
Verify in constant time:
import { createHmac, timingSafeEqual } from "node:crypto";
export function verifyLinearSignature(rawBody: Buffer, signature: string, secret: string): boolean {
const expected = createHmac("sha256", secret).update(rawBody).digest("hex");
const a = Buffer.from(signature, "hex");
const b = Buffer.from(expected, "hex");
if (a.length !== b.length) return false;
return timingSafeEqual(a, b);
}
Always read the raw body bytes, not the parsed JSON. Express:
app.use("/linear/webhook", express.raw({ type: "application/json" }));
Each delivery has a webhookTimestamp field in the JSON body (Unix ms). Reject events older than 5 minutes:
if (Math.abs(Date.now() - body.webhookTimestamp) > 5 * 60_000) reject();
Linear may re-deliver. Each event has:
delivery.id — unique per delivery (use this!)data.id — entity IDStore seen delivery.id in Redis with 7-day TTL; ignore duplicates.
Issue, IssueLabel, Comment, Cycle, Project, ProjectUpdate, Initiative, InitiativeUpdate, Customer, CustomerNeed, Reaction, Attachment, Document.
Subscribe selectively — fewer types means smaller event volume.
create | update | remove. Some resources support more; consult the schema.
{
"action": "update",
"actor": { "id": "...", "name": "..." },
"createdAt": "2026-04-30T12:00:00.000Z",
"data": { /* the resource */ },
"type": "Issue",
"url": "https://linear.app/...",
"webhookTimestamp": 1714478400000,
"webhookId": "...",
"delivery": { "id": "..." }
}
Don't trust webhook payload state for reads. Linear may send out-of-order events. After receiving an Issue update, re-fetch via GraphQL using the id to get the canonical state.
Implementation in lib/webhook-dlq.ts:
/linear:webhook dlq lists; /linear:webhook replay --since 24h retries from DLQUse ngrok http 3000 and set the public URL as the webhook URL. Linear has no built-in test-replay UI; use webhookTest mutation if available, or the DLQ replay path.
delivery.id idempotencytools
Build Teams-native agents with the Teams SDK (formerly Teams AI Library v2) — App class, activity routing, adaptive cards, streaming, AI-generated labels, feedback, message extensions, Teams-as-MCP-server, and the bring-your-own-AI pattern with Agent Framework.
tools
Run agents on Microsoft Foundry (formerly Azure AI Foundry) Agent Service — prompt agents vs hosted agents, threads/runs and the Responses API, built-in tools (Bing grounding, code interpreter, file search, MCP, OpenAPI, A2A), connected agents, Entra agent identity, SDKs, and observability/evaluations.
tools
Build and host custom engine agents with the Microsoft 365 Agents SDK — AgentApplication, the Activity protocol, channel reach via Azure Bot Service, hosting Agent Framework or Semantic Kernel engines, and the Agents Toolkit/Playground workflow. Successor to the Bot Framework SDK.
tools
Design, govern, and extend Microsoft Copilot Studio agents — topics, generative orchestration, knowledge, tools and MCP, agent flows, autonomous triggers, publishing channels, Copilot Credits pricing, and solution-based ALM on Power Platform.