omamori 0.1.2 → 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 +34 -14
  5. data/README.md +202 -49
  6. data/README_ja.md +204 -46
  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 +30 -22
  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 +96 -19
  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 +89 -69
  36. data/lib/omamori/core_runner.rb +485 -286
  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 +61 -14
  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: 2c6e52c517c84f78c559299c80b6d0c3817ea6b1cc7cdb9e0bc041bb2c6ccad1
4
- data.tar.gz: c654919d2b1db48f3bb286e55ccd8909a82b9c69d4c3fd88d67fadfe03a621e7
3
+ metadata.gz: 8f3533e1d6c54d0dc29d8c7eb569e9931cdd55b8214180e7380f3cf7080c0caa
4
+ data.tar.gz: ed4ca270d8a0d490b1c756e6508509609af5c495094ea3dd81e196baa91e6d66
5
5
  SHA512:
6
- metadata.gz: ded5134ca28c5835ba121b637c7105a5cbe6930777275562fbc49b45fcfc021ddb7d57f5c26c1bbb5958a56f52d1f7e9df6175de1274de19fee2683081db3bfa
7
- data.tar.gz: c495125630ff1467816c47c21888d4e984c08a5e074cc8f904a10045860c11e17212432ef146bd5a37324601589dca67c4ffe1546b2196518d9b3faa216e79cf
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,30 +1,41 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- omamori (0.1.2)
4
+ omamori (0.2.0)
5
+ brakeman (~> 7.0)
6
+ bundler-audit (~> 0.9.2)
5
7
  colorize (~> 0.8)
6
8
  dotenv (~> 2.0)
7
- ruby-gemini-api (~> 0.1.1)
9
+ ruby_llm (~> 2.1)
8
10
 
9
11
  GEM
10
12
  remote: https://rubygems.org/
11
13
  specs:
12
14
  ast (2.4.3)
15
+ base64 (0.3.0)
16
+ brakeman (7.0.2)
17
+ racc
18
+ bundler-audit (0.9.2)
19
+ bundler (>= 1.2.0, < 3)
20
+ thor (~> 1.0)
13
21
  colorize (0.8.1)
14
- diff-lcs (1.6.1)
22
+ diff-lcs (1.6.2)
15
23
  dotenv (2.8.1)
16
24
  faraday (2.13.1)
17
25
  faraday-net_http (>= 2.0, < 3.5)
18
26
  json
19
27
  logger
20
- faraday-multipart (1.1.0)
28
+ faraday-multipart (1.2.0)
21
29
  multipart-post (~> 2.0)
22
30
  faraday-net_http (3.4.0)
23
31
  net-http (>= 0.5.0)
24
- json (2.11.3)
25
- language_server-protocol (3.17.0.4)
32
+ faraday-retry (2.4.0)
33
+ faraday (~> 2.0)
34
+ json (2.12.0)
35
+ language_server-protocol (3.17.0.5)
26
36
  lint_roller (1.1.0)
27
37
  logger (1.7.0)
38
+ marcel (2.1.0)
28
39
  multipart-post (2.4.1)
29
40
  net-http (0.6.0)
30
41
  uri
@@ -43,14 +54,14 @@ GEM
43
54
  rspec-mocks (~> 3.13.0)
44
55
  rspec-core (3.13.3)
45
56
  rspec-support (~> 3.13.0)
46
- rspec-expectations (3.13.3)
57
+ rspec-expectations (3.13.4)
47
58
  diff-lcs (>= 1.2.0, < 2.0)
48
59
  rspec-support (~> 3.13.0)
49
- rspec-mocks (3.13.2)
60
+ rspec-mocks (3.13.4)
50
61
  diff-lcs (>= 1.2.0, < 2.0)
51
62
  rspec-support (~> 3.13.0)
52
- rspec-support (3.13.2)
53
- rubocop (1.75.3)
63
+ rspec-support (3.13.3)
64
+ rubocop (1.75.6)
54
65
  json (~> 2.3)
55
66
  language_server-protocol (~> 3.17.0.2)
56
67
  lint_roller (~> 1.1.0)
@@ -64,15 +75,24 @@ GEM
64
75
  rubocop-ast (1.44.1)
65
76
  parser (>= 3.3.7.2)
66
77
  prism (~> 1.4)
67
- ruby-gemini-api (0.1.1)
68
- faraday (~> 2.0)
69
- faraday-multipart (~> 1.0)
70
- json (~> 2.0)
71
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)
90
+ thor (1.3.2)
72
91
  unicode-display_width (3.1.4)
73
92
  unicode-emoji (~> 4.0, >= 4.0.4)
74
93
  unicode-emoji (4.0.4)
75
94
  uri (1.0.3)
95
+ zeitwerk (2.8.3)
76
96
 
77
97
  PLATFORMS
78
98
  ruby
data/README.md CHANGED
@@ -9,102 +9,213 @@ 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`) or the entire codebase 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.
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.
23
25
 
24
- ## Installation
26
+ ## How It Works
25
27
 
26
- Add this line to your application's Gemfile:
28
+ Omamori's AI analysis has two roles.
27
29
 
28
- ```ruby
29
- gem 'omamori'
30
- ```
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.
31
32
 
32
- And then execute:
33
+ With a classifier, a scan works like this:
33
34
 
34
- ```bash
35
- bundle install
36
- ```
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.
37
38
 
38
- 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.
39
40
 
40
- ```bash
41
- gem install omamori
42
- ```
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.
43
42
 
44
- ## Usage
43
+ ## Getting Started
45
44
 
46
- ### Initialization
45
+ 1. Add omamori to your Gemfile and install it.
47
46
 
48
- To generate an initial configuration file (`.omamorirc`), run:
47
+ ```ruby
48
+ gem 'omamori', group: :development, require: false
49
+ ```
49
50
 
50
- ```bash
51
- omamori init
52
- ```
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).
56
+
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
+ ```
53
70
 
