beskar 0.1.0 → 0.2.1

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 (90) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +177 -19
  3. data/README.md +142 -122
  4. data/app/channels/concerns/beskar/channels/session_security.rb +46 -0
  5. data/app/controllers/beskar/administrative_actions_controller.rb +16 -0
  6. data/app/controllers/beskar/application_controller.rb +69 -25
  7. data/app/controllers/beskar/banned_ips_controller.rb +116 -141
  8. data/app/controllers/beskar/dashboard_controller.rb +20 -28
  9. data/app/controllers/beskar/security_events_controller.rb +37 -55
  10. data/app/controllers/concerns/beskar/controllers/audit_export.rb +54 -0
  11. data/app/controllers/concerns/beskar/controllers/security_tracking.rb +76 -48
  12. data/app/controllers/concerns/beskar/controllers/session_security.rb +29 -0
  13. data/app/jobs/beskar/notification_job.rb +33 -0
  14. data/app/mailers/beskar/security_mailer.rb +59 -0
  15. data/app/models/beskar/administrative_action.rb +41 -0
  16. data/app/models/beskar/banned_ip.rb +91 -132
  17. data/app/models/beskar/security_event.rb +37 -4
  18. data/app/models/beskar/security_state.rb +58 -0
  19. data/app/services/beskar/banned_ip_manager.rb +16 -6
  20. data/app/views/beskar/administrative_actions/index.html.erb +33 -0
  21. data/app/views/beskar/administrative_actions/show.html.erb +21 -0
  22. data/app/views/beskar/banned_ips/edit.html.erb +25 -89
  23. data/app/views/beskar/banned_ips/index.html.erb +20 -62
  24. data/app/views/beskar/banned_ips/new.html.erb +18 -138
  25. data/app/views/beskar/banned_ips/review.html.erb +24 -0
  26. data/app/views/beskar/banned_ips/show.html.erb +18 -15
  27. data/app/views/beskar/dashboard/index.html.erb +6 -6
  28. data/app/views/beskar/security_events/index.html.erb +18 -16
  29. data/app/views/beskar/security_events/show.html.erb +10 -20
  30. data/app/views/beskar/shared/_export_form.html.erb +10 -0
  31. data/app/views/beskar/shared/_waf_analysis.html.erb +25 -0
  32. data/app/views/layouts/beskar/_behavior.html.erb +121 -0
  33. data/app/views/layouts/beskar/application.html.erb +9 -76
  34. data/config/routes.rb +10 -21
  35. data/db/migrate/20251016000001_create_beskar_security_events.rb +3 -3
  36. data/db/migrate/20260910000001_create_beskar_security_states.rb +14 -0
  37. data/db/migrate/20260911000001_create_beskar_administrative_actions.rb +22 -0
  38. data/db/migrate/20260911000002_expand_administrative_action_targets.rb +6 -0
  39. data/docs/README.md +73 -0
  40. data/docs/archive/project-documentation.md +659 -0
  41. data/docs/audits/project-review.md +437 -0
  42. data/docs/audits/repair-status.md +216 -0
  43. data/docs/guides/audit-and-waf.md +188 -0
  44. data/docs/guides/audit-lifecycle.md +172 -0
  45. data/docs/guides/authentication.md +213 -0
  46. data/docs/guides/configuration.md +182 -0
  47. data/docs/guides/dashboard-and-search.md +251 -0
  48. data/docs/guides/notifications-and-recovery.md +157 -0
  49. data/docs/guides/risk-scoring.md +116 -0
  50. data/docs/operations/monitor-only-mode.md +85 -0
  51. data/docs/operations/security-hardening.md +167 -0
  52. data/docs/operations/state-storage.md +144 -0
  53. data/docs/research/rust-performance-assessment.md +69 -0
  54. data/lib/beskar/configuration.rb +84 -13
  55. data/lib/beskar/configuration_validator.rb +188 -0
  56. data/lib/beskar/devise_authentication.rb +24 -0
  57. data/lib/beskar/engine.rb +21 -88
  58. data/lib/beskar/logger.rb +30 -35
  59. data/lib/beskar/middleware/request_analyzer.rb +49 -82
  60. data/lib/beskar/models/security_trackable_authenticable.rb +72 -93
  61. data/lib/beskar/models/security_trackable_devise.rb +32 -23
  62. data/lib/beskar/models/security_trackable_generic.rb +169 -212
  63. data/lib/beskar/risk_level.rb +22 -0
  64. data/lib/beskar/services/account_locker.rb +85 -76
  65. data/lib/beskar/services/administrative_audit.rb +36 -0
  66. data/lib/beskar/services/administrative_bans.rb +104 -0
  67. data/lib/beskar/services/audit_data.rb +72 -0
  68. data/lib/beskar/services/authentication.rb +31 -0
  69. data/lib/beskar/services/authentication_attempt.rb +148 -0
  70. data/lib/beskar/services/ban_expiry.rb +28 -0
  71. data/lib/beskar/services/device_detector.rb +32 -41
  72. data/lib/beskar/services/event_search.rb +58 -0
  73. data/lib/beskar/services/geolocation_service.rb +83 -114
  74. data/lib/beskar/services/ip_whitelist.rb +31 -40
  75. data/lib/beskar/services/location_assessment.rb +109 -0
  76. data/lib/beskar/services/native_account_lock.rb +82 -0
  77. data/lib/beskar/services/notifications.rb +46 -0
  78. data/lib/beskar/services/rate_limiter.rb +103 -125
  79. data/lib/beskar/services/request_context.rb +69 -0
  80. data/lib/beskar/services/risk_assessment.rb +58 -0
  81. data/lib/beskar/services/session_revocation.rb +62 -0
  82. data/lib/beskar/services/waf.rb +166 -280
  83. data/lib/beskar/services/waf_request.rb +70 -0
  84. data/lib/beskar/version.rb +1 -1
  85. data/lib/beskar/warden_authentication.rb +53 -0
  86. data/lib/beskar.rb +53 -4
  87. data/lib/generators/beskar/install/install_generator.rb +36 -36
  88. data/lib/generators/beskar/install/templates/initializer.rb.tt +105 -20
  89. data/lib/tasks/beskar_tasks.rake +15 -19
  90. metadata +61 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 025703c477080d31ed167a7012be2cd390d3d73b2447b61624bffd3243f1aa6b
