fix(core): Remove insights:read scope from member API keys#30906
fix(core): Remove insights:read scope from member API keys#30906konstantintieber wants to merge 3 commits into
Conversation
Recommended reviewersBased on ownership of the 5 changed files in this PR:
|
| FROM ${userApiKeysTable} | ||
| JOIN ${userTable} ON ${userApiKeysTable}.${userIdCol} = ${userTable}.${idCol} | ||
| WHERE ${userTable}.${roleSlugCol} = 'global:member' | ||
| AND ${userApiKeysTable}.${createdAtCol} >= '2026-04-06' |
There was a problem hiding this comment.
This date filter is here because Apr 7th is the day that the insights:read scope was added to members for the first time: #27868 (comment)
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
2 issues found across 5 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/@n8n/db/src/migrations/postgresdb/1784000000009--RemoveInsightsReadScopeFromMemberApiKeys.ts">
<violation number="1" location="packages/@n8n/db/src/migrations/postgresdb/1784000000009--RemoveInsightsReadScopeFromMemberApiKeys.ts:25">
P1: Role filter uses current user role, not role at key creation. Keys created by members can be missed after role changes. Use a key-selection rule that does not depend on mutable current role.
According to linked Linear issue LIGO-550, this does not fully match the migration target.</violation>
</file>
Architecture diagram
sequenceDiagram
participant App as Application
participant Migration as DB Migration
participant PSql as PostgreSQL DB
participant SQLite as SQLite DB
participant UserTable as user Table
participant ApiKeyTable as user_api_keys Table
Note over App,SQLite: Startup Migration Phase
App->>Migration: Run migration: RemoveInsightsReadScopeFromMemberApiKeys1779321600000
Migration->>Migration: Execute up() method
alt PostgreSQL Database
Migration->>PSql: Query: SELECT id FROM user_api_keys JOIN user ON user_api_keys.userId = user.id
PSql->>UserTable: WHERE user.roleSlug = 'global:member'
PSql->>ApiKeyTable: AND user_api_keys.createdAt >= '2026-04-06'
PSql->>ApiKeyTable: AND scopes::jsonb @> '["insights:read"]'
UserTable-->>PSql: Matching user rows
ApiKeyTable-->>PSql: Matching API key rows
PSql-->>Migration: Return matching key IDs
alt Matching keys found
Migration->>PSql: UPDATE user_api_keys SET scopes = remove 'insights:read' FROM scopes JSONB
PSql->>ApiKeyTable: COALESCE(json_agg(elem), '[]') excluding 'insights:read'
ApiKeyTable-->>PSql: Updated rows
PSql-->>Migration: Query complete
else No matching keys
Migration->>Migration: Return early, no update needed
end
else SQLite Database
Migration->>SQLite: Query: SELECT id FROM user_api_keys JOIN user ON user_api_keys.userId = user.id
SQLite->>UserTable: WHERE user.roleSlug = 'global:member'
SQLite->>ApiKeyTable: AND user_api_keys.createdAt >= '2026-04-06'
SQLite->>ApiKeyTable: AND EXISTS (SELECT 1 FROM json_each(scopes) WHERE value = 'insights:read')
UserTable-->>SQLite: Matching user rows
ApiKeyTable-->>SQLite: Matching API key rows
SQLite-->>Migration: Return matching key IDs
alt Matching keys found
Migration->>SQLite: UPDATE user_api_keys SET scopes = remove 'insights:read' FROM scopes JSON
SQLite->>ApiKeyTable: COALESCE(json_group_array(value), '[]') excluding 'insights:read'
ApiKeyTable-->>SQLite: Updated rows
SQLite-->>Migration: Query complete
else No matching keys
Migration->>Migration: Return early, no update needed
end
end
Migration-->>App: Migration complete (irreversible)
Note over App,SQLite: Scope affected: global:member users with insights:read API keys created on/after 2026-04-06
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
| SELECT ${userApiKeysTable}.${idCol} | ||
| FROM ${userApiKeysTable} | ||
| JOIN ${userTable} ON ${userApiKeysTable}.${userIdCol} = ${userTable}.${idCol} | ||
| WHERE ${userTable}.${roleSlugCol} = 'global:member' |
There was a problem hiding this comment.
P1: Role filter uses current user role, not role at key creation. Keys created by members can be missed after role changes. Use a key-selection rule that does not depend on mutable current role.
According to linked Linear issue LIGO-550, this does not fully match the migration target.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/@n8n/db/src/migrations/postgresdb/1784000000009--RemoveInsightsReadScopeFromMemberApiKeys.ts, line 25:
<comment>Role filter uses current user role, not role at key creation. Keys created by members can be missed after role changes. Use a key-selection rule that does not depend on mutable current role.
According to linked Linear issue LIGO-550, this does not fully match the migration target.</comment>
<file context>
@@ -0,0 +1,46 @@
+ SELECT ${userApiKeysTable}.${idCol}
+ FROM ${userApiKeysTable}
+ JOIN ${userTable} ON ${userApiKeysTable}.${userIdCol} = ${userTable}.${idCol}
+ WHERE ${userTable}.${roleSlugCol} = 'global:member'
+ AND ${userApiKeysTable}.${createdAtCol} >= '2026-04-06'
+ AND ${userApiKeysTable}.${scopesCol}::jsonb @> '["insights:read"]'::jsonb
</file context>
There was a problem hiding this comment.
Optimizing for user role changes in this migration that removes a scope that gives access to non-sensitive data would be a bit too much.
There was a problem hiding this comment.
Thanks for clarifying the scope here.
Summary
Migration to remove insights:read scope from API keys that have been created by members in n8n versions spanning 2.16.x to 2.22.x.
See #27868 and #30778
While this migration makes sense on a technical level, I'm still not sure if we should merge it, since the data that a member gets access to by having
insights:readscope on an API key is not sensitive.I am leaning towards not merging this migration, but would like to hear the migration's team opinion.
Related Linear tickets, Github issues, and Community forum posts
closes https://linear.app/n8n/issue/LIGO-550/
Review / Merge checklist
Backport to Beta,Backport to Stable, orBackport to v1(if the PR is an urgent fix that needs to be backported)