Grant pg_read_all_stats to the Claude read-only DB user#5122
Merged
Conversation
Lets the read-only DB role see the query and state columns of every other backend in pg_stat_activity (and the other system statistics views) instead of <insufficient privilege>, so stuck/slow queries can be diagnosed during indexing incidents. pg_read_all_stats is a read-only stats-visibility grant only; it confers no data-write or table-read privilege. The migration is gated to staging and production, where the role exists, and no-ops elsewhere. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
Contributor
There was a problem hiding this comment.
Pull request overview
Adds an operationally-scoped Postgres migration to grant the built-in pg_read_all_stats role to the dedicated Claude triage read-only DB user (gated to staging/production), enabling full visibility into pg_stat_activity during incident debugging without expanding data access beyond existing read-only permissions.
Changes:
- Add a new Postgres migration that
GRANTs/REVOKEspg_read_all_statsfor the role named byCLAUDE_DB_USER, with conservative identifier validation and env gating. - Update the generated host schema snapshot to the latest migration timestamp (DDL unchanged).
Reviewed changes
Copilot reviewed 1 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| packages/postgres/migrations/1780620712404_grant-claude-readonly-pg-read-all-stats.js | New migration granting pg_read_all_stats to the Claude read-only DB role in staging/production, with username validation. |
| packages/host/config/schema/1780620712404_schema.sql | Regenerated/renamed schema snapshot to reflect latest migration timestamp (no schema DDL changes). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
lukemelia
approved these changes
Jun 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a Postgres migration that grants the built-in
pg_read_all_statsrole to the dedicated read-only DB user that Claude uses for triage.The grant target is read from
CLAUDE_DB_USER— the same source the existing claude-readonly migration used to create the role — so the GRANT always lands on the role that actually exists in the deployed environment. The user name is validated against a conservative Postgres-identifier regex before it's interpolated into the rawGRANT/REVOKE(mirroring the existing migration), so it can't become a SQL-injection vector.Why
The read-only DB user is a member of
readonly_roleand can already query application tables. But forpg_stat_activityit can only see its own session in full — for every other backend thequeryandstatecolumns render as<insufficient privilege>. That masking hid the SQL a worker backend was actually running while a from-scratch indexing job hung in its invalidation-discovery phase, so we couldn't tell what was stuck.pg_read_all_statsis exactly the fix: it's a read-only statistics-visibility role. It lifts the masking onpg_stat_activityand the other system statistics views without conferring any data-write or table-read privilege beyond what the user already has. With it, stuck/slow queries can be attributed to a specific backend and statement during an indexing incident.Scope / safety
GRANTis idempotent, so a re-run is a no-op.pg_read_all_statsonly widens visibility into the statistics views.Schema snapshot
pnpm make-schemawas run. Because this is a GRANT to a built-in role and adds no table DDL, the generated schema snapshot content is byte-identical — the only change is the snapshot file being renamed to track the new latest-migration timestamp (the repo keeps one snapshot named after the most recent migration).🤖 Generated with Claude Code