13 October 2026, 09:00 UTC · PostgreSQL 16.15 (Ubuntu 16.15-0ubuntu0.24.04.1) · 2 logins · BareSQL 0.1.0
1high
2medium
0low
2logins that read personal data
10columns with personal data
BareSQL logged in as postgres (a superuser) over an unencrypted connection and read the system catalogs inside one read-only transaction.
It read up to 200 rows of each table to see what the columns hold; the values were looked at in memory and are not in this report.
For every login, the server's own privilege checks were asked about every table and column, and each answer below comes with the grant, membership, ownership or view that gives it.
Findings
HIGHEvery role, including roles created later, can read personal data in shop.newsletter.
public-reads-personal · shop.newsletter
Details
email (email)
MEDIUMNew tables that shop_owner creates in schema shop are granted SELECT to PUBLIC.
default-grants-to-public · shop_owner
MEDIUMshop.count_orders() runs with the rights of shop_owner, who can read 10 personal data columns; it can be run by every role (PUBLIC).
Columns and tables count base tables, partitions and materialized views, reached in any way listed below. Changes counts tables with personal data the login can insert into, update, delete from or empty.
Personal data in this database
Column
Holds
How BareSQL knows
Read by
shop.api_credentials.credential
table · text
key, token or secret
high confidence
4 of 4 sampled values look like random tokens; 4 of 4 sampled values contain a key or token
no audited login
shop.customers.first_name
table · text
person's name
medium confidence
the column name suggests person's name
shop_alice, shop_bob
shop.customers.last_name
table · text
person's name
medium confidence
the column name suggests person's name
shop_alice, shop_bob
shop.customers.email
table · text
email address
high confidence
40 of 40 sampled values are email addresses
shop_alice, shop_bob
shop.customers.phone
table · text
phone number
high confidence
40 of 40 sampled values are phone numbers
shop_alice, shop_bob
shop.customers.card_number
table · text
payment card number
high confidence
40 of 40 sampled values are payment card numbers (valid check digit)
no audited login
shop.customers.notes
table · text
email address
medium confidence
1 of 40 sampled values contain an email address
no audited login
shop.newsletter.email
table · text
email address
high confidence
25 of 25 sampled values are email addresses
shop_alice, shop_bob
shop.users.password_hash
table · text
password or password hash
high confidence
20 of 20 sampled values are password hashes
no audited login
shop.users.last_login_ip
table · inet
IP address
high confidence
20 of 20 sampled values are IP addresses
no audited login
support.customer_lookup.customer_name
view · text
person's name
medium confidence, computed
comes from shop.customers.first_name; comes from shop.customers.last_name
shop_alice, shop_bob
support.customer_lookup.email
view · text
email address
high confidence
comes from shop.customers.email
shop_alice, shop_bob
support.customer_lookup.phone
view · text
phone number
high confidence
comes from shop.customers.phone
shop_alice, shop_bob
Logins
shop_alice
member of shop_support_team · no password set
Personal data it can read
Holds
How
shop.customers.first_name
table
person's name
through view support.customer_lookup (rights of shop_owner)
shop.customers.last_name
table
person's name
through view support.customer_lookup (rights of shop_owner)
shop.customers.email
table
email address
through view support.customer_lookup (rights of shop_owner)
shop.customers.phone
table
phone number
through view support.customer_lookup (rights of shop_owner)
shop.newsletter.email
table
email address
granted to PUBLIC
support.customer_lookup.customer_name
view
person's name
granted to shop_support_team
support.customer_lookup.email
view
email address
granted to shop_support_team
support.customer_lookup.phone
view
phone number
granted to shop_support_team
10 other columns it can read
Column
How
shop.customers.id
through view support.customer_lookup (rights of shop_owner)
shop.newsletter.id
granted to PUBLIC
shop.newsletter.subscribed_at
granted to PUBLIC
shop.orders.id
through view support.order_status (rights of shop_owner)
shop.orders.tracking_number
through view support.order_status (rights of shop_owner)
shop.orders.shipped_at
through view support.order_status (rights of shop_owner)
support.customer_lookup.id
granted to shop_support_team
support.order_status.id
granted to shop_support_team
support.order_status.shipped_at
granted to shop_support_team
support.order_status.tracking_number
granted to shop_support_team
Functions that run with someone else's rights (1)
Function
Runs as
How
shop.count_orders()
shop_owner
granted to PUBLIC
shop_bob
noinherit · member of shop_support_team (no inherit) · can SET ROLE shop_support_team · no password set
Personal data it can read
Holds
How
shop.customers.first_name
table
person's name
after SET ROLE shop_support_team: through view support.customer_lookup (rights of shop_owner)
shop.customers.last_name
table
person's name
after SET ROLE shop_support_team: through view support.customer_lookup (rights of shop_owner)
shop.customers.email
table
email address
after SET ROLE shop_support_team: through view support.customer_lookup (rights of shop_owner)
shop.customers.phone
table
phone number
after SET ROLE shop_support_team: through view support.customer_lookup (rights of shop_owner)
shop.newsletter.email
table
email address
granted to PUBLIC
support.customer_lookup.customer_name
view
person's name
after SET ROLE shop_support_team: granted to shop_support_team
support.customer_lookup.email
view
email address
after SET ROLE shop_support_team: granted to shop_support_team
support.customer_lookup.phone
view
phone number
after SET ROLE shop_support_team: granted to shop_support_team
10 other columns it can read
Column
How
shop.customers.id
after SET ROLE shop_support_team: through view support.customer_lookup (rights of shop_owner)
shop.newsletter.id
granted to PUBLIC
shop.newsletter.subscribed_at
granted to PUBLIC
shop.orders.id
after SET ROLE shop_support_team: through view support.order_status (rights of shop_owner)
shop.orders.tracking_number
after SET ROLE shop_support_team: through view support.order_status (rights of shop_owner)
shop.orders.shipped_at
after SET ROLE shop_support_team: through view support.order_status (rights of shop_owner)
support.customer_lookup.id
after SET ROLE shop_support_team: granted to shop_support_team
support.order_status.id
after SET ROLE shop_support_team: granted to shop_support_team
support.order_status.shipped_at
after SET ROLE shop_support_team: granted to shop_support_team
support.order_status.tracking_number
after SET ROLE shop_support_team: granted to shop_support_team
Functions that run with someone else's rights (1)
Function
Runs as
How
shop.count_orders()
shop_owner
granted to PUBLIC
Everyone (PUBLIC)
What every role can read, including roles created after this audit.
Personal data
Holds
How
shop.newsletter.email
email address
granted to PUBLIC
2 other columns every role can read
Column
How
shop.newsletter.id
granted to PUBLIC
shop.newsletter.subscribed_at
granted to PUBLIC
Tables created later
Default privileges hand these rights out on objects that don't exist yet.
BareSQL never calls a function written in SQL or a procedural language, never reads views or foreign tables, and never writes. Sampled values are turned into text by their type's own output function, never by a cast, and each table is read on its own, without its partitions or child tables. Views are traced to the columns they read from their stored definitions, without running them.
Every fact in this report is also in audit.json, which baresql diff and baresql audit --baseline compare with a later audit.