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 delegates analysis to the specified provider backend (e.g.,
genaiormock). - 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 chosen provider executes analysis on the source files and compiles the results.
- Dashboard Generation: The run's raw findings are compiled into reports and a local HTML dashboard.
- app/mjolnir/: Core Python application engine, including agent tools, data models, and providers (mock, genai). 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.
Mjolnir requires Nix with flakes enabled.
To run a predefined project audit runner target, execute nix run:
nix run .#<project-runner-target>- Run Caliptra SW Mock E2E Audit:
nix run .#caliptra-sw-runner-test - Run OpenTitan ROM Audit:
nix run .#opentitan-rom
To aggregate the results of existing runs and regenerate the dashboard, you can use the gen-dashboard target:
nix run .#gen-dashboardBy default, this looks for runs in ./output/runs. You can override the target directory using the -- separator to pass arguments to the underlying application engine:
nix run .#gen-dashboard -- --output-dir /path/to/custom/runsMjolnir supports both Google Cloud Vertex AI and the Gemini Developer API.
Set the API key in your environment:
export GEMINI_API_KEY="AIzaSy..."Set up Application Default Credentials (ADC) and project context:
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/credentials.json"
export GOOGLE_CLOUD_PROJECT="your-gcp-project-id"
export GOOGLE_CLOUD_LOCATION="global"Mjolnir includes a suite of test targets to verify local pipelines, GCS uploads, and live LLM integration.
To verify that the Nix derivations build cleanly:
nix build .#smoke-test --no-linkTo run a local mock test (verifies the python runner and local file system hooks):
nix run .#smoke-testTo verify GCS storage uploads with mock data:
export MJOLNIR_GCS_BUCKET="your-bucket"
nix run .#gcs-testTo verify your credentials or GEMINI_API_KEY against a real Gemini model (runs on a small subset of files using gemini-2.5-flash):
# Option A: Using API Key
export GEMINI_API_KEY="AIzaSy..."
nix run .#gemini-test
# Option B: Using GCP Vertex AI
export GOOGLE_CLOUD_PROJECT="your-project"
export GOOGLE_CLOUD_LOCATION="global"
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/credentials.json"
nix run .#gemini-testTo verify end-to-end LLM scanning combined with GCS upload:
export MJOLNIR_GCS_BUCKET="your-bucket"
nix run .#gemini-gcs-testTo run all mock and live tests in a single command:
nix run .#test-allTo test the project runners (firmware compilation verification) locally:
nix run .#test-all-runners