opentide

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.

FieldDescription
nameRegistry key (e.g. defender_for_endpoint)
enabledWhether platform is active in client config
configLoaded platform configuration, built on first access
deployerRule deployer instance or None, built on first access
validatorQuery validator instance or None, built on first access
can_deployProperty — the platform declares a deployer (does not build it)
can_validateProperty — the platform declares a validator (does not build it)

Query validators

Six platforms register validators (see QUERY_VALIDATION_PLATFORMS in opentide.cli.enums):

  • sentinel → KQL
  • defender_for_endpoint → KQL
  • splunk → SPL
  • sentinel_one → S1QL
  • carbon_black_cloud → Lucene
  • elastic → 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_validate

Honesty 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

On this page