4
- data.tar.gz: a056e8c20364351e9f96734836991be7949a92b279dfba05a6b327dad0b3d823
3
+ metadata.gz: d9899541c9baa5b2c2a0ac7106dba36f9fff668962e5b70e11d34efa483a7d76
4
+ data.tar.gz: 6f7e9d0f5f725ea486974958a517ec32a725e5a2723efa7bb5e8738e794b39ca
5
5
  SHA512:
6
- metadata.gz: 1a70b96954525ebdf9867fcc1656b5313e111a0fd6c4e2e31f111d3d8c9320a156f5d29ed582ee06c5d418f26c7c04601147d749c7825747b601ae1975855211
7
- data.tar.gz: 6523638cd97d91b78779f5fd8cf6276e5d07c39f3ba87ec342abae007ffed99dd505adf346917ed3601be0085d81ff247c874feed92effe27b34e94d523ab7c5
6
+ metadata.gz: 6f79580e66cc3c2e777d10b65fb14e4e7bc6bc7ea2abb86763cea85b059f439867a2a8167f41896bbed907b6d8cfdcbf9ca00407407cc22881ac42ea69e09b63
7
+ data.tar.gz: 1cede8ef21ba6c4a3704cac25b055e42719c543fdfdefd10916e56576f0b18f644723ac73528979a20a4a0c489d8178b656d38cf8d0bc072f1d2d1c901354ebe
data/CHANGELOG.md CHANGED
@@ -2,10 +2,172 @@
2
2
 
3
3
  All notable changes to Beskar will be documented in this file.
4
4
 
5
+ The entries below include historical behavior. For the current contract and
6
+ upgrade requirements, use the [documentation index](docs/README.md) and
7
+ [repair status](docs/audits/repair-status.md).
8
+
5
9
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
10
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
11
 
