Skip to content

feat(allocation_policies): per-tenant attachment via match blocks - #8393

Open
pbhandari wants to merge 7 commits into
masterfrom
prajjwalbhandari/eap-726-per-tenant-allocation-policy-attachment-via-match-blocks
Open

feat(allocation_policies): per-tenant attachment via match blocks#8393
pbhandari wants to merge 7 commits into
masterfrom
prajjwalbhandari/eap-726-per-tenant-allocation-policy-attachment-via-match-blocks

Conversation

@pbhandari

Copy link
Copy Markdown
Contributor

Stacked on #8387. Linear: EAP-726.

Summary

  • allocation_policy is a per-resource list of {match, policies, remove} blocks.
  • Match keys (organization_id, project_id, referrer) are always lists; AND across keys, OR within a key; match: {} always matches.
  • Matching blocks apply in file order: remove names, then add/replace policies by name.
  • EAP routing and SNQL db_query pass request tenant_ids into get_active_allocation_policies.
  • Drop unused required_tenant_types. Stop baking policies onto Table; attach at quota time from storage_key.

Testing

  • SNUBA_SETTINGS=test uv run pytest -q tests/query/allocation_policies/test_attachment.py tests/web/test__get_allocation_policy.py

@pbhandari
pbhandari requested review from a team as code owners August 25, 2026 17:41
@linear-code

linear-code Bot commented Aug 25, 2026

Copy link
Copy Markdown

EAP-726

Comment on lines +585 to +586
def _block_matches(match: Mapping[str, Any], tenant_ids: Mapping[str, str | int]) -> bool:
return all(key in tenant_ids and tenant_ids[key] in expected for key, expected in match.items())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The function _block_matches assumes match values are iterable. A scalar value (e.g., an integer) will cause an uncaught TypeError, crashing the request handler.
Severity: HIGH

Suggested Fix

Add a type check in _block_matches to ensure the expected value from the match dictionary is a list or other iterable. If it's not, either wrap it in a list to handle the scalar case gracefully or log a warning and skip the invalid policy, similar to how other malformed configuration entries are handled.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: snuba/query/allocation_policies/__init__.py#L585-L586

Potential issue: The `_block_matches` function assumes that values for keys in the
`match` dictionary of an allocation policy are always iterable. However, if a policy is
misconfigured with a scalar value (e.g., `{"organization_id": 123}`) instead of a list
(`{"organization_id": [123]}`), the expression `tenant_ids[key] in expected` will raise
a `TypeError`. This exception is not caught within the call stack
(`_resolve_policy_specs` -> `get_active_allocation_policies` ->
`_get_allocation_policies`). Since `_get_allocation_policies` is called outside the main
`try/except` block in `db_query`, this error will crash the request handler for any
query using that resource until the configuration is corrected.

Did we get this right? 👍 / 👎 to inform future reviews.

Comment thread snuba/query/allocation_policies/__init__.py
@pbhandari
pbhandari force-pushed the prajjwalbhandari/eap-725-configure-allocation-policy-attachment-via-sentry-options branch from d2e969e to c109434 Compare August 25, 2026 19:34
@pbhandari
pbhandari force-pushed the prajjwalbhandari/eap-726-per-tenant-allocation-policy-attachment-via-match-blocks branch from 0b17c2c to 4d85c49 Compare August 26, 2026 14:30
Comment thread snuba/web/db_query.py
@pbhandari
pbhandari force-pushed the prajjwalbhandari/eap-726-per-tenant-allocation-policy-attachment-via-match-blocks branch from 4d85c49 to fa4a193 Compare August 26, 2026 14:46
Comment thread snuba/query/allocation_policies/__init__.py

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit fa4a193. Configure here.

Comment thread snuba/web/db_query.py
@pbhandari
pbhandari force-pushed the prajjwalbhandari/eap-726-per-tenant-allocation-policy-attachment-via-match-blocks branch from fa4a193 to b283a5d Compare August 27, 2026 13:44
Base automatically changed from prajjwalbhandari/eap-725-configure-allocation-policy-attachment-via-sentry-options to master August 27, 2026 14:36
@pbhandari
pbhandari force-pushed the prajjwalbhandari/eap-726-per-tenant-allocation-policy-attachment-via-match-blocks branch from b283a5d to c23cb58 Compare August 27, 2026 17:42
Comment thread snuba/web/db_query.py
Comment on lines 691 to 697
allocation policy be applied at the top level of the db_query process
"""

allocation_policies = _get_allocation_policies(clickhouse_query)
allocation_policies = _get_allocation_policies(clickhouse_query, attribution_info.tenant_ids)
query_id = uuid.uuid4().hex
result = None
error = None

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The finally block in db_query accesses allocation_policies[0] without checking if the list is empty, which can cause an IndexError for queries without tables.
Severity: MEDIUM

Suggested Fix

Add a conditional check in the finally block to ensure allocation_policies is not empty before attempting to access its first element, allocation_policies[0]. The call to _record_bytes_scanned should only proceed if the list contains at least one policy.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: snuba/web/db_query.py#L691-L697

Potential issue: In the `db_query` function, `_get_allocation_policies` can return an
empty list if the processed query contains no `Table` data sources. A `finally` block is
guaranteed to execute and calls `_record_bytes_scanned`, which unconditionally accesses
`allocation_policies[0]`. If `allocation_policies` is an empty list, this will raise an
`IndexError`, causing the request to crash. While queries without tables are considered
uncommon, they are a valid input to the query pipeline, making this a potential
production issue.

Also affects:

  • snuba/query/allocation_policies/__init__.py:616~689

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