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
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.
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
HogFlowViewSetaccepts a project secret API key (phs_...,Authorization: Bearer) for the actions a push needs:list(the?key=resolve),retrieve,create,updateandpartial_update. Nothing else: no delete, no bulk delete, no publish or invocation actions. Follow the skilladding-project-secret-api-key-authexactly: thehog_flowscope joins the PSAK scope allowlist, the viewset gets the PSAK authenticator,psak_allowed_actions, and a PSAK-aware throttle, in the shapeproducts/feature_flags/backend/api/feature_flag.pyandproducts/endpoints/backend/presentation/views/api.pyalready 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_byonHogFlow,created_byonHogFlowRevision,log_activity_from_viewset,_report_workflow_action, and the_emit_resource_editedcall. StoreNonewhere 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_writerclassifies byUser-Agentevent source, so a PSAK request from the CLI (posthog-workflows/<version>, event sourceapi) passes unchanged. State this in the PR body; do not touch that branch.Write scope
products/workflows/backend/api/hog_flow.pyproducts/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
POST,PATCHandGET ?key=with aphs_key return 401 or 403 before the change; green after, with the key echoed and the row created withcreated_bynullDELETEand a PSAKPOST .../bulk_deletestay refusedcreated_bynull (depends on fix(workflows): write the first revision when a workflow is created PostHog/posthog#104156; if that is not onupstream/masteryet, assert the update path's revision instead and say so)hogli test products/workflows/backend/api/test/green,ruff, repo-widemypyhogli build:openapioutput in the diff if the schema changedhogli ci:preflight --stricton pushBlocked by
Nothing.
Stack base and ship target
feat/workflows-psak-authcut fromupstream/master.PostHog/posthog,--head Silthus:feat/workflows-psak-auth. It stays a draft until Michael says otherwise. Nothing merges into the fork'smaster.adding-project-secret-api-key-auth,improving-drf-endpoints,writing-tests,writing-code-comments,reviewing-with-coderabbitandwriting-pr-descriptions.