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.
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.
- Run the hoop.dev agent next to your GCP environment so it dials out to the gateway and exposes no inbound port.
- 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. - 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.
- 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.