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, 威胁情报, 开发者工具, 文档结构分析, 无后门, 漏洞情报, 目标导入, 网络调试, 自动化, 逆向工具