Granted read scope

BurnLedger has always checked that a customer-supplied credential cannot write. It never reported what that credential may read.

The two are not the same question, and only one of them was being asked. A customer who hands over a warehouse-wide GRANT SELECT ON *.* passes every admission gate: the credential is genuinely read-only, the transport is genuinely verified, and the registered query genuinely touches one table. Nobody — not the operator running the registration, not the customer who issued the credential — was shown that the grant reaches every schema on the server.

Read scope is that disclosure.

What it is not

It is not enforcement. No connection is refused for being broadly scoped, and none ever will be by this mechanism. BurnLedger cannot know what else a credential is legitimately used for, and a product that started rejecting working credentials on a guess would be worse than one that says nothing.

It is not attested. Like transport_security before it, the read scope is operator-facing diagnostics. It is not bound into the signed attestation payload, so a relying party holding a certificate cannot check it. It describes the grants at the moment of the check and says nothing about the grants an hour later.

An empty scope does not mean "reads nothing." It means the scope was not established — usually because the engine will not answer the question. Read it beside read_only_enforcement, which says whether anything was introspected at all.

Where it surfaces

Surface Field
POST /v1/systems/test-connection read_scope (array of strings), and appended to the read_only step's detail
Enclave health check HealthCheckResponse.read_scope
Audit log, system.registered read_scope in the entry's metadata

It is deliberately not a column on the systems table. A column would claim to describe the credential as it is now, and would be wrong the moment a grant was widened without telling BurnLedger. An audit entry claims only what was true when the system was admitted, which is what was actually measured — and it is what an auditor asking "what could this credential see when it was registered" needs.

Coverage

Reporting the scope requires the engine to answer a question about its own grants. Some will, some will not, and some can be asked but have not been wired up yet. The table states which is which, because a blank field whose reason is unstated is not a disclosure.

Reports granted read scope

