docs/ref/modules/sca/database-schema.md
The SCA module uses SQLite database to store policy metadata and check results. The database maintains the state of security configuration assessments and enables change detection between scans.
The schema according to the Wazuh Common Schema (WCS) is available in src/external/indexer-plugins and is downloaded during the agent build process as part of external dependencies (make deps):
sca.jsonThis schema defines the standardized format for SCA data that is sent to the Wazuh indexer.
CREATE TABLE IF NOT EXISTS sca_policy (
id TEXT PRIMARY KEY,
name TEXT,
file TEXT,
description TEXT,
refs TEXT
);
This table stores data for each security policy used in the SCA module, including its unique ID, name, source file, description, and external references.
| Mandatory | Column | Data Type | Description | ECS Mapping | ECS Data Type |
|---|---|---|---|---|---|
| ✔️ | id | TEXT | Unique identifier of the policy | policy.id | keyword |
name | TEXT | Human-readable name of the policy | policy.name | keyword | |
file | TEXT | Path to the policy definition file | policy.file | keyword | |
description | TEXT | Description of the policy purpose and content | policy.description | text | |
refs | TEXT | External references related to the policy (e.g. CIS) | policy.references | keyword |
Indexes:
id for fast policy lookupsfile for policy file trackingExample Data:
INSERT INTO sca_policy VALUES (
'cis_debian10',
'CIS Debian Linux 10 Benchmark v1.0.0',
'etc/shared/cis_debian10.yml',
'This document provides prescriptive guidance for establishing a secure configuration posture for Debian Linux 10',
'https://www.cisecurity.org/cis-benchmarks/'
);
CREATE TABLE IF NOT EXISTS sca_check (
checksum TEXT NOT NULL,
id TEXT PRIMARY KEY,
policy_id TEXT REFERENCES sca_policy(id),
name TEXT,
description TEXT,
rationale TEXT,
remediation TEXT,
refs TEXT,
result TEXT DEFAULT 'Not run',
reason TEXT,
condition TEXT,
compliance TEXT,
mitre TEXT,
rules TEXT,
regex_type TEXT DEFAULT 'pcre2',
version INTEGER NOT NULL DEFAULT 1,
sync INTEGER NOT NULL DEFAULT 0
);
This table stores individual checks associated with a policy. Each check includes metadata, logic conditions, rules to be evaluated, and tracking fields for results and compliance.
| Mandatory | Column | Data Type | Description | ECS Mapping | ECS Data Type |
|---|---|---|---|---|---|
| ✔️ | checksum | TEXT | SHA1 checksum of the check data used for synchronization | checksum.hash.sha1 | keyword |
| ✔️ | id | TEXT | Unique identifier of the check | check.id | keyword |
| ✔️ | policy_id | TEXT | Reference to the associated policy ID | policy.id | keyword |
name | TEXT | Short name summarizing the check | check.name | keyword | |
description | TEXT | Detailed explanation of what the check evaluates | check.description | text | |
rationale | TEXT | Justification or reason behind the check | check.rationale | text | |
remediation | TEXT | Instructions for correcting a failed check | check.remediation | text | |
refs | TEXT | External references related to the check | check.references | keyword | |
result | TEXT | Current evaluation result (Passed, Failed, Not run, Not applicable) | check.result | keyword | |
reason | TEXT | Explanation for the check's result | check.reason | text | |
condition | TEXT | Logical condition under which the check applies (all, any, none) | check.condition | keyword | |
compliance | TEXT | JSON-serialized compliance object (see Compliance format) | check.compliance.* | keyword | |
mitre | TEXT | JSON-serialized MITRE ATT&CK object (see MITRE format) | check.mitre.* | keyword | |
rules | TEXT | Serialized rule(s) logic used to perform the actual check | check.rules | text | |
regex_type | TEXT | Internal regex engine identifier for rule evaluation | N/A | N/A | |
| ✔️ | version | INTEGER | Monotonic version for stateful synchronization | state.document_version | long |
| ✔️ | sync | INTEGER | Internal sync flag (1 = synced, 0 = local-only) | N/A | N/A |
Indexes:
id for fast check lookupspolicy_id for policy-check relationshipsresult for filtering by check status(policy_id, result) for policy-specific result queriesResult Values:
Not run: Check has not been executed yetPassed: Check passed successfullyFailed: Check failedNot applicable: Check is not applicable to this systemThe compliance column stores a JSON-serialized object that maps compliance framework keys to arrays of identifier strings. Only the following keys are allowed:
cmmc, fedramp, gdpr, hipaa, iso_27001, nis2, nist_800_171, nist_800_53, pci_dss, tsc
Unknown keys are rejected with a warning during policy parsing and excluded from the stored value.
The mitre column stores a JSON-serialized object that maps MITRE ATT&CK categories to arrays of identifier strings. The following keys are supported:
tactic, technique, subtechnique, mitigation
Example Data:
INSERT INTO sca_check (checksum, id, policy_id, name, description, rationale, remediation, refs, result, reason,
condition, compliance, mitre, rules, regex_type, version, sync)
VALUES (
'f1e2d3c4b5a697887766554433221100aabbccdd',
'5501',
'cis_debian10',
'Ensure permissions on /etc/ssh/sshd_config are configured',
'The /etc/ssh/sshd_config file contains configuration specifications for sshd',
'The /etc/ssh/sshd_config file needs to be protected from unauthorized changes',
'Run: chmod og-rwx /etc/ssh/sshd_config',
'https://www.cisecurity.org',
'Passed',
NULL,
'all',
'{"pci_dss":["5.2.1"],"nist_800_53":["14.6"]}',
'{"tactic":["TA0005"],"technique":["T1548"]}',
'[{"type":"file","path":"/etc/ssh/sshd_config","permissions":"600"}]',
'pcre2',
1,
1
);
sca_check.policy_id references sca_policy.idCREATE TABLE IF NOT EXISTS sca_metadata (
key TEXT PRIMARY KEY,
value INTEGER
);
This table stores module-level metadata for tracking operational state, such as the last integrity check timestamp.
| Mandatory | Column | Data Type | Description |
|---|---|---|---|
| ✔️ | key | TEXT | Unique identifier for the metadata entry |
value | INTEGER | Numeric value associated with the key |
Current Keys:
last_integrity_check: Unix timestamp (seconds since epoch) of the last integrity checkExample Data:
INSERT INTO sca_metadata VALUES ('last_integrity_check', 1733316000);
The database enables change detection by: