bigquerystorage.googleapis.com) is gRPC and fits a gRPC lane directly. The jobs and query API (bigquery.googleapis.com), the plane the bq CLI and the client libraries use for SQL, is REST over HTTPS; a gRPC lane never sees it, and the section below covers what an HTTP lane can and cannot do there.
The Storage API on a grpc lane
BigQueryRead streams table data as Arrow or Avro batches; BigQueryWrite appends rows. Method identity is the policy surface: the service and method travel in Tables, so a table rule fences the write plane with no new rule type.
config.yaml
PERMISSION_DENIED with that message on AppendRows and reach CreateReadSession untouched.
With descriptors and capture_payload (the spanner page shows the buf command; add --path google/cloud/bigquery/storage), payload rules also see request fields. CreateReadSession names the table it opens, so the audit trail records who read which table. Row payloads stay opaque: ReadRows carries serialized Arrow batches inside a protobuf bytes field, and no descriptor turns those bytes into named columns. Content scanning and masking stop at that boundary.
ReadRows and OPA
Capture also turns everyReadRows response message into a statement, and a lane with an opa block sends each one to OPA. A read that streams 50k messages waits on 50k OPA calls in series. The rows are opaque bytes, so OPA has nothing to read there; keep it on the request side:
config.yaml
CreateReadSession and AppendRows still reach OPA with the table they name. The guardrails still judge every message, and the audit trail still records each one, marked opa.skipped: responses. To decide this per method inside Rego instead, return responses: false on the request decision; Config File shows the rule.
The REST plane
BigQuery SQL travels as JSON over HTTPS tobigquery.googleapis.com. Two facts bound what a Sidecar lane can do with it today:
- The
httpprotocol is a relay: it does not terminate TLS toward the client and copies bytes as they are,Hostheader included. Google’s front end routes onHost, so a client pointed at the lane by address sends aHostthe front end refuses. Working around that means overriding DNS forbigquery.googleapis.comon the client, which is a test-bench move. - The client’s OAuth token crosses the client-to-lane hop in cleartext.
config.yaml
jobs.insert the way the spanner lane reads ExecuteSql, would need a dedicated extraction seam. The lexer dialect already exists; the seam does not.
The emulator
goccy/bigquery-emulator serves the REST plane on one port and the Storage gRPC plane beside it, BigQueryRead and BigQueryWrite included. We validated both directions through a licensed lane: AppendRows came back PERMISSION_DENIED with the fence rule’s message, and CreateReadSession crossed the lane and drew a real answer from the emulator about the named table.
The gcloud-stack compose file carries the emulator, a method-only bqstorage lane in front of it, and the write-plane rule shown above (commented out where the free tier’s one-rule budget is already spent).
Next
Spanner
The lane that reads GoogleSQL out of the RPC payloads.
HTTP
What the http relay captures, and the identity contract behind a proxy.