SESSIONS CANNABIS - INTERNAL INCIDENT REPORT

Menu Data Outage: Automated IP Block by Data Provider

July 29-30, 2026 · Prepared by Ravi (Marketing / Web) for Darryl & Sophie · Published July 30, 2026
RESOLVED - PERMANENT FIX IN PLACE

TL;DR

What happened: Bright Data (the network provider our menu-refresh pipeline runs through) has an automated security system that hunts for stolen accounts. It mistook our own Cloudflare servers for suspicious traffic and silently blocked the IP addresses our pipeline uses.

Impact: Website menus stopped refreshing for roughly 30 hours across all 54 stores. Ordering kept working, but stock info on the site went stale - some customers saw "out of stock" on items that were in stock, and a few checkouts were blocked.

Fix: Root cause pinpointed on July 30. Within about 5 hours the blocks were cleared, a permanent 33-entry IP allowlist was installed in Bright Data (their auto-blocker cannot touch allowlisted addresses), and an automated self-heal now re-fixes it without human involvement if it ever recurs. All 54 store menus were fully refreshed the same day.

The numbers

54stores affected (menu staleness 27-31 hours)
~30 htotal impact window (Jul 29 morning to Jul 30 evening)
~5 hfrom root-cause diagnosis to permanent fix live
33IP ranges permanently allowlisted at Bright Data
0manual steps needed if it happens again (auto self-heal)

Background - how menus get to the website

Every store's live menu on sessions.ca comes from an automated pipeline: a Cloudflare worker fetches each store's menu from the POS system every half hour and caches it for the website. Because the POS blocks ordinary datacenter traffic, those fetches travel through Bright Data, a commercial network provider. This same pipeline is what makes brand links, the shop grid, and promo pages show accurate, per-store stock.

Root cause

Bright Data operates an automated defense called lum_auth_monitor. Its job is to detect leaked or stolen account credentials by watching where traffic comes from. Cloudflare workers (where our pipeline lives) send traffic from Cloudflare's shared IP ranges - which, to that system, looked like our account being used from "too many unknown places." It responded by automatically adding Cloudflare address blocks to our account's IP denylist. No notification is sent when this happens; requests simply start failing with an error (HTTP 520) that looks like a generic network fault.

Small partial blocks appeared as early as July 20, 26 and 27 (intermittent, self-masked by retries). On July 29 the blocks accumulated enough to cover our whole egress path, and menu refreshes stopped fleet-wide.

Timeline (July 30, all times ET)

WhenWhat
Jul 29, ~morningAuto-blocks reach full coverage; menu refreshes silently begin failing on every run.
Jul 30, middayStaleness detected while QA-testing a marketing link that showed missing products. Investigation traced it from the website back through the cache to the refresh pipeline.
early afternoonRoot cause identified: 7 Cloudflare ranges sitting in Bright Data's "Blocked IPs" list, added by their automated system. Blocks cleared manually in the control panel.
~12:00 PMPermanent allowlist rollout begins. Brief 5-minute self-lockout while the list was partially entered (expected and planned around - a partial allowlist blocks everything not yet on it).
~1:30 PMFull 33-entry allowlist confirmed in place, covering all 15 of Cloudflare's published IP ranges (their console rejects large blocks, so four had to be split into 22 smaller /16 ranges).
afternoonForced refresh of every stale store begins (sequential, paced to avoid tripping the same defense); pipeline hardening deployed in parallel.
~4:40 PMFleet fully refreshed. Refresher cron green on every run since (8 stores per run, 0 failures).

Customer-visible impact

Why it took ~30 hours to notice - the honest part

Our monitoring actually caught this. A "catalog stall" alert fired correctly and repeatedly. Two things kept it from reaching a human: (1) the alert-email key was never configured on that worker, so every alert sat unsent in the database; and (2) when the alert was reviewed, it was checked against the wrong internal data table (a second, healthy pipeline) and dismissed as a false alarm. Both failure modes are now fixed: the daily automated health check audits every fired alert and treats undelivered ones as unseen incidents, and it is hard-coded to verify each alert against its own pipeline's data. The email key is being installed as the last step.

The permanent fix (defense in depth)

LIVE1. Permanent IP allowlist at Bright Data. All 15 published Cloudflare ranges (33 entries after splitting) are on the account's Allowed IPs list. Bright Data's auto-blocker cannot block an allowlisted address - this removes the root cause outright.
LIVE2. Automated guard. A protected endpoint re-syncs the allowlist against Cloudflare's published ranges and clears any stray blocks, using an account-level API credential. Every run is logged to a database table for audit.
LIVE3. Pipeline self-heal. If an entire refresh batch ever fails with the block signature again, the pipeline calls the guard automatically - no human needed, recovery in minutes instead of hours.
LIVE4. Hardened refresh schedule. Refresh runs moved off the shared :00/:30 minute grid (they collided with other jobs on the same Bright Data account, which looked like a burst and fed the false "leaked account" signal), plus request pacing and one automatic retry per store.
LIVE5. Daily end-to-end health check. Every morning an automated check tests the Bright Data path directly, verifies menu freshness for all 54 stores against the correct table, reads the refresher's run log, and audits every alert fired in the last 24 hours - including undelivered ones.
LIVE6. Alert email delivery. Closed August 2: the email key is installed and verified with a live delivery to ravi@sessions.ca. Alerts fired by the monitoring now reach a human inbox within minutes - the full detection-to-notification chain is operational.

What this cost / did not cost

No data was lost, no orders were mischarged, and no systems were compromised - this was an availability issue in menu freshness only. The measurable costs were ~30 hours of stale menus, a handful of blocked checkouts, one support ticket, and one marketing link that briefly looked broken. The lasting benefit: the entire class of "our own provider silently blocks us" failures is now prevented, self-healing, and independently monitored.

Sessions Cannabis internal document · helps.sessions.ca/incident-bd-2026-07/ · Questions: marketing@sessions.ca (Ravi)