omamori 0.1.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +19 -7
  5. data/README.md +185 -60
  6. data/README_ja.md +187 -57
  7. data/demo/ai_analysis_vulnerability.rb +3 -3
  8. data/demo/csrf_vulnerability.rb +1 -1
  9. data/demo/eval_vulnerability.rb +1 -1
  10. data/demo/idor_vulnerability.rb +2 -2
  11. data/demo/insecure_cookie_vulnerability.rb +1 -1
  12. data/demo/open_redirect_vulnerability.rb +1 -1
  13. data/demo/static_analysis_vulnerability.rb +1 -1
  14. data/demo/xss_vulnerability.rb +1 -1
  15. data/exe/omamori +2 -2
  16. data/lib/omamori/ai_analysis_engine/checklist_scanner.rb +143 -0
  17. data/lib/omamori/ai_analysis_engine/cli_clients/base.rb +43 -0
  18. data/lib/omamori/ai_analysis_engine/cli_clients/claude_code_client.rb +35 -0
  19. data/lib/omamori/ai_analysis_engine/cli_clients/codex_client.rb +47 -0
  20. data/lib/omamori/ai_analysis_engine/diff_splitter.rb +17 -4
  21. data/lib/omamori/ai_analysis_engine/fallback_client.rb +23 -0
  22. data/lib/omamori/ai_analysis_engine/judge_client.rb +45 -0
  23. data/lib/omamori/ai_analysis_engine/llm_client.rb +71 -0
  24. data/lib/omamori/ai_analysis_engine/prompt_manager.rb +72 -12
  25. data/lib/omamori/ai_analysis_engine/ruby_llm_context.rb +23 -0
  26. data/lib/omamori/ai_analysis_engine/sub_checks/audit_log_missing.yml +12 -0
  27. data/lib/omamori/ai_analysis_engine/sub_checks/csrf.yml +22 -0
  28. data/lib/omamori/ai_analysis_engine/sub_checks/insecure_deserialization_rce.yml +9 -0
  29. data/lib/omamori/ai_analysis_engine/sub_checks/insufficient_encryption.yml +19 -0
  30. data/lib/omamori/ai_analysis_engine/sub_checks/mass_assignment.yml +19 -0
  31. data/lib/omamori/ai_analysis_engine/sub_checks/open_redirect.yml +17 -0
  32. data/lib/omamori/ai_analysis_engine/sub_checks/sql_injection.yml +20 -0
  33. data/lib/omamori/ai_analysis_engine/sub_checks/xss.yml +37 -0
  34. data/lib/omamori/ai_settings.rb +273 -0
  35. data/lib/omamori/config.rb +71 -72
  36. data/lib/omamori/core_runner.rb +332 -359
  37. data/lib/omamori/doctor.rb +95 -0
  38. data/lib/omamori/parallel.rb +24 -0
  39. data/lib/omamori/report_generator/console_formatter.rb +48 -42
  40. data/lib/omamori/report_generator/html_formatter.rb +6 -6
  41. data/lib/omamori/report_generator/json_formatter.rb +1 -1
  42. data/lib/omamori/setup_files.rb +260 -0
  43. data/lib/omamori/static_analysers/brakeman_runner.rb +7 -7
  44. data/lib/omamori/static_analysers/bundler_audit_runner.rb +8 -6
  45. data/lib/omamori/version.rb +2 -2
  46. data/lib/omamori.rb +11 -11
  47. metadata +45 -26
  48. data/lib/omamori/ai_analysis_engine/gemini_client.rb +0 -71
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bafa258377208d15c678d88752804be6963159d28b83c13958de28bdd8bf8fa7
4
- data.tar.gz: 9739ae26075e9e5c0f2f87eafd68f2ed6cce0baee719a4c31c1042e8b1c8abf9
3
+ metadata.gz: 8f3533e1d6c54d0dc29d8c7eb569e9931cdd55b8214180e7380f3cf7080c0caa
4
+ data.tar.gz: ed4ca270d8a0d490b1c756e6508509609af5c495094ea3dd81e196baa91e6d66
5
5
  SHA512:
6
- metadata.gz: 373c41e264bc7548b3b4f37a526ed98fcefdd6a51fc6eaa8571b18d7688e131b4852c7e4ce839c7cdd43e540c3bf83b7466a1a66c29cea7c5d6e03dcd59f5cac
7
- data.tar.gz: 102078caed02ab830885759ddf21bc8430b15c6a829a5f4ed7c1fcca99360ac707bb938ab19a8f2f9a5ed8ad2ccd86427acfaecc1da6d55a48c27338ae753454
6
+ metadata.gz: 9fa320c3f0bf6f02cf9f76888a691b24322101e3c8c6787a3e1397f66445248e8edb8a8f6265ceae6870b4fd4aed966dc70425ae02d83d736b6ac972b327d4ce
7
+ data.tar.gz: 7a6cad8d83abeb40a5e833aadebf3ac0ee10a5629c64df88707852cdc11b42c55b06131dfe5299b0e3393370785b8237ceee74637a1f11f61382c1f687e55e91
data/CHANGELOG.md ADDED
@@ -0,0 +1,25 @@
1
+ # Changelog
2
+
3
+ ## 0.2.0 (2026-10-25)
4
+
5
+ ### Breaking changes
6
+
7
+ - **There is no default reporter.** Choose one with `omamori init --reporter ...` (or `--reporter` on `omamori scan`). Without one, `omamori scan` stops and shows how to run `init`. An 0.1 config that only sets `api_key` keeps using Gemini, now with `gemini-3.8-flash`.
8
+ - `omamori init` takes the settings as flags (`--reporter`, `--reporter-model`, `--classifier`, `--classifier-model`, `--language`, `--ci`, `--force`) and requires `--reporter`. It no longer overwrites an existing `.omamorirc` unless `--force` is given.
9
+ - Without a classifier, all checks are now run by default (0.1 ran 6 main checks). The checks are now 35: `server_error_information_exposure` is merged into `overly_detailed_errors`, and `dependency_trojan_package` (malicious packages) is no longer judged by AI. Use bundler-audit (run by omamori) for known vulnerable versions, and a scanner with a malicious-package database (such as OSV-Scanner or GitHub dependency review) for malicious packages.
10
+ - Checks about something being absent (CSP and other security headers, production settings, two-factor authentication, password policy, audit logging) now ask whether the change weakens or removes an existing protection, instead of whether the application has it.
11
+
12
+ ### Added
13
+
14
+ - **Classifier**: a fast decision model (TypeSafe Jev, OpenAI Decisions, or one on Ollama) checks each risk as a yes/no question, and only the flagged checks are sent to the reporter. Several risks are also asked as concrete sub-checks. The default threshold is 0.5.
15
+ - **Reporter choice**: any provider RubyLLM supports, or a Claude Code (`claude -p`) / Codex (`codex exec`) subscription. A fallback reporter (`reporter.fallback`) is asked when the reporter refuses or fails.
16
+ - `omamori doctor`: sends the configured classifier and reporters one small request each and says what is missing.
17
+ - `omamori scan --base REF`: scans the diff between REF and HEAD (what a pull request contains).
18
+ - CI configurations generated by `init --ci` / `ci-setup` pass the API keys your classifier and reporter need.
19
+ - An eval set (`evals/`) with AI-written cases, a holdout set, real security fixes from the GitHub Advisory Database, and ordinary commits for measuring false alarms.
20
+ - README sections on getting started and on setting omamori up with an AI agent.
21
+
22
+ ### Fixed
23
+
24
+ - A reporter refusing to analyze content (Gemini sometimes refuses security analysis) was shown as "no risks". Refused or failed checks are now kept as flags, so nothing is silently passed.
25
+ - The `ci-setup` command was not recognized.
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- source "https://rubygems.org"
3
+ source 'https://rubygems.org'
4
4
 
5
5
  # Specify your gem's dependencies in omamori.gemspec
6
6
  gemspec
data/Gemfile.lock CHANGED
@@ -1,17 +1,18 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- omamori (0.1.4)
4
+ omamori (0.2.0)
5
5
  brakeman (~> 7.0)
6
6
  bundler-audit (~> 0.9.2)
7
7
  colorize (~> 0.8)
8
8
  dotenv (~> 2.0)
9
- ruby-gemini-api (~> 0.1.1)
9
+ ruby_llm (~> 2.1)
10
10
 
11
11
  GEM
12
12
  remote: https://rubygems.org/
13
13
  specs:
14
14
  ast (2.4.3)
15
+ base64 (0.3.0)
15
16
  brakeman (7.0.2)
16
17
  racc
17
18
  bundler-audit (0.9.2)
@@ -24,14 +25,17 @@ GEM
24
25
  faraday-net_http (>= 2.0, < 3.5)
25
26
  json
26
27
  logger
27
- faraday-multipart (1.1.0)
28
+ faraday-multipart (1.2.0)
28
29
  multipart-post (~> 2.0)
29
30
  faraday-net_http (3.4.0)
30
31
  net-http (>= 0.5.0)
32
+ faraday-retry (2.4.0)
33
+ faraday (~> 2.0)
31
34
  json (2.12.0)
32
35
  language_server-protocol (3.17.0.5)
33
36
  lint_roller (1.1.0)
34
37
  logger (1.7.0)
38
+ marcel (2.1.0)
35
39
  multipart-post (2.4.1)
36
40
  net-http (0.6.0)
37
41
  uri
@@ -71,16 +75,24 @@ GEM
71
75
  rubocop-ast (1.44.1)
72
76
  parser (>= 3.3.7.2)
73
77
  prism (~> 1.4)
74
- ruby-gemini-api (0.1.1)
75
- faraday (~> 2.0)
76
- faraday-multipart (~> 1.0)
77
- json (~> 2.0)
78
78
  ruby-progressbar (1.13.0)
79
+ ruby_llm (2.1.1)
80
+ base64
81
+ faraday (>= 1.10.0, != 2.0.0)
82
+ faraday-multipart (>= 1)
83
+ faraday-net_http (>= 1)
84
+ faraday-retry (>= 1)
85
+ json (< 4)
86
+ marcel (>= 1.0, < 3)
87
+ schematist (~> 1.1)
88
+ zeitwerk (~> 2)
89
+ schematist (1.1.0)
79
90
  thor (1.3.2)
80
91
  unicode-display_width (3.1.4)
81
92
  unicode-emoji (~> 4.0, >= 4.0.4)
82
93
  unicode-emoji (4.0.4)
83
94
  uri (1.0.3)
95
+ zeitwerk (2.8.3)
84
96
 
85
97
  PLATFORMS
86
98
  ruby
data/README.md CHANGED
@@ -9,59 +9,111 @@ However, please note that this gem is merely a "protective charm" and does not g
9
9
  It might help prevent vulnerabilities that could occur even after human review.
10
10
 
11
11
  Caution:
12
- AI analysis can uncover vulnerabilities that static analysis alone might miss, but the accuracy of diagnostics may vary depending on the AI model’s "mood."
13
- Running the analysis multiple times may help reduce false negatives.
14
-
12
+ AI analysis can uncover vulnerabilities that static analysis alone might miss, but LLM results tend to vary from run to run.
15
13
 
16
14
  ## Features
17
15
 
18
- - Scan staged changes (`git diff --staged`), the entire codebase, or specified files and directories for security risks.
16
+ - Scan staged changes (`git diff --staged`), a branch diff (`--base`), the entire codebase, or specified files and directories.
17
+ - Fast checklist: each of 35 vulnerability types is checked as a yes/no question by a decision model (TypeSafe Jev, OpenAI Decisions, ...), and an LLM writes a detailed report only for the flagged checks.
18
+ - Choose the classifier and the reporter independently. The reporter can be any API RubyLLM supports (Gemini, Claude, OpenAI, ...) or a Claude Code (`claude -p`) / Codex (`codex exec`) subscription.
19
19
  - Integrates with static analysis tools like Brakeman and Bundler-Audit.
20
- - Utilizes the Gemini API for advanced code analysis to detect vulnerabilities.
21
20
  - Supports multiple report formats (console, HTML, JSON).