Connector Source Shape
PostgreSQL information_schema.role_table_grants SELECT on 1284 tables in schema public — one line per schema, so a warehouse-wide grant stays readable
MySQL SHOW GRANTS FOR CURRENT_USER() SELECT ON *.* — privileges and object, grantee dropped
SQL Server HAS_PERMS_BY_NAME over sys.objects SELECT on 412 tables in schema dbo — one line per schema, views on their own line (SELECT on 3 views in schema dbo) because a view can read tables the login holds no direct grant on
Redis ACL GETUSER ACL rules: -@all +@read ~user:* — verbatim, because the rules are the scope in the operator's own vocabulary
Elasticsearch _security/user/_privileges read on logs-* — the index pattern is the whole disclosure
Oracle USER_TAB_PRIVSROLE_TAB_PRIVS, plus SESSION_PRIVS SELECT on 3 tables in schema APPOWNER — one line per owning schema; a system privilege that reads everything is its own line, SELECT ANY TABLE (system privilege). Verified against the shared Oracle Free container under the guide's grant. Roles not enabled by default are counted if ROLE_TAB_PRIVS shows them
Redshift pg_class through has_table_privilege SELECT on 12 tables in schema analytics — the PostgreSQL shape, but not the PostgreSQL query: Redshift has no role_table_grants or pg_has_role. Verified against the PostgreSQL container the Redshift suite runs on, not against a live Redshift cluster
Teradata DBC.AllRightsVDBC.AllRoleRightsV (roles walked recursively, as the write check does), RETRIEVE right only SELECT on 2 tables in database appdb, or SELECT on all tables in database appdb for a database-level grant (TableName = 'All'). Verified against a recorded Query Service response, not against a live Teradata system
Snowflake SHOW GRANTS TO ROLE <current role> — the statement the write check already runs SELECT on 4000 tables in ANALYTICS.PUBLIC, SELECT on 1 view in ANALYTICS.PUBLIC — one line per schema and object kind. Does not expand the role hierarchy or SHOW FUTURE GRANTS. Verified against recorded SHOW GRANTS output, not against a live Snowflake account
Databricks INFORMATION_SCHEMA.TABLE_PRIVILEGES in the configured catalog SELECT on 4000 tables in main.sales — a catalog- or schema-level SELECT is inherited onto every table there, so this is the effective breadth in tables. The configured catalog only; group-carried grants are not expanded; hive_metastore has no information schema and reports nothing. Verified against a recorded aggregate, not against a live workspace
Cassandra LIST ALL PERMISSIONS OF <role> — the statement the write check already runs SELECT on <table myapp.user_events>, SELECT on <keyspace myapp> — the resource verbatim, as cqlsh shows it, because a keyspace grant does not enumerate its tables. Empty under AllowAllAuthorizer, where the statement is refused and read-only rests on the operator's assertion; that pairing is what the container test pins
DynamoDB ListTables + iam:SimulatePrincipalPolicy for dynamodb:Query on each table ARN Query on table UserProfiles — one line per table; when the credential cannot ListTables (the documented least-privilege policy does not grant it) the list carries ListTables not granted; only the registered table could be checked, so one table is never mistaken for the measured breadth. Nothing against a DynamoDB-compatible endpoint, which has no IAM to ask
MongoDB connectionStatus with showPrivileges find on all collections in app — one line per resource the credential may find on, in MongoDB's own resource vocabulary: app.users, all collections in app, all databases, any resource. find is the action that returns documents; the write check has already refused everything outside the read role's set
Neo4j SHOW USER PRIVILEGES AS COMMANDS GRANT MATCH {*} ON GRAPH * NODE * — the ACCESS, MATCH, READ and TRAVERSE commands verbatim, DENY rows included because Neo4j applies them over any grant, role name dropped. Enterprise only: Community Edition has no privileges to show
S3 ListBuckets, and one page of ListObjectsV2 from the bucket root s3:ListAllMyBuckets: 47 buckets visible and s3:ListBucket on uploads: 1000+ top-level prefixes — the two things a credential can hold beyond the one prefix a registered query touches. A refused call is the absence of its line. An S3-compatible store may answer ListBuckets with the reachable subset instead of refusing (MinIO does), which is still the credential's reach
GCS one page of objects.list from the bucket root storage.objects.list on bucket uploads: 12 top-level prefixes — whether a prefix-conditioned IAM binding confines the credential, or it lists the whole bucket. Other buckets in the project are not measured: the connector holds no project id to list them under
BigQuery datasets.list, and tables.list on the configured dataset 3 datasets visible in project p and 12 tables in dataset ds. The service filters datasets.list to what the caller may access, which is what puts a project-level roles/bigquery.dataViewer beside a dataset-scoped role — the dataset ACL cannot, because project-level grants never appear in it. tables.list is not in the guide's custom role and its line is absent under it. No emulator exists: the probe is tested against a recorded REST fixture, not the service

Does not report it yet, but could

Nothing, as of this revision: every connector that introspects privileges for the write check now reports the read side with the same query or one more.

Cannot report it

These have no privilege introspection reachable by the query credential, which is the same reason their read-only status rests on the operator's read_only assertion rather than on anything BurnLedger verified. For these four, a blank read scope is the honest answer and not a gap to close.

Connector Why
Azure Blob Azure exposes no data-plane permission simulation
MarkLogic Privilege introspection needs the Management REST API, which the query credential cannot reach
HBase No permission introspection over its wire API
Redis (when ACL is unreadable) Redis 5 and earlier have no ACL system; the scope is reported only when ACL GETUSER answers

Bounds

A single check reports at most 32 entries, each at most 200 characters. A truncated list ends with a marker naming how many were hidden — showing 32 of 1,284 without saying so would understate exactly the breadth this field exists to show. Entries are deduplicated and sorted, so two checks against an unchanged credential produce an identical value and an auditor diffing two registrations sees a difference only when the grant actually changed.

© 2026 ProChatFlow LLC Last updated present → absent → proven