SIRT Triage Agent Workshop
~15 min

Wire up D1 to surface the incident queue

Create a D1 database, run the seed migration, add the binding, and watch the incident queue populate with four sample incidents.

Steps0 / 5
~15 min
  1. Create a D1 database

    Run `npx wrangler d1 create sirt-incidents`. Note the database_id from the output.

  2. Uncomment the D1 binding in wrangler.jsonc

    Open `wrangler.jsonc`, uncomment the `d1_databases` block, paste your `database_id`.

  3. Run the seed migration

    Run `npx wrangler d1 execute sirt-incidents --remote --file=migrations/001-seed.sql`.

  4. Change STATE to state-2-d1 in wrangler.jsonc

    Find the STATE var and change it from `state-1-empty` to `state-2-d1`.

  5. Redeploy and verify the queue

    Run `npx wrangler deploy`, reload your app. You should see 4 incidents in the queue.

What is D1?

D1 is Cloudflare’s serverless SQL database. Under the hood, it’s SQLite — you get full SQL support, but it runs at the edge alongside your Worker. There’s no connection string, no VPN, no cold start penalty. Your Worker accesses D1 through a binding, which means it’s available as env.INCIDENTS_DB in your code with zero network hops.

Why D1 here? The incident queue needs structured data: incident IDs, titles, severity levels, timestamps, alert types, and raw telemetry payloads. D1 gives you a real SQL database for this without any infrastructure management.

D1 data flow: Worker to incident queue

flowchart LR
W[Worker] -->|env.INCIDENTS_DB| D1[(D1 Database)]
D1 --> T[incidents table]
T --> id[incident_id]
T --> title[title]
T --> sev[severity]
T --> typ[type]
T --> ts[created_at]
T --> tel[telemetry]
D1 -->|SQL query| W
W -->|JSON response| UI[UI Incident Queue]

Step 1: Create the D1 database

From inside your sirt-workshop-app/ directory, run:

npx wrangler d1 create sirt-incidents

The output will look like:

✅ Successfully created DB 'sirt-incidents' in region WNAM
Created your new D1 database.

[[d1_databases]]
binding = "INCIDENTS_DB"
database_name = "sirt-incidents"
database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

Copy the database_id value. You’ll need it in the next step.

Step 2: Add the D1 binding to wrangler.jsonc

Open sirt-workshop-app/wrangler.jsonc in your editor. Find the commented-out d1_databases block — it looks something like this:

// Uncomment for lesson 06:
// "d1_databases": [
//   {
//     "binding": "INCIDENTS_DB",
//     "database_name": "sirt-incidents",
//     "database_id": "<your-database-id>"
//   }
// ]

Uncomment the block and replace <your-database-id> with the actual database_id from Step 1:

"d1_databases": [
  {
    "binding": "INCIDENTS_DB",
    "database_name": "sirt-incidents",
    "database_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
  }
]

Step 3: Run the seed migration

The workshop app includes a pre-written migration file at migrations/001-seed.sql. This file creates an incidents table and inserts four sample incidents matching the scenarios from lesson 02.

Run the migration against your remote D1 database:

npx wrangler d1 execute sirt-incidents --remote --file=migrations/001-seed.sql

The --remote flag is important — it runs the migration on your deployed D1 database, not a local copy.

You should see output confirming the SQL was executed successfully. The migration creates the incidents table with columns for:

  • id — unique incident identifier
  • title — human-readable incident name
  • type — alert category (malware, phishing, auth_anomaly, data_exfiltration)
  • severity — initial severity rating
  • status — current status (new, investigating, triaged, closed)
  • created_at — timestamp
  • telemetry — JSON blob with raw alert data specific to each scenario

The four seeded incidents are:

  1. Malware + C2 Beacon — Encoded PowerShell, C2 IP communication
  2. Phishing + BEC — Credential harvesting click, mailbox forwarding rule
  3. Anomalous Authentication — Service account, impossible travel, 3 countries in 10 min
  4. Data Exfiltration — Off-hours upload to unapproved cloud storage

Step 4: Change STATE to state-2-d1

In wrangler.jsonc, find the STATE variable and update it:

"vars": {
  "STATE": "state-2-d1"
}

This tells the app to fetch incidents from D1 instead of showing the empty state message. The queue component will query env.INCIDENTS_DB and render a card for each row in the incidents table.

Step 5: Redeploy and verify

Deploy the updated configuration:

npx wrangler deploy

Now reload your app in the browser. Instead of “No incidents yet,” you should see four incident cards in the queue, each showing:

  • The incident title
  • The severity level (critical, high, medium)
  • The alert type
  • The timestamp

Click on an incident to see its detail view. At this stage, the detail view shows raw telemetry data but no analysis — that comes in later lessons when you add Workers AI and the agent harness.

Knowledge check