All posts

Configuring AI agents access to BigQuery with just-in-time access

Count the BigQuery grants your AI agents hold right now. If you cannot, that is the problem. Standing access accumulates quietly: an agent gets a dataset role for one task, the task ships, and the role never gets revoked. Six months later the agent can read tables nobody remembers granting, and the only record of why is gone. Just-in-time access inverts that default. Instead of an agent holding a grant in case it needs it, the grant exists only while a specific task runs and disappears the mome

Free White Paper

Just-in-Time Access + AI Human-in-the-Loop Oversight: The Complete Guide

Architecture patterns, implementation strategies, and security best practices. Delivered to your inbox.

Free. No spam. Unsubscribe anytime.

Count the BigQuery grants your AI agents hold right now. If you cannot, that is the problem. Standing access accumulates quietly: an agent gets a dataset role for one task, the task ships, and the role never gets revoked. Six months later the agent can read tables nobody remembers granting, and the only record of why is gone.

Just-in-time access inverts that default. Instead of an agent holding a grant in case it needs it, the grant exists only while a specific task runs and disappears the moment the task ends. For an autonomous agent querying BigQuery, just-in-time access is the difference between a permanent attack surface and a window that closes on its own.

Standing access is a liability that compounds

Every durable grant is a bet that the holder stays trustworthy and uncompromised forever. With agents, that bet is worse than with humans, because an agent can be prompted into doing something its operator never intended, and a compromised agent with standing BigQuery access can exfiltrate at machine speed.

The fix is not a tighter review of who gets standing access. It is to stop issuing standing access at all and grant it per task instead.

What just-in-time access means for a BigQuery agent

For a BigQuery agent, just-in-time access has a concrete shape. The agent asks to run a task. A grant opens that scopes it to the datasets the task needs, for a bounded window. The agent runs its queries through the native bq client. When the task ends or the window lapses, the grant is gone, and the next query has to request access again. Between tasks the agent holds nothing.

Continue reading? Get the full guide.

Just-in-Time Access + AI Human-in-the-Loop Oversight: Architecture Patterns & Best Practices

Free. No spam. Unsubscribe anytime.

Compare that to the default, where the agent carries a dataset role indefinitely. The standing model leaves a permanent door. Just-in-time access opens a door for the work, then closes it. One model ends access on a schedule nobody enforces. The other ends it the moment the task is done.

Where the time bound has to live

An expiry the agent enforces on itself is not a control, because a compromised agent ignores it. The grant has to be issued and revoked by something the agent cannot reconfigure. That something has to sit on the connection path to BigQuery, so it can refuse a query the moment the window closes.

hoop.dev is built to that requirement. It proxies the connection to BigQuery and grants access just in time for the session, then ends it. When GCP IAM federation is enabled, the credential it brokers for that session is itself short-lived, so the time bound exists in two places: the gateway's grant and the OAuth token's lifetime.

Configure it

  1. Run the hoop.dev agent next to your GCP environment so it dials out to the gateway and exposes no inbound port.
  2. Define a BigQuery connection with CLOUDSDK_CORE_PROJECT set and GCP IAM federation on, so each session gets per-user OAuth instead of a shared key.
  3. Attach a just-in-time access policy to the connection, so an agent's request opens a scoped, time-limited session rather than a permanent grant.
  4. Route the agent's bq traffic through the gateway endpoint.
# access is granted for this session and expires when it closes
bq query --use_legacy_sql=false \
  'SELECT date, revenue FROM finance.daily LIMIT 50'

Verify the window closes

Open a session, run a query, let the window expire, and try again. The second query should be refused at the gateway. In the session log you should see the grant, the queries inside it, and the close, all tied to the agent's identity.

Pitfalls

  • Do not set the window to a week to avoid friction. A week-long grant is standing access wearing a timer.
  • Do not let an agent re-request access in a loop without an approval or rate boundary. Just-in-time should not become always-on by automation.
  • Do not pair short windows with a broad dataset scope. Time and scope are two dials, and both have to be tight.

hoop.dev is open source, so you can audit the grant-and-revoke path yourself. See the getting started guide and how the same gateway gives agents a brokered non-human identity on BigQuery rather than a shared key. Clone github.com/hoophq/hoop and put a time-limited BigQuery connection in front of a test agent.

FAQ

How is just-in-time access different from a short-lived token?

A short-lived token bounds how long a credential is valid. Just-in-time access bounds when a grant exists at all, issued for a task and revoked at its end. hoop.dev gives you both: a time-limited session grant and, with GCP federation, a short-lived OAuth credential.

Does just-in-time access slow agents down?

The grant happens at session open, which is fast. What it removes is the permanent grant that would otherwise sit idle and exploitable between tasks.

Open source

Save the open-source gateway for agent data access

Hoop is MIT-licensed infrastructure for controlling how AI agents reach production data. Star hoophq/hoop so you can inspect it, deploy it, or share it when your team starts governing agent access.

Star and save the repo →More posts