Skip to content

Repository files navigation

og - OpenGraph JSON Builder

og (short for OpenGraph) is a command-line tool that builds BloodHound-compatible OpenGraph JSON from structured graph inputs:

  • CSV files containing nodes and edges
  • graphify knowledge graphs (graph.json), converted directly with no intermediate CSV

Both input types can be mixed in a single run and share one ID space, so a graphify code graph can be enriched with hand-written CSV nodes and edges in one pass.

Built using the gopengraph library for BloodHound OpenGraph compatibility.

Features

  • Multiple input methods: Read from stdin (pipeline) or specify files via command-line arguments
  • Automatic CSV detection: Automatically recognizes node CSVs (with id and kinds columns) and edge CSVs (with start, end, and kind columns)
  • graphify import: Convert a graphify knowledge-graph graph.json straight to OpenGraph (-g/--graphify)
  • Multiple file support: Process multiple CSV and/or graphify files in a single run
  • Optional source_kind: Add a source_kind to the metadata when needed
  • Built with gopengraph: Leverages the official BloodHound gopengraph library

Installation

go build -o og

Usage

Basic Usage

Process CSV files via pipeline:

cat nodes.csv edges.csv | og > output.json

Piped stdin is read as CSV automatically only when no input flags are given. Once any -c/--csv or -g/--graphify flag is present, stdin is consumed only where an explicit - appears — so scripted runs never block on an idle inherited pipe.

Process CSV files via command-line arguments:

og -c nodes.csv -c edges.csv > output.json
og --csv nodes.csv --csv edges.csv > output.json

With source_kind

Add a source_kind to the metadata:

cat nodes.csv edges.csv | og -s MyDataSource > output.json
cat nodes.csv edges.csv | og --source_kind MyDataSource > output.json

Example Use Case

cat nodes1.csv nodes2.csv edges1.csv edges2.csv | og > opengraph.json

CSV Format

Node CSV Format

Node CSVs must have at minimum:

  • id: Unique identifier for the node
  • kinds: Node types (comma-separated for multiple kinds)

Additional columns become node properties.

Example:

id,kinds,displayname,email
user-001,User,Alice Smith,alice@example.com
dept-001,"Department,OrgUnit",Engineering,IT

Edge CSV Format

Edge CSVs must have:

  • start: ID of the start node
  • end: ID of the end node
  • kind: Type of the relationship

Additional columns become edge properties.

Note: All edges use match_by: "id" in the OpenGraph output, meaning they reference nodes by their ID field.

Example:

start,end,kind,since
user-001,dept-001,MemberOf,2020-01-15

This produces edges that reference nodes by ID:

{
  "start": {
    "match_by": "id",
    "value": "user-001"
  },
  "end": {
    "match_by": "id",
    "value": "dept-001"
  },
  "kind": "MemberOf",
  "properties": {
    "since": "2020-01-15"
  }
}

graphify Input

graphify builds a code/knowledge graph and writes a graph.json. og can convert that file directly to OpenGraph — no intermediate CSV needed:

og -g graphify-out/graph.json -s Graphify > opengraph.json
og --graphify graph.json --source_kind Graphify > opengraph.json
cat graph.json | og -g - -s Graphify > opengraph.json      # '-' reads JSON from stdin

You can mix graphify and CSV inputs in one run (IDs are shared across both). When any -c/-g flag is present, stdin is only read on an explicit -:

cat extra_nodes.csv | og -g graph.json -c - -c more_edges.csv -s Combined > opengraph.json

Generate a graph.json with graphify first (code-only extraction needs no API key):

graphify extract ./your-repo --code-only     # local AST, deterministic, no LLM

Mapping

The converter is schema-tolerant: it accepts both graphify writers (edges under links or edges), the {"graph": {...}} wrapper, and the common field-name variants (src/dst, name-as-id, cluster, weight, object-valued endpoints, …).

Nodes → OpenGraph nodes:

OpenGraph Source
id graphify node id (id/node_id/name/…); colons are replaced with _ — BloodHound does not support colons in object ids
kinds a single classified kind, inferred from node_type and label/file heuristics (e.g. Class, Endpoint, Entrypoint, Concept, Function)
properties name, displayname, source_file, community, node_type, file_type, kind_heuristic, plus any extra scalar fields (numbers/bools preserved). BloodHound-reserved property names (objectid, ref) are never emitted

Emitting a single classified kind is deliberate: gopengraph appends the import-wide source_kind (-s) to every node on export, so each node ends up with at most two kinds — within the cap that cogs enforces. That means graphify output merges cleanly:

og -g graph.json -s Graphify | cogs -j other-source.json -s Combined > merged.json

Edges → OpenGraph edges:

OpenGraph Source
kind PascalCased relation (callsCalls, imports_fromImportsFrom)
start / end node ids, match_by: "id"
properties relation, confidence, confidence_score, include (graphify's confidence filter: EXTRACTED, or INFERRED ≥ 0.85), plus extra scalar fields

No edges are dropped — low-confidence ones are kept with include: false. A source_kind (-s) is folded into every node's kinds so the whole import can be filtered or deleted as a unit in BloodHound.

Output Format

The tool generates BloodHound-compatible OpenGraph JSON with the following structure:

{
  "graph": {
    "nodes": [...],
    "edges": [...]
  },
  "metadata": {
    "source_kind": "..." // Only included if --source_kind/-s is provided
  }
}

Testing

Run the test suite:

go test -v

Test with sample data:

cat testdata/nodes1.csv testdata/nodes2.csv testdata/edges1.csv testdata/edges2.csv | ./og -s ExampleSource

Command-line Options

  • -c, --csv: CSV file to process (can be specified multiple times; - reads CSV from stdin)
  • -g, --graphify: graphify graph.json to convert (can be specified multiple times; - reads JSON from stdin)
  • -s, --source_kind: Source kind for the OpenGraph metadata (optional)

Examples

See the testdata/ directory for example CSV files:

  • nodes1.csv - User nodes
  • nodes2.csv - Department nodes
  • edges1.csv - MemberOf relationships
  • edges2.csv - Permission relationships

About

Build BloodHound OpenGraph JSON from CSV files and graphify knowledge graphs

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages