opentide

Platforms

opentide ships eight detection platform integrations. Each platform has bundled TOML configuration, a deployer, an optional query validator, and a typed rule block under `configurations.<platform>`.

The block's schema identifier is platform::<identifier>::1.0. This page is the capability matrix and the shared block. The field contract for each block is its own spec:

IdentifierSchemaSpec
sentinelplatform::sentinel::1.0sentinel-1.0.md
defender_for_endpointplatform::defender_for_endpoint::1.0defender-for-endpoint-1.0.md
splunkplatform::splunk::1.0splunk-1.0.md
sentinel_oneplatform::sentinel_one::1.0sentinel-one-1.0.md
carbon_black_cloudplatform::carbon_black_cloud::1.0carbon-black-cloud-1.0.md
crowdstrikeplatform::crowdstrike::1.0crowdstrike-1.0.md
harfanglabplatform::harfanglab::1.0harfanglab-1.0.md
elasticplatform::elastic::1.0elastic-1.0.md

These specs describe the blocks as the engine accepts them today, including every optional key. Generated JSON Schema is a build artifact. Where it disagrees with this page or a platform spec, the spec wins. opentide's usage and SDK pages link here. They do not restate the keys. Change a field here first; the implementation follows.

Requirements

  • Platform identifiers MUST use the keys in the capability matrix (snake_case).
  • A platform MUST be marked enabled: true in merged configuration to appear in enabled_systems().
  • Deploy and validate capabilities MUST be reported honestly. A platform without a query validator MUST NOT claim query validation support.
  • CrowdStrike and HarfangLab MUST NOT advertise query validation (can_validate: false).
  • A typed block SHOULD set schema to platform::<identifier>::1.0. Implementations MUST accept a missing schema and MUST accept a legacy identifier (sentinel::2.4, splunk::2.0, splunk::3.0, carbon_black_cloud::3.0, and the same shape for the other platforms). The identifier is not a closed enum.
  • Unknown keys on a block MUST fail static validation. The model forbids them.
  • A block MUST NOT carry a vendor-assigned external id. rule_id, rule_id_bundle, and rule_id::<tenant> at the root of any block, on every platform, MUST fail with external_id_in_rule (External rule ids).
  • Registry load is stricter or looser depending on the platform. Defender, Splunk, Carbon Black, and Elastic pass leftover keys on the block into the model, so an unknown key at the block root fails load as well. The Splunk loader still drops unknown keys inside scheduling other than type, expires, schedule, and timerange. Sentinel, SentinelOne, CrowdStrike, and HarfangLab drop keys the loader does not map, so those keys pass load and fail opentide validate. The Splunk aliases and Defender's quarantine_files alias are mapped before that check.
  • In every field table, optional means the key may be omitted at static validation. A later sentence in that platform spec names the keys deploy or registry load still require.
  • query, where the platform spec marks it required, MUST be a string and MUST NOT be empty or whitespace.
  • Static validation (opentide validate) MUST enforce the Required column of each platform spec. It MUST NOT require a field only because generated JSON Schema lists it.
  • A successful deploy MUST also satisfy that platform spec's Deploy section. Those checks are not static-validation failures.

Three checks, three bars. Static validation parses the YAML with the platform model. Registry load parses it again through the platform loader before a rule can be deployed. Deploy then applies vendor constraints (a Sentinel rule with no grouping validates and fails at deploy). Each platform spec separates those bars. A field marked optional is optional for opentide validate.

Definition

Platform capability matrix

IdentifierDisplay nameDeployQuery validateDetection languageSchema spec
sentinelMicrosoft Sentinelyes*yesKQLsentinel-1.0
defender_for_endpointMicrosoft Defender for Endpointyes*yesKQLdefender-for-endpoint-1.0
splunkSplunkyesyesSPLsplunk-1.0
sentinel_oneSentinelOneyes*yesS1QLsentinel-one-1.0
carbon_black_cloudVMware Carbon Black CloudyesyesLucenecarbon-black-cloud-1.0
crowdstrikeCrowdStrike Falconyes*nocorrelation filtercrowdstrike-1.0
harfanglabHarfangLabyes*noSigma or YARAharfanglab-1.0
elasticElastic Securityyes*yes†KQL, Lucene, EQL, or ES|QL, chosen by the block's type and languageelastic-1.0

