fix(activity-log): attribute bearer-token API writes to the key's user - #73120
Conversation
|
😎 This pull request was merged. |
🦔 Hogbox preview · ✅ ready▶ Open the preview
commit |
|
Reviews (1): Last reviewed commit: "fix(activity-log): attribute bearer-toke..." | Re-trigger Greptile |
🤖 CI report
|
| Root | Eager (shipped) | Δ vs base | Budget |
|---|---|---|---|
entry (logged-out pages, app bootstrap)src/index.tsx |
1.24 MiB · 22 files | no change | ███░░░░░░░ 27.5% of 4.51 MiB |
authenticated shell (every logged-in page)src/scenes/AuthenticatedShell.tsx |
8.07 MiB · 3,010 files | 🔺 +271 B (+0.0%) | ████████░░ 83.0% of 9.71 MiB |
🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
Largest files eagerly shipped from src/index.tsx
| Size | File |
|---|---|
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 24.6 KiB | ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js |
| 6.3 KiB | ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js |
| 4.5 KiB | ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js |
| 3.9 KiB | ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js |
| 1.4 KiB | ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js |
| 1.3 KiB | src/RootErrorBoundary.tsx |
| 912 B | ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js |
| 789 B | src/scenes/ChunkLoadErrorBoundary.tsx |
| 762 B | src/index.tsx |
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
| Size | File |
|---|---|
| 281.5 KiB | ../node_modules/.pnpm/posthog-js@1.407.2/node_modules/posthog-js/dist/rrweb.js |
| 267.7 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 236.0 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 226.1 KiB | ../node_modules/.pnpm/posthog-js@1.407.2/node_modules/posthog-js/dist/module.js |
| 154.3 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 105.8 KiB | src/lib/api.ts |
| 94.0 KiB | ../packages/quill/packages/quill/dist/index.js |
| 93.3 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
| 90.6 KiB | ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js |
Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479
✅ Toolbar bundle — eager 2.18 MiB within budget
What the toolbar ships to customer pages, measured from the esbuild output (minified, post-tree-shake). The eager set is the entry plus everything statically imported from it — fetched before any feature runs; deferred chunks load lazily. The eager guardrail is 5.72 MiB. Each output file must also stay below 10 MB, where CloudFront stops compressing it. The module boundary is enforced separately by check-toolbar-graph.
| Metric | Size | Δ vs base | Budget |
|---|---|---|---|
| Eager (shipped) entry + static imports |
2.18 MiB · 17 files | no change | ████░░░░░░ 38.1% of 5.72 MiB |
| Deferred (lazy) | 2.07 MiB · 33 files | no change | n/a — loads on demand |
Loader dist/toolbar.js |
1.1 KiB | no change | █░░░░░░░░░ 5.8% of 19.5 KiB |
Largest eagerly-shipped chunks
| Size | File |
|---|---|
| 713.8 KiB | dist/toolbar/toolbar-app-HLTHZTTF.css |
| 545.0 KiB | dist/toolbar/chunk-chunk-JGF7ZYC3.js |
| 484.2 KiB | dist/toolbar/chunk-chunk-YMFODIKP.js |
| 133.6 KiB | dist/toolbar/chunk-chunk-YSVTUFEA.js |
| 131.8 KiB | dist/toolbar/chunk-chunk-T5KY5WYR.js |
| 71.0 KiB | dist/toolbar/toolbar-app-Y3ZKEAFE.js |
| 69.0 KiB | dist/toolbar/chunk-chunk-27JL52RE.js |
| 35.6 KiB | dist/toolbar/chunk-chunk-ALQOU6WO.js |
| 20.9 KiB | dist/toolbar/chunk-chunk-VMBXRLPQ.js |
| 12.2 KiB | dist/toolbar/chunk-chunk-PIK3PADE.js |
Posted automatically by check-toolbar-size · sizes are toolbar output bytes (shipped, post-tree-shake) from the esbuild metafile
✅ Dist folder size — 🔺 +3.4 KiB (+0.0%)
Total size of the built frontend/dist folder (all assets), compared against the base branch.
Total: 1352.21 MiB · 🔺 +3.4 KiB (+0.0%)
⚠️ Backend snapshots — 11 updated (11 modified, 0 added, 0 deleted)
Query snapshots: Backend query snapshots updated
Changes: 11 snapshots (11 modified, 0 added, 0 deleted)
What this means:
- Query snapshots have been automatically updated to match current output
- These changes reflect modifications to database queries or schema
Next steps:
- Review the query changes to ensure they're intentional
- If unexpected, investigate what caused the query to change
⚠️ Backend coverage — 96.0% of changed backend lines covered — 3 uncovered
🧪 Backend test coverage
Patch coverage — changed backend lines (products + core): ███████████████████░ 96.0% (79 / 82)
| File | Patch | Uncovered changed lines |
|---|---|---|
posthog/api/test/test_team.py |
50.0% | 78–79 |
posthog/models/activity_logging/model_activity.py |
80.0% | 188 |
🤖 Agents: add a test covering the lines above, or note why under "How did you test this code?". Machine-readable gap list: the patch-coverage artifact on this run (gh run download 30077258277 -n patch-coverage), or the coverage-data block at the end of this comment.
Per-product line coverage (touched products)
| Product | Coverage | Lines |
|---|---|---|
platform_features |
██░░░░░░░░░░░░░░░░░░ 12.1% |
7 / 58 |
batch_exports |
████████░░░░░░░░░░░░ 39.6% |
8,414 / 21,249 |
demo |
███████████░░░░░░░░░ 56.2% |
1,497 / 2,663 |
warehouse_sources_queue |
████████████░░░░░░░░ 59.2% |
148 / 250 |
tasks |
██████████████░░░░░░ 69.4% |
30,050 / 43,291 |
data_tools |
██████████████░░░░░░ 70.0% |
63 / 90 |
ai_gateway |
███████████████░░░░░ 75.0% |
9 / 12 |
signals |
████████████████░░░░ 80.0% |
22,084 / 27,597 |
cdp |
████████████████░░░░ 81.0% |
3,146 / 3,883 |
data_modeling |
█████████████████░░░ 82.7% |
5,547 / 6,708 |
wizard |
█████████████████░░░ 84.8% |
935 / 1,102 |
notebooks |
█████████████████░░░ 85.3% |
7,275 / 8,531 |
agent_platform |
█████████████████░░░ 86.4% |
3,807 / 4,405 |
actions |
█████████████████░░░ 86.6% |
717 / 828 |
cohorts |
██████████████████░░ 87.8% |
4,488 / 5,114 |
product_tours |
██████████████████░░ 87.9% |
1,303 / 1,482 |
exports |
██████████████████░░ 88.4% |
6,951 / 7,863 |
data_warehouse |
██████████████████░░ 88.9% |
11,887 / 13,378 |
business_knowledge |
██████████████████░░ 89.0% |
4,391 / 4,936 |
conversations |
██████████████████░░ 89.3% |
16,869 / 18,883 |
engineering_analytics |
██████████████████░░ 89.4% |
6,386 / 7,145 |
visual_review |
██████████████████░░ 89.4% |
5,818 / 6,505 |
dashboards |
██████████████████░░ 89.5% |
5,989 / 6,693 |
error_tracking |
██████████████████░░ 89.7% |
10,168 / 11,336 |
alerts |
██████████████████░░ 90.0% |
4,056 / 4,508 |
early_access_features |
██████████████████░░ 90.1% |
1,031 / 1,144 |
mcp_analytics |
██████████████████░░ 90.1% |
2,763 / 3,065 |
streamlit_apps |
██████████████████░░ 90.4% |
2,501 / 2,767 |
links |
██████████████████░░ 90.6% |
183 / 202 |
slack_app |
██████████████████░░ 90.7% |
9,028 / 9,951 |
marketing_analytics |
██████████████████░░ 91.0% |
11,792 / 12,964 |
stamphog |
██████████████████░░ 91.1% |
4,056 / 4,450 |
mcp_store |
██████████████████░░ 91.9% |
4,257 / 4,634 |
product_analytics |
███████████████████░ 92.6% |
5,852 / 6,322 |
notifications |
███████████████████░ 92.6% |
1,011 / 1,092 |
ai_observability |
███████████████████░ 92.8% |
15,041 / 16,214 |
surveys |
███████████████████░ 93.0% |
5,734 / 6,167 |
managed_migrations |
███████████████████░ 93.1% |
1,424 / 1,530 |
web_analytics |
███████████████████░ 93.1% |
14,426 / 15,492 |
posthog_ai |
███████████████████░ 93.2% |
1,326 / 1,422 |
approvals |
███████████████████░ 93.3% |
3,437 / 3,682 |
reminders |
███████████████████░ 93.4% |
468 / 501 |
workflows |
███████████████████░ 93.6% |
6,390 / 6,826 |
legal_documents |
███████████████████░ 94.1% |
1,568 / 1,667 |
endpoints |
███████████████████░ 94.1% |
8,640 / 9,177 |
messaging |
███████████████████░ 94.3% |
2,682 / 2,845 |
tracing |
███████████████████░ 94.5% |
2,670 / 2,826 |
review_hog |
███████████████████░ 94.7% |
6,814 / 7,199 |
skills |
███████████████████░ 94.7% |
3,300 / 3,483 |
logs |
███████████████████░ 95.4% |
10,012 / 10,498 |
experiments |
███████████████████░ 95.7% |
25,036 / 26,159 |
growth |
███████████████████░ 96.1% |
3,245 / 3,376 |
annotations |
███████████████████░ 96.2% |
732 / 761 |
replay_vision |
███████████████████░ 96.2% |
15,260 / 15,864 |
revenue_analytics |
███████████████████░ 96.3% |
1,887 / 1,960 |
feature_flags |
███████████████████░ 96.5% |
17,112 / 17,736 |
user_interviews |
███████████████████░ 96.5% |
2,638 / 2,734 |
access_control |
███████████████████░ 96.9% |
870 / 898 |
customer_analytics |
███████████████████░ 97.1% |
9,047 / 9,317 |
warehouse_sources |
███████████████████░ 97.1% |
330,460 / 340,224 |
data_catalog |
███████████████████░ 97.5% |
2,368 / 2,429 |
analytics_platform |
████████████████████ 98.0% |
2,153 / 2,197 |
metrics |
████████████████████ 98.2% |
2,491 / 2,536 |
pulse |
████████████████████ 98.4% |
2,017 / 2,049 |
live_debugger |
████████████████████ 99.2% |
613 / 618 |
field_notes |
████████████████████ 99.4% |
158 / 159 |
Report-only. Patch coverage = changed backend lines covered vs origin/master. Sorted lowest first.
Known gaps: lines covered only by Temporal tests show as uncovered; core line numbers may drift if master changed the same file.
|
Note 🤖 stamphog reviewed Gates denied (auth deny-list hit) and the change genuinely touches authentication attribution logic in posthog/auth.py — real risky territory, not an incidental keyword. No substantive independent review exists (only a bot 👍 reaction), so this needs a human auth-focused review before merge.
Gate mechanics and policy version
|
|
✅ Visual changes approved by @jurajmajerik — baseline updated in 10 changed. |
| return ids | ||
|
|
||
|
|
||
| def has_uncalculated_cohorts(team: Team, *filter_sources: Any) -> bool: |
There was a problem hiding this comment.
This cohort-gating change (and the exposures-runner + test changes that go with it) is unrelated to bearer-token activity-log attribution.
| <div className="text-secondary"> | ||
| <div className="text-secondary flex items-center gap-1.5"> | ||
| <TZLabel time={logItem.created_at} /> | ||
| {logItem.client && ( |
There was a problem hiding this comment.
Added client to the serializer. We have two serializers for the same rows, hence the inconsistency, but I'd rather fix that in a follow-up.
PR overviewAll previously flagged issues have been addressed. No open security concerns remain on this pull request. Security reviewNo open security issues remain on this pull request. Fixed/addressed: 2 · PR risk: 0/10 |
00970ca to
82e5706
Compare
…during impersonation
10 updated Run: 109e2fce-60de-40fe-8c3d-e367195e5002 Co-authored-by: jurajmajerik <22996112+jurajmajerik@users.noreply.github.com>
a-lider
left a comment
There was a problem hiding this comment.
Looks good, thanks for fixing impersonation!
Guard activity_storage writes in bearer auth behind a middleware-owned request-scoped marker so direct authenticate() calls can't leak a stale user into the thread-local. Update remaining activity payload assertions for the new envelope fields.
…-auth-attribution


Problem
API writes authenticated with a personal API key or OAuth token (e.g. via MCP) show up in activity logs as "PostHog" system entries.
ActivityLoggingMiddlewarecaptures the acting user before DRF auth runs, so bearer-token requests never get one. Affects models with signal-driven activity logging (experiments, holdouts, shared metrics, ...) — viewsets that log explicitly withrequest.userwere fine.Changes
x-posthog-clientheader, already captured and serialized, just never rendered).How did you test this code?
Two regression tests: an experiment created via personal API key and via OAuth token gets an activity entry attributed to the key's user instead of system. Both fail without the auth change. No existing test covered bearer-auth attribution. Also ran the activityLogLogic jest tests, frontend typescript check, and mypy on
posthog/auth.py.