Skip to content

feat(snuba): send service auth for snuba deletes - #122094

Draft
phacops wants to merge 1 commit into
masterfrom
feat/snuba-delete-service-auth
Draft

feat(snuba): send service auth for snuba deletes#122094
phacops wants to merge 1 commit into
masterfrom
feat/snuba-delete-service-auth

Conversation

@phacops

@phacops phacops commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

summary

Sentry now mints a short-lived aud=snuba-deletes JWT for Snuba destructive calls only.

  • HTTP DELETE /{storage} via _raw_delete_query
  • RPC EndpointDeleteTraceItems via delete_trace_items_rpc
  • Claims are project_ids / organization_ids taken from the already-authorized server-side delete request, not from a user body passthrough
  • Read/query Snuba pools are unchanged
  • If SENTRY_SNUBA_DELETE_AUTH_SECRET is unset, no header is sent so this PR can land before snuba enforce

Pairs with getsentry/snuba#8310 (AuthN) and #8311 (predicate AuthZ).

threat addressed

Without this, snuba AuthN has no legitimate caller and product deletes 401 after #8310. Tokens carry the tenant ids AuthZ will check.

non-goals

  • Does not put delete credentials on the read pool
  • Does not implement mesh identity
  • Does not change product delete UX

rollout

  1. Set SENTRY_SNUBA_DELETE_AUTH_SECRET to the same value as snuba SNUBA_DELETE_SERVICE_AUTH_SECRET.
  2. Deploy this PR (safe with or without snuba AuthN: extra header is ignored until fix(dashboard): Fix team sort (APP-188) #8310).
  3. Deploy snuba fix(dashboard): Fix team sort (APP-188) #8310 then ref(tagstore): Return sets for any collections that are not explicitly ordered #8311.

rollback

Revert this PR. If snuba AuthN is already enforced, deletes 401 until the secret/header path is restored.

test plan

  • test_mint_token_contains_authorized_ids
  • test_auth_headers_are_bearer
  • test_missing_secret_omits_headers
  • test_missing_secret_mint_fails_closed

residual risk

  • A compromised sentry-delete secret can mint tokens for any project/org. Keep the secret in env, not options, and rotate independently of query credentials.
  • Mesh still needs distinct sentry-query vs sentry-delete identities (PR F).
  • Callers must only pass ids they already authorized. Current callers (delete_request, delete_groups_from_eap_rpc, preprod artifact delete) build those ids from trusted server-side arguments.

Mint a short-lived audience-bound JWT after Sentry has already authorized the delete. Attach it only on HTTP DELETE and EndpointDeleteTraceItems. Claims come from server-side project/org ids, never request-body passthrough. Read paths are unchanged.
@phacops phacops self-assigned this Aug 14, 2026
@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label Aug 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Backend Test Failures

Failures on 28ada6a in this run:

tests/sentry/utils/test_snuba.py::SnubaResponseCompressionTest::test_skips_delete_querylog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/utils/test_snuba.py:786: in test_skips_delete_query
    self._run_query(mock.Mock(spec=DeleteQuery, storage_name="events"))
tests/sentry/utils/test_snuba.py:770: in _run_query
    _snuba_query(
src/sentry/utils/snuba.py:1464: in _snuba_query
    _raw_delete_query(request, headers),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/sentry/utils/snuba.py:1496: in _raw_delete_query
    project_ids = list(query.column_conditions.get("project_id") or [])
                       ^^^^^^^^^^^^^^^^^^^^^^^
/opt/hostedtoolcache/Python/3.13.1/x64/lib/python3.13/unittest/mock.py:688: in __getattr__
    raise AttributeError("Mock object has no attribute %r" % name)
E   AttributeError: Mock object has no attribute 'column_conditions'

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

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant