Skip to content

feat(admin): Add read-only agent query passthrough endpoint - #8689

Draft
sentry-junior[bot] wants to merge 2 commits into
masterfrom
feat/admin-agent-query-passthrough
Draft

sentry-junior[bot] wants to merge 2 commits into
masterfrom
feat/admin-agent-query-passthrough

Conversation

@sentry-junior

@sentry-junior sentry-junior Bot commented Nov 10, 2026

Copy link
Copy Markdown
Contributor

Adds POST /agent/query to snuba-admin. Automation clients such as Junior can use it to run read-only SQL against ClickHouse system tables and the querylog cluster.

{"target": "system", "storage": "errors", "sql": "SELECT count() FROM system.parts"}
{"target": "querylog", "sql": "SELECT count() FROM querylog_local"}

Safety

  • Uses the existing System Queries and Querylog validation (run_system_query_on_host_with_sql / run_querylog_query): system queries can read only system.* tables, and querylog queries can read only the querylog table.
  • Always runs with sudo_mode=False and clusterless_mode=False. Any sudo key in the body is ignored.
  • For system queries, host/port are optional and default to the storage's query node.
  • Responses are capped at 1000 rows and include a truncated flag.
  • Each query is logged with the caller identity, plus an optional X-Snuba-Admin-Requester header that says which person the agent is acting for. That header is only logged and is never used for authorization.

Auth

  • New AgentQueries role that grants only the new agent tool. The tool is also added to /clickhouse_nodes and /clickhouse_querylog_schema so a client can discover storages and the querylog schema.
  • The IAM policy now accepts serviceAccount:<email> members.
  • A service account that the policy binds explicitly gets only its bound roles, without DEFAULT_ROLES (which includes ProductTools). Service accounts with no binding keep today's behavior, so no existing caller changes.

Still needed before this works end to end (not in this PR)

  • Create a GCP service account for Junior and grant it IAP-secured Web App User on the snuba-admin backend.
  • Add a serviceAccount: → roles/AgentQueries binding to the deployed IAM policy file.
  • Give Junior a way to mint IAP ID tokens for that service account, plus a Junior plugin/skill in getsentry/junior-prod that calls this endpoint.

Open questions

  • Is /agent/query the shape we want, or should agents call the existing /run_clickhouse_system_query and /clickhouse_querylog_query directly with the new role?
  • Should unbound service accounts also stop receiving DEFAULT_ROLES? This PR leaves them unchanged.

Tests
tests/admin/test_agent_views.py covers role resolution, the 403 check, request validation, the no-sudo guarantee, truncation, and real ClickHouse system and querylog queries. I ran it locally together with test_authorization.py, test_api.py, test_system_queries.py, and test_querylog_audit_log.py. The only failure was test_merge_table_function_is_rejected, which also fails on master against my local ClickHouse. ruff and mypy pass.

via @phacops.

--

View Session [Sentry]

Add POST /agent/query so automation clients such as Junior can run
read-only SQL against ClickHouse system tables and the querylog cluster.
It reuses the System Queries and Querylog validation and never runs in
sudo or clusterless mode. System queries default to the storage's query
node, and responses are capped at 1000 rows.

Gate it on a new AgentQueries role. IAM policy bindings now accept
serviceAccount: members, and a bound service account gets only its
bound roles instead of the default roles every person gets.

Co-Authored-By: Pierre Massat <336345+phacops@users.noreply.github.com>
The querylog table is querylog_dist in distributed mode, so the
hardcoded querylog_local failed the test_distributed CI job.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant