Skip to main content

Database Schema (AI Agent-Oriented)

This document summarizes the current schema for AI-agent workflows, using Alembic migrations as source of truth in backend/alembic/versions/*.py.
  • Current migration head in this repo: fb51d610b306 (backend/alembic/versions/fb51d610b306_add_github_audit_tables.py)
  • Base migration: bdf40d064ed1 (backend/alembic/versions/bdf40d064ed1_initial_database_migration.py)

Practical Domain Map

For typical agent change work, these domains are most relevant:
  • Connectors and integration metadata: connectors*, available_*, customer_*_connectors*, customer_*integrations*, integration_*, network_connectors_*, custom_alert_creation_*, monitoring_alerts, sigma_queries, github_audit_*
  • Auth / users / roles: user, role, user_customer_access, user_tag_access, role_tag_access
  • Incidents (alerts/cases/tags/comments): all incident_management_* tables
  • Scheduler/job metadata: scheduled_job_metadata, schedulerjob, index_snapshot_schedules
  • Agent data store / artifacts / reports: agent_datastore, incident_management_case_datastore, incident_management_case_report_template_datastore, vulnerability_reports, sca_reports, agent_vulnerabilities

Critical relationship graph

Compact relationship views for incident workflows and access controls.

Tags (alert/tag join)

IoCs (alert/ioc join)

Comments (alert comments + case comments)

Case datastore + report template datastore

Tag access control and alert visibility

When tag access control is enabled, alert visibility is constrained by the tag IDs reachable through user_tag_access and/or role_tag_access joined through incident_management_alert_to_tag. incident_management_tag_access_settings controls whether this filtering is active and what happens for untagged alerts (untagged_alert_behavior, optional default_tag_id fallback). Tag access enforcement location (code pointers)
  • Core tag RBAC logic: backend/app/incidents/middleware/tag_access.py (TagAccessHandler)
    • is_tag_rbac_enabled() (global enable/disable)
    • build_alert_query_filters() (computes accessible tags + untagged behavior)
    • check_alert_tag_access() / can_user_access_alert() (per-alert decision)
  • Applied in incident DB query layer:
    • backend/app/incidents/services/db_operations.py uses tag_access_handler.build_alert_query_filters() to add SQL exists() conditions when counting/listing alerts.

SIEM data origin + query pattern

  • Graylog alerting uses the gl-events index pattern (for example gl-events* in query flows).
  • Those Graylog alert documents live in Wazuh indexer storage (OpenSearch-backed).
  • Wazuh indexer is the backing SIEM event store across event sources (endpoints, O365 integrations, network connectors, and other ingested streams).
  • CoPilot commonly resolves and displays SIEM records by querying Wazuh indexer with index_name plus index_id.
  • Code pointers:
    • backend/app/connectors/wazuh_indexer/routes/alerts.py
    • backend/app/connectors/wazuh_indexer/services/alerts.py
    • backend/app/routers/wazuh_indexer.py
    • frontend/src/api/endpoints/alerts.ts

Table Inventory (Alembic-Derived)

Customer, Auth, and Core Platform

Agents, Vulnerability, and Artifact/Data Store

Scheduler and Job Metadata

Connectors and Integrations

Incident Management (Alerts, Cases, Tags, Comments)

GitHub Audit (Added at Head)

Quick Model Scan: Tables Not Obvious From Alembic

The following SQLModel tables are defined in code but do not appear in backend/alembic/versions/*.py migrations. Treat them as drift candidates / runtime-created tables unless there is an out-of-band migration process.

Where To Change Schema

Source of truth locations

  • Alembic migrations: backend/alembic/versions/
  • Alembic env/config: backend/alembic/env.py
  • SQLModel definitions commonly touched:
    • backend/app/db/universal_models.py
    • backend/app/incidents/models.py
    • backend/app/auth/models/users.py
    • backend/app/network_connectors/models/network_connectors.py
    • backend/app/integrations/models/customer_integration_settings.py

Practical workflow

  1. Update or add SQLModel fields/classes in the relevant model file.
  2. Generate a migration under backend/alembic/versions/ (or author manually if needed).
  3. Review migration upgrade() and downgrade() carefully (FK names, nullable transitions, indexes).
  4. Apply migration locally and run tests.
  5. Update this document if table shape/ownership changes.

Notes for agent changes

  • Prefer extending existing domain tables over creating parallel tables when possible (especially incidents and connector metadata).
  • For incident workflows, changes usually involve: incident_management_alert, incident_management_case, link tables (*_to_*), and optional datastore tables.
  • For connector onboarding, changes usually involve: available_*, customer_*, *_services, *_subscriptions, *_configs, *_keys, and *_meta tables.
  • For scheduler automation, coordinate changes between scheduled_job_metadata, schedulerjob, and domain-specific tables storing job outcomes.