Skip to content

chore(scopes): per-surface invariant test for ALLOWED_PROVISIONING_SCOPES (1↔4) #57533

@MattBro

Description

@MattBro

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions