Context
Per the OAuth scope drift RFC's pre-flight #2, three of the 15 OAuth scope incidents in the last 90 days were drift between posthog/scopes.py and ALLOWED_PROVISIONING_SCOPES (surface 1↔4):
- #54272 — provisioned PATs created with empty scopes (completely unusable until
MCP_PRESET_SCOPES was added)
- #55755 — direct auth-code path applied to all partners; missing scope-allowlist validation
- #57509 — wizard's PKCE flow needed
llm_gateway:read, dashboard:write, insight:write (this session)
#57526's subset test catches "non-grantable scope in the allowlist" but does NOT catch "grantable scope missing from the allowlist that the wizard / partner integrations need." That gap is what bit Insforge.
Change
Add a new test in ee/api/agentic_provisioning/test/test_scope_validation.py (the file added in #57509):
WIZARD_BARE_MINIMUM_SCOPES = {
"user:read", "project:read", "query:read",
"llm_gateway:read", "dashboard:write", "insight:write",
}
def test_provisioning_allowlist_grants_wizard_required_scopes():
missing = WIZARD_BARE_MINIMUM_SCOPES - ALLOWED_PROVISIONING_SCOPES
assert not missing, (
f"Partner allowlist is missing scopes the wizard needs: {missing}. "
f"Either add them to ALLOWED_PROVISIONING_SCOPES, or update WIZARD_BARE_MINIMUM_SCOPES "
f"if the wizard no longer needs them."
)
Pair this with the existing subset/superset/ground-truth tests in #57526 — together they form the per-surface invariant for partner-issued tokens.
Why
A test that catches under-provisioning would have stopped the Insforge bug from ever reaching the customer. Cheap to maintain, fails CI clearly with the named scope.
Tracking
Parent: #57524
Project: https://github.com/orgs/PostHog/projects/194
RFC: https://github.com/PostHog/requests-for-comments-internal/blob/matt/oauth-scope-drift-rfc/engineering/2026-05-04-oauth-scope-drift.md
Context
Per the OAuth scope drift RFC's pre-flight #2, three of the 15 OAuth scope incidents in the last 90 days were drift between
posthog/scopes.pyandALLOWED_PROVISIONING_SCOPES(surface 1↔4):MCP_PRESET_SCOPESwas added)llm_gateway:read,dashboard:write,insight:write(this session)#57526's subset test catches "non-grantable scope in the allowlist" but does NOT catch "grantable scope missing from the allowlist that the wizard / partner integrations need." That gap is what bit Insforge.
Change
Add a new test in
ee/api/agentic_provisioning/test/test_scope_validation.py(the file added in #57509):Pair this with the existing subset/superset/ground-truth tests in #57526 — together they form the per-surface invariant for partner-issued tokens.
Why
A test that catches under-provisioning would have stopped the Insforge bug from ever reaching the customer. Cheap to maintain, fails CI clearly with the named scope.
Tracking
Parent: #57524
Project: https://github.com/orgs/PostHog/projects/194
RFC: https://github.com/PostHog/requests-for-comments-internal/blob/matt/oauth-scope-drift-rfc/engineering/2026-05-04-oauth-scope-drift.md