A RAG-based security analysis system using Google Cloud Vertex AI RAG Engine.
Zero-Day Scout is an AI-powered security intelligence system that combines multi-agent orchestration with advanced document analysis to identify and analyze security vulnerabilities. Built on Google's Agent Development Kit (ADK), it features a sequential three-agent workflow (Plan → Research → Analyze) that processes security documents through Vertex AI RAG Engine for deep insights.
The system provides two modes of interaction -
- RAG System - Direct document retrieval & question answering
- Agentic RAG - Deep security research with multi-agent workflow
The system integrates with CVE databases via Model Context Protocol (MCP) to provide real-time vulnerability data, and offers both a Scout CLI for security analysis and an interactive CVE CLI for vulnerability searches. It generates comprehensive security reports in markdown format, making it an essential tool for security researchers and professionals seeking to understand emerging threats and vulnerabilities in their technology stack.
# Create a conda environment
conda create --name scout python=3.11
# Activate the environment
conda activate scout
# Install dependencies
pip install -r requirements.txt
# or with uv (which is listed as a dependency)
uv pip install -r requirements.txt
# Set up environment variables (copy template first)
cp .env.template .env
# Edit .env with your actual valuesconfig/: Configuration files for the applicationconstants.py: Default configuration valuesconfig_manager.py: Manages loading config from environment variables
src/: Source code for the applicationrag/: RAG pipeline implementationpipeline.py: Main RAG pipeline using Vertex AIgcs_utils.py: Utilities for working with Google Cloud Storage
examples/: Example usage scripts
tests/: Test files for the application
Configuration is managed through environment variables and default values:
- Copy
.env.templateto.envand edit with your values - Key environment variables:
GOOGLE_CLOUD_PROJECT: Your GCP project IDGOOGLE_APPLICATION_CREDENTIALS: Path to service account keyGCS_BUCKET: GCS bucket for document storageRAG_CORPUS_NAME: Name for the RAG corpusDOCUMENT_PREFIXES: Comma-separated list of GCS prefixes to scan for documents (e.g., "research/,papers/,publications/")
The system can be configured to ingest documents from specific prefixes in your GCS bucket:
-
Configure document prefixes in your
constants.pyfile:DOCUMENT_PREFIXES=research/,papers/,publications/ -
Default prefixes are set in
config/constants.pyif not specified:DEFAULT_DOCUMENT_PREFIXES = [ "arxiv_security_papers/", "uploaded_papers/", "cves/",]
-
To ingest documents from these prefixes, call the
ingest_documentsmethod with an empty list:pipeline.ingest_documents([]) # Uses configured prefixes
MCP server can be tested with MCP Inspector
- Start MCP server using
start_cve_mcp_server.sh, this will launch MCP server in background mode.2025-05-24 08:11:18,721 - cve-search-mcp - INFO - Starting MCP server at http://0.0.0.0:8080 2025-05-24 08:11:18,721 - cve-search-mcp - INFO - - StreamableHTTP MCP: http://0.0.0.0:8080/mcp/ 2025-05-24 08:11:18,721 - cve-search-mcp - INFO - - SSE MCP (Legacy): http://0.0.0.0:8080/mcp/sse 2025-05-24 08:11:18,721 - cve-search-mcp - INFO - - HTTP Ping: http://0.0.0.0:8080/ping 2025-05-24 08:11:18,721 - cve-search-mcp - INFO - - JSON response mode for StreamableHTTP: disabled INFO: Started server process [53353] INFO: Waiting for application startup. 2025-05-24 08:11:18,760 - mcp.server.streamable_http_manager - INFO - StreamableHTTP session manager started 2025-05-24 08:11:18,760 - cve-search-mcp - INFO - MCP server started with StreamableHTTPSessionManager and SSE transport INFO: Application startup complete.```
The system now tracks ingested documents to prevent duplicates:
- Previously ingested documents are stored in a JSON file (
.ingested_docs.jsonby default) - When ingesting documents, only new documents not previously ingested are processed
- The tracking file path can be customized when initializing the pipeline:
pipeline = VertexRagPipeline(tracking_file="/custom/path/to/tracking.json")
The system uses Vertex AI Reranking to improve quality of content.
See README_RERANKING.md for more information on setting up and using the reranking feature.
Zero-Day Scout includes an agentic RAG system that uses Google ADK (Agent Development Kit) to orchestrate multiple specialized agents for comprehensive security analysis.
The system uses a SequentialAgent that coordinates three specialized agents:
-
PlannerAgent: Creates a structured research plan from the user query
- Output stored in:
state["research_plan"]
- Output stored in:
-
ResearchAgent: Executes the plan using multiple tools (RAG, CVE lookup, web search)
- Reads from:
state["research_plan"] - Output stored in:
state["research_findings"]
- Reads from:
-
AnalysisAgent: Analyzes findings and generates security insights
- Reads from:
state["research_plan"]andstate["research_findings"] - Produces the final response
- Reads from:
The Google ADK SequentialAgent automatically manages data flow between agents:
- Each agent defines an
output_keywhen initialized - The agent's output is automatically stored in the shared state using this key
- Subsequent agents can access previous outputs from the state
- The state is passed automatically - no manual intervention required
Example flow:
User Query → PlannerAgent → state["research_plan"] → ResearchAgent → state["research_findings"] → AnalysisAgent → Final Response
Issue: The Research Agent may not use the RAG query tool even when it should.
Cause: Tool naming mismatch between prompts and actual tool definitions.
Solution: Ensure tool names in prompts match the function names:
- RAG tool:
rag_query(notrag_query_tool) - Web search tool:
web_search(notweb_search_tool) - CVE tool:
cve_lookup_specialist
The prompts should reference these exact tool names. Additionally, the Research Agent prompt should enforce RAG-first approach:
- Make RAG query mandatory as the first step
- Use other tools only to supplement RAG results
- Explicitly state that
rag_queryis the PRIMARY source
Issue: Agents may not properly access data from previous agents.
Solution: Ensure prompts explicitly specify the state keys:
# In Research Agent prompt:
"The research plan from the planner agent will be available in the agent state with the key 'research_plan'."
# In Analysis Agent prompt:
"The research plan will be available in the agent state with the key 'research_plan'."
"The research findings will be available in the agent state with the key 'research_findings'."# Run the Scout Agent with CVE MCP integration
python -m src.scout_agent.run --query "Tell me about Log4Shell vulnerability"
# Start the CVE MCP server (required for CVE lookups)
./start_cve_mcp_server.sh startWhen working with this codebase:
- Always ensure proper authentication with Google Cloud
- Update environment variables in .env for your specific setup
- Follow the existing module structure for new features
- Add tests for new functionality when implementing
- When modifying agent prompts, ensure tool names match actual function definitions
- Test the full agent pipeline after any prompt changes




