Skip to content

Workflows accept the project secret API key, so CI pushes without a personal key #106

Description

@Silthus

Part of #68. Locked by Michael on 2026-09-22 after the research on #104: v1 pushes from CI with the project secret API key (PSAK) that already exists on the project, not with a personal API key.

What to build

HogFlowViewSet accepts a project secret API key (phs_..., Authorization: Bearer) for the actions a push needs: list (the ?key= resolve), retrieve, create, update and partial_update. Nothing else: no delete, no bulk delete, no publish or invocation actions. Follow the skill adding-project-secret-api-key-auth exactly: the hog_flow scope joins the PSAK scope allowlist, the viewset gets the PSAK authenticator, psak_allowed_actions, and a PSAK-aware throttle, in the shape products/feature_flags/backend/api/feature_flag.py and products/endpoints/backend/presentation/views/api.py already use.

A PSAK request carries a synthetic user (ProjectSecretAPIKeyUser). Find every place the create and update paths assume a real user and make them hold: created_by on HogFlow, created_by on HogFlowRevision, log_activity_from_viewset, _report_workflow_action, and the _emit_resource_edited call. Store None where the model allows it and say so in the activity detail; never crash and never invent a user.

Compatibility with the read-only PR (PostHog/posthog#103540): its guard is_code_managed_writer classifies by User-Agent event source, so a PSAK request from the CLI (posthog-workflows/<version>, event source api) passes unchanged. State this in the PR body; do not touch that branch.

Write scope

  • products/workflows/backend/api/hog_flow.py
  • The PSAK scope allowlist module the skill names
  • products/workflows/backend/api/test/test_hog_flow_psak_auth.py (new)
  • products/workflows/CONTRIBUTING.md (one paragraph on which key a CI push may use)

Proof gate

  • Red: POST, PATCH and GET ?key= with a phs_ key return 401 or 403 before the change; green after, with the key echoed and the row created with created_by null
  • A PSAK DELETE and a PSAK POST .../bulk_delete stay refused
  • A PSAK for team A cannot read or write team B's workflow
  • Revision 1 is written on a PSAK create with created_by null (depends on fix(workflows): write the first revision when a workflow is created PostHog/posthog#104156; if that is not on upstream/master yet, assert the update path's revision instead and say so)
  • hogli test products/workflows/backend/api/test/ green, ruff, repo-wide mypy
  • hogli build:openapi output in the diff if the schema changed
  • hogli ci:preflight --strict on push

Blocked by

Nothing.

Stack base and ship target

  • Branch feat/workflows-psak-auth cut from upstream/master.
  • A draft PR against upstream PostHog/posthog, --head Silthus:feat/workflows-psak-auth. It stays a draft until Michael says otherwise. Nothing merges into the fork's master.
  • Invoke adding-project-secret-api-key-auth, improving-drf-endpoints, writing-tests, writing-code-comments, reviewing-with-coderabbit and writing-pr-descriptions.

Activity

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

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions