Alert and Incident Enrichment#
Enrichment is the mechanism for attaching arbitrary key/value metadata to an alert or incident after it has been received. Status changes, ticket links, comments, environment tags, and any custom field are all modeled as enrichments. Enrichments are stored in the AlertEnrichment table — a shared table for both alerts and incidents despite the name — and merged on top of the raw alert event at read time.
Data Model#
AlertEnrichment is the single persistence table for enrichment data:
| Field | Type | Notes |
|---|---|---|
alert_fingerprint | str (unique) | Keyed by alert fingerprint or incident UUID |
enrichments | dict (JSON) | Arbitrary key/value payload |
tenant_id | str | FK → Tenant |
Each Alert row has a one-to-one relationship back to AlertEnrichment via fingerprint . Incidents reuse the same table with the incident UUID as alert_fingerprint .
REST API#
POST /alerts/enrich#
The primary enrichment endpoint is enrich_alert in keep/api/routes/alerts.py. Requires write:alert scope.
Request body: { "fingerprint": "<str>", "enrichments": { "<key>": "<value>", ... } }
Query param: dispose_on_new_alert=true makes the enrichment disposable — it is automatically removed when the alert fires again.
Post-enrichment side effects (via _enrich_alert):
- Calls
EnrichmentsBl.enrich_entity()(ordisposable_enrich_entity()whendispose_on_new_alert=true) to persist the enrichment - Re-indexes the enriched alert to Elasticsearch
- Pushes a
poll-alertsPusher event to connected clients - Triggers workflow evaluation via
WorkflowManager.insert_events()when status changes - Checks incident auto-resolution when status becomes
resolved
get_enrichment_metadata() classifies each enrichment as one of: MANUAL_RESOLVE, API_AUTOMATIC_RESOLVE, COMMENT, TICKET_ASSIGNED, or GENERIC_ENRICH, and determines whether to trigger workflows or check incident resolution.
POST /alerts/batch_enrich#
Bulk version. Accepts either an explicit fingerprints list or a CEL expression (not both) to resolve target alerts . Follows the same side-effect chain as the single endpoint.
POST /alerts/unenrich#
Removes specific enrichment keys from an alert .
Business Logic Layer#
EnrichmentsBl (keep/api/bl/enrichments_bl.py) wraps all enrichment DB operations:
enrich_entity— upserts enrichments persistently.disposable_enrich_entity— stores enrichments with adisposable_prefix and timestamp; they are automatically discarded when a new alert arrives on the same fingerprint.
The actual SQL upserts are delegated to enrich_entity and batch_enrich in keep/api/core/db.py.
Workflow-Driven Enrichment#
Provider actions and steps in workflows can write enrichments back to the triggering entity using enrich_alert or enrich_incident inside with:. Both fields are validated by WithSchema.
enrich_alert supports an optional disposable: bool flag per key-value pair . enrich_incident does not .
The provider base class extracts these kwargs in notify() and query(), then calls _enrich() which :
- Detects entity type (alert vs. incident) from execution context
- Resolves the fingerprint/UUID of the entity
- Evaluates
valueexpressions against the provider result (e.g.results.body.name) - Routes to
enrich_entity()ordisposable_enrich_entity()based on thedisposableflag
Example Workflows#
HTTP call → alert enrichment — fetches an external API and maps a response field back to the alert :
actions:
- name: http-action
provider:
type: http
with:
url: https://api.restful-api.dev/objects/7
method: GET
enrich_alert:
- key: computerName
value: results.body.name
OpenAI structured output → alert enrichment — uses GPT-4 to infer missing fields, then writes them back to the alert :
actions:
- name: enrich-alert
provider:
type: mock
with:
enrich_alert:
- key: environment
value: "{{ steps.get-enrichments.results.response.environment }}"
- key: impacted_customer_name
value: "{{ steps.get-enrichments.results.response.impacted_customer_name }}"
Incident tier escalation — enriches the incident with a current_tier value after each Slack notification, enabling conditional branching on subsequent triggers :
enrich_incident:
- key: current_tier
value: 0
Static incident metadata — sets fixed fields (environment, incident_id, incident_url, incident_provider) on every incident created/updated event .
Key Source Files#
| File | Role |
|---|---|
keep/api/routes/alerts.py | REST endpoints: /enrich, /batch_enrich, /unenrich |
keep/api/bl/enrichments_bl.py | Business logic: enrich_entity, disposable_enrich_entity, get_enrichment_metadata |
keep/api/core/db.py | SQL upsert implementations |
keep/api/models/db/alert.py | AlertEnrichment ORM model |
keep-ui/entities/workflows/model/schema.ts | Frontend Zod schema for enrich_alert / enrich_incident |
keep/providers/base/ | Provider base: _enrich(), notify(), query() hooks |