* Deploy requires a loaded deployer entry point and enabled: true in workspace configuration.

† Live only, through Kibana rule preview (/api/detection_engine/rules/preview) plus the Elasticsearch checks, against a tenant, for every language the block can carry. Elastic has no offline syntax check (elastic-1.0).

Query validation platforms

opentide validate query supports:

sentinel, defender_for_endpoint, splunk, sentinel_one, carbon_black_cloud, elastic

Query validation is a tenant check on every platform in this allowlist: opentide validate query --live. Without --live the command refuses and names --live.

Excluded: crowdstrike, harfanglab. Implementations MUST report supported: false for those two and MUST NOT invent a passing result.

What a block must contain to validate

This is the static-validation bar. Deploy adds the constraints in each platform spec.

PlatformRequired when the block is present
sentinelquery, scheduling, alert
defender_for_endpointquery, alert (with category), impacted_entities, scheduling
splunkquery, or legacy search which fills query
sentinel_onecondition (with type)
carbon_black_cloudquery
crowdstrikedetails (with trigger and outcome), schedule (with frequency and lookback), query
harfanglabno platform field is required; maturity, confidence, and action have defaults. Deploy requires sigma or yara
elastictype, status, and query (except for machine_learning), plus the type object: threshold, new_terms, threat, or machine_learning for those types. Every block also meets the Elastic constraints

Shared platform block

Every block includes these fields. Platform specs do not repeat them except where deploy treats one differently.

FieldYAML keyTypeRequiredDefaultDescription
enabledenabledbooleanoptionalfalseWhen true, the block is active for deploy. A rule with no enabled block is still valid.
namenamestringoptional""Platform-specific rule name. Empty means the deployer uses the rule name, where that platform has a name field.
platform_schemaschemastringoptionalnullSchema identifier. Canonical value: platform::<identifier>::1.0. Templates emit it. Validation does not require it.
statusstatusstringoptionalnullDeployment status for this block. When set, it MUST be a status name from deployment.md. DISABLEMENT disables an existing rule; DELETION removes it. Other strategies deploy it enabled. Required on elastic (elastic-1.0).
flagsflagslist[string]optionalnullFree-form flags. Splunk modifiers may match on them.
tenantstenantslist[string]optionalnullTenant names this block targets. Empty or omitted means every tenant the run reaches.
contributorscontributorslist[string]optionalnullPeople credited on the platform rule. CrowdStrike joins them into the rule comment.

schema is the YAML key. The model field is platform_schema because schema would collide with the base model's schema method.

Platform configuration location

Workspace TOML enables a platform and holds tenant credentials. It is not the rule block.

LocationPurpose
opentide/data/configurations/platforms/<id>.tomlBundled defaults
.opentide/configurations/platforms/<id>.tomlClient override
[platform]
enabled = false
identifier = "sentinel"
name = "Microsoft Sentinel"
description = "Microsoft Sentinel analytics rules"
flags = []

All bundled platforms default to enabled = false. Enable one by setting enabled = true under [platform]. Tenant tables, modifiers, and secrets live in the same file and are configuration, not part of platform::<identifier>::1.0.

External rule ids

Platform blocks MUST NOT contain vendor-assigned external identifiers. Defender for Endpoint, SentinelOne, and CrowdStrike use the committed deployment-state shard defined in deployment-state.md. Sentinel, HarfangLab, and Elastic use metadata.uuid; Carbon Black Cloud uses metadata.uuid for the IOC and the title for the report; Splunk uses its saved-search identity.

PlatformHow deploy addresses the remote ruleWhere a vendor id lives
sentinelmetadata.uuid is the analytics rule idNowhere
defender_for_endpointDefender-assigned rule id.opentide/states/deployment/<uuid>.json
splunkThe saved searchNowhere
sentinel_oneSentinelOne-assigned STAR rule id.opentide/states/deployment/<uuid>.json
carbon_black_cloudmetadata.uuid on the IOC; title on the reportNowhere
crowdstrikeCrowdStrike-assigned correlation rule id.opentide/states/deployment/<uuid>.json
harfanglabmetadata.uuid on the Sigma rule and the YARA meta idNowhere
elasticmetadata.uuid is the Kibana rule_id, in every tenant and spaceNowhere

