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