8
- ## [Unreleased]
12
+ ## Unreleased
13
+
14
+ ## 0.2.1 - 2026-11-04
15
+
16
+ Bug fixes for monitor mode and requests without a client address, plus
17
+ requested-path evidence for WAF threats in the dashboard.
18
+
19
+ ### Changed
20
+
21
+ - WAF events and ban metadata now retain `waf_analysis.request_path`: the
22
+ requested path with its original percent encoding, limited to 1,024 characters.
23
+ Queries and fragments are removed and host `request_path` filters apply. Event
24
+ and ban details show it beside the matched rules, and the events list has a
25
+ Requested Path column. Records created before this release show "Not recorded".
26
+ - The dashboard overview labels top threat IPs as "in the selected period".
27
+
28
+ ### Fixed
29
+
30
+ - Monitor mode and whitelisted addresses no longer deny a login when one request
31
+ sets a second user on a scope. Each user is recorded as a login of its own.
32
+ Enforcement still denies it as `identity_changed`.
33
+ - A request with no usable client address no longer raises
34
+ `IPAddr::InvalidAddressError` in the middleware. `RequestContext.ip` returns nil,
35
+ and the middleware passes the request to the application without ban or WAF
36
+ checks. A login from such a request succeeds without an audit row. Logins
37
+ through non-password Warden strategies (such as OAuth) from such a request also
38
+ reach authentication; rate limiting with no applicable tier is now an allowed
39
+ no-op instead of raising `ArgumentError`.
40
+
41
+ ## 0.2.0 - 2026-09-21
42
+
43
+ Security hardening, coordinated enforcement, and auditable administration.
44
+ This release includes breaking changes for 0.1.0 installations; read the
45
+ [rollout checklist](docs/operations/security-hardening.md#rollout) before upgrading.
46
+
47
+ ### Breaking changes
48
+
49
+ - Security state is now coordinated through the database, independently of the
50
+ `Rails.cache` backend. Apply the new state and administrative-history migrations
51
+ before starting upgraded workers. Users, sessions, and security state must share
52
+ the writer connection pool; old cache counters are not imported.
53
+ - Dashboard authentication no longer grants administrative permissions by itself.
54
+ Configure `authorize_admin` separately for `:read`, `:manage_bans`, `:export`,
55
+ and `:read_audit`. Ban mutations and exports require a trusted `audit_actor`,
56
+ a reason, and successfully recorded administrative history.
57
+ - Configuration is validated and sealed at startup. Invalid or unsupported
58
+ settings stop boot; direct runtime mutation is rejected. Runtime changes through
59
+ `Beskar.configure` require separate authorization, actor/reason/request context,
60
+ and an audit record. Runtime publication remains process-local.
61
+ - Global authentication budgets and request-wide blocking for exhausted IP login
62
+ quotas now default off. Opt in with `global_attempts[:enabled]` and
63
+ `ip_attempts[:block_requests]` under `rate_limiting` if those policies are needed.
64
+ Notifications and automatic pattern analysis also default off and require
65
+ explicit host configuration when enabled.
66
+ - Monitor-only mode records observations in separate state without automatically
67
+ creating IP bans, locking accounts, or resetting passwords. Review bans created
68
+ by older monitor-mode versions before enabling enforcement; existing bans are
69
+ not automatically removed.
70
+ - Devise session and remember-cookie salts now include a durable revocation
71
+ generation, causing a one-time sign-out of existing credentials. Confirmed locks
72
+ revoke prior credentials regardless of `immediate_signout`; unlocking does not
73
+ restore them. Risk-based locking itself remains opt-in.
74
+ - Rails-native authentication must use the admission, session-creation, and
75
+ session-resumption guards. OAuth, custom tokens, API controllers, and Action Cable
76
+ require the appropriate host integration; they are not automatically protected
77
+ merely by mounting the engine.
78
+ - Deleting an account retains its security events unchanged, including their
79
+ original account identifiers. Security events and administrative history reject
80
+ ordinary model-level rewrites/deletes. This is not anonymization or protection
81
+ against privileged SQL/bulk updates; hosts still own retention policy.
82
+ - Exports are bounded to 1,000 rows per cursor page and use filtered fields and
83
+ CSV formula-injection defenses. Scripted consumers must supply an audit reason
84
+ on every page and accommodate the revised export contract.
85
+
86
+ ### Added
87
+
88
+ - Framework-neutral authentication admission, API and Action Cable session guards,
89
+ explicit session revocation, and persistent Rails-native account locks with
90
+ automatic or manual-only unlock policies.
91
+ - An append-only administrative journal and read-only history dashboard for ban
92
+ changes, export preparation, and authorized runtime configuration changes, with
93
+ actor, reason, request/operation correlation, and filtered before/after state.
94
+ - Opt-in post-commit notification delivery jobs with bounded retries, plus an
95
+ explicit host-job contract for background analysis. Password recovery remains
96
+ owned by the host application or Devise; no built-in analyzer or recovery-token
97
+ issuer is supplied.
98
+ - Organized, gem-packaged guides and operational contracts under `docs/`, including
99
+ authentication coverage, deployment requirements, and remaining limitations.
100
+ - Complete dashboard initializer examples for Rails built-in authentication and
101
+ Devise, including permission checks and audit identity. The Rails example checks
102
+ the signed session cookie and session revocation, with explicit instructions to
103
+ include `SecurityTrackableAuthenticable` in the host user model. Installation
104
+ guidance explains Devise's Warden scopes and the dashboard controller context.
105
+
106
+ ### Security and fixes
107
+
108
+ - Enforce Devise password/HTTP Basic admission before credential verification;
109
+ coordinate IP/account limits and backoff across workers without double-counting
110
+ outcomes. Required enforcement-state failures deny access while optional audit
111
+ failures do not undo authentication decisions.
112
+ - Honor monitor/whitelist policy for automatic enforcement and isolate observation
113
+ counters. Whitelisted attempts do not consume enforced global capacity.
114
+ - Fix lost updates in rate-limit/WAF state, concurrent ban extensions, and mixed
115
+ administrative/automatic changes. MySQL locking reads prevent stale transaction
116
+ snapshots from overwriting ban updates or missing sessions during revocation;
117
+ native cleanup also ignores stale loaded associations and preserves callbacks.
118
+ - Read ban decisions from the authoritative database, preserve permanent bans
119
+ during cleanup, normalize individual IP addresses, and reject invalid durations.
120
+ Administrative extensions no longer fabricate additional violations.
121
+ - Retain security events after account deletion, tolerate missing accounts in
122
+ dashboards/exports, and make bulk administrative changes and their history
123
+ transactional. Failed or aborted persistence no longer reports success.
124
+ - Bound and filter audit metadata, headers, identities, and error logging; use
125
+ Rails-resolved client IPs and consistent Rack 3 headers and retry deadlines.
126
+ - Correct timestamped geographic risk history, impossible-travel calculations,
127
+ provider/cache isolation, and shared decision/audit evidence. Mock geography
128
+ cannot supply geographic risk evidence; repeated IP use and unlocks no longer
129
+ grant implicit trust discounts.
130
+ - Narrow WAF exception scoring to relevant evidence by default, improve path
131
+ canonicalization and exclusions, and prevent duplicate charges for one request.
132
+ - Fix dashboard reporting/search/pagination, UTC and DST-sensitive ban editing,
133
+ unchanged microsecond expiry preservation, persistent validation messages, and
134
+ nonce-based scripts. Native forms retain CSRF protection and work with JavaScript
135
+ disabled or host Turbo loaded.
136
+ - Fix migration installation, MySQL JSON defaults and foreign-key types, Ruby 4
137
+ test dependencies, Chrome sandbox setup, and browser navigation synchronization.
138
+ CI covers Ruby 3.4/4.0, SQLite, PostgreSQL, MySQL, and Chromium system tests.
139
+
140
+ ### Removed
141
+
142
+ - Nonfunctional versioned API routes and their helpers. Dashboard resource exports
143
+ remain available behind their dedicated permissions.
144
+ - Claims of support for unimplemented capabilities: general SQL injection/XSS
145
+ filtering, JavaScript challenges, honeypots, and a built-in automatic pattern
146
+ analyzer. Unsupported custom lock strategies and geolocation providers are
147
+ rejected rather than silently accepted.
148
+
149
+ ### Upgrading from 0.1.0
150
+
151
+ 1. Copy and apply all engine migrations with `bin/rails beskar:install:migrations`
152
+ and `bin/rails db:migrate`, including the administrative-action target expansion.
153
+ 2. Configure administrative permissions, actor resolution, and reasons; review
154
+ [configuration](docs/guides/configuration.md) and
155
+ [audit lifecycle](docs/guides/audit-lifecycle.md) for the changed contracts.
156
+ 3. Adopt the [authentication guards](docs/guides/authentication.md), review all
157
+ credential entry points, and plan the one-time Devise sign-out. Legacy custom
158
+ tokens without a revocation generation must be rejected or reissued.
159
+ 4. Drain old workers and restart from the same reviewed configuration. Review
160
+ legacy bans and risk evidence in monitor mode before enforcing, and schedule
161
+ `bin/rails beskar:cleanup_security_state` to reclaim expired enforcement state.
162
+ This task does not purge audit events or account-lifetime revocation generations.
163
+ 5. Validate host recovery/delivery, shared-NAT behavior, and database load/failure
164
+ handling in staging. Cache independence does not remove database availability
165
+ requirements or establish production capacity guarantees.
166
+
167
+ ## 0.1.0 - 2025-11-25
168
+
169
+ Historical notes carried forward from the 0.1.0 release. In particular, the
170
+ monitor-mode ban creation described below is superseded by 0.2.0.
9
171
 
10
172
  ### ⚠️ BREAKING CHANGES
11
173
 
@@ -14,7 +176,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
14
176
  - Use `config.monitor_only = true/false` at the configuration root level instead
15
177
  - The method `Beskar.configuration.waf_monitor_only?` has been **removed**
16
178
  - Use `Beskar.configuration.monitor_only?` instead
17
- - See [BREAKING_CHANGES.md](BREAKING_CHANGES.md) for detailed migration guide
179
+ - See [Current upgrade guidance](docs/operations/security-hardening.md) for detailed migration guide
18
180
 
19
181
  - **Dashboard authentication now required in all environments**
20
182
  - Previous behavior: Dashboard allowed access in development/test without authentication
@@ -46,7 +208,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
46
208
  - Configurable authentication via `config.authenticate_admin` proc
47
209
  - Rails 7+ compatible with built-in CSRF protection
48
210
  - Install generator for easy setup (`rails generate beskar:install`)
49
- - Full documentation in [DASHBOARD.md](DASHBOARD.md)
211
+ - Full documentation in [Current dashboard guide](docs/guides/dashboard-and-search.md)
50
212
  - **WAF Rails Exception Detection** - Enhanced security through Rails exception analysis
51
213
  - Detects `ActionController::UnknownFormat` exceptions (e.g., `/users/1.exe`) as potential scanning attempts
52
214
  - Detects `ActionDispatch::RemoteIp::IpSpoofAttackError` as critical IP spoofing attacks
@@ -104,10 +266,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
104
266
  ### Documentation
105
267
 
106
268
  - Updated README with new configuration structure
107
- - Enhanced MONITOR_ONLY_MODE.md with examples of querying ban records
269
+ - Enhanced docs/operations/monitor-only-mode.md with examples of querying ban records
108
270
  - Added migration guide in BREAKING_CHANGES.md
109
- - Created PROJECT_DOCUMENTATION.md for development reference
110
- - Updated PROJECT_DOCUMENTATION.md with comprehensive dashboard authentication section
271
+ - Created docs/archive/project-documentation.md for development reference
272
+ - Updated docs/archive/project-documentation.md with comprehensive dashboard authentication section
111
273
  - Documented authentication flow and architecture
112
274
  - Added configuration examples and design principles
113
275
  - Included test coverage details
@@ -117,27 +279,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
117
279
  - Clear warnings about development-only bypass patterns
118
280
 
119
281
 
120
- ### Versioning Policy
282
+ ## Versioning policy
121
283
 
122
- - **Major version (X.0.0)**: Breaking changes that require code changes
123
- - **Minor version (0.X.0)**: New features, backward compatible
124
- - **Patch version (0.0.X)**: Bug fixes and minor improvements
284
+ - Before 1.0, minor releases (0.X.0) may include explicitly documented breaking changes.
285
+ - Patch releases (0.X.Y) contain backward-compatible fixes.
286
+ - From 1.0 onward, breaking changes require a major version increment.
125
287
 
126
- ### Upgrade Guide
288
+ ## Upgrade guide
127
289
 
128
290
  When upgrading between versions with breaking changes:
129
291
 
130
- 1. Read the [BREAKING_CHANGES.md](BREAKING_CHANGES.md) file
292
+ 1. Read the [Current upgrade guidance](docs/operations/security-hardening.md) file
131
293
  2. Update your configuration according to the migration guide
132
294
  3. Run any new migrations: `rails db:migrate`
133
295
  4. Test in development/staging before deploying to production
134
296
  5. Start with `monitor_only = true` to verify behavior
135
297
 
136
- ### Support
137
-
138
- - GitHub Issues: https://github.com/humadroid-io/beskar/issues
139
- - Documentation: https://humadroid.io/beskar
140
-
141
- ---
298
+ ## Support
142
299
 
143
- [Unreleased]: https://github.com/humadroid-io/beskar/compare/v0.0.2...HEAD
300
+ - [GitHub issues](https://github.com/AuditBadger-com/beskar/issues)
301
+ - [Documentation](docs/README.md)