Skip to content

Latest commit

 

History

History
134 lines (95 loc) · 3.51 KB

README.GRAPH_DB.md

File metadata and controls

134 lines (95 loc) · 3.51 KB

Neo4j Graph Database for RedAmon

Quick Start

cd graph_db
docker compose up -d

Endpoints

Credentials

Configured via root .env file:

  • NEO4J_URI - Bolt connection URI (default: bolt://localhost:7687)
  • NEO4J_USER - Username (default: neo4j)
  • NEO4J_PASSWORD - Your password

The schema

This file covers running Neo4j. What the graph CONTAINS - every node label, its properties, and the relationships between them - is declared once, in graph_db/schema_sections.md.

# the whole schema, as the agent is served it
python3 -c "from graph_db.schema_render import render_schema; print(render_schema())"

# one label
python3 -c "from graph_db.schema_render import render_label; print(render_label('Subdomain'))"

Constraints and indexes are generated from graph_db/schema_keys.py and applied by init_schema on every container spawn, so a fresh database needs no manual DDL.

After editing the schema, re-seed the catalog:

python3 tooling/scripts/seed_schema_catalog.py

GRAPH.SCHEMA.md explains WHY the graph is shaped this way - the tenancy model, the Muted label, Scan Timeline. It deliberately lists no labels.

Configuration

The graph is automatically populated after each recon scan phase completes. Graph updates are controlled by the UPDATE_GRAPH_DB setting in the project configuration. GitHub Secret Hunt results are also ingested into the graph after scan completion.

Docker Commands

# Start Neo4j
cd graph_db && docker compose up -d

# Stop Neo4j
docker compose down

# Stop and remove all data (fresh start)
docker compose down -v

# View logs
docker compose logs -f

# View last 50 lines of logs
docker compose logs --tail 50

# Check container status
docker compose ps

# Restart Neo4j
docker compose restart

# Enter container shell
docker exec -it redamon-neo4j bash

Cypher Queries

Run these in the Neo4j Browser at http://localhost:7474

Queries sent through the AI agent, the MCP server or a saved graph view are tenant-scoped before they run, and they refuse variable-length paths and namespaced function calls (graph_db/tenant_filter.py, injectProjectFilter.ts; rules in the MCP Server wiki page). To read an attack chain's steps there, match (s:ChainStep {chain_id: $chain_id}): HAS_STEP links only the first step, and a NEXT_STEP* walk is refused.

View All Data

-- Show all nodes and relationships
MATCH (n) OPTIONAL MATCH (n)-[r]->(m) RETURN n, r, m

-- Show all nodes (browser auto-draws relationships)
MATCH (n) RETURN n

-- Count all nodes by type
MATCH (n) RETURN labels(n) AS type, count(n) AS count

Query by Project

-- Show all nodes and relationships for a project
MATCH (n {project_id: "first_test"})
OPTIONAL MATCH (n)-[r]->(m)
RETURN n, r, m

-- Filter by both user_id and project_id
MATCH (n {user_id: "samgiam", project_id: "first_test"})
OPTIONAL MATCH (n)-[r]->(m)
RETURN n, r, m

Delete Data

-- Delete all nodes and relationships (clear database)
MATCH (n) DETACH DELETE n

-- Delete all data for a specific project
MATCH (n {project_id: "first_test"})
DETACH DELETE n

-- Delete by user_id and project_id
MATCH (n {user_id: "samgiam", project_id: "first_test"})
DETACH DELETE n