Skip to content

Add OAuth app and webhook management#34

Open
itz4blitz wants to merge 3 commits into
tacticlaunch:mainfrom
itz4blitz:justin/oauth-app-webhook-management
Open

Add OAuth app and webhook management#34
itz4blitz wants to merge 3 commits into
tacticlaunch:mainfrom
itz4blitz:justin/oauth-app-webhook-management

Conversation

@itz4blitz

@itz4blitz itz4blitz commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Add an end-to-end OAuth application and webhook management surface for agent and CI pipelines.

  • Add the official manifest/setup flow for personal-API-key users, with an explicit human-confirmation result.
  • Add Linear's alpha managed child OAuth application lifecycle: list, get, create, update, archive, and client/webhook secret rotation.
  • Add OAuth authorization URL generation with validated scopes and S256 PKCE.
  • Add guarded client_credentials token issuance for non-interactive GitHub/agent pipelines.
  • Complete ordinary workspace webhook management with get-by-ID, update, label clearing, and signing-secret rotation.
  • Tighten webhook creation to require exactly one of teamId or allPublicTeams: true, unique non-empty resource names, and a publicly reachable HTTPS destination; OAuth installation webhooks retain Linear's exact 22-value enum.
  • Support OAuth access-token authentication through LINEAR_OAUTH_ACCESS_TOKEN and --oauth-token while preserving API-key behavior and explicit CLI precedence.
  • Upgrade @linear/sdk to 88.1.0 and bump the package to 1.4.0.

Linear API behavior represented truthfully

  • A personal API key cannot directly call Linear's managed-child-app API. linear_generateOAuthApplicationSetup returns the official manifest/setup URL and says that an admin must confirm it.
  • Direct app creation and management requires an eligible managing OAuth application's access token. Those alpha operations are not first-class LinearClient methods, so this PR keeps their raw GraphQL slice narrow and documented.
  • Scopes are issued during /oauth/authorize or /oauth/token; they are not mutable app fields.
  • App-actor tokens cannot request admin. Workspace webhook administration therefore may need a separate MCP server entry authenticated with a workspace-admin API key or eligible user-actor token.
  • Client-credentials scope changes can revoke existing app-actor tokens, so token issuance requires explicit scope-change and secret-exposure acknowledgements.

References: OAuth 2.0, OAuth app manifests, agent scopes, and webhooks.

Safety and validation

  • One-time client, access-token, and webhook secrets require confirmSecretExposure: true.
  • Scope-changing token requests also require confirmScopeChangeRisk: true.
  • Errors from secret-producing operations are sanitized before logging or returning through MCP.
  • Token POSTs reject redirects and abort after 15 seconds.
  • Webhook validation rejects embedded credentials, localhost/local names, and obvious loopback/private/link-local destinations.
  • Existing isDiffHidden update input compatibility is preserved across the SDK upgrade.

TDD / verification

  • npm test — 26 suites, 187 tests passed.
  • MCP stdio smoke — 198 tools, 6 resources, and 4 prompts passed.
  • npm run build — passed.
  • npm pack --dry-run — passed.
  • git diff --check — passed.
  • Live Linear GraphQL introspection — all seven managed-OAuth operations, four webhook mutations, payload fields, grant types, SDK webhook methods, and 22 OAuth webhook resource values matched.
  • Live manifest schema — minimal private and full public/webhook manifests both validated against Linear's current Draft 2020-12 schema.
  • Live negative token integration — Linear's real token endpoint rejected fake credentials and the MCP returned/logged only a sanitized error with no supplied-secret leakage.
  • Two independent final reviews covered API semantics, schema/guard/service parity, backward compatibility, timeout behavior, and secret handling; all actionable findings were resolved.

Successful live Linear mutations were not run because this checkout had no Linear API or OAuth credential. No workspace resources were created. DEVELOPMENT.md now documents using temporary child apps/webhooks and cleaning them up for a credentialed live pass.

npm run lint remains unavailable on current main: ESLint 9 is configured without an eslint.config.* file. This PR does not expand scope into the existing lint-tooling issue.

… precision

- Validate webhook args before the sanitizing try in create/update handlers so
  invalid-args failures are labeled as such instead of as omitted Linear errors
- State the teamId-XOR-allPublicTeams rule and public-HTTPS requirement in the
  createWebhook description and encode it as a source-level anyOf
- Document the app-only scope and admin/actor rules on generateOAuthAuthorizationUrl
- Narrow the IPv4 deny-list from 192.0.0.0/16 to the reserved /24s and add
  TEST-NET-2/3; derive schema maxItems from the shared constants
- Cover the full public-URL deny/allow matrix, token-endpoint HTTP failure and
  invalid-JSON branches, and invalid-args-with-secret labeling in tests
@itz4blitz
itz4blitz force-pushed the justin/oauth-app-webhook-management branch from ac8568d to d408b70 Compare July 12, 2026 14:11
@itz4blitz
itz4blitz marked this pull request as ready for review July 12, 2026 14:12
@itz4blitz

Copy link
Copy Markdown
Contributor Author

@beautyfree Heads up — alongside this PR I've opened three more, all independent and reviewable in any order:

Suggested merge order: this one and #35 in either order, then #36/#37 (I'll rebase those promptly if this PR lands first, as they touch some of the same files). Happy to split, trim, or adjust any of them however you prefer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant