Edge

bhopengraph.Edge.validate_kind(kind)[source]

Validate an OpenGraph edge kind.

A valid edge kind is non-empty, matches ^[A-Za-z0-9_]+$ (no spaces, dashes, or punctuation), and does not use the reserved tag_ prefix (in any letter case).

Source: https://bloodhound.specterops.io/opengraph/developer/edges

Parameters:

kind (-) – The edge kind to validate

Returns:

An error message if the kind is invalid, otherwise None

Return type:

  • str | None

class bhopengraph.Edge.PropertyMatcher(key, value, operator='equals')[source]

Bases: object

A single property-based match criterion, used when an edge endpoint’s match strategy is property.

Matcher values are restricted to primitives (string, number, boolean) by the schema. Multiple matchers on an endpoint are AND-combined. Only the equals operator is currently supported by BloodHound.

Source: https://bloodhound.specterops.io/opengraph/developer/edges

Parameters:
__init__(key, value, operator='equals')[source]

Initialize a PropertyMatcher.

Parameters:
  • key (-) – The property name to match against

  • value (-) – The value to compare against (must be a primitive)

  • operator (-) – The comparison operator (defaults to “equals”)

validate()[source]

Validate the property matcher.

Returns:

(is_valid, list_of_errors)

Return type:

  • tuple[bool, list[str]]

to_dict()[source]

Convert the matcher to a dictionary for JSON serialization.

Returns:

Matcher as {“key”: …, “operator”: …, “value”: …}

Return type:

  • dict

class bhopengraph.Edge.Endpoint(match_by='id', value='', kind='', property_matchers=None)[source]

Bases: object

Identifies the start or end of an edge and describes how BloodHound should resolve it to a node.

An endpoint can be resolved by node id (the default and preferred strategy), by name (deprecated but still accepted), or dynamically by property matchers. An optional kind filter constrains the matched node to a specific kind; it is strongly recommended when matching by name or property to avoid attaching the edge to the wrong node on a name collision.

Source: https://bloodhound.specterops.io/opengraph/developer/edges

Parameters:
__init__(match_by='id', value='', kind='', property_matchers=None)[source]

Initialize an Endpoint.

Prefer the by_id, by_name, and by_property constructors for clarity.

Parameters:
  • match_by (-) – One of “id”, “name”, or “property”

  • value (-) – The id or name value (for “id”/”name” strategies)

  • kind (-) – Optional kind filter

  • property_matchers (-) – PropertyMatcher list (for “property”)

classmethod by_id(value)[source]

Create an endpoint resolved by node id.

Parameters:

value (str)

Return type:

Endpoint

classmethod by_name(value, kind='')[source]

Create an endpoint resolved by name. kind is optional and disambiguates the kind of the target node.

Parameters:
Return type:

Endpoint

classmethod by_property(property_matchers, kind='')[source]

Create an endpoint resolved by property matchers. kind is optional.

Parameters:
  • property_matchers (list)

  • kind (str)

Return type:

Endpoint

validate()[source]

Validate the endpoint for internal consistency with its match strategy.

Returns:

(is_valid, list_of_errors)

Return type:

  • tuple[bool, list[str]]

to_dict()[source]

Convert the endpoint to a dictionary for JSON serialization, matching the shape BloodHound expects for the endpoint’s match strategy.

Returns:

Endpoint as a dictionary

Return type:

  • dict

classmethod from_dict(data)[source]

Create an Endpoint from a dictionary (typically parsed from JSON).

Defaults to id matching when match_by is omitted.

Parameters:

data (-) – Dictionary containing endpoint data

Returns:

Endpoint instance

Return type:

  • Endpoint

signature()[source]

Return a hashable signature uniquely identifying this endpoint, used for edge equality and deduplication.

Returns:

A hashable representation of the endpoint

Return type:

  • tuple

class bhopengraph.Edge.Edge(start_node, end_node, kind, properties=None, start_match_by='id', end_match_by='id')[source]

Bases: object

Edge class representing a directed edge in the OpenGraph.

Follows BloodHound OpenGraph schema requirements with start/end endpoints, kind, and properties. All edges are directed and one-way as per BloodHound requirements.

Sources: - https://bloodhound.specterops.io/opengraph/developer/edges - https://bloodhound.specterops.io/opengraph/developer/graph-data

Parameters:
__init__(start_node, end_node, kind, properties=None, start_match_by='id', end_match_by='id')[source]

Initialize an Edge whose endpoints are resolved by id or name.

For property-based matching or kind filters on endpoints, use the with_endpoints constructor.

Parameters:
  • start_node (-) – Value of the source endpoint (id or name)

  • end_node (-) – Value of the destination endpoint (id or name)

  • kind (-) – Type/class of the edge relationship

  • properties (-) – Edge properties

  • start_match_by (-) – “id” (default) or “name”

  • end_match_by (-) – “id” (default) or “name”

classmethod with_endpoints(start, end, kind, properties=None)[source]

Create an Edge from explicit endpoints, allowing any match strategy for either end (id, name, or property).

Parameters:
  • start (-) – The source endpoint

  • end (-) – The destination endpoint

  • kind (-) – Type/class of the edge relationship

  • properties (-) – Edge properties

Returns:

A new Edge instance

Return type:

  • Edge

property start_node: str
property end_node: str
property start_match_by: str
property end_match_by: str
set_property(key, value)[source]

Set a property on the edge.

Parameters:
  • key (-) – Property name

  • value (-) – Property value

get_property(key, default=None)[source]

Get a property from the edge.

Parameters:
  • key (-) – Property name

  • default (-) – Default value if property doesn’t exist

Returns:

  • Property value or default

remove_property(key)[source]

Remove a property from the edge.

Parameters:

key (-) – Property name to remove

to_dict()[source]

Convert edge to dictionary for JSON serialization.

Returns:

Edge as dictionary following BloodHound OpenGraph schema

Return type:

  • dict

classmethod from_dict(edge_data)[source]

Create an Edge instance from a dictionary.

Parameters:

edge_data (-) – Dictionary containing edge data

Returns:

Edge instance or None if data is invalid

Return type:

  • Edge

get_start_node()[source]

Get the start endpoint value (the id or name; empty for property-matched endpoints).

Returns:

Start endpoint value

Return type:

  • str

get_end_node()[source]

Get the end endpoint value (the id or name; empty for property-matched endpoints).

Returns:

End endpoint value

Return type:

  • str

get_kind()[source]

Get the edge kind/type.

Returns:

Edge kind

Return type:

  • str

get_unique_id()[source]

Get a unique ID for the edge.

Returns:

Unique ID for the edge

Return type:

  • str

__eq__(other)[source]

Check if two edges are equal based on their endpoints and kind.

Parameters:

other (-) – The other edge to compare to

Returns:

True if the edges are equal, False otherwise

Return type:

  • bool

__hash__()[source]

Hash based on endpoints and kind for use in sets and as dictionary keys.

Returns:

Hash of the endpoints and kind

Return type:

  • int

validate()[source]

Validate the edge against the EDGE_SCHEMA.

Returns:

(is_valid, list_of_errors)

Return type:

  • tuple[bool, list[str]]