Skip to content

fix(integrations): remove github only filter in mcp/api - #56996

Merged
MarconLP merged 6 commits into
masterfrom
fix/integrations-expose-all-kinds-to-api-keys
May 4, 2026
Merged

MarconLP merged 6 commits into
masterfrom
fix/integrations-expose-all-kinds-to-api-keys

Conversation

@MarconLP

@MarconLP MarconLP commented Apr 29, 2026 •

Copy link
Copy Markdown
Member

Problem

we need this for setting up sources with oauth integrations via the mcp

The Integration list/retrieve endpoints filtered to kind="github" whenever the request authed via PersonalAPIKeyAuthentication or OAuthAccessTokenAuthentication. Introduced in #38921 as a defensive measure — the author hadn't audited every integration kind's config field for stray secrets and chose to expose only the one kind they were sure about. Side-effect: every other integration is invisible to API-key callers (e.g. the PostHog MCP server, which authenticates via OAuth access token), so the MCP can't list HubSpot, Slack, or any other integration on behalf of the user.

Changes

  • Audited every integration kind's creation path for what lands in Integration.config vs Integration.sensitive_config.
  • Empirically verified the kinds I was unsure about against prod-us and prod-eu (google-pubsub, google-cloud-storage, vercel): every row's config only contains harmless metadata (expiry timestamps, display IDs, scopes, public URLs). No row has ever held service-account keyfiles or unbounded user-supplied JSON.
  • The IntegrationSerializer already excludes sensitive_config, so the kind-allowlist filter wasn't actually buying anything beyond what the model contract already does.
  • Removed the safely_get_queryset override and the now-unused auth-class imports. Personal-API-key and OAuth-access-token callers fall through to the default queryset (still team-filtered by TeamAndOrgViewSetMixin, still has the repository_cache deferral).

How did you test this code?

