算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
adding-api-scopes【设计与创意】Guidance for adding an API scope object to posthog/scopes.py and making it work for personal API keys, OAuth tokens and MCP clients. Use when adding a scope object, exposing a viewset or MCP tool to tokens, moving a viewset off scope_object = "INTERNAL", deciding if a scope is internal, OAuth-hidden or privileged, choosing a scope group, reading the …
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
A scope has two parts: an object and an action, as in feature_flag:read.
Adding a scope means adding a scope object, such as feature_flag. It gives tokens feature_flag:read and feature_flag:write.
posthog/scopes.py is the source of the object list.
The frontend type and the MCP OAuth list are generated from it.
The picker rows and the groups are kept by hand in frontend/src/lib/scopes.tsx, and a test checks them.
They stay in the frontend on purpose: labels, plurals, groups and picker omissions are UI decisions, while posthog/scopes.py decides what exists and what it grants.
Most endpoints fit an existing scope, for example insight:read.
Add a new scope only for a product area that a person wants to grant or withhold on its own, on a key or an OAuth app.
Name its object with a snake_case singular noun, such as feature_flag.
INTERNAL_API_SCOPE_OBJECTS.OAUTH_HIDDEN_SCOPE_OBJECTS.llm_gateway. Use PRIVILEGED_SCOPES, and set unprivilegedExcluded: true on the picker row.Then decide two more things, separately from the kind:
PROJECT_SECRET_API_KEY_ALLOWED_API_SCOPE_ACTION, in both posthog/scopes.py and frontend/src/lib/scopes.tsx. Read /adding-project-secret-api-key-auth first.ACCESS_CONTROL_RESOURCES in products/access_control/backend/facade/user_access_control.py. Access control resources use scope object names by design, so a viewset's scope_object names both its token scope and its access control resource. Do not give access control a naming or a type of its own. The resource fields of the access control serializers take GRANTABLE_API_SCOPE_OBJECTS as their choices, and the frontend APIScopeObject type is generated from those fields (be careful: the personal API key modal, the OAuth consent screen, CLI login and the key presets also use that type).APIScopeObject literal in posthog/scopes.py. If you chose internal, OAuth-hidden or privileged above, also add it to that set.scope_object = "<object>" on each viewset the scope covers.
list and retrieve need :read, and create, update and destroy need :write.@action needs required_scopes, for example required_scopes=["<object>:write"]. Use :read if it only reads data, and :write if it changes data. Without it, token requests get a 403.scope_object = "INTERNAL" accepts only logged-in sessions. Change it to the new object to open it to tokens.hogli build:openapi, which carries the object to the frontend type, and hogli build:projections, which updates the OAuth lists of the MCP server and the web app. DO NOT EDIT GENERATED FILES BY HAND.frontend/src/lib/scopes.tsx:
API_SCOPES with a sentence-case label and plural (/writing-user-facing-copy). Disable write if no endpoint writes. If the key modal should not offer the object, add a reason to API_SCOPES_OMITTED_FROM_MODAL instead.API_SCOPE_GROUPS. See "Choose a group".scopes: in products/<product>/mcp/tools.yaml.The OAuth consent screen and the scope pickers show objects in groups, from API_SCOPE_GROUPS in frontend/src/lib/scopes.tsx.
The groups make a long list readable, so a person can find a product quickly.
frontend/src/lib/scopes.test.ts, the coverage test: a grantable object has no picker row and no omission reason. Add a row to API_SCOPES, or a reason to API_SCOPES_OMITTED_FROM_MODAL. If the object is missing from APIScopeObject, run hogli build:openapi first. If the object is OAuth-hidden, run hogli build:projections instead, so the test learns to skip it.frontend/src/lib/scopes.test.ts, the group test: an object is in no group, or in two groups. Put it in exactly one group of API_SCOPE_GROUPS. It also fails when an OAuth-hidden object has a row or a group. Remove them, because no picker shows a hidden object.posthog/test/test_scopes.py: an internal, OAuth-hidden or privileged scope leaks into a list it must stay out of, or the project secret API key list in posthog/scopes.py differs from the copy in frontend/src/lib/scopes.tsx. Fix the set, or make the two lists equal.services/mcp/tests/unit/tool-filtering.test.ts, the completeness test: an MCP tool requires a scope that OAuth does not advertise. If the scope is new, run hogli build:projections. If it is internal, add it to the test's server-only list. Otherwise fix the scope name in tools.yaml.@action without required_scopes. Tokens get a 403.scope_object.Use these instead of writing your own list of scopes.
posthog.scopes.
API_SCOPE_OBJECTS: every object, internal ones too.GRANTABLE_API_SCOPE_OBJECTS: the objects a person can grant.ALL_SCOPES: the grantable object:action strings.get_oauth_scopes_supported(): what the OAuth server advertises.APIScopeObject from ~/types.Object.values(ScopeObjectEnumApi), from products/access_control/frontend/generated/api.schemas.API_SCOPES, API_SCOPE_GROUPS and getScopeDescription from lib/scopes.OAUTH_SCOPES_SUPPORTED and OAUTH_SCOPES_HIDDEN, from lib/oauthScopes.generated in the web app and services/mcp/src/lib/oauth-scopes.generated.ts in the MCP server. The two files are the same.