22
- - Configurable via a `.omamorirc` file.
23
- - Exclusion of files and directories via a `.omamoriignore` file (except in `diff` mode).
21
+ - `omamori init` runs with flags only and `omamori doctor` checks the setup, so an AI agent can set omamori up for you.
22
+ - Generates GitHub Actions / GitLab CI configuration.
23
+ - An eval set (`evals/`) for measuring detection accuracy.
24
+ - Configuration via a `.omamorirc` file, and exclusions via a `.omamoriignore` file.
24
25
 
25
- ## Installation
26
+ ## How It Works
26
27
 
27
- Add this line to your application's Gemfile:
28
+ Omamori's AI analysis has two roles.
28
29
 
29
- ```ruby
30
- gem 'omamori'
31
- ```
30
+ - **Classifier:** A fast decision model that checks each of the 35 risks as a yes/no question, such as TypeSafe Jev or OpenAI Decisions. Optional.
31
+ - **Reporter:** The LLM that writes vulnerability reports. Without a classifier, the reporter checks every risk itself in one prompt.
32
32
 
33
- And then execute:
33
+ With a classifier, a scan works like this:
34
34
 
35
- ```bash
36
- bundle install
37
- ```
35
+ 1. The diff is split per file. For each file, all checks (35 by default) are sent to the classifier in a single request. Files are processed in parallel.
36
+ 2. Checks whose probability is below the threshold pass immediately.
37
+ 3. Only the remaining checks are sent to the reporter, which writes a report following that vulnerability's detection steps.
38
38
 
39
- Or install it yourself as:
39
+ The questions sent to the classifier contain the same vulnerability definitions and detection steps that the reporter receives. For XSS, SQL injection, mass assignment, CSRF, open redirect, missing audit logging, insufficient encryption, and insecure deserialization, the classifier also answers sub-checks: concrete patterns that alone make the risk real (for XSS, for example, "is a URL from users put into `href` without checking its scheme?"). The highest probability among the overall question and its sub-checks is used, and the matched sub-checks are passed on to the reporter.
40
40
 
41
- ```bash
42
- gem install omamori
43
- ```
41
+ Risks about something being absent (CSP and other security headers, production settings, two-factor authentication, password policy, audit logging) are judged as "does this change weaken or remove an existing protection?". Whether the application had the protection in the first place cannot be told from a diff that does not touch it. If the classifier fails for a file, every check for that file is escalated to the reporter. If the reporter cannot write a report, the classifier's flag is kept in the results, so nothing is silently skipped.
44
42
 
45
- ## Usage
43
+ ## Getting Started
46
44
 
47
- ### Initialization
45
+ 1. Add omamori to your Gemfile and install it.
48
46
 
49
- To generate an initial configuration file (`.omamorirc`), run:
47
+ ```ruby
48
+ gem 'omamori', group: :development, require: false
49
+ ```
50
50
 
51
- ```bash
52
- omamori init
53
- ```
51
+ ```bash
52
+ bundle install
53
+ ```
54
+
55
+ 2. Choose a reporter and write the config file. The provider and model are given as flags (there are no interactive questions).
54
56
 
