The consecutive-failure alert keys are scoped by destination ID only, omitting the tenant:
{deployment}alert:{destinationID}:cf
Destination IDs are only unique within a tenant, and the create API accepts a caller-supplied id. So two tenants can both have a destination named e.g. "prod", and their alert state then collides on a shared key — corrupting consecutive-failure counts and auto-disable behavior across tenants.
The alert store methods already receive tenantID; it's just ignored when building the key. The fix is to fold it in:
{deployment}alert:{tenantID}:{destinationID}:cf
Migration consideration: changing the key format orphans existing cf/cfeval keys. Given the 24h TTL and reset-on-success behavior they'd age out on their own, so an in-place/lazy migration may be sufficient rather than a hard cutover — leaving the exact approach to the implementor.
The consecutive-failure alert keys are scoped by destination ID only, omitting the tenant:
Destination IDs are only unique within a tenant, and the create API accepts a caller-supplied
id. So two tenants can both have a destination named e.g."prod", and their alert state then collides on a shared key — corrupting consecutive-failure counts and auto-disable behavior across tenants.The alert store methods already receive
tenantID; it's just ignored when building the key. The fix is to fold it in:Migration consideration: changing the key format orphans existing
cf/cfevalkeys. Given the 24h TTL and reset-on-success behavior they'd age out on their own, so an in-place/lazy migration may be sufficient rather than a hard cutover — leaving the exact approach to the implementor.