54
- Edit the generated `.omamorirc` file to configure your Gemini API key, preferred model, checks to perform, and other settings.
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
55
100
 
56
101
  ### Scanning
57
102
 
103
+ Any setting in `.omamorirc` can be changed for one run with flags (see Choosing the Classifier and Reporter).
104
+
58
105
  Scan staged changes (default):
59
106
 
60
107
  ```bash
61
108
  omamori scan
62
109
  ```
63
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
+
64
117
  Scan the entire codebase:
65
118
 
66
119
  ```bash
67
120
  omamori scan --all
68
121
  ```
122
+ This mode respects the `.omamoriignore` file.
69
123
 
70
- Specify output format (console, html, json):
124
+ Scan specific files or directories:
71
125
 
72
126
  ```bash
73
- bundle exec omamori scan --format html
74
- bundle exec omamori scan --all --format json
127
+ omamori scan app/controllers/users_controller.rb app/models/user.rb config/routes.rb lib/
75
128
  ```
129
+ This mode also respects the `.omamoriignore` file.
76
130
 
77
- ### AI Analysis Only
131
+ Specify the output format (console, html, json):
132
+
133
+ ```bash
134
+ omamori scan --format html
135
+ omamori scan --all --format json
136
+ ```
78
137
 
79
- To perform only AI analysis without running static analysis tools, use the `--ai` option:
138
+ Run only AI analysis, skipping static analysis tools:
80
139
 
81
140
  ```bash
82
141
  omamori scan --ai
83
142
  ```
84
143
 
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)).
147
+
148
+ ```bash
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
153
+ ```
154
+
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**
169
+
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 |
175
+
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.
179
+
180
+ ```bash
181
+ omamori scan --base main --classifier typesafe --reporter-fallback claude_code --reporter-fallback-model sonnet
182
+ ```
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
+
85
186
  ## Configuration
86
187
 
87
188
  The `.omamorirc` file in the project root directory allows you to customize Omamori's behavior.
88
189
 
89
- Here's a detailed breakdown of the configuration options:
90
-
91
190
  ```yaml
92
191
  # .omamorirc
93
192
  # Configuration file for omamori gem
94
193
 
95
- # Gemini API Key (required for AI analysis)
96
- # You can also set this via the GEMINI_API_KEY environment variable
97
- api_key: YOUR_GEMINI_API_KEY # Replace with your actual API key
98
-
99
- # Gemini Model to use (optional, default: gemini-1.5-pro-latest)
100
- model: gemini-2.5-flash-preview-04-17
101
-
102
- # 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)
103
215
  # checks:
104
- # xss: true
105
- # csrf: true
106
- # idor: true
107
- # ... # Add other checks as they become available
216
+ # - xss
217
+ # - csrf
218
+ # - idor
108
219
 
109
220
  # Custom prompt templates (optional)
110
221
  # prompt_templates:
@@ -127,9 +238,9 @@ model: gemini-2.5-flash-preview-04-17
127
238
  # language: ja
128
239
  ```
129
240
 
130
- * `api_key`: Your API key for accessing the Gemini API. Can also be set via the `GEMINI_API_KEY` environment variable.
131
- * `model`: The Gemini model to use for AI analysis. Defaults to `gemini-1.5-pro-latest`.
132
- * `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.
133
244
  * `prompt_templates`: Define custom prompt templates for AI analysis.
134
245
  * `report`: Configure report output settings.
135
246
  * `output_path`: The output directory or prefix for HTML and JSON reports.
@@ -139,6 +250,33 @@ model: gemini-2.5-flash-preview-04-17
139
250
  * `bundler_audit`: Additional command-line options for Bundler-Audit.
140
251
  * `language`: Language setting for the details provided in AI analysis reports. Defaults to English (`en`).
141
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
+
255
+ ## .omamoriignore File
256
+
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:
258
+
259
+ * **Effective Modes:** It is only effective in `--all` mode or when scanning specified files/directories.
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`).
264
+
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.
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
+
142
280
  ## Demo Files
143
281
 
144
282
  The `demo` directory contains example files with known vulnerabilities that can be used to demonstrate Omamori's capabilities.
@@ -153,15 +291,30 @@ To run Omamori on the demo files, you need to stage the changes in the `demo` di
153
291
  ```bash
154
292
  git add demo_
155
293
  ```
156
- 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):
157
295
  ```bash
158
296
  omamori scan
159
297
  ```
298
+ To try a classifier (Jev):
299
+ ```bash
300
+ omamori scan --classifier typesafe
301
+ ```
160
302
  Or to scan all files in the demo directory (after staging them):
161
303
  ```bash
162
304
  omamori scan --all
163
305
  ```
164
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
+
165
318
  ## Contributing
166
319
 
167
320
  Bug reports and pull requests are welcome on GitHub. This project is intended to be a safe, welcoming space for collaboration.