55
- Edit the generated `.omamorirc` and `.omamoriignore` files to configure your Gemini API key, preferred model, checks to perform, and files/directories to exclude from scanning, and other settings.
57
+ ```bash
58
+ bundle exec omamori init --reporter claude_code # Claude Code subscription (claude -p)
59
+ bundle exec omamori init --reporter codex # Codex subscription (codex exec)
60
+ bundle exec omamori init --reporter anthropic --reporter-model claude-sonnet-5-5 # Any API RubyLLM supports
61
+ ```
62
+
63
+ Add `--classifier typesafe` to use a classifier, `--language ja` for reports in Japanese, and `--ci github_actions` (or `gitlab_ci`) to also generate a CI configuration. This writes `.omamorirc` and `.omamoriignore`, then prints the next steps (such as the environment variables to set). An existing `.omamorirc` is not overwritten unless you pass `--force`.
64
+
65
+ 3. Set the environment variables it printed, and check the setup.
66
+
67
+ ```bash
68
+ bundle exec omamori doctor
69
+ ```
70
+
71
+ This sends the classifier and the reporter one small request each, and says what is missing (an API key, or installing or logging in to a CLI) and how to fix it. It exits with 0 when everything works and 1 otherwise.
72
+
73
+ 4. Scan.
74
+
75
+ ```bash
76
+ bundle exec omamori scan --base main
77
+ ```
78
+
79
+ There is no default reporter. If neither `.omamorirc` nor `--reporter` sets one, `omamori scan` stops and shows how to run `init`.
80
+
81
+ ### API Keys
82
+
83
+ API keys are passed through environment variables, named after RubyLLM's settings in upper case (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GEMINI_API_KEY`, `OPENROUTER_API_KEY`, `TYPESAFE_API_KEY` for the Jev classifier, ...). `omamori init` prints the ones your setup uses. The `claude_code` / `codex` reporters use the installed CLI's login, so no API key is needed.
84
+
85
+ Code diffs are sent to the classifier and reporter providers you choose. For code that must not leave your environment, choose a model that runs locally, such as one on Ollama.
86
+
87
+ ## Setting Up with an AI Agent
88
+
89
+ When you ask an AI coding agent (Claude Code, Codex, ...) to set up omamori, it can follow these steps:
90
+
91
+ 1. Add `gem 'omamori', group: :development, require: false` to the Gemfile and run `bundle install`
92
+ 2. Choose the reporter: `claude_code` if the `claude` command exists, `codex` if `codex` exists. Otherwise, ask the developer which API provider and model they use
93
+ 3. Ask the developer whether to use a classifier (`--classifier typesafe`, ...). It makes scans faster and cheaper and raises fewer false alarms, but needs that provider's API key and sends the code to that provider as well
94
+ 4. Run `bundle exec omamori init --reporter ... [--reporter-model ...] [--classifier ...] [--language ja] [--ci github_actions]`
95
+ 5. Ask the developer to set the environment variables it printed. Do not ask them to paste API keys into the chat, and do not write keys into files
96
+ 6. Run `bundle exec omamori doctor`, fixing what it reports, until it exits with 0
97
+ 7. Run `bundle exec omamori scan --base main` and report the results. If a CI configuration was generated, also tell the developer the secret names to register (printed by `init`)
98
+
99
+ ## Usage
56
100
 
57
101
  ### Scanning
58
102
 
103
+ Any setting in `.omamorirc` can be changed for one run with flags (see Choosing the Classifier and Reporter).
104
+
59
105
  Scan staged changes (default):
60
106
 
61
107
  ```bash
62
108
  omamori scan
63
109
  ```
64
110
 
111
+ Scan the changes on the current branch (`main...HEAD`, i.e. what a pull request contains; useful in CI):
112
+
113
+ ```bash
114
+ omamori scan --base main
115
+ ```
116
+
65
117
  Scan the entire codebase:
66
118
 
67
119
  ```bash
@@ -69,60 +121,101 @@ omamori scan --all
69
121
  ```
70
122
  This mode respects the `.omamoriignore` file.
71
123
 
72
- Specify output format (console, html, json):
124
+ Scan specific files or directories:
73
125
 
74
126
  ```bash
75
- bundle exec omamori scan --format html
76
- bundle exec omamori scan --all --format json
127
+ omamori scan app/controllers/users_controller.rb app/models/user.rb config/routes.rb lib/
77
128
  ```
129
+ This mode also respects the `.omamoriignore` file.
78
130
 
79
- ### Scan Specific Files/Directories
131
+ Specify the output format (console, html, json):
80
132
 
81
- You can specify particular files or directories to scan:
133
+ ```bash
134
+ omamori scan --format html
135
+ omamori scan --all --format json
136
+ ```
137
+
138
+ Run only AI analysis, skipping static analysis tools:
82
139
 
83
140
  ```bash
84
- omamori scan <file_path1> <file_path2> ... <directory_path1> ...
141
+ omamori scan --ai
85
142
  ```
86
143
 
