Skip to content

fix(flags): Deterministic project selection for the remote_config endpoint - #36154

Merged
haacked merged 3 commits into
masterfrom
haacked/35303-remote-config-fix
Aug 6, 2025
Merged

haacked merged 3 commits into
masterfrom
haacked/35303-remote-config-fix

Conversation

@haacked

@haacked haacked commented Aug 4, 2025 •

Copy link
Copy Markdown
Contributor

Adds a means for deterministic project selection when calling the remote_config endpoint.

Problem

See #35303 for more context, but in-short, remote_config endpoint is accessed with a GET request to /api/projects/@current/feature_flags/unencrypted-remote-config-setting/remote_config/

When using a personal access token for authentication, this causes the request to route to whichever project the user the token belongs to last visited.

Fixes #35303

Changes

  1. Update remote_config to support POST requests.
  2. When a POST request occurs, look in the request body for project_api_key to override the @current token.
  3. Update ProjectSecretAPIKeyAuthentication to validate that the token team and resolved team match.

The changes should be backwards compatible. So if somebody had a need for the project switching ability of the @current URL, they still get that behavior when making a GET request.

I'll update the SDKs to make a POST request and pass the project api token in the request body.

How did you test this code?

Manually.
Unit Tests.

  • GET personal_api_key, no request body. Expect: returns last visited project
  • GET personal_api_key, api_key in request body. Expect: returns last visited project
  • POST personal_api_key, no request body. Expect: returns last visited project
  • POST personal_api_key, api_key in request body. Expect: returns project with api_key
  • POST personal_api_key, api_key for different project in request body. Expect: Auth error
  • GET secret_api_key, no request body. Expect: returns project associated with the key
  • GET secret_api_key, api_key in request body. Expect: returns project associated with the key
  • POST secret_api_key, no request body. Expect: returns project associated with the key
  • POST secret_api_key, api_key in request body. Expect: returns project associated with the key
  • POST secret_api_key, api_key for a different project in request body. Expect: Auth error

👉 Stay up-to-date with PostHog coding conventions for a smoother review.

Client SDKs that need to be updated

@haacked
haacked requested a review from a team as a code owner August 4, 2025 21:25
@dmarticus dmarticus moved this to In Review in Feature Flags Aug 4, 2025
@haacked
haacked requested review from Piccirello and Copilot August 4, 2025 21:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull Request Overview

This PR implements deterministic project selection for the remote_config endpoint by adding support for POST requests and project API token validation. This fixes an issue where personal access tokens would route to whichever project the user last visited.

  • Enhanced ProjectSecretAPIKeyAuthentication to validate project API tokens in request bodies
  • Updated the feature flag endpoint to accept both GET and POST methods
  • Modified project routing logic to handle request body tokens for POST/PUT/PATCH methods

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
posthog/auth.py Added security validation to ensure project API tokens in request body match authenticated projects
posthog/api/test/test_authentication.py Added comprehensive test coverage for the new authentication validation scenarios
posthog/api/routing.py Updated team resolution logic to check request body for tokens on POST/PUT/PATCH methods
posthog/api/feature_flag.py Extended remote_config endpoint to support POST requests alongside existing GET support
Comments suppressed due to low confidence (1)

posthog/api/test/test_authentication.py:1082

  • The test is catching a generic Exception instead of the specific AuthenticationFailed exception that should be raised. This makes the test less precise and could pass if a different exception is thrown.
        with self.assertRaises(Exception) as context:

Comment thread posthog/auth.py Outdated
Comment thread posthog/api/test/test_authentication.py Outdated

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Greptile Summary

This PR fixes a critical issue with the remote_config endpoint where personal API keys would route to whichever project the user last visited rather than the intended project. The solution introduces deterministic project selection by enabling POST requests with a project API token in the request body.

The key changes include:

  1. Enhanced endpoint support: The remote_config endpoint in posthog/api/feature_flag.py now accepts both GET and POST methods, with POST allowing project specification via request body

  2. Request routing updates: Modified _get_team_from_request() in posthog/api/routing.py to conditionally pass request data to get_token() for POST/PUT/PATCH methods, enabling project token extraction from request bodies

  3. Security validation: Added authentication checks in ProjectSecretAPIKeyAuthentication class in posthog/auth.py to ensure any project API key provided in the request body matches the team associated with the secret API key used for authentication

  4. Comprehensive testing: Added unit tests in posthog/api/test/test_authentication.py covering scenarios with matching keys, mismatched keys, and no keys in the request body

The implementation maintains full backward compatibility - existing GET requests continue to work with the @current project behavior, while new POST requests provide deterministic routing. This fits into PostHog's broader authentication and project management system by extending the existing token validation mechanisms to handle multi-project scenarios more reliably.

