Digital Forensics Investigation
This document describes how to use Sec-Gemini for performing a digital forensics investigation based on logs.
Two steps are required to perform a digital forensics investigation with Sec-Gemini:
- Run the local logs MCP server, which allows Sec-Gemini to search through logs without having to send potentially terabytes of sensitive logs data through the network.
- Run the terminal user interface, or use the Python SDK to instruct Sec-Gemini to investigate the provided logs.
1. Setting up the logs MCP server
Section titled “1. Setting up the logs MCP server”The forensics capability of Sec-Gemini is designed to operate on logs that are both massive in quantity (multiple TBs) and sensitive. To give Sec-Gemini the ability to access the logs under investigation, you run a local logs MCP server.
There are currently two supported log sources for the local logs MCP server:
- local SQLite3 DB file — greatest flexibility at the cost of a longer setup,
- Google SecOps (Chronicle) — easiest to setup if your data is already in a Chronicle instance.
Using a SQLite3 DB file
Section titled “Using a SQLite3 DB file”In this setup, your logs are stored in a local SQLite3 database file, which Sec-Gemini will repeatedly query during the investigation.
SQLite DB Schema
Section titled “SQLite DB Schema”The SQLite3 database file must contain two tables with the following schemas:
records Table
| Column Name | Data Type | Description | Example values |
|---|---|---|---|
record_id | TEXT | Unique record identifier | E6vV41eMYw, … |
log_type | TEXT | Log source or type classification | syslog:line, fs:stat, … |
timestamp_micros | INTEGER | Epoch timestamp in microseconds | 1645056112000000, … |
timestamp_desc | TEXT | Human-readable timestamp description | Content Modification Time, Start Time, … |
message | TEXT | Main log message payload | [sshd, pid: 31357] Received disconnect from 218.157.73.75: 11: Bye Bye [preauth], … |
enrichment | TEXT | Extra enrichment details or metadata (optional) | tags: [is_tor_ip], … |
Notice that log records do not need to be parsed or otherwise structured beyond providing a timestamp.
You may use arbitrary values for the log_type field, or even a single value for all records, as long as each value has a corresponding entry in the log_descriptions table below.
log_descriptions Table
| Column Name | Data Type | Description | Example values |
|---|---|---|---|
log_type | TEXT | Reference classification identifier | syslog:line, fs:stat, … |
description | TEXT | Summary details of corresponding log records | Syslog line event data., File system stat event data., … |
Running the logs MCP server
Section titled “Running the logs MCP server”To run the logs MCP server with a single Sqlite DB file, use the following command:
sec-gemini-mcp --transport=sse --port=8000 --dfir-sqlite=PATH_TO_FILE.DBAlternatively, if you have multiple Sqlite DB files, each corresponding to one investigation to perform,
you can name them following the convention TICKET_ID.db, where ticket IDs are always numerical, e.g., 12345.db, and place them in the same directory.
You can use the same command as before by providing the path to the directory instead of the path to the file:
sec-gemini-mcp --transport=sse --port=8000 --dfir-sqlite=PATH_TO_DIRECTORYUsing a Chronicle instance
Section titled “Using a Chronicle instance”With this backend, Sec-Gemini will query the logs in your Chronicle instance, via your local network connection.
sec-gemini-mcp --transport=sse --port=8000 --dfir-chronicle=CUSTOMER_ID,PROJECT_ID,REGIONFor example:
sec-gemini-mcp --transport=sse --port=8000 --dfir-chronicle=12345678-9abc-def0-1234-567890abcdef,chronicle-project,us2. Performing an Investigation
Section titled “2. Performing an Investigation”You can now ask Sec-Gemini to perform an investigation using the local logs MCP server you just started. You can either use the TUI or the Python SDK to do so.
TUI-based Investigation
Section titled “TUI-based Investigation”Run the TUI in DFIR mode and tell it to use the logs MCP server:
sec-gemini --mode=dfir --mcp http://localhost:8000/sseOnce your session is established, you may simply prompt Sec-Gemini to perform a forensics investigation.
If you want Sec-Gemini to perform an unhinted investigation (i.e., operate in threat hunting mode), you may keep your prompt as simple as:
Perform a forensics investigation on the given logs.When a starting point is available, or if you want to focus the agent’s attention on a specific part, you may provide the information in the prompt itself. Here are good examples of additional information to provide:
- an (approximate) incident time, e.g., 2026-05-06 13:00
- a hostname
- an account or username
- a specific filename
For instance:
Perform a forensics investigation on the given logs.An alert was triggered at 2026-05-06 13:00 on hostname "machine1234".If you are using the SQLite3 DB logs backend and have more than one logs DB file, you must tell Sec-Gemini which one to use:
Perform a forensics investigation on the logs with ticket ID 12345.Python SDK-based Investigation
Section titled “Python SDK-based Investigation”To perform a digital forensics investigation via the Python SDK, you will need to explicitly run the sec-gemini-byot client in a separate terminal to tunnel your local sec-gemini-mcp server to the cloud agent.
1. Start the Tunneling Client
Section titled “1. Start the Tunneling Client”In a separate terminal, run sec-gemini-byot pointing to your local logs server:
sec-gemini-byot --no-base-tools --mcp http://localhost:8000/sse2. Run your Python SDK Script
Section titled “2. Run your Python SDK Script”Use the SDK to create a session, activate the byot tool tunnel, and prompt the agent in dfir mode:
import asynciofrom sec_gemini import SecGemini
async def main(): async with SecGemini(api_key="YOUR_API_KEY") as client: session = await client.sessions.create()
# Ensure the BYOT tool tunnel is active for this session await session.mcps.set(["byot"])
# Enable the digital forensics engine by setting the mode to dfir await session.prompt( "Perform a forensics investigation on the given logs.", meta={"mode": "dfir"} )
async for msg in session.messages.stream(): msg_type = msg.get("message_type", "") content = msg.get("content", "")
if msg_type == "MESSAGE_TYPE_RESPONSE": print(f"Agent: {content}") elif msg_type == "MESSAGE_TYPE_TOOL_CALL": print(f" [tool] {msg.get('title', '')}")
asyncio.run(main())