Platforms API
Platform registry, entry-point plugins, deployers, and query validators.
Platforms register through setuptools entry points in pyproject.toml:
[project.entry-points."opentide.platforms"]
sentinel = "opentide.platforms.sentinel:declare"
splunk = "opentide.platforms.splunk:declare"
# …PlatformsRegistry
from opentide import Opentide
Opentide.initialise()
for name, platform in Opentide.Platforms.items():
print(name, platform.enabled, platform.can_deploy, platform.can_validate)Platform
config, deployer and validator are built the first time they are read. Listing platforms (opentide info, the MCP platforms resource) therefore never builds a client or reads the tenant configuration of a platform you do not use.
| Field | Description |
|---|---|
name | Registry key (e.g. defender_for_endpoint) |
enabled | Whether platform is active in client config |
config | Loaded platform configuration, built on first access |
deployer | Rule deployer instance or None, built on first access |
validator | Query validator instance or None, built on first access |
can_deploy | Property — the platform declares a deployer (does not build it) |
can_validate | Property — the platform declares a validator (does not build it) |
Query validators
Six platforms register validators (see QUERY_VALIDATION_PLATFORMS in opentide.cli.enums):
sentinel→ KQLdefender_for_endpoint→ KQLsplunk→ SPLsentinel_one→ S1QLcarbon_black_cloud→ Luceneelastic→ Kuery, Lucene, EQL, ES|QL (live tenant check only)
CrowdStrike and HarfangLab have deployers only.
Rule deployment
rule = Opentide.Rules[uuid]
result = rule.deploy("sentinel", dry_run=True)
print(result.dry_run, result.message)Plugin declaration
Each platform module exposes declare() returning deployer/validator factories. Client enablement is read from .opentide/configurations/platforms/.
Authoring a custom platform plugin
You can add support for a platform opentide does not ship by publishing a small package that registers an opentide.platforms entry point. At a high level:
Implement a declare()
Expose a declare() callable in your module that returns the platform's deployer and (optionally) query validator factories. Return only a deployer if the platform cannot validate queries — never return a validator that fakes success.
# my_opentide_acme/__init__.py
def declare():
from .deployer import AcmeDeployer
return {
"identifier": "acme",
"name": "Acme SIEM",
"deployer": AcmeDeployer, # required for deploy support
"validator": None, # None → can_validate is False
}Register the entry point
In your package's pyproject.toml:
[project.entry-points."opentide.platforms"]
acme = "my_opentide_acme:declare"Install the package into the same environment as opentide; the registry discovers it at Opentide.initialise().
Provide a rule configuration model
Define the typed block that appears under configurations.acme in rule YAML, following the shared platform-block fields from rule-1.0 plus your platform's query fields. Declare its schema id as platform::acme::1.0.
Verify
Opentide.initialise()
plat = Opentide.Platforms["acme"]
assert plat.can_deploy and not plat.can_validateHonesty is a hard requirement: a platform with no real query validator MUST report can_validate=False (return validator=None). Do not return a validator that always passes — the CLI and MCP rely on this flag to avoid claiming false coverage.
Capability matrix
Human-readable table and the fields each block must contain: Usage: Platforms. The normative field contracts are the platform specs (platform::<identifier>::1.0). Python models are listed on Models.
Source
src/opentide/platforms/registry.py, src/opentide/platforms/plugins.py