Confidence score: 4/5

  • This PR is safe to merge with minimal risk as it maintains backward compatibility while fixing a legitimate routing issue
  • Score reflects solid implementation with comprehensive testing and proper security validation, though the complexity of authentication logic requires careful attention
  • Pay close attention to the authentication validation logic in posthog/auth.py to ensure the security checks work correctly across different authentication scenarios

4 files reviewed, 1 comment

Edit Code Review Bot Settings | Greptile

Comment thread posthog/api/test/test_authentication.py Outdated
@haacked
haacked force-pushed the haacked/35303-remote-config-fix branch 2 times, most recently from 1ce9c28 to 709a43c Compare August 4, 2025 22:11
haacked added a commit to PostHog/posthog-python that referenced this pull request Aug 4, 2025
Updates remote_config to always make POST requests with the project API key
in the request body for deterministic project selection and validation.

- Modified remote_config() to use POST instead of GET
- Always include project_api_key parameter in request body
- Ensures deterministic routing for personal API keys
- Validates secret API keys match expected project
- Updated tests to reflect new behavior

This aligns with backend changes in PostHog/posthog#36154
@haacked
haacked force-pushed the haacked/35303-remote-config-fix branch from 5b284ad to ab8a10a Compare August 5, 2025 15:31
@haacked

haacked commented Aug 5, 2025

Copy link
Copy Markdown
Contributor Author

Hmm, test failures seem unrelated to the changes in this PR.

@github-project-automation github-project-automation Bot moved this from In Review to Approved in Feature Flags Aug 5, 2025
@haacked
haacked force-pushed the haacked/35303-remote-config-fix branch 3 times, most recently from 90d96b6 to b475fe7 Compare August 5, 2025 22:34
Comment thread posthog/auth.py Outdated
@haacked
haacked force-pushed the haacked/35303-remote-config-fix branch from b475fe7 to c95793a Compare August 6, 2025 02:30
@haacked
haacked requested a review from benjackwhite August 6, 2025 02:33
@haacked

haacked commented Aug 6, 2025

Copy link
Copy Markdown
Contributor Author

@benjackwhite Added you because this touches the project secret api token logic.

@haacked haacked changed the title fix(flags): Deterministic project selection for the remote_config endpoint fix(flags): Deterministic project selection for the remote_config and local_evaluation endpoint Aug 6, 2025
@haacked
haacked force-pushed the haacked/35303-remote-config-fix branch from d9a3140 to c95793a Compare August 6, 2025 02:56
@haacked haacked changed the title fix(flags): Deterministic project selection for the remote_config and local_evaluation endpoint fix(flags): Deterministic project selection for the remote_config endpoint Aug 6, 2025
haacked added a commit to PostHog/posthog-python that referenced this pull request Aug 6, 2025
Updates `remote_config` to always make POST requests with the project API key in the request body for deterministic project selection and validation.

- Modified remote_config() to use POST instead of GET
- Always include `project_api_key` parameter in request body
- Ensures deterministic routing for personal API keys
- Validates secret API keys match expected project
- Updated tests to reflect new behavior

This aligns with backend changes in PostHog/posthog#36154
@haacked
haacked force-pushed the haacked/35303-remote-config-fix branch 3 times, most recently from 6eb2883 to e881a4d Compare August 6, 2025 16:23
haacked added 2 commits August 6, 2025 09:26
…lidation

Move project secret API key team validation from authentication to permissions layer
for better architectural separation of concerns.

Changes:
- Enhanced ProjectSecretAPITokenPermission to validate authenticated team matches resolved team
- Added comprehensive test for cross-team access prevention with secret API keys
- Maintains security while following proper authentication vs authorization patterns

This prevents secret API keys from accessing other teams' data when project_api_key
is provided in request body, while still allowing personal API keys to deterministically
override team selection with proper user membership validation.
If "project_api_key" is in the request body for a `POST`, `PATCH`, or `PUT` request, we use that as the project token instead of the default team associated with the personal access token.
@haacked
haacked force-pushed the haacked/35303-remote-config-fix branch from e881a4d to 6280b2b Compare August 6, 2025 16:26
@haacked
haacked requested a review from andyzzhao August 6, 2025 16:43
@dmarticus dmarticus moved this from Approved to In Review in Feature Flags Aug 6, 2025
@haacked

haacked commented Aug 6, 2025

Copy link
Copy Markdown
Contributor Author

Changing get_token broke too many tests. Those test failures were in fact related to the changes I had made. I refactored this PR to be more targeted and not to mess with get_token.

@github-project-automation github-project-automation Bot moved this from In Review to Approved in Feature Flags Aug 6, 2025
@haacked
haacked merged commit 3439086 into master Aug 6, 2025
@haacked
haacked deleted the haacked/35303-remote-config-fix branch August 6, 2025 17:18
@github-project-automation github-project-automation Bot moved this from Approved to Done in Feature Flags Aug 6, 2025
@haacked haacked removed this from Feature Flags Jun 9, 2026
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.

Bug: get_remote_config_payload() returns data from wrong project when using personal API key with access to multiple projects

4 participants