87
- Example:
144
+ ### Choosing the Classifier and Reporter
145
+
146
+ Both roles are set with a `provider` and a `model`, on the command line or in `.omamorirc` (see [Configuration](#configuration)).
88
147
 
89
148
  ```bash
90
- omamori scan app/controllers/users_controller.rb app/models/user.rb config/routes.rb lib/
149
+ omamori scan --base main --classifier typesafe --reporter gemini --reporter-model gemini-3.8-flash # Jev decides, Gemini reports
150
+ omamori scan --base main --classifier typesafe --reporter claude_code # Jev decides, claude -p reports
151
+ omamori scan --base main --classifier openai --reporter anthropic --reporter-model claude-sonnet-5-5
152
+ omamori scan --reporter codex # No classifier; codex exec checks everything
91
153
  ```
92
154
 
93
- This mode respects the `.omamoriignore` file.
155
+ **Do you need a classifier?** It is optional. In our measurements with `claude -p` (sonnet) as the reporter, on real security fixes from Rails applications and on ordinary commits from open-source Rails apps, the reporter alone caught at least as many vulnerabilities as the classifier pipeline. The classifier made scans faster and cheaper (the reporter is called only for flagged checks) and raised fewer false alarms on changes that look risky but are safe. Cheaper reporters have not been measured on their own.
156
+
157
+ **Classifier providers**
158
+
159
+ | provider | Decision model | API key |
160
+ | --- | --- | --- |
161
+ | `typesafe` | TypeSafe Jev (`jev-1.13.0` when `model` is omitted) | `TYPESAFE_API_KEY` |
162
+ | `openai` | OpenAI Decisions API (`gpt-6-luna` when `model` is omitted) | `OPENAI_API_KEY` |
163
+ | `ollama` | A decision model running on Ollama (such as Clef). `model` and the server's `base_url` (or `OLLAMA_API_BASE`) are required | None |
164
+ | `none` | No classifier (default) | None |
165
+
166
+ With `base_url`, you can point a classifier at any other server that speaks the SystemOne protocol.
167
+
168
+ **Reporter providers**
94
169
 
95
- ### AI Analysis Only
170
+ | provider | What it calls |
171
+ | --- | --- |
172
+ | A RubyLLM provider (`gemini`, `anthropic`, `openai`, `openrouter`, `ollama`, ...) | An API through [RubyLLM](https://rubyllm.com). `model` is required |
173
+ | `claude_code` | `claude -p` (subscription) with all tools disabled, in an empty temporary directory |
174
+ | `codex` | `codex exec` (subscription) in a read-only sandbox, in an empty temporary directory |
96
175
 
97
- To perform only AI analysis without running static analysis tools, use the `--ai` option:
176
+ In `.omamorirc`, the reporter's `provider` can be omitted, in which case it is inferred from the model name. Set `provider` when the model is too new to be in RubyLLM's model registry.
177
+
178
+ A reporter may refuse to analyze some content (Gemini sometimes refuses security analysis). A refused check is not silently passed; the classifier's flag is kept. With a fallback reporter (`reporter.fallback`), refused or failed checks are asked again there, and only those.
98
179
 
99
180
  ```bash
100
- omamori scan --ai
181
+ omamori scan --base main --classifier typesafe --reporter-fallback claude_code --reporter-fallback-model sonnet
101
182
  ```
102
183
 
184
+ Diffs contain code from outside sources, so `claude_code` / `codex` run without the ability to execute commands. Because subscriptions have tighter rate limits, reports are written 3 at a time when a CLI is used (change with `reporter.concurrency`).
185
+
103
186
  ## Configuration
104
187
 
105
188
  The `.omamorirc` file in the project root directory allows you to customize Omamori's behavior.
106
189
 
107
- Here's a detailed breakdown of the configuration options:
108
-
109
190
  ```yaml
110
191
  # .omamorirc
111
192
  # Configuration file for omamori gem
112
193
 
113
- # Gemini API Key (required for AI analysis)
114
- # You can also set this via the GEMINI_API_KEY environment variable
115
- api_key: YOUR_GEMINI_API_KEY # Replace with your actual API key
116
-
117
- # Gemini Model to use (optional, default: gemini-2.5-flash-preview-04-17)
118
- model: gemini-2.5-flash-preview-04-17
119
-
120
- # Security checks to enable (optional, default: all implemented checks)
194
+ # Classifier (optional). Without it, the reporter checks every risk. Can be overridden with --classifier
195
+ # classifier:
196
+ # provider: typesafe # typesafe / openai / ollama
197
+ # model: jev-1.13.0 # Pin a version (not jev-latest) if you tune the threshold
198
+ # threshold: 0.5 # Checks at or above this probability go to the reporter
199
+ # concurrency: 8 # Parallel requests to the classifier
200
+ # base_url: https://api.typesafe.ai # Optional. Another SystemOne server
201
+ # api_key: ... # Optional. Environment variables (TYPESAFE_API_KEY, ...) are recommended
202
+
203
+ # Reporter (required; written by omamori init). Can be overridden with --reporter
204
+ reporter:
205
+ provider: anthropic # A RubyLLM provider, or claude_code / codex
206
+ model: claude-sonnet-5-5 # Required for API providers. For CLIs, omit it to use the CLI's default model
207
+ # concurrency: 8 # Reports written in parallel (default 3 for CLIs, 8 for APIs)
208
+ # command: /path/to/claude # Optional. Path to the claude_code / codex CLI
209
+ # api_key: ... # Optional. Environment variables (ANTHROPIC_API_KEY, ...) are recommended
210
+ # fallback: # Optional. Asked only when the reporter refuses or fails
211
+ # provider: claude_code
212
+ # model: sonnet
213
+
214
+ # Security checks to run (optional; default: all 35)
121
215
  # checks:
122
- # xss: true
123
- # csrf: true
124
- # idor: true
125
- # ... # Add other checks as they become available
216
+ # - xss
217
+ # - csrf
218
+ # - idor
126
219
 
127
220
  # Custom prompt templates (optional)
128
221
  # prompt_templates:
@@ -145,9 +238,9 @@ model: gemini-2.5-flash-preview-04-17
145
238
  # language: ja
146
239
  ```
147
240
 
148
- * `api_key`: Your API key for accessing the Gemini API. Can also be set via the `GEMINI_API_KEY` environment variable.
149
- * `model`: The Gemini model to use for AI analysis. Defaults to `gemini-2.5-flash-preview-04-17`.
150
- * `checks`: Configure which types of security checks to enable. By default, all implemented checks are enabled. You can selectively enable/disable checks here (e.g., `xss: true`, `csrf: false`).
241
+ * `classifier`: `provider`, `model`, `threshold` (default 0.5), `concurrency` (default 8), `base_url`, `api_key`.
242
+ * `reporter`: `provider`, `model`, `concurrency`, `command`, `api_key`, `fallback` (a fallback reporter with its own `provider`, `model`, ...).
243
+ * `checks`: The list of security checks to run. The former `server_error_information_exposure` is merged into `overly_detailed_errors`. `dependency_trojan_package` (malicious packages) is no longer judged by AI, because it cannot be judged reliably from code: use bundler-audit (run by omamori) for known vulnerable versions, and a scanner with a malicious-package database, such as OSV-Scanner or GitHub dependency review.
151
244
  * `prompt_templates`: Define custom prompt templates for AI analysis.
152
245
  * `report`: Configure report output settings.
153
246
  * `output_path`: The output directory or prefix for HTML and JSON reports.
@@ -157,16 +250,33 @@ model: gemini-2.5-flash-preview-04-17
157
250
  * `bundler_audit`: Additional command-line options for Bundler-Audit.
158
251
  * `language`: Language setting for the details provided in AI analysis reports. Defaults to English (`en`).
159
252
 
253
+ The older keys (`engine`, `llm`, `model`, `provider`, `api_key`, `decision`, `claude`, `codex`) and options (`--engine`, `--llm`) still work. A 0.1 config that only sets `api_key` keeps using Gemini (`gemini-3.8-flash`).
254
+
160
255
  ## .omamoriignore File
161
256
 
162
- The `.omamoriignore` file allows you to exclude specific files and directories from the scan target. Its behavior is similar to a `.gitignore` file, but with the following considerations:
257
+ The `.omamoriignore` file allows you to exclude specific files and directories from the scan target. However, if the `--force-scan-ignored` option is used, the settings in this file will be ignored. Its behavior is similar to a `.gitignore` file, but with the following considerations:
163
258
 
164
259
  * **Effective Modes:** It is only effective in `--all` mode or when scanning specified files/directories.
165
- * **Ineffective Mode:** In `diff` mode (i.e., `omamori scan` without arguments), the `.omamoriignore` file is ignored. This is because `diff` mode only targets changes retrieved by `git diff`.
166
- * **Format:** Each line specifies one pattern. Lines starting with `#` are treated as comments. It is recommended to append a `/` to directory patterns (e.g., `vendor/`). Patterns are evaluated using simple prefix matching (e.g., `config/initializers` matches `config/initializers/devise.rb`). Wildcards (`*`) are not currently supported.
260
+ * **Ineffective Mode:** In `diff` mode (i.e., `omamori scan` without arguments, or with `--base`), the `.omamoriignore` file is ignored. This is because `diff` mode only targets changes retrieved by `git diff`.
261
+ * **Format:** Each line specifies one pattern. Lines starting with `#` are treated as comments.
262
+ * A pattern ending with `/` excludes everything under that directory (e.g., `vendor/bundle/`).
263
+ * Other patterns are evaluated as globs against the path relative to the project root or the file name (e.g., `*.log`, `spec/fixtures/*.rb`).
167
264
 
168
265
  When you run the `omamori init` command, a `.omamoriignore` file pre-filled with patterns for common files and directories to ignore in a Rails project will be generated. You can edit this file as needed.
169
266
 
267
+ ## Using in CI
268
+
269
+ Pass `--ci` to `omamori init`, or generate the configuration later from `.omamorirc`:
270
+
271
+ ```bash
272
+ omamori ci-setup --ci github_actions # .github/workflows/omamori_scan.yml
273
+ omamori ci-setup --ci gitlab_ci # .gitlab-ci.yml
274
+ ```
275
+
276
+ The generated configuration scans the branch diff with `--base` on pull requests (merge requests) and the entire codebase with `--all` otherwise. It fetches the full history so the diff can be taken. It passes the environment variables your classifier and reporter need, and prints the names of the secrets (CI/CD variables on GitLab) to register.
277
+
278
+ `claude_code` / `codex` use the CLI's login on the machine. The generated configuration does not install or log in a CLI on the CI runner: in CI, add `--reporter PROVIDER --reporter-model MODEL` to the scan command to use an API reporter, or set up the runner yourself.
279
+
170
280
  ## Demo Files
171
281
 
172
282
  The `demo` directory contains example files with known vulnerabilities that can be used to demonstrate Omamori's capabilities.
@@ -181,15 +291,30 @@ To run Omamori on the demo files, you need to stage the changes in the `demo` di
181
291
  ```bash
182
292
  git add demo_
183
293
  ```
184
- 3. Now you can run Omamori on the staged demo files:
294
+ 3. Now you can run Omamori on the staged demo files (set it up with `omamori init --reporter ...` first):
185
295
  ```bash
186
296
  omamori scan
187
297
  ```
298
+ To try a classifier (Jev):
299
+ ```bash
300
+ omamori scan --classifier typesafe
301
+ ```
188
302
  Or to scan all files in the demo directory (after staging them):
189
303
  ```bash
190
304
  omamori scan --all
191
305
  ```
192
306
 
307
+ ## Measuring Detection Accuracy
308
+
309
+ `evals/` contains code changes with known answers. For each of the 35 risks there are two vulnerable changes and two "near miss" changes that look similar but are safe, plus a set of benign changes. XSS, SQL injection, mass assignment, IDOR, CSRF, and open redirect also have cases for specific patterns that are easy to miss. Use it to see how misses and false positives change when you switch the classifier or reporter.
310
+
311
+ ```bash
312
+ bundle exec ruby evals/run.rb --classifier typesafe --runs 3
313
+ bundle exec ruby evals/run.rb --classifier none --reporter claude_code --reporter-model sonnet
314
+ ```
315
+
316
+ See [evals/README.md](evals/README.md) for details.
317
+
193
318
  ## Contributing
194
319
 
195
320
  Bug reports and pull requests are welcome on GitHub. This project is intended to be a safe, welcoming space for collaboration.