Mjolnir is an AI-driven security auditing framework designed for open-source Root-of-Trust (RoT) projects.
It leverages AI foundation models and adversarial review pipelines to provide continuous security assurance through periodic, incremental scanning of firmware and RTL.
Mjolnir separates the declarative configuration and environment definition (Nix) from the imperative analysis execution (Python application engine).
graph TD
subgraph Nix Layer [Nix Orchestration]
A[projects/ directory] -->|1. Auto-discover| B(discovery.nix)
B --> C[flake.nix targets]
C -->|nix run .#job| D(orchestrator.nix)
D -->|2. Generate| E[Job Spec JSON]
D -->|3. Generate| F[Launcher Script]
end
subgraph Python Layer [Application Engine]
F -->|4. Execute| G(main.py)
E -.->|Reads configuration| G
G --> H[Checkout target repo]
H --> I[Discover source files]
%% Parallel File Analysis
I --> J1(Analysis Provider: File 1)
I --> J2(Analysis Provider: File 2)
I --> J3(Analysis Provider: File N)
J1 --> M[vulnerabilities.json]
J2 --> M
J3 --> M
M --> N[HTML Dashboard Generator]
N --> O[Local/GCS Output]
end
- Nix Layer (Orchestration):
- Discovery (
discovery.nix): Scans theprojects/directory to automatically register every project and job configuration as a Nix package target. - Orchestration (
orchestrator.nix): When a target is executed (vianix run), it packages the job by serializing the configuration attributes into a static JSON spec file in the Nix store, and builds a launcher script.
- Discovery (
- Python Layer (Application Engine):
- Orchestrator (
main.py): Parses the serialized JSON spec, sets up the workspace directory, clones the target repository, and checks out the designated revision. - Analysis Execution: Filters files based on source directories and extensions, then runs the ADK multi-agent analysis pipeline (or mock simulation if
model = "mock"). - Reporting & Dashboarding: Compiles the findings into
vulnerabilities.jsonand generates an interactive HTML dashboard in the output directory.
- Orchestrator (
- Nix Auto-Discovery: Nix dynamically generates packages from the
projects/directory targets. - Target Launch: Running
nix run .#<job-name>executes the Nix-generated wrapper script. - JSON Spec Materialization: The launcher script runs the application engine, passing a path to the serialized JSON job specification.
- Checkout & Discovery: Python clones/updates the target repository and identifies files matching the job's scope.
- Scan Execution: The analysis engine scans the source files using the configured model and compiles the results.
- Dashboard Generation: The run's raw findings are compiled into reports and a local HTML dashboard.
- INTEGRATION_GUIDE.md: Guide for integrating Mjolnir security audits into repositories (GitHub Actions, GCS export, PR diff mode).
- app/mjolnir/: Core Python application engine, including agent tools, data models, and the ADK analysis pipeline. See Application Engine README.
- nix/: Nix infrastructure for job packaging, auto-discovery, and orchestration. See Nix README.
- projects/: Supported project definitions and job configurations. See Projects README.
output/: Generated analysis reports, run logs, and HTML dashboards.
All project definitions, job configurations, and nix setups are located under projects/. See the Projects README for more details on how to register new targets, or read the Integration Guide for step-by-step onboarding instructions.
Mjolnir requires Nix with flakes enabled.
To run a predefined project audit target, execute nix run:
nix run .#<project-target>- Run OpenTitan ROM Audit:
nix run .#opentitan-rom - Run All OpenTitan Jobs:
nix run .#opentitan-all
Mjolnir features a WebAssembly (WASM) dashboard for browsing security audit runs, filtering findings, and visualizing vulnerability flow telemetry.
To compile the WASM engine and start the local development server (default: http://localhost:8080):
nix run .#web-viewerDeploy static WebAssembly dashboard assets to Google Cloud Storage:
nix run .#deploy-gcs-webSync local analysis runs from output/v1/runs/ to Google Cloud Storage (test project runs are excluded by default):
nix run .#deploy-gcs-runsOptional flags for run deployment:
--include-tests: Include test and mock benchmark runs.
nix run .#deploy-gcs-runs -- --include-testsConvert findings from the most recent scan into GitHub-Flavored Markdown:
# Emit Markdown report for the latest run:
nix run .#emit-report -- --output report.md
# Specify format explicitly (defaults to markdown):
nix run .#emit-report -- --output report.md --format markdownYou can also run it directly via cargo xtask:
cargo xtask emit-report --output report.md --format markdownMjolnir uses Application Default Credentials (ADC) with Google Cloud Vertex AI by default, requiring zero environment variables or secrets in production.
-
In Production (GCP / Compute Engine / GKE): Authentication and GCP Project ID resolution are completely automatic via Application Default Credentials (ADC) and the Instance Metadata Server. No environment variables or credentials files are needed.
-
On Local Development Workstations: Authenticate once with
gcloud:gcloud auth application-default login gcloud config set project your-gcp-project-idMjolnir auto-discovers your credentials and project with zero configuration required.
If running outside Google Cloud without ADC, you can optionally set a Gemini Developer API key:
export GEMINI_API_KEY="AIzaSy..."Mjolnir supports multiple foundation models via ADK's native registry:
- Gemini:
gemini-*(via Vertex AI ADC orGEMINI_API_KEY) - Claude:
claude-*(via Vertex AI ADC) oranthropic/claude-*(via directANTHROPIC_API_KEY) - OpenAI:
gpt-*,o1-*,o3-*(viaOPENAI_API_KEY) - Ollama / Local:
ollama/<tag>connects to an external Ollama server (defaults tohttp://localhost:11434or$OLLAMA_HOST). Ensure the model is pulled beforehand (ollama pull <tag>).
nix run .#adk-ollama-test # runs against local ollama/gemma4:31bMjolnir includes a suite of test targets to verify local pipelines, GCS uploads, and live LLM integration. These targets run against a synthetic git repository fixture without requiring a compiler development shell (devShell = null).
To verify that the Nix derivations build cleanly:
nix build .#mock-smoke-test --no-linkTo run a local mock test (verifies the python analysis engine and local file system hooks):
nix run .#mock-smoke-testRun live scans on test fixtures using ambient ADC or optional API key:
# ADK Provider Target (Google Agent Development Kit)
nix run .#adk-gemini-test
# Option C: ADK Ingestion Mode
nix run .#adk-gemini-ingest-testnix run .#test-allMjolnir enforces code formatting and quality checks across Rust (rustfmt), Markdown/JavaScript (prettier), Python (ruff), Shell (shfmt), and Starlark (buildifier).
# Auto-format all supported files in the repository:
bazel run //quality:format
# Check formatting compliance:
bazel test //quality:format_check
# Run full quality test suite (formatting, license headers, shellcheck):
bazel test //qualityMjolnir includes a shared Git pre-commit hook in .githooks/pre-commit that automatically formats staged files and verifies formatting before each commit.
To activate the hook in your local clone, run once:
git config core.hooksPath .githooks