mcpField
A
adding-project-secret-api-key-auth

adding-project-secret-api-key-auth

github.com/posthog安全40.5k140 次安装今天更新
代码仓库

关于 adding-project-secret-api-key-auth

指导开发者在 PostHog API 端点接入项目密钥 API 密钥(PSAK)的技能文档。内容涵盖作用域授权、认证配置、限流和合成用户处理,并列出相关测试要求。

主要功能

  1. 01项目级无用户服务凭据说明
  2. 02作用域白名单配置
  3. 03端点认证与操作授权
  4. 04密钥级及团队级限流
  5. 05合成用户与权限处理

适用场景

  1. 01为 API 操作启用 PSAK 认证
  2. 02设置可授予的密钥作用域
  3. 03避免合成用户触发错误权限逻辑
  4. 04测试授权、团队绑定和限流

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/posthog/posthog --skill adding-project-secret-api-key-auth

安装后在 Claude Code 中输入/adding-project-secret-api-key-auth确认已加载。

详细介绍

为端点添加项目密钥 API key (PSAK) 认证

什么是 PSAK

ProjectSecretAPIKey 是一种项目范围内、无用户的服务凭证(posthog/models/project_secret_api_key.py)。它的行为类似个人 API key,但在用户离开项目后仍然有效,自带作用域,并以合成用户身份进行认证——而非真实的 User 行。

  • Token 格式:phs_...(仅限 Bearer 请求头——不像旧版 token 那样支持请求体回退)。
  • 作用域在其资源类型内是项目级的,并有意忽略对象级访问控制(按资源的 RBAC)。
  • 不要与 TeamSecretTokenAuthentication 混淆——后者验证的是旧版按团队的 Team.secret_api_token(同样以 phs_ 为前缀),仅用于功能开关本地评估及类似的 PSAK 之前的接口。它被计划在某个时候迁移到 PSAK。

Key 通过 POST /api/environments/:id/project_secret_api_keys 进行管理(label + scopes;明文值仅返回一次;roll 操作用于轮换;每个项目最多 50 个;不允许通配符 * 作用域)。

为 viewset action 接线——检查清单

相关机制已经就绪,但尚未有任何东西接入它——第一个计划的消费者是 endpoints(该产品)的 run action。四件事,全都必需:

1. 将作用域/操作对加入白名单

可分配给 PSAK 的作用域是 posthog/scopes.py 中的全局允许列表:

PROJECT_SECRET_API_KEY_ALLOWED_API_SCOPE_ACTION: list[tuple[APIScopeObject, APIScopeActions]] = [("endpoint", "read")]

如果你的产品未列出,key 创建会在认证尚未尝试之前就拒绝该作用域。请先在此处添加你的 (scope_object, action) 元组。

将同样的作用域添加到 frontend/src/lib/scopes.tsx 中的 PROJECT_SECRET_API_KEY_ALLOWED_API_SCOPE_ACTION。项目设置中的作用域选择器根据该列表构建其复选框,因此仅修改后端会让用户无法授予该作用域。posthog/test/test_scopes.py 会比较这两个列表。

2. 添加认证器并让 action 选择启用
class MyViewSet(TeamAndOrgViewSetMixin, viewsets.ModelViewSet):
    scope_object = "endpoint"
    authentication_classes = [ProjectSecretAPIKeyAuthentication]  # extends, TeamAndOrgViewSetMixin keeps session/PAK auth
    psak_allowed_actions = ["run"]

psak_allowed_actions 是默认拒绝的:APIScopePermission 会拒绝任何 action 未列出的 PSAK 请求(“This action does not support project secret API key access”)。只列出程序化 action——绝不要列出应保持人工驱动的 CRUD。

APIScopePermission 还会自动强制执行团队绑定:PSAK 仅对 view.team == key.team 生效,因此 PSAK 认证只在项目范围(/api/environments/:id/...)的路由上才有意义。

3. 使用可感知 PSAK 的限流器

PersonalApiKeyRateThrottle 的子类会静默地绕过 PSAK 请求(没有个人 key → 没有限流)。请使用 posthog/rate_limit.py 中可感知 PSAK 的一对:

  • PersonalOrProjectSecretApiKeyRateThrottle——按 key 的预算(以 psak:{key_id} 为键),同时也仍然对个人 key 限流。
  • ProjectSecretApiKeyTeamRateThrottle——按团队的聚合(以 psak-team:{team_id} 为键),无论项目铸造多少 key,都限制 PSAK 总负载。将其与按 key 的限流器叠加使用。

将它们子类化以设置产品特定的 scope/rate;请记住每个限流器会按 scope 字符串保留各自的缓存桶。

4. 处理合成用户

request.user 是 ProjectSecretAPIKeyUser(一个 SyntheticUser,posthog/synthetic_user.py),而不是 User:

  • user.id 为 None —— 绝不要将其用作外键。请使用 user.current_team_id。

  • has_perm() 始终返回 False —— Django 权限检查会静默拒绝。

  • 对它跳过按对象的访问控制检查(PSAK 作用域按设计是项目级的):

    if is_authenticated_via_project_secret_api_key(request):
        return  # PSAK bypasses object-level RBAC deliberately
    

    仅在没有 request 可用时使用 isinstance(user, ProjectSecretAPIKeyUser)。

  • report_user_action 会丢弃合成用户 —— 如果你需要针对 PSAK 认证调用的分析数据,请用 posthoganalytics.capture(distinct_id=user.distinct_id, ...) 显式捕获,并包含一个 auth_method 属性,以便两条路径发出相同形状的事件。

  • HogQL 系统表:Database.create_for 会隐藏该密钥作用域未覆盖的 RBAC 作用域系统表(通过 readable_system_table_access_scopes())。

当你需要分支时,可使用 posthog/permissions.py 中的辅助函数:is_authenticated_via_project_secret_api_key(request) 和 is_service_auth(request)(涵盖 PSAK + 旧版团队令牌)。

免费获得的功能

  • 查询标记:认证器会调用 tag_authentication(access_method=AccessMethod.PROJECT_SECRET_API_KEY, api_key_mask=..., api_key_label=...),因此 ClickHouse query_log 归因无需任何按端点的代码即可生效。如果你添加新的认证器,请通过 tag_authentication(posthog/clickhouse/query_tagging.py 中的唯一入口)进行标记 —— 而不是用临时的 tag_queries 调用。
  • last_used_at 跟踪:最多每小时通过 .update() 更新一次(绕过 ModelActivityMixin,这样常规认证不会刷爆活动日志)。
  • 密钥创建/更新/轮换/删除时的活动日志记录。

调用受 PSAK 保护的端点

curl -s https://us.posthog.com/api/environments/<project_id>/<your_action_path>/ \
  -H "Authorization: Bearer phs_<key>" \
  -H "Content-Type: application/json" \
  -d '{...}'

测试

参照 posthog/api/test/test_authentication.py、posthog/test/test_permissions.py 和 posthog/test/test_rate_limit.py 中的 PSAK 部分。至少覆盖:

  • 具有正确作用域的允许操作 → 200
  • 操作不在 psak_allowed_actions 中 → 403
  • 缺失/错误的作用域 → 403
  • 来自另一个团队项目的密钥 → 403
  • 同一操作上的非 PSAK 认证仍然有效

评论

支持 Markdown