← Data Console

Browse PostgreSQL safely, without handing out credentials

The usual way to let someone look at production PostgreSQL is a shared read-only login, which grants everything to everyone and records nothing. The Data Console is the alternative: people browse the tables they are allowed to browse, sensitive columns come back masked unless they have been granted otherwise, and every access is logged against a person rather than a role.

Create a read-only PostgreSQL user

Run against a live server, then re-connected as that user to confirm SELECT worked and INSERT and DROP were refused.

-- PostgreSQL 16, verified
CREATE ROLE dbshift_ro LOGIN PASSWORD 'a-strong-password';
GRANT CONNECT ON DATABASE your_db TO dbshift_ro;
GRANT USAGE ON SCHEMA public TO dbshift_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO dbshift_ro;

-- Without this, tables created LATER are invisible to the role.
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT SELECT ON TABLES TO dbshift_ro;

What browsing PostgreSQL looks like

  • Schema-qualified tables, so a database using more than the public schema stays navigable rather than collapsing into one flat list.
  • Real foreign keys, which is what makes following a relationship one click instead of a hand-written join.
  • jsonb columns are shown as formatted JSON rather than one long line, and stay searchable.
  • Arrays, ranges, uuid and timestamptz keep their types instead of being flattened to text.

What catches people out on PostgreSQL

SELECT on existing tables does not cover future ones

GRANT SELECT ON ALL TABLES applies only to the tables that exist at that moment. A table created next week is invisible to the role until someone grants it again, which usually surfaces as 'the console cannot see our new table'. ALTER DEFAULT PRIVILEGES is what actually fixes it.

Row-level security applies to the console too

If RLS policies are enabled on a table, the role sees what the policy allows and no more. That is usually what you want, but it means two people can legitimately see different rows through the same console.

A view can leak past its base table's grants

Views run with the permissions of their owner unless declared with security_invoker. A read-only role denied a base table may still read it through a view built on top.

A read-only login still shows everything

The user above stops writes. It does not stop someone reading every email address, card number and salary in the database, and it does not record who did. The console adds the other half: sensitive columns are detected and masked before the rows leave the server, unmasking is granted per column to named people, and every access is logged. Access Review answers "who can see what" across every source in one report, which is the question that is very hard to answer from a pile of grants.

Questions

How do I create a read-only user in PostgreSQL?

Create a LOGIN role, grant CONNECT on the database and USAGE on the schema, then SELECT on the tables — and add ALTER DEFAULT PRIVILEGES so tables created later are included. The exact sequence above was run against PostgreSQL 16 and verified to allow SELECT while refusing INSERT and DROP.

Can I let people query production PostgreSQL without exposing customer data?

Yes. Run the sensitivity scan so PII columns are flagged, and they come back masked for anyone without an explicit unmask grant. Masking is applied server-side before the rows leave, so it is not something the browser can undo.

More on PostgreSQL

Other databases