{"slug": "agents-that-act-on-connected-data-building-blastshield-with-falkordb", "title": "Agents That Act on Connected Data: Building BlastShield with FalkorDB", "summary": "A developer built BlastShield, a security-investigation prototype that uses FalkorDB as a graph database and Gemini via MCP tools to trace modeled access routes from an alert to critical data assets. Gemini selects from server-derived response candidates but cannot write Cypher or access the mutation tool; a separate controller applies bounded changes to synthetic graph data and re-queries the graph to verify results. The project, presented at Graph Hacks 2026, runs on a React/Vite dashboard and FastAPI backend and ships with four canonical scenarios scored by a transparent demo rule set rather than calibrated breach probabilities.", "body_md": "*How we used graph evidence, constrained tools, and a fresh query after every simulated response action.*\n\n**Graph Hacks 2026 · Track 01: Agents That Act on Connected Data**\n\n**Repository:** [github.com/sdkharade12/blast-shield-graph-hacks](https://github.com/sdkharade12/blast-shield-graph-hacks)\n\n**In brief:** BlastShield is a security-investigation prototype that explores how a graph-backed agent can trace modeled access routes to critical data. FalkorDB supplies the paths and relationships. Gemini can choose from response candidates derived by the server, but it does not write Cypher or receive the mutation tool. A separate controller applies bounded changes to synthetic graph data and queries the graph again to check the result.\n\nImagine an alert for an active session belonging to `developer_07`. Its demonstration risk score is 35 out of 100, labelled Medium.\n\nIs that dangerous? The score alone cannot answer the question. The relevant context is several relationships away:\n\n```\ndeveloper_07\n  └─ HAS_SESSION → sess_007\n       └─ CAN_ACCESS → build-runner-03\n            └─ RUNS_AS → deployment-role\n                 └─ CAN_ASSUME → production-role\n                      └─ CAN_READ → customer-db\n```\n\nThe identity can reach a customer database through a chain of represented relationships. No single record tells the whole story; the route only becomes visible when the connections are traversed together.\n\nThat is the question behind BlastShield: **what modeled route connects an alert to a critical asset, and what remains if one route is blocked?**\n\nA boundary matters here. All data in BlastShield is synthetic. The prototype does not connect to a real cloud account, identity provider, or production telemetry. A path represents reachability in the model, not proof of exploitation. Likewise, no qualifying path in the graph is not proof that a real environment is safe.\n\nBlastShield combines a React and Vite dashboard, a FastAPI backend, FalkorDB as the graph database, and Gemini accessed through MCP tools. The dashboard presents four canonical scenarios:\n\n| Scenario | Investigation target | Seeded baseline described by the project | \n|---|---|---|\n| `BH-1042` — identity access path | `developer_07` | One modeled route to the customer database; 35/100, Medium | \n| `BH-IAM-2001` — excessive IAM permission | `analytics-role` | A path through a relationship classified `EXCESSIVE` ; 65/100, High | \n| `BH-WORKLOAD-3001` — exposed workload | `exposed-api-01` | Three qualifying paths to critical assets; 75/100, High | \n| `BH-CONTAINMENT-4001` — containment | `containment-user-01` | Two independent active routes; 60/100, High | \n\nThe scores use the project's demonstration rule set, `demo-rules-v1`. They are transparent prototype values, not calibrated probabilities of a breach. The graph paths, risk presentation, and response state should be read as evidence from the synthetic model rather than claims about a live cloud tenant.\n\nThe model represents five main kinds of entities: `Identity`, `Session`, `Workload`, `IAMRole`, and `DataAsset`. The access path uses relationships such as:\n\n``` php\n(Identity)-[:HAS_SESSION]->(Session)\n  -[:CAN_ACCESS]->(Workload)\n  -[:RUNS_AS]->(IAMRole)\n  -[:CAN_ASSUME]->(IAMRole)\n  -[:CAN_READ]->(DataAsset)\n```\n\nEdges can carry properties that affect an investigation, including route identifiers, containment and response status, permission assessment, granted actions, scope, and sensitivity. Those properties help the query distinguish an active modeled route from a route that has been blocked.\n\nA simplified version of the identity query looks for an active session, a running workload, the roles involved, and a critical data asset:\n\n``` php\nMATCH p =\n  (i:Identity {id: $identity_id})\n  -[session_edge:HAS_SESSION]->(s:Session {status: 'ACTIVE'})\n  -[:CAN_ACCESS]->(w:Workload {status: 'RUNNING'})\n  -[:RUNS_AS]->(r:IAMRole)\n  -[:CAN_ASSUME]->(pr:IAMRole)\n  -[:CAN_READ]->(d:DataAsset {sensitivity: 'critical'})\nWHERE coalesce(session_edge.response_status, 'ACTIVE') = 'ACTIVE'\nRETURN\n  [node IN nodes(p) | {\n    id: node.id,\n    label: coalesce(node.name, node.id),\n    type: labels(node)[0]\n  }] AS nodes,\n  [rel IN relationships(p) | {\n    source: startNode(rel).id,\n    target: endNode(rel).id,\n    type: type(rel),\n    properties: properties(rel)\n  }] AS edges\n```\n\nThe important result is not just `true` or `false`. The query returns the path, its nodes, its directed edges, and the edge properties. That is the evidence the dashboard can draw and the agent can use.\n\nThis is also why FalkorDB is central to the product. The graph query provides the path evidence, response candidates are derived from the returned relationships, and verification after a response action relies on a fresh graph query. Remove the graph and the application loses the connected evidence and the means to check whether a simulated route remains.\n\nA shallow lookup can miss exposure that sits behind role assumptions. To demonstrate that, we added a supplemental audit fixture separate from the four canonical scenarios.\n\n| Source | Target | Maximum depth | Expected result | \n|---|---|---|---|\n| `auditor_02` | `analytics-cache` | 1 | No qualifying path | \n| `auditor_02` | `analytics-cache` | 4 | Path found | \n| `auditor_02` | `staging-report` | 4 | No qualifying path | \n| `auditor_02` | `staging-report` | 5 | Path found | \n\nThe five-hop route to `staging-report` is:\n\n```\nauditor_02 → sess_auditor_02 → audit-reporter-02\n          → audit-readonly-role → staging-observer-role\n          → staging-report\n```\n\nThe final connection depends on a `CAN_ASSUME` relationship in the middle of the chain. With a depth limit of four, the modeled report appears unreachable; at depth five, the route can be discovered. This is the core demonstration: changing the allowed traversal depth changes which relationships the query can find.\n\nBlastShield uses a bounded, directed traversal and allow-lists the relationship types it follows. Blocked session routes and blocked relationships are excluded. The depth supplied by the caller is validated as an integer between one and six and selects one of six prebuilt query templates; caller text is not inserted into Cypher.\n\nFalkorDB versions used during development did not consistently accept a parameter inside the variable-length path bound. Keeping six fixed templates avoids composing executable query text from arbitrary caller input while preserving a validated depth control.\n\nIt is tempting to provide a model with a schema and ask it to generate Cypher. That gives the model too much freedom and makes it harder to explain or audit a result. BlastShield instead exposes a fixed catalogue of reviewed tools. Examples include:\n\n`investigate_alert(alert_id)` — returns the canonical graph investigation.`get_blast_radius(alert_id)` — returns workload, role, and asset entities derived from paths.`find_shortest_access_path(source_id, target_id, max_hops)` — performs the bounded traversal.`get_containment_route_statuses(alert_id)` — returns route states for the containment scenario.\nThe query templates are written by a person. Tool inputs are validated before execution, and tool traces capture details such as the tool name, inputs, outcome, duration, and result count.\n\nThe distinction between unknown and disconnected entities is just as important. An entity that does not exist should produce an unknown-source or unknown-target outcome; two known entities with no qualifying connection should produce a no-path outcome. Invalid input and query failures are different again. None should silently become a claim that the environment is safe.\n\nInvestigation is read-only. Response is where an agent can create risk, so we separated proposing an action from executing it.\n\nThe response flow has three boundaries:\n\nThe candidate list is derived from the current graph evidence, not invented by Gemini. When Gemini proposes an action, the server re-derives the current candidates and rejects a choice that is no longer present. The action service validates the choice again before performing the write. Gemini does not receive the mutation tool and does not write Cypher.\n\nFor example, the synthetic containment operation can mark a modeled active session route as blocked. It changes graph state used by the demonstration; it does not disable a real session or modify a cloud resource.\n\nThis design deliberately gives the model a short leash: it can select among supported options, but server-side code decides whether the choice is valid and which write may execute.\n\nIssuing a command and verifying its effect are different things. An agent should not announce success just because it requested a change.\n\nIn `BH-CONTAINMENT-4001`, the seeded model has two independent routes. Blocking only the primary route should not end the run if the alternate route still qualifies. The controller therefore queries the graph after each action and decides whether to continue based on the fresh result:\n\n```\nInvestigate\n   ↓\nFind qualifying route\n   ↓\nChoose supported action\n   ↓\nApply synthetic change\n   ↓\nQuery FalkorDB again\n   ↓\nVerify remaining routes\n   ↓\nContinue or stop\n```\n\nThe intended seeded sequence is: block the primary route, re-query and discover the alternate route, block the alternate route, then re-query and confirm that no qualifying route remains. A run is complete only when the controller reaches the no-qualifying-path outcome and all actions have been verified. Reaching the action limit with a route still present is a stopped run, not a completed one. Unknown, invalid, or failed outcomes do not count as successful containment.\n\nA regression test exposed a subtle failure mode in the response loop. If an action result did not include a post-action investigation, the controller could reuse its previous snapshot. The next decision could then be made from stale evidence.\n\nWe fixed the controller to fetch a canonical investigation from FalkorDB whenever the action response omits the `after` object. We also corrected the test fixture so its serialized path list matches its actual path data, then strengthened the regression to check that the second decision receives the alternate route rather than the primary route again.\n\nThe lesson is simple: **a response agent must reason over the latest evidence, not the last evidence it happened to see.**\n\nGemini can produce a useful briefing, but fluent text is not evidence. A briefing checker compares the proposed summary with the canonical investigation. It can flag entity IDs that were not returned by the graph, risk scores that do not match the computed value, relationship types not present in the evidence, and containment claims that are unsupported while a qualifying route remains.\n\nIf validation fails, or Gemini is unavailable, the UI uses a deterministic summary assembled from canonical evidence and labels it as a fallback. The safeguard is not to loosen the checks until every summary appears grounded; the safeguard is to keep the evidence authoritative and make fallback states visible.\n\nTool-level unit tests cover response-loop behavior such as re-querying between actions, terminal no-path handling, unknown or invalid outcomes, action limits, and verification failures. The latest backend test run reported 32 passing tests and six skipped tests. Those six are opt-in live-FalkorDB tests; a skipped test is not a verified pass. Live graph behavior, Gemini/MCP grounding across all scenarios, and the final browser flow require separate end-to-end checks.\n\nThere are deliberate limits to the prototype:\n\n`algo.SPpaths`.` demo-rules-v1` provides transparent scenario scores, not calibrated breach probabilities.\nTo run BlastShield locally, start FalkorDB, install the Python dependencies from `requirements.txt`, seed the scenarios from the `backend` directory, start FastAPI, and launch the React/Vite frontend in a second terminal. Set `GEMINI_API_KEY` in the repository-root `.env` file to enable Gemini-assisted explanations and response decisions; never publish that file or its values. Follow the repository README for exact commands so the article and submitted code stay in sync: [BlastShield repository](https://github.com/sdkharade12/blast-shield-graph-hacks).\n\nThis article was prepared with AI assistance and reviewed by the authors for factual accuracy. AI coding assistants were used during development; the team remains responsible for reviewing, testing, understanding, and explaining the submitted code. Gemini is a runtime component, constrained by the fixed MCP tools and checked against canonical graph evidence.\n\nBlastShield explores a practical way to make an AI agent's security decisions easier to inspect: put the relationships in a graph, expose only reviewed tools, derive actions from current evidence, and query the graph after every simulated change. An agent should not be trusted because it can describe its work; it should be evaluated on the evidence it uses and the verification it performs.", "url": "https://wpnews.pro/news/agents-that-act-on-connected-data-building-blastshield-with-falkordb", "canonical_source": "https://dev.to/rohan07taigade/agents-that-act-on-connected-data-building-blastshield-with-falkordb-5ea4", "published_at": "2026-10-18 06:02:34+00:00", "updated_at": "2026-10-18 06:13:54.445886+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "artificial-intelligence"], "entities": ["BlastShield", "FalkorDB", "Gemini", "Graph Hacks 2026", "FastAPI", "React", "Vite", "MCP"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/agents-that-act-on-connected-data-building-blastshield-with-falkordb", "markdown": "https://wpnews.pro/news/agents-that-act-on-connected-data-building-blastshield-with-falkordb.md", "text": "https://wpnews.pro/news/agents-that-act-on-connected-data-building-blastshield-with-falkordb.txt", "jsonld": "https://wpnews.pro/news/agents-that-act-on-connected-data-building-blastshield-with-falkordb.jsonld"}}