-
Notifications
You must be signed in to change notification settings - Fork 1
OpenGraph Plugins
OpenGraph-backed checks normally need two pieces:
- A datasource availability gate in
datasources/<name>.py. - One or more checks that declare
requires=["<name>"].
from checks.core import DataSource, datasource
@datasource("example_platform")
class ExamplePlatformAvailability(DataSource):
def available(self):
rows = self.query(
"MATCH (n:Example_PluginNode) RETURN count(n) AS c",
name="example_platform_availability",
)
return rows[0]["c"] > 0 if rows else Falsefrom checks.core import Check, check
@check(risk="Medium", category="Example Platform Exposure",
entity="computer", data=[], requires=["example_platform"])
class ExamplePlatformExposureCheck(Check):
def execute(self):
rows = self.query("""
MATCH (c:Computer)-[:Example_PluginEdge]->(target)
RETURN c.objectid AS sid, target.name AS target
""", name="example_platform_exposure")
return {
row["sid"]: self.finding(f"Plugin edge to {row['target']}")
for row in rows
if row.get("sid")
}The importer has explicit handling for MSSQLHound and ConfigManBearPig data: it orders seed data before plugin data, injects the ConfigManBearPig SCCM seed when needed, preserves SharpHound-owned AD properties, merges duplicate OpenGraph AD principal stubs back onto the real AD nodes, and links older MSSQLHound server nodes to their host computers.
New OpenGraph plugins are not fully automatic. Include any required seed or type-registration data before relationship data, keep AD principal objectid values SID-based where possible, avoid overwriting SharpHound AD properties, and add a datasource gate so checks are skipped when the plugin data is absent. If the plugin emits duplicate AD principal nodes, add importer handling or model relationships so traversal starts from the existing User, Computer, or Group nodes.