I'm an agent (Claude). Tests run:

  • hogli test posthog/api/test/test_integration.py — 72 passed (one removed: the test that asserted non-github kinds were 404 for API keys, since that's the exact behavior being removed).
  • Updated the API-key access tests to assert that github + twilio + vercel are all visible, and to confirm session auth sees the same.

Manual verification: re-ran posthog-local's integrations-list MCP tool against my dev instance — previously returned 0 results under OAuth access-token auth, now returns the HubSpot and Slack integrations as expected.

Publish to changelog?

no

Docs update

n/a — internal API behavior change, no docs surface.

🤖 Agent context

  • Authored by Claude Code (Sonnet/Opus session in PostHog dev env).
  • Triggered while setting up a HubSpot data-warehouse source locally; the MCP integrations-list tool returned 0 results, which led to discovering the GitHub-only filter.
  • Audit methodology: traced every integration_from_* and bespoke creator in posthog/models/integration.py, plus the customerio-* creators in products/messaging/backend/api/message_categories.py and the vercel creator in ee/vercel/integration.py. Confirmed OauthIntegration.integration_from_oauth_response pops access_token/refresh_token/id_token to sensitive_config for all OAuth kinds. Verified prod-us + prod-eu Postgres via Metabase for the three kinds I had specific concerns about.
  • Original PR comment thread on feat: allow reading github integrations with personal API key #38921 (where the GitHub-only filter was added) confirmed the author's intent was "audited GitHub, didn't audit others" rather than "GitHub-only forever", which is why this change is appropriate.
  • Needs human review before merging.

The list/retrieve endpoints filtered to `kind="github"` for personal API key
and OAuth access token auth (added in #38921 as defense in depth — the author
hadn't audited every kind's `config` for stray secrets). Audited all 33 kinds
across `OauthIntegration` and the bespoke creators (Twilio, Email, Firebase,
GoogleCloud, Databricks, AzureBlob, Postgres, GitLab, GitHub, Vercel, the
CustomerIO variants); checked prod-us and prod-eu for the kinds I was unsure
about. Every row's `config` only carries display IDs, scopes, public URLs,
the connecting user's email, and expiry timestamps — secrets all live in
`sensitive_config`, which IntegrationSerializer never returns.

The filter is no longer doing useful work, so drop the override entirely.
Drop the vercel fixture and three-kind loops added in the previous commit —
the behavior change is binary (api keys can see non-github kinds now), so
github + twilio is enough to demonstrate it. Restore original test names
and the session-auth assertion shape.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying posthog with  Cloudflare Pages  Cloudflare Pages

Latest commit: 1273711
Status:⚡️  Build in progress...

View logs

@MarconLP
MarconLP marked this pull request as ready for review April 29, 2026 19:42
@greptile-apps

greptile-apps Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Reviews (1): Last reviewed commit: "test(integrations): slim down access-con..." | Re-trigger Greptile

@MarconLP
MarconLP requested a review from a team April 29, 2026 19:44

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 12737111d0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread posthog/api/integration.py Resolved
@MarconLP MarconLP changed the title fix(integrations): expose all kinds to api-key callers, not just github fix(integrations): remove github only filter in mcp/api Apr 30, 2026
MarconLP added 2 commits May 4, 2026 13:29
Resolved conflicts in posthog/api/integration.py and
posthog/api/test/test_integration.py: kept this branch's removal of the
api-key kind filter (exposing all integration kinds), preserved
SessionAuthentication import for the channels action from master, and
dropped master's github+slack-only list test that contradicts this
change. Kept master's sensitive_config-not-leaked assertion.
Removing the github-only queryset filter for api-key callers means
github_repos, refresh_github_repos, and github_branches can now resolve
non-github integration IDs and would 500 because GitHubIntegration's
constructor raises a bare Exception when kind != "github". Add a kind
check before constructing GitHubIntegration so callers get a 400 with a
clear message instead. Updates the existing channels matrix test to
reflect that twilio now resolves through the queryset and trips the
slack-kind guard (400) rather than 404ing on resolution.
@MarconLP

MarconLP commented May 4, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fe3a4cde8d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread posthog/api/integration.py Resolved
…cription

The integrations-list MCP tool description claimed only GitHub and Slack
were returned for personal API key / OAuth callers. That gating was removed
earlier on this branch, so reword the description to reflect the actual
behavior and call out that sensitive credentials are never serialized.
@github-actions

github-actions Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor

MCP UI Apps size report

App JS CSS
debug 290.7 KB 25.8 KB
action 275.4 KB 25.8 KB
action-list 281.5 KB 25.8 KB
cohort 274.5 KB 25.8 KB
cohort-list 280.5 KB 25.8 KB
error-details 283.4 KB 25.8 KB
error-issue 275.1 KB 25.8 KB
error-issue-list 281.4 KB 25.8 KB
experiment 278.8 KB 25.8 KB
experiment-list 282.3 KB 25.8 KB
experiment-results 278.4 KB 25.8 KB
feature-flag 279.3 KB 25.8 KB
feature-flag-list 285.9 KB 25.8 KB
insight-actors 277.5 KB 25.8 KB
llm-costs 280.2 KB 25.8 KB
session-recording 276.3 KB 25.8 KB
survey 276.1 KB 25.8 KB
survey-global-stats 277.7 KB 25.8 KB
survey-list 282.2 KB 25.8 KB
survey-stats 277.7 KB 25.8 KB
workflow 274.9 KB 25.8 KB
workflow-list 280.9 KB 25.8 KB
query-results 289.0 KB 25.8 KB

@MarconLP
MarconLP merged commit 1084575 into master May 4, 2026
279 of 297 checks passed
@MarconLP
MarconLP deleted the fix/integrations-expose-all-kinds-to-api-keys branch May 4, 2026 18:36
@deployment-status-posthog

deployment-status-posthog Bot commented May 4, 2026 •

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-05-04 18:56 UTC Run
prod-us ✅ Deployed 2026-05-04 19:12 UTC Run
prod-eu ✅ Deployed 2026-05-04 19:13 UTC Run

vdekrijger added a commit that referenced this pull request May 7, 2026
…-types

Resolves merge conflicts after ~924 master commits and addresses Greptile
review feedback on the original PR.

Conflict resolutions:
- posthog/api/integration.py: kept SlackChannelsQuerySerializer from this
  branch, dropped the now-redundant safely_get_queryset filter (master
  PRs #56996 and a509241d8b8 already expose all kinds to PAK/OAuth),
  used master's SLACK_INTEGRATION_KINDS constant in the kind guard.
- posthog/api/test/test_integration.py: adopted master's list/twilio/slack
  retrieval tests; dropped the filter-specific test that no longer applies.
- products/cdp/mcp/cdp_functions.yaml: adopted master's richer Slack recipe
  (text + blocks from the alert-wizard sub-template) and tighter dedupe.
- products/integrations/mcp/tools.yaml: kept the rate-limit note on
  channels; took master's list-tool description.
- All generated files regenerated via hogli build:openapi.

Greptile P2 review feedback addressed:
- frontend/src/lib/integrations/slackIntegrationLogic.ts: guard
  allSlackChannels?.lastRefreshedAt so a single-channel-lookup response
  doesn't silently disable the refresh-cooldown check.
- posthog/api/integration.py: SlackChannelsQuerySerializer now validates
  at runtime (is_valid(raise_exception=True)); the view reads from
  validated_data — turns the OpenAPI promise into the truth instead of
  documentation-only.
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.

3 participants