alvinto27/RuleForge
GitHub: alvinto27/RuleForge
RuleForge 是一个 AI 辅助的检测工程 CLI 平台,帮助安全分析师将 CVE 漏洞和威胁情报转化为经过验证的 Sigma 检测规则。
Stars: 0 | Forks: 0
# RuleForge
RuleForge is one CLI for turning a requested CVE into normalized evidence, a
validated CVE-to-MITRE ATT&CK Intermediate Representation (IR), and either a
review-ready Sigma draft or an auditable no-rule outcome.
CVE ID or request ticket
-> NVD with official CVE List V5 fallback
-> CISA KEV, EPSS, OSV, GitHub Advisories, and optional vendor evidence
-> normalized vulnerability record with source health and cited evidence
-> evidence-gated ATT&CK mapping
-> versioned JSON IR
-> configured AI provider proposes a cited DetectionPlan
-> local schema, evidence, platform, telemetry, and ATT&CK policy
-> deterministic Sigma compiler
-> validation, review, and approved-only export
When OpenAI or Ollama is configured, AI is the primary detection-planning stage:
it chooses the proposed behavior, log source, and selectors from a bounded IR
evidence catalog. RuleForge remains authoritative for evidence acceptance,
ATT&CK mappings, UUIDs, references, Sigma structure, lifecycle state, and export.
An explicit `--deterministic` mode remains as the offline baseline.
RuleForge is on demand. It does not poll for CVEs, deploy detections, or tune rules for a production environment.
New users can follow the step-by-step [RuleForge User Guide](docs/USER_GUIDE.md).
The default terminal view is an analyst summary, not just a completion receipt.
Depending on the command, it shows CVSS/KEV/product context, source health,
mapping rationale and evidence, rejected alternatives, Sigma selectors,
and validation warnings. Use `--json` when another tool needs the complete
stable payload.
## Install
Python 3.10 or newer is required.
python -m pip install -e .
There are two equivalent ways to run the same interface:
ruleforge --help
python -m ruleforge --help
`ruleforge` is used throughout this guide for brevity.
## Live CVE access
An NVD credential is not required for a first run. RuleForge uses public NVD
access and automatically falls back to the official CVE List API when NVD is
unavailable, so users can immediately run:
ruleforge ingest CVE-2021-44228
Live sources remain subject to their current availability, policies, and public
rate limits. Independent enrichment failures do not discard a valid core CVE
record: CISA KEV, EPSS, OSV, GitHub Advisories, and approved vendor sources are
reported individually as available, absent, or unavailable.
Run the guided setup when first choosing how RuleForge should handle AI:
ruleforge setup
The first setup screen shows every setting before prompting:
- an optional NVD API key, with public NVD access available when it is left blank;
- a default AI provider: OpenAI, Ollama, or none;
- for OpenAI, a masked API key and a model menu with `gpt-5.6-sol` (highest
quality), `gpt-5.6-terra` (balanced cost and quality), `gpt-5.6-luna`
(lowest cost), and a custom-model option;
- for Ollama, the local model and loopback service URL.
Setup stores the selected provider and model but never calls either provider.
`draft` and `batch` then use that saved selection automatically for CVE and
validated-IR inputs; text and URL inputs stay deterministic. Choosing none keeps
all drafting deterministic. The `--openai`, `--ollama`, `--openai-model`, and
`--ollama-model` options remain available as advanced one-run overrides and do
not change the saved setup.
NVD keys come from the [official NVD API key form](https://nvd.nist.gov/developers/request-an-api-key).
OpenAI keys come from the [OpenAI API keys page](https://platform.openai.com/api-keys).
Secret input is masked. The credentials file is plaintext JSON protected with
best-effort user-only file permissions rather than an operating-system keyring.
Its default location is:
| Operating system | Default credentials file |
| --- | --- |
| Windows | `%LOCALAPPDATA%\RuleForge\credentials.json` |
| macOS | `~/Library/Application Support/RuleForge/credentials.json` |
| Linux | `${XDG_CONFIG_HOME:-~/.config}/ruleforge/credentials.json` |
Override the location before running setup when necessary:
$env:RULEFORGE_CREDENTIALS_FILE = "C:\Private\RuleForge\credentials.json"
ruleforge setup
Process environment variables take precedence over matching values saved by
setup, while an explicit provider/model option takes precedence for that one
command. RuleForge does not automatically load a project `.env` file.
RuleForge does not bundle or expose a shared NVD key. A deployment may inject `NVD_API_KEY` without asking ordinary users to configure it.
The CLI always displays its `RULEFORGE` ASCII-art startup branding. It recalculates its frame width before each screen is rendered and splits the block lettering into smaller groups on narrow screens. You can resize, minimize, or maximize the terminal without breaking later output; content and long paths wrap to the newly available width. Text already present in terminal scrollback is still reflowed by the terminal application itself.
The detailed path from the current development build to a production system is
documented in [`docs/production_roadmap.md`](docs/production_roadmap.md).
You can also use the included offline fixtures without network access. See
[Reliable offline presentation demo](#reliable-offline-presentation-demo).
## Workspace
Runtime files are kept out of the source packages. The default layout is:
workspace/
config.json
ingested/
ir/
drafts/
/
/
.yml
.yml.meta.json
.source.ir.json
exports/
/
/
.yml
.yml.meta.json
.source.ir.json
cache/
The Sigma file is absent from a draft bundle when policy rejects the plan or
the planner abstains. Default draft and export directories are immutable
revisions; repeated direct drafts do not replace earlier review state.
Set `RULEFORGE_WORKSPACE` to use another root:
$env:RULEFORGE_WORKSPACE = "C:\RuleForgeData"
`RULEFORGE_HOME` is still accepted when an existing installation explicitly sets it, but `RULEFORGE_WORKSPACE` is preferred. Do not set both; the preferred variable wins.
## PowerShell and interactive syntax
From PowerShell, prefix every command with `ruleforge`:
ruleforge ingest CVE-2021-44228
ruleforge map CVE-2021-44228
ruleforge draft CVE-2021-44228
To enter the interactive shell, run `ruleforge` without a command. At its prompt, omit the executable name:
ingest CVE-2021-44228
map CVE-2021-44228
draft CVE-2021-44228
help
exit
Do not repeat `ruleforge` at the interactive prompt. `exit` closes only the interactive shell.
## Quick start
Create evidence, an IR, and a Sigma draft step by step:
ruleforge ingest CVE-2021-44228
ruleforge map CVE-2021-44228
ruleforge draft workspace/ir/CVE-2021-44228.ir.json
ruleforge validate
ruleforge dashboard CVE-2021-44228
Or let `draft` run the CVE-to-IR stage first:
ruleforge draft CVE-2021-44228
Ingested records and current IR files are written under `workspace/ingested/`
and `workspace/ir/`. Each default draft attempt receives a unique
`workspace/drafts///` revision bundle unless an output
option or workspace environment variable changes the location.
## Command reference
| Command | Purpose | Example |
| --- | --- | --- |
| `setup` | Configure optional NVD access and the default AI provider/model | `ruleforge setup` |
| `ingest` | Retrieve and normalize one CVE | `ruleforge ingest CVE-2021-44228` |
| `map` | Build and save a validated ATT&CK IR | `ruleforge map CVE-2021-44228` |
| `draft` | Run AI-primary or explicit deterministic generation, producing Sigma or an auditable no-rule attempt | `ruleforge draft CVE-2021-44228` |
| `process-ticket` | Build an IR from a strict JSON request ticket | `ruleforge process-ticket request.json` |
| `validate-ir` | Validate an IR and its recorded ATT&CK mapping | `ruleforge validate-ir workspace/ir/CVE-2021-44228.ir.json` |
| `validate` | Validate a Sigma YAML rule | `ruleforge validate ` |
| `export` | Revalidate and export existing approved metadata | `ruleforge export ` |
| `batch` | Draft rules for CVEs in a CSV or JSON file | `ruleforge batch cves.csv` |
| `config` | List, read, or change workspace configuration | `ruleforge config list` |
| `dashboard` | Start the local CVE analysis dashboard | `ruleforge dashboard` |
| `help` | Show general or command-specific help | `ruleforge help map` |
| `exit` | Close the interactive shell | `exit` |
Use `ruleforge help ` for command-specific help.
Options are command-scoped. A recognized option used with the wrong command is rejected instead of being silently ignored. The common options are `--json`, `--quiet`/`-q`, `--config `, `--help`/`-h`, and `--version`.
### Output options
Use `--output` or `-o` when you need an exact output file:
ruleforge ingest CVE-2021-44228 -o workspace/ingested/log4shell.json
ruleforge map CVE-2021-44228 --output workspace/ir/log4shell.ir.json
ruleforge draft CVE-2021-44228 -o workspace/drafts/log4shell.yml
`map` and `process-ticket` also accept `--output-root`. It keeps the standard generated filename while changing the IR root:
ruleforge map CVE-2021-44228 --output-root C:\RuleForgeData\ir
ruleforge process-ticket request.json --output-root C:\RuleForgeData\ir
For ticket `SEC-1042`, the default ticket path is `workspace/ir/SEC-1042/CVE-2021-44228.ir.json`. `--output`/`-o` takes precedence when both forms are supplied.
A default direct draft creates a new revision bundle and does not replace an
earlier attempt. An explicit `draft --output` writes the requested YAML path
plus adjacent `.meta.json` and `.source.ir.json` files and refuses any existing
destination. Add `--replace` only when intentional replacement of that explicit
draft output is required:
ruleforge draft CVE-2021-44228 --output workspace/drafts/log4shell.yml --replace
`--replace` requires `--output` or `-o` and applies only to `draft`. Export has
no replacement mode. Batch also treats an existing artifact for a row as a
failure, so it cannot silently replace earlier work.
### Ingest and map
`ingest` accepts a CVE, URL marker, text file, or standard input:
ruleforge ingest CVE-2021-44228
ruleforge ingest --url https://vendor.example/advisory
ruleforge ingest --text-file .\advisory.txt
Get-Content .\advisory.txt -Raw | ruleforge ingest --stdin
`--format json|yaml` is available for the URL/text modes; evidence-backed CVE ingestion is always JSON. Use `--record-id` to map a record already saved under `workspace/ingested/`:
ruleforge map --record-id CVE-2021-44228
Force fresh source requests instead of cache reads:
ruleforge map CVE-2021-44228 --refresh
Run fully offline with the included test fixtures:
ruleforge map CVE-2021-44228 `
--nvd-fixture tests/fixtures/nvd/CVE-2021-44228.json `
--kev-fixture tests/fixtures/kev/CVE-2021-44228.json `
--mapping-rules tests/fixtures/mitre/development-rules.json `
--attack-catalog tests/fixtures/mitre/enterprise-attack-catalog.json
This fixture run bypasses live NVD and CISA network access and explicitly pins
curated development rules and their matching test catalog. These mappings are
not enabled by default, require analyst review, and must not be treated as
production ATT&CK intelligence. The curated source corpus contains 64 complete
CVE List V5 records under `tests/fixtures/mitre/cves/`, a matching
CISA-KEV-format subset at `tests/fixtures/kev/popular-cves.json`, and a
searchable cross-source index at
`tests/fixtures/mitre/popular-cves-index.json`. See
`tests/fixtures/README.md` for provenance, layout, and refresh instructions.
For normal ingestion, `ruleforge map CVE-2021-44228` is enough, but its mapping
status is `provider_not_configured` until reviewed mapping rules are supplied.
Use `--mapping-rules` and its matching `--attack-catalog`. The bundled 64-CVE
rules are demo-only and require `RULEFORGE_ENABLE_DEMO_MAPPING=1`.
`--min-confidence <0..1>` controls the evidence-mapping threshold; `--refresh`
forces fresh source retrieval.
Refresh the canonical catalogue after generating a pinned full matrix snapshot:
python scripts\sync_attack_catalog.py `
--input ruleforge\data\enterprise-attack-matrix.json `
--output ruleforge\data\enterprise-attack-catalog.json
The catalogue authorizes canonical technique metadata only. It does not create
CVE-to-ATT&CK relationships; those remain in separately reviewed mapping rules.
Every human-readable mapping result uses the same six-section overview:
`Primary Technique`, `Observed Techniques`, `Confidence`,
`Detection Opportunities`, `AI Explanation`, and `Evidence Type`. The values
are rebuilt from the requested CVE; the Citrix example is not copied into other
results. `Observed Techniques` contains only separately cited incident or
advisory observations that match the active bundled catalog. When no such
source is configured for a CVE, RuleForge says so explicitly. Detection
opportunities are review priorities derived from that CVE's evidence, not a
claim that the behavior was observed.
The `AI Explanation` position is always present for a stable layout. A plain
`map` command does not make a paid or live AI request, so it clearly labels its
text as an evidence-based fallback. It must not be interpreted as runtime
model output.
Fixture and refresh options on `ingest`, and evidence/mapping options on `draft`, are CVE-only. RuleForge rejects them for URL/free-text sources instead of silently ignoring them. In a mixed batch, incompatible rows are explicit row failures.
### Draft controls
A generated Sigma draft starts in `needs_review`, whether machine validation
runs or is explicitly skipped for a deterministic draft. A rejected or
insufficient AI plan creates a `not_generated` metadata-only attempt instead.
Use these options to control generation:
ruleforge draft CVE-2021-44228 --logsources sysmon,zeek
ruleforge draft CVE-2021-44228 --confidence-threshold 0.70
ruleforge draft CVE-2021-44228 --deterministic
ruleforge draft CVE-2021-44228 --openai --allow-deterministic-fallback
ruleforge draft CVE-2021-44228 --dry-run
ruleforge draft CVE-2021-44228 --no-validate
`--min-confidence` controls which ATT&CK candidates enter the IR;
`--confidence-threshold` controls which mapped techniques are available to the
planner and compiler. `--deterministic` bypasses a configured provider for one
run. `--allow-deterministic-fallback` applies only to AI-primary runs and makes
fallback explicit if the provider fails or its plan is not accepted. Without
that flag, RuleForge never silently substitutes a deterministic rule.
`--dry-run` writes no IR, draft, or metadata artifact, although live ingestion
may still populate the HTTP cache and a selected provider request still runs.
`--no-validate` skips structural Sigma validation only in deterministic mode;
it never approves a draft and is rejected in AI-primary mode.
For a generated rule, human-readable output shows the generation stages, draft
summary, generated rule, validation, files, and review handoff. A no-rule
attempt instead shows its explicit outcome, reason, policy result, and metadata
path without pretending that a Sigma rule exists.
The deterministic baseline and explicit fallback paths extract a structured
behavior layer from vulnerability and mapping evidence. They recognize concrete
process images and command-line arguments, network, file, web, authentication,
registry, cloud, and application observables. The generated
selector, its behavior type, source text, and source reference are retained in
`behavior_analysis` and `reasoning.selector_evidence` in the draft metadata and
JSON output.
When no concrete observable is present, RuleForge abstains for every platform
instead of emitting an assumed process or operating-system selector. No Sigma
draft is written; a non-dry-run attempt
persists `not_generated` metadata and identifies the concrete evidence needed to
continue.
For example, CVE evidence that publishes a crafted `sudo -u#...` invocation is
converted into evidence-linked `sudo` image and command-line selectors. The
Windows fallback is not used merely because no other extractor happened to
match first.
AI-primary drafting uses the validated IR before any deterministic Sigma
candidate exists. The normal flow is to choose the provider and model once,
then use flagless `draft` and `batch` commands:
# Choose OpenAI, Ollama, or none and complete the displayed provider settings.
ruleforge setup
ruleforge draft CVE-2021-44228
ruleforge batch cves.csv
# Advanced one-run overrides; these do not change the saved setup.
ruleforge draft CVE-2021-44228 --openai --openai-model gpt-5.6-sol
ruleforge draft CVE-2021-44228 --ollama --ollama-model llama3.2:1b
If OpenAI is not saved as the default provider, a process-environment key can
be paired with the one-run OpenAI override:
$env:OPENAI_API_KEY = ""
ruleforge draft CVE-2021-44228 --openai
For interactive secret entry without placing the key in shell history, PowerShell
7 users can use:
$env:OPENAI_API_KEY = Read-Host "OpenAI API key" -MaskInput
ruleforge draft CVE-2021-44228 --openai
Remove-Item Env:OPENAI_API_KEY
The equivalent Bash pattern is:
read -rsp "OpenAI API key: " OPENAI_API_KEY && printf '\n'
export OPENAI_API_KEY
ruleforge draft CVE-2021-44228 --openai
unset OPENAI_API_KEY
In CI, map `OPENAI_API_KEY` from the platform's encrypted secret store directly
into the job environment. Do not interpolate it into command arguments, echo it,
or save it as an artifact. A ChatGPT subscription does not provide API
credentials; API access and billing are configured separately.
OpenAI credentials are read from `OPENAI_API_KEY` when present, otherwise from
the per-user credentials file created by `ruleforge setup`. They are never
accepted as a command argument or written to the RuleForge workspace. For team,
CI, or production use, prefer an environment variable or managed secret store
over the local plaintext setup file. API-key requests are pinned to
`https://api.openai.com/v1/responses`. OpenAI uses strict JSON Schema output and
`store: false`; selecting it sends a bounded, detection-relevant projection of
the schema-validated IR, a catalog of allowlisted evidence leaves with stable
paths and SHA-256 hashes, the requested telemetry-profile names, and the safe selector
vocabulary. It does not send a deterministic base rule. The projection excludes
ticket IDs, record IDs, timestamps, rejected alternative mappings, and raw
source-provenance entries. Provider inputs and outputs are bounded and their
hashes, model identity, response ID when available, usage, and latency are
recorded in draft metadata.
Provider provenance is mandatory and fail-closed. The local orchestrator
requires prompt/schema version and digest fields plus provider input/output
digests, then independently verifies the DetectionPlan schema hash and returned
proposal hash. Accepted output must already match its canonical parsed plan;
Pydantic normalization cannot silently change it. Provider-output,
orchestrator-proposal, orchestrator-plan, and accepted-plan hashes therefore
agree. Missing or inconsistent provenance rejects the AI attempt.
`store: false` is not by itself a Zero Data Retention guarantee, so organization
data-handling approval is still required.
Ollama uses `http://localhost:11434/api/generate` by default.
`RULEFORGE_OLLAMA_URL` may select another loopback HTTP(S) endpoint; the CLI
rejects remote hosts. Library integrations must opt in explicitly to a remote
Ollama endpoint, and remote endpoints require HTTPS.
The provider returns a versioned `DetectionPlan`, not YAML. Its proposed log
source, platform, selector fields and values, ATT&CK IDs, references,
assumptions, and uncertainties must satisfy a strict schema. Every selector must
cite an allowlisted IR path, its exact evidence hash, and a supporting excerpt.
Local policy then verifies the requested telemetry, affected platform,
authoritative ATT&CK set and vulnerability references, selector vocabulary,
citation path/hash/excerpt, and explicit or safely normalized grounding.
Instruction-like source text cannot ground a selector, and inferred selectors
are reserved for human authorship. Acceptance is atomic: RuleForge never
silently compiles a weakened subset of a rejected plan.
Requested telemetry is deployment configuration and can never establish the
affected platform. Every named platform must be independently supported by
validated IR evidence. An empty `platforms` list makes no platform claim: it is
valid for `insufficient_evidence`, or for a grounded proposal using a genuinely
platform-neutral profile such as `generic` or `zeek`. A platform-specific
profile still fails closed without compatible IR platform evidence.
Only an accepted plan reaches the deterministic compiler. RuleForge—not the
model—creates the UUID, date, status, author, ATT&CK tags, references,
description, condition, false-positive text, level, and Sigma YAML. The plan's
`summary`, `false_positives`, and `level` are retained as analyst-facing advice;
they do not control those Sigma fields. The compiler uses a static
evidence-neutral description, a generic false-positive note, and `medium` level.
The resulting rule is parsed with duplicate-key and unsafe-YAML checks and
always begins in `needs_review`. The authoritative IR mapping cannot be changed
by the provider.
Outcomes are explicit:
- `ai_primary`: the complete plan passed local policy and was compiled;
- `ai_plan_rejected`: schema or policy rejected the proposal, so only attempt
metadata is written and the command exits nonzero;
- `insufficient_evidence`: the provider correctly abstained, so only attempt
metadata is written and the command exits nonzero;
- `deterministic_fallback`: generated only when
`--allow-deterministic-fallback` was explicitly supplied;
- `deterministic_baseline`: generated because no provider was configured or
`--deterministic` was selected;
- `legacy_ai_assisted`: compatibility label for a third-party provider that
still implements the old advisory interface; built-in providers do not use it.
A provider outage or malformed response is a hard error by default. A saved
provider applies automatically only to CVE and validated RuleForge IR inputs;
text and URL drafts remain deterministic. `--openai` and `--ollama` are mutually
exclusive, a model override requires its matching provider option, and
AI-primary drafting cannot use `--no-validate`.
Draft JSON and metadata retain the accepted plan or a size-bounded rejected
proposal, policy decisions, input/output/plan/policy/Sigma hashes, prompt/schema/
policy/compiler versions, effective ATT&CK IDs, requested telemetry profiles, provider
identity and usage, failure classification, and any explicit fallback reason.
The current AI contract records DetectionPlan schema 1.3, prompt 2.7, policy
1.5, deterministic compiler 1.3, and telemetry-profile registry 1.1.
`--logsources` values are local telemetry
profiles, not Sigma `product` values. The compiler owns the canonical mapping:
for example, `sysmon` becomes `product: windows` plus `service: sysmon`,
`auditd` becomes `product: linux` plus `service: auditd`, and `generic` becomes
a category-only log source. Unsupported or platform-ambiguous mappings fail
closed instead of writing collector names into the Sigma product field.
`--dry-run` prevents IR, draft, and metadata artifact writes but still
performs—and for OpenAI may bill—the selected provider request. Live source
retrieval may still update the workspace cache.
When drafting from an existing IR, RuleForge uses the bundled full catalog by
default and revalidates mapped techniques before generating tags. An IR made
with a different catalog version must be given that exact catalog:
ruleforge draft workspace/ir/CVE-2021-44228.ir.json
If the IR was created with a custom catalog, pass that same catalog with
`--attack-catalog` or configure `RULEFORGE_ATTACK_CATALOG`.
Free-text and URL-marker drafts remain available for the original CLI workflow.
They can produce an evidence-linked selector when the supplied text contains a
supported concrete observable. Otherwise they abstain for every platform.
Selecting a Windows telemetry profile is deployment configuration, not evidence
that the vulnerability affects Windows. A concrete but platform-neutral observable can compile
only through a platform-neutral profile such as `generic` or `zeek`; a Windows,
Linux, macOS, or platform-derived profile additionally requires compatible IR
platform evidence. They remain untagged with `provider_not_configured` and never
invent ATT&CK techniques. `map` only accepts a CVE or an ingested record
containing a CVE ID.
Local platform inference recognizes common explicit negations such as “Windows
builds are unaffected” and “does not affect systems running Windows.” It remains
a conservative lexical guard, not general semantic proof; ambiguous or unusually
worded platform scope should be normalized in source intelligence or reviewed by
an analyst. If structured `affected_products` name a platform, those fields take
precedence and prose cannot add another OS. Otherwise prose must use an anchored
affected-target relationship; client/attacker/human roles, mitigation or
documentation context, and identifier fragments such as `windows.exe` do not
establish the vulnerable platform.
### Tickets
The current ticket contract is strict: `cve_id` is required, the other shown fields are optional, and unknown fields are rejected.
{
"ticket_id": "SEC-1042",
"requested_at": "2026-07-21T10:30:00Z",
"cve_id": "CVE-2021-44228"
}
ruleforge process-ticket request.json
Ticket IDs may contain letters, numbers, dots, underscores, and hyphens. `requested_at`, when present, must include a timezone.
### Validate IR versus Sigma
The validators have deliberately different names:
# JSON IR schema and ATT&CK metadata
ruleforge validate-ir workspace/ir/CVE-2021-44228.ir.json
# Portable Sigma YAML structure
ruleforge validate
A mapped IR is validated against the same ATT&CK catalog identity and version
recorded when it was created. The bundled catalog is automatic; an IR created
with a custom catalog needs that custom catalog supplied again. Validation
checks persisted structure and catalog metadata; it does not re-fetch the
original evidence.
### Batch, configuration, dashboard, and approved export
ruleforge export
ruleforge batch cves.csv --output-dir workspace/drafts
ruleforge config list
ruleforge config get logsources
ruleforge config set logsources sysmon,zeek
ruleforge dashboard --host 127.0.0.1 --port 8080 --no-browser
Machine validation and analyst review are separate. Generated rules still start
with `needs_review`, but the CLI no longer exposes a review queue or commands to
approve or reject metadata. The approval record and integrity model remain in
the artifact format for existing approved artifacts and a future trusted review
interface. Approval data binds the reviewer, time, exact Sigma bytes, generation
manifest, source snapshot, policy report, and preceding history. Its local
SHA-256 chain detects accidental or partial edits; it is not a signature or an
external audit log.
`export` accepts only approved native metadata whose current rule bytes,
source-IR snapshot, and approval-bound generation manifest still match. It
repeats AI-primary replay and revalidates the Sigma rule. By default it publishes
a new `workspace/exports///` bundle containing the
exact Sigma bytes, an export-provenance `.meta.json` sidecar, and the verified IR
snapshot when one exists. Its 20-character release ID is derived from the draft
ID, approval-event UUID and digest, approval-subject hash, and approved Sigma
digest. The
sidecar uses `export_manifest_schema_version=1.1`, records the source draft
metadata schema separately, and binds the release, approval, generation, and
artifact hashes. It includes its own canonical manifest digest and both the
canonical IR hash and exact exported snapshot-byte hash. The export artifact
layout version is 1.1. Both default and
explicit releases are assembled and verified in staging, then atomically
published with a no-replace directory rename. For
`--output releases/log4shell-v1/log4shell.yml`, the requested filename remains
exact and `releases/log4shell-v1/` must not already exist. A destination won by
a concurrent publisher is refused; export never overwrites and rejects a
destination that aliases the source draft. A changed rule, snapshot, manifest,
or legacy approval requires a new approval through a trusted review interface
before it can be exported. Legacy
metadata is projected as `legacy_unverified`; migration never invents missing
hashes or silently upgrades its claims.
Default drafts and all export bundles are staged outside their final bundle and
published with an atomic no-replace directory rename. This provides a safe
local publication boundary, not a multi-user transaction or a power-loss
durability guarantee; artifact writes do not fsync every file and directory.
Review metadata has no lock or optimistic concurrency check, so simultaneous
reviewers can overwrite one another's decision and a concurrent rejection can
race an already-running export. The export sidecar is self-hashed, but RuleForge
does not yet provide a post-transfer bundle-verification command. RuleForge also has no automatic retention or garbage
collection: revision bundles and IR snapshots remain until an operator archives
or removes them under an approved policy.
Rule validation covers RuleForge's deliberately supported Sigma subset,
including selector value shapes, condition references and quantifiers, and
known log-source product/category compatibility. It is not pySigma or backend
validation and is not evidence that a rule is deployable or effective.
Batch CSV rows need a `source` or `cve_id` column. JSON input may be a list of strings/objects or an object with an `items` list. Use `--output-dir` for its draft directory and inspect the resulting `.yml` and `.meta.json` artifacts directly or through the dashboard. Duplicate sources and existing output files are row failures rather than silent overwrites. Any failed row is included in the result and makes the command return a nonzero status.
The dashboard opens the requested CVE workspace, or the newest usable local
artifact when no CVE is supplied. It reuses validated persisted IR, Sigma, and
version-2 generation-attempt metadata before considering an in-memory
deterministic preview. A persisted `ai_plan_rejected` or
`insufficient_evidence` attempt is shown as the authoritative no-rule outcome
and is not replaced by a preview. The workspace presents available validation,
CVE explanation, ATT&CK coverage, provenance, and export previews. The visual
workspace appears only inside the MITRE ATT&CK tab. It includes a possible-chain
view that keeps validated IR mappings separate from exact-CVE, separately cited
observations. Dashed links mean possible association only: RuleForge does not
invent missing techniques, direction, causation, confidence, or chronology. If
that evidence is unavailable, the view reports that no defensible chain can be
shown.
The same workspace renders a compact, mapping-only Enterprise ATT&CK heat map
from the bundled, versioned catalog. Technique names, tactic membership, tactic
order, and URLs come from that catalog; only an exact technique-and-tactic
relationship in the validated IR is shown. Red intensity is driven by the
absolute mapping confidence value, while unscored mappings remain neutral. A
telemetry-readiness matrix compares Sigma selectors and selector evidence with
the configured log-source names. Because the current configuration has no
deployed-field inventory, exact alignment is reported as a candidate and field
availability remains not assessed. Dashboard interactions do not change
workspace artifacts, deploy a rule, or run a real SIEM converter.
Open the address printed by the command and press Ctrl+C to stop it. Use global
`--config ` when you need a configuration file other than
`/config.json`; selecting a config file does not relocate the
workspace or its artifacts.
## Configuration
Public NVD access works without credential setup. Run `ruleforge setup` when
first selecting a default AI provider/model or storing an optional NVD key. The
setup introduction displays the complete set of possible inputs before asking
for the provider-specific values. Supported values may instead be injected
through environment variables. RuleForge does not automatically load `.env`.
AI provider precedence is:
1. A one-run `--deterministic` override, which disables AI for that run.
2. An advanced one-run `--openai` or `--ollama` option.
3. The provider saved by `ruleforge setup`.
4. No provider, which uses deterministic baseline drafting.
Provider model precedence is the matching one-run model option, then the process
environment, then the setup value, then the built-in default. For credentials
and endpoints, a process-environment value takes precedence over the matching
setup value; built-in public or loopback defaults apply where available.
`RULEFORGE_CREDENTIALS_FILE` selects a different credentials file; it does not relocate the workspace. The file contains plaintext JSON with best-effort user-only permissions and must be protected like any other local secret file.
NVD and CISA endpoint overrides must be absolute HTTPS URLs without embedded credentials, query strings, or fragments. This prevents the NVD key or source evidence from being exposed through an unsafe endpoint.
| Variable | Purpose | Default |
| --- | --- | --- |
| `RULEFORGE_WORKSPACE` | Preferred runtime root | `workspace` |
| `RULEFORGE_HOME` | Legacy runtime-root override | Used only when the preferred variable is absent |
| `RULEFORGE_HISTORY` | Interactive history-file override | Operating-system user-state directory |
| `RULEFORGE_CREDENTIALS_FILE` | Override the local setup credential file | Platform-specific user configuration directory shown above |
| `NO_COLOR` | Disable ANSI terminal color when non-empty | Color when output is an interactive terminal |
| `NVD_API_KEY` | Optional administrator-provided key for authenticated NVD service limits; overrides the stored key | Stored setup value, otherwise public access |
| `NVD_API_ENDPOINT` | NVD endpoint override; overrides the stored endpoint | Stored setup value, otherwise official NVD CVE 2.0 endpoint |
| `CISA_KEV_FEED_URL` | Public CISA KEV feed override; no CISA key is used | Stored setup value, otherwise official CISA feed |
| `RULEFORGE_CVE_LIST_ENDPOINT` | Official CVE List fallback endpoint | CVE Services public CVE-record endpoint |
| `RULEFORGE_EPSS_ENDPOINT` | FIRST EPSS enrichment endpoint | FIRST public EPSS API |
| `RULEFORGE_OSV_ENDPOINT` | OSV enrichment endpoint | OSV public vulnerability API |
| `RULEFORGE_GITHUB_ADVISORY_ENDPOINT` | GitHub Advisory enrichment endpoint | GitHub public global-advisory API |
| `GITHUB_TOKEN` | Optional token for higher GitHub public API limits | Unauthenticated public access |
| `RULEFORGE_DISABLE_ENRICHMENT` | Disable EPSS, OSV, and GitHub enrichment when truthy | Enrichment enabled |
| `RULEFORGE_SOURCE_TIMEOUT_SECONDS` | Per-source HTTP timeout | `12` |
| `RULEFORGE_MAX_EVIDENCE_TEXT_CHARS` | Maximum bounded risk/package evidence length, with truncation metadata | `2000` |
| `RULEFORGE_MAX_OBSERVABLE_EXCERPT_CHARS` | Maximum observable excerpt length, with truncation metadata | `1200` |
| `RULEFORGE_MAX_OBSERVABLE_EXCERPTS` | Maximum observable excerpts retained per source | `12` |
| `RULEFORGE_ATTACK_CATALOG` | Custom Enterprise ATT&CK catalog JSON override | Bundled full active Enterprise ATT&CK catalog |
| `RULEFORGE_ATTACK_MATRIX` | Custom display-only Enterprise ATT&CK matrix JSON override | Bundled full active Enterprise ATT&CK matrix |
| `RULEFORGE_MAPPING_RULES` | Reviewed candidate mapping rules JSON | Unconfigured |
| `RULEFORGE_ENABLE_DEMO_MAPPING` | Explicitly enable bundled curated 64-CVE demonstration rules | Disabled |
| `RULEFORGE_OBSERVED_INTELLIGENCE` | Separately cited observed-technique dataset | Unconfigured |
| `RULEFORGE_DETECTION_CAPABILITIES` | Versioned selector and telemetry capability registry | Bundled registry |
| `RULEFORGE_GITHUB_API_VERSION` | GitHub REST API version header | `2026-03-10` |
| `RULEFORGE_NON_VENDOR_HOSTS` | Comma-separated source hosts excluded from vendor classification | Public aggregator hosts |
| `RULEFORGE_USER_AGENT` | HTTP User-Agent override | Versioned RuleForge client identifier |
| `RULEFORGE_DEFAULT_OPENAI_MODEL` | Process default OpenAI model when no saved or run override exists | `gpt-5.6-sol` |
| `RULEFORGE_DEFAULT_OLLAMA_MODEL` | Process default Ollama model when no saved or run override exists | `llama3.2:1b` |
| `RULEFORGE_DISABLE_BUILTIN_MAPPING` | Disable both bundled mapping datasets when set to `1`, `true`, `yes`, or `on` | Disabled |
| `RULEFORGE_MIN_MAPPING_CONFIDENCE` | Minimum rule confidence from 0 to 1 | `0.60` |
| `RULEFORGE_CACHE_DIR` | Optional cache-directory override | `/cache` |
| `RULEFORGE_CACHE_TTL_SECONDS` | Cache reuse lifetime | `14400` |
| `RULEFORGE_OUTPUT_DIR` | Optional IR-directory override | `/ir` |
| `RULEFORGE_VENDOR_ALLOWED_HOSTS` | Comma-separated vendor hosts allowed for retrieval | Blank; vendor retrieval disabled |
| `OPENAI_API_KEY` | OpenAI API credential used when OpenAI is the saved provider or one-run override; overrides setup | Stored setup value, otherwise unconfigured |
| `RULEFORGE_OPENAI_MODEL` | OpenAI model used when no one-run model override is supplied; overrides setup | Stored setup value, otherwise `gpt-5.6-sol` |
| `RULEFORGE_OLLAMA_MODEL` | Local Ollama model used when no one-run model override is supplied; overrides setup | Stored setup value, otherwise `llama3.2:1b` |
| `RULEFORGE_OLLAMA_URL` | Loopback Ollama generate endpoint; overrides setup | Stored setup value, otherwise `http://localhost:11434/api/generate` |
Never commit, share, or print API keys or credential files. If you choose a custom credentials path, restrict access to your user account.
## Mapping guarantees and limits
RuleForge bundles CVE-scoped development rules for 64 curated CVEs and a
matching ATT&CK catalog, so those CVEs can map without extra path options. A
candidate is selected only when its CVE scope, source evidence, confidence, and
catalog metadata pass every gate. Unknown or unsupported CVEs return
`insufficient_evidence` rather than receiving a default technique.
Custom datasets override the bundled files. If built-in mapping is explicitly
disabled and no custom pair is configured, the IR records
`provider_not_configured` with an empty technique list.
Mapping statuses are:
- `mapped`: one or more candidates passed evidence, confidence, and catalog checks.
- `insufficient_evidence`: the providers worked, but no candidate passed every gate.
- `provider_not_configured`: mapping rules or the ATT&CK catalog are missing.
- `provider_unavailable`: configured mapping data could not be loaded or used.
Live CVE processing requires one valid core record, not NVD specifically.
RuleForge prefers NVD and falls back to the official CVE List V5 API. CISA KEV,
EPSS, OSV, GitHub Advisories, and vendor retrieval are isolated enrichers; their
failures remain explicit source outages rather than false negative claims.
Concrete observable excerpts are bounded, hashed, and retained in the IR for
AI citation. Risk scores, package metadata, and generic advisory prose cannot
authorize a Sigma selector. The bundled catalog and rules are curated
development data, not an analyst-approved production mapping set. Generated
mappings and Sigma rules remain `human_reviewed=false` and require analyst
review and environment-specific tuning.
The supplemental observed-technique dataset is independently source-backed.
For example, the CVE-2023-3519 observations cite CISA Cybersecurity Advisory
AA23-201A. KEV membership alone proves known exploitation status; it does not
prove a post-exploitation ATT&CK technique. RuleForge therefore leaves
`Observed Techniques` empty unless a separate cited source supports the claim.
This product uses the NVD API but is not endorsed or certified by the NVD.
## Test the CLI
### Fast command checks
These commands confirm that the installed executable, general help, and the new command-specific help are available:
ruleforge --version
ruleforge help
ruleforge help setup
ruleforge help map
ruleforge help process-ticket
ruleforge help validate-ir
ruleforge help batch
### Reliable offline presentation demo
Run this from the repository root when live NVD or KEV ingestion is unreliable:
powershell -ExecutionPolicy Bypass -File scripts/run_demo.ps1
The launcher creates an isolated temporary workspace, processes the committed
CVE-2019-14287 fixture, maps the evidence to T1548.003, extracts the documented
Linux `sudo` command into an `auditd` Sigma candidate, validates the IR, and
opens the dashboard. It does not contact NVD, CISA, an AI provider, or any other
external network service. Press Ctrl+C to stop it.
Use a different port or prepare the artifacts without starting the server:
powershell -ExecutionPolicy Bypass -File scripts/run_demo.ps1 -Port 9000
powershell -ExecutionPolicy Bypass -File scripts/run_demo.ps1 -PrepareOnly
This is an evidence-backed deterministic presentation path, not proof that live
source availability is reliable. The included ATT&CK mapping is explicitly
marked as an owner-reviewed demo mapping and remains subject to analyst review
before production use.
### Live access check
Verify a live request without credential setup:
ruleforge ingest CVE-2021-44228
The command contacts NVD and the official CVE List fallback, then concurrently
attempts CISA KEV, EPSS, OSV, GitHub Advisories, and any approved vendor source.
It is subject to those services' availability, policies, and public rate
limits. Administrators who configure an optional key must not paste it into
source files, command history, screenshots, or bug reports.
### Batch, configuration, and dashboard checks
$batch = Join-Path $testWorkspace "batch.json"
$batchDrafts = Join-Path $testWorkspace "batch-drafts"
[IO.File]::WriteAllText(
$batch,
'["PowerShell process creation test", "Command shell activity test"]',
[Text.UTF8Encoding]::new($false)
)
ruleforge batch $batch --output-dir $batchDrafts
Get-ChildItem -Recurse $batchDrafts -Filter *.meta.json
ruleforge dashboard --host 127.0.0.1 --port 8080 --no-browser
The dashboard command runs until you press Ctrl+C. The isolated test directory is stored in `$testWorkspace`; remove it when you finish testing.
### Automated test suite
Run the single offline test suite from the repository root:
python -m unittest discover -s tests -v
The suite uses fakes and local fixtures; it does not require network access.
Run the versioned workflow evaluator after collecting comparable manual,
direct-LLM, deterministic, and AI-primary run records:
python scripts/evaluate_workflows.py `
--corpus evaluation-corpus.json `
--runs evaluation-runs.json `
--split test `
--require-complete `
--require-ready `
--output evaluation-report.json `
--markdown evaluation-report.md
The schema-2.0 evaluator uses equal-weight case-macro metrics so repeated easy
trials cannot hide a failed case. It reports selector and ATT&CK
precision/recall/F1, pinned-taxonomy violations, log-source and outcome
agreement, citation/grounding, separate model-resistance/policy-containment/end-
to-end injection measurements, recorded validation and safety observations,
latency, tokens, cost, peak memory, analyst review, and canonical input hashes.
Quality and recorded-safety gates require actual adjudicated labels, complete and
balanced held-out coverage, case-bound IR inputs, and comparable configurations.
Baseline deltas are suppressed when those comparison conditions fail. The
offline evaluator cannot authenticate analyst independence or governance
declarations, and bundled fixtures are synthetic harness tests rather than
evidence that the product is accurate. See
[Evaluation harness](docs/evaluation_harness.md) for the required corpus and
claim discipline.
## More documentation
- [Current project architecture](docs/current_project.md)
- [CLI architecture](CLI_ARCHITECTURE.md)
- [Historical integration workplan (superseded)](docs/integration_workplan.md)
- [Migration notes](docs/migration_notes.md)
- [Evaluation harness](docs/evaluation_harness.md)
- [Source-to-IR mapping](docs/cve_schema_mapping.md)
- [Project-owner decisions still required](docs/user_input_required.md)
标签:AI辅助, AI风险缓解, Homebrew安装, Petitpotam, Python, Sigma规则, XSS, 威胁情报, 开发者工具, 文档结构分析, 无后门, 漏洞情报, 目标导入, 网络调试, 自动化, 逆向工具