Elastic Security (elastic-1.0, RFC 0007) addresses every rule by metadata.uuid. Elastic never stores an external id: Kibana's internal id is not recorded in a block or in deployment state.

rule_id, rule_id_bundle, and rule_id::<tenant> are legacy keys from before RFC 0010. Static validation and every deploy path MUST reject them with external_id_in_rule, on every platform block, whether or not a shard also holds the id. No loader folds them into a field. opentide deploy migrate-state moves Defender, SentinelOne, and CrowdStrike values into shards and removes the keys from every other platform with an external_id_unused warning.

Defender also accepts the alias quarantine_files for actions.files.quarantine_file on the loader path only.

Generated schema drift

Published JSON Schema is built from the models plus a required overlay. The overlay currently names fields the model does not require:

PlatformOverlay required beyond the model
every platformstatus
sentinelgrouping, entities
splunkscheduling

opentide validate follows the model, not the overlay. A Sentinel block without grouping validates. Deploy of that block fails. Editor validation that consumes the generated schema may reject objects the engine accepts.

The same overlay sets a default for schema that is the legacy identifier. The model default is null, and the bundled templates write platform::<identifier>::1.0. Validation accepts both. Splunk, Carbon Black, and Elastic also set a pattern that only matches the legacy identifier shape (^splunk::[1-9]\.[0-9]$, ^carbon_black_cloud::[1-9]\.[0-9]$, ^elastic::[1-9]\.[0-9]$). That pattern rejects platform::splunk::1.0, platform::carbon_black_cloud::1.0, and platform::elastic::1.0. opentide validate does not apply it. Elastic has no legacy identifier, so its generated default elastic::1.0 names no schema that ever existed.

Splunk extras also name threshold, throttling, and security_domain on the block root, and cron and lookback directly under scheduling. Those properties are not on the model. The generator skips an extra whose property is missing. The live keys are the nested ones in splunk-1.0.md.

PlatformGenerated default schema
sentinelsentinel::2.4
defender_for_endpointdefender_for_endpoint::2.3
splunksplunk::3.0
sentinel_onesentinel_one::2.0
crowdstrikecrowdstrike::2.0
harfanglabharfanglab::2.0
carbon_black_cloudcarbon_black_cloud::3.0
elasticelastic::1.0

Entry points

Deployers register via opentide.platforms entry points. Validators load from opentide.validation.<platform>_query when the platform supports query validation.

Relationships

Defaults & overrides

SettingDefaultOverride
Platform enabledfalse in bundled TOML.opentide/configurations/platforms/<id>.toml
Block enabledfalsePer-block YAML
Block statusnull (rule-level status still applies to the rule). Required on elastic, with no default.Per-block YAML
Block schemaomittedTemplates write platform::<identifier>::1.0

Vocabulary files are not platform configuration. See configuration.md.

Examples

History

VersionDateNotes
1.32026-10-20Block tenants: omitted means every tenant the run reaches; opentide 0.17.0 removed deployment plans.
1.02026-06-25Initial matrix for seven bundled platforms
1.02026-09-30Field contracts moved to per-platform specs. Static validation, registry load, and deploy are specified separately. Generated JSON Schema is no longer described as the field contract.
1.12026-10-16Platform blocks carry no external ids. rule_id, rule_id_bundle, and the rule_id::<tenant> loader alias are removed from every block and fail external_id_in_rule; Defender, SentinelOne, and CrowdStrike ids live in deployment state (RFC 0010). Elastic is recorded as addressed by metadata.uuid with no stored id. Platform schema_ids stay ::1.0.
1.22026-10-19Elastic Security joins the matrix as the eighth platform (elastic-1.0, RFC 0007): capability row (deploy; live query validation through Kibana rule preview for KQL, Lucene, EQL, and ES|QL), query-validation allowlist, static-validation bar, metadata.uuid identity with no stored id, and its generated-schema pattern. validate query is a tenant check on every platform in the query-validation allowlist (--live).

On this page