standard_audit 0.5.0 → 0.6.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/{MIT-LICENSE → LICENSE} +3 -1
- data/README.md +41 -0
- data/lib/standard_audit/checks/retention.rb +58 -0
- data/lib/standard_audit/configuration.rb +16 -1
- data/lib/standard_audit/version.rb +1 -1
- data/lib/standard_audit.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 84f59bffd4df4a9174ba0a88645a4c7d5818eddf862b5badfb55c3880fb5849d
|
|
4
|
+
data.tar.gz: 7747fdff93658f34f3ba3a9bfa70ca40fdc581125d182c996319a161f5c30809
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 03f2f84e0418106b8899b9aaff009e95fdbb116f9eb98c37308d2b4ae41df3cfbfe9d9b1615bdd4beb4391d983989cb658e4195451cb56214a75e4cf46ba4375
|
|
7
|
+
data.tar.gz: 6b2e84e5bcd6e6e933535a6ae9e654deb3502e69b575d613044c7b02de843e2a8886c43a0c82bd8cb6313ff012510d36a52f290ca36dd778634c4b3c70cefb80
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.6.0] - 2026-06-24
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `config.retention_days` now defaults from the `STANDARD_AUDIT_RETENTION_DAYS` environment variable, so a deployment can opt into a retention window without a code change. Unset/blank/zero/negative/non-numeric resolves to `nil` (infinite retention — the compliance-safe default that never auto-deletes). Host apps can still override `config.retention_days` in their initializer.
|
|
15
|
+
- `StandardAudit::Checks::Retention` — a StandardHealth-compatible (duck-typed, no hard dependency) readiness check that flags unbounded retention on **production** deployments. Register it non-critical in `config/initializers/standard_health.rb`:
|
|
16
|
+
```ruby
|
|
17
|
+
c.register_check :audit_retention, StandardAudit::Checks::Retention, critical: false
|
|
18
|
+
```
|
|
19
|
+
When `APP_ENVIRONMENT == "production"` (falling back to `Rails.env.production?` so staging is not flagged) and `retention_days` is nil, it returns `:warn`, rolling `GET /health/ready` to `:degraded` — still HTTP 200, so it surfaces the advisory without failing the probe or blocking a deploy.
|
|
20
|
+
|
|
10
21
|
## [0.5.0] - 2026-04-29
|
|
11
22
|
|
|
12
23
|
### Changed
|
data/{MIT-LICENSE → LICENSE}
RENAMED
data/README.md
CHANGED
|
@@ -209,6 +209,8 @@ StandardAudit.configure do |config|
|
|
|
209
209
|
config.anonymizable_metadata_keys = %i[email name ip_address]
|
|
210
210
|
|
|
211
211
|
# -- Retention (schedule StandardAudit::CleanupJob to enforce) --
|
|
212
|
+
# Defaults from STANDARD_AUDIT_RETENTION_DAYS (see Retention below); set here
|
|
213
|
+
# to override per app. Leave unset for infinite retention.
|
|
212
214
|
config.retention_days = 90
|
|
213
215
|
end
|
|
214
216
|
```
|
|
@@ -339,6 +341,45 @@ File.write("export.json", JSON.pretty_generate(data))
|
|
|
339
341
|
|
|
340
342
|
Returns a hash with `subject`, `exported_at`, `total_records`, and a `records` array.
|
|
341
343
|
|
|
344
|
+
## Retention
|
|
345
|
+
|
|
346
|
+
`config.retention_days` controls how long audit logs are kept. It is only
|
|
347
|
+
enforced when you actually run cleanup (the `StandardAudit::CleanupJob` or the
|
|
348
|
+
`standard_audit:cleanup` rake task) — setting it alone deletes nothing.
|
|
349
|
+
|
|
350
|
+
It defaults from the `STANDARD_AUDIT_RETENTION_DAYS` environment variable, so a
|
|
351
|
+
deployment can opt into a retention window without a code change:
|
|
352
|
+
|
|
353
|
+
```bash
|
|
354
|
+
STANDARD_AUDIT_RETENTION_DAYS=365 # keep 365 days
|
|
355
|
+
# unset / blank / 0 / negative / non-numeric => nil => infinite retention
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
Infinite retention (the default) is the compliance-safe behavior: nothing is
|
|
359
|
+
ever auto-deleted. For financial/legal domains that is usually what you want;
|
|
360
|
+
enabling a finite window is a deliberate decision.
|
|
361
|
+
|
|
362
|
+
### Production retention warning (StandardHealth)
|
|
363
|
+
|
|
364
|
+
`StandardAudit::Checks::Retention` is a [StandardHealth](https://github.com/rarebit-one/standard_health)-compatible
|
|
365
|
+
check that flags unbounded retention **on production deployments** as an
|
|
366
|
+
advisory. Register it (non-critical) in `config/initializers/standard_health.rb`:
|
|
367
|
+
|
|
368
|
+
```ruby
|
|
369
|
+
StandardHealth.configure do |c|
|
|
370
|
+
c.register_check :audit_retention,
|
|
371
|
+
StandardAudit::Checks::Retention,
|
|
372
|
+
critical: false
|
|
373
|
+
end
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
When `APP_ENVIRONMENT == "production"` (falling back to `Rails.env.production?`
|
|
377
|
+
when that var is unset — so staging is not flagged) and `retention_days` is nil,
|
|
378
|
+
the check returns `:warn`. That rolls `GET /health/ready` up to `:degraded`,
|
|
379
|
+
which is **still HTTP 200** — it surfaces the advisory in the readiness JSON
|
|
380
|
+
without failing the probe or blocking a deploy. The check is duck-typed and has
|
|
381
|
+
no hard dependency on `standard_health`.
|
|
382
|
+
|
|
342
383
|
## Rake Tasks
|
|
343
384
|
|
|
344
385
|
```bash
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module StandardAudit
|
|
2
|
+
module Checks
|
|
3
|
+
# A StandardHealth-compatible readiness check that warns when audit_logs
|
|
4
|
+
# retention is unbounded on a production deployment.
|
|
5
|
+
#
|
|
6
|
+
# It is intentionally duck-typed (no hard dependency on standard_health):
|
|
7
|
+
# it exposes the `#initialize(name:, critical:)` + `#run` contract the
|
|
8
|
+
# StandardHealth aggregator calls, so it loads even where standard_health
|
|
9
|
+
# is absent.
|
|
10
|
+
#
|
|
11
|
+
# Register it (NON-critical) in config/initializers/standard_health.rb:
|
|
12
|
+
#
|
|
13
|
+
# c.register_check :audit_retention,
|
|
14
|
+
# StandardAudit::Checks::Retention,
|
|
15
|
+
# critical: false
|
|
16
|
+
#
|
|
17
|
+
# A :warn result rolls /health/ready up to :degraded, which is still
|
|
18
|
+
# HTTP 200 — it surfaces the advisory in the readiness JSON WITHOUT failing
|
|
19
|
+
# the probe or blocking a deploy. Only a *critical* check failure returns
|
|
20
|
+
# 503, and this check is never critical.
|
|
21
|
+
#
|
|
22
|
+
# "Production" is ENV["APP_ENVIRONMENT"] == "production" when that var is
|
|
23
|
+
# set (so staging — which also runs RAILS_ENV=production — is not flagged);
|
|
24
|
+
# otherwise it falls back to Rails.env.production?.
|
|
25
|
+
class Retention
|
|
26
|
+
def initialize(name: :audit_retention, critical: false)
|
|
27
|
+
@name = name
|
|
28
|
+
@critical = critical
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def run
|
|
32
|
+
unless production?
|
|
33
|
+
return { status: :ok, detail: "retention advisory only runs on production deployments" }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
days = StandardAudit.config.retention_days
|
|
37
|
+
return { status: :ok, retention_days: days } if days
|
|
38
|
+
|
|
39
|
+
{
|
|
40
|
+
status: :warn,
|
|
41
|
+
message: "audit_logs retention is unbounded on production. Set " \
|
|
42
|
+
"STANDARD_AUDIT_RETENTION_DAYS (or config.retention_days) and schedule " \
|
|
43
|
+
"StandardAudit::CleanupJob, or treat indefinite retention as a deliberate " \
|
|
44
|
+
"compliance decision."
|
|
45
|
+
}
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def production?
|
|
51
|
+
app_env = ENV["APP_ENVIRONMENT"].to_s
|
|
52
|
+
return app_env == "production" unless app_env.empty?
|
|
53
|
+
|
|
54
|
+
defined?(Rails) && Rails.respond_to?(:env) && Rails.env.production?
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -45,7 +45,22 @@ module StandardAudit
|
|
|
45
45
|
]
|
|
46
46
|
@metadata_builder = nil
|
|
47
47
|
@anonymizable_metadata_keys = %i[email name ip_address]
|
|
48
|
-
|
|
48
|
+
|
|
49
|
+
# Retention defaults from ENV so it can be set per-environment without a
|
|
50
|
+
# code change. Unset/blank/non-positive => nil (infinite retention, the
|
|
51
|
+
# compliance-safe default that never auto-deletes). A host app can still
|
|
52
|
+
# override with `config.retention_days = N` in its initializer.
|
|
53
|
+
@retention_days = self.class.retention_days_from_env
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Parses STANDARD_AUDIT_RETENTION_DAYS into a positive Integer, or nil when
|
|
57
|
+
# unset/blank/zero/negative/non-numeric (=> infinite retention).
|
|
58
|
+
def self.retention_days_from_env
|
|
59
|
+
raw = ENV["STANDARD_AUDIT_RETENTION_DAYS"]
|
|
60
|
+
return nil if raw.nil? || raw.strip.empty?
|
|
61
|
+
|
|
62
|
+
days = Integer(raw, exception: false)
|
|
63
|
+
days&.positive? ? days : nil
|
|
49
64
|
end
|
|
50
65
|
|
|
51
66
|
def subscribe_to(pattern)
|
data/lib/standard_audit.rb
CHANGED
|
@@ -5,6 +5,7 @@ require "standard_audit/subscriber"
|
|
|
5
5
|
require "standard_audit/event_subscriber"
|
|
6
6
|
require "standard_audit/auditable"
|
|
7
7
|
require "standard_audit/audit_scope"
|
|
8
|
+
require "standard_audit/checks/retention"
|
|
8
9
|
|
|
9
10
|
module StandardAudit
|
|
10
11
|
# Metadata keys owned internally by StandardAudit. Never filtered by
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: standard_audit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jaryl Sim
|
|
@@ -89,7 +89,7 @@ extensions: []
|
|
|
89
89
|
extra_rdoc_files: []
|
|
90
90
|
files:
|
|
91
91
|
- CHANGELOG.md
|
|
92
|
-
-
|
|
92
|
+
- LICENSE
|
|
93
93
|
- README.md
|
|
94
94
|
- Rakefile
|
|
95
95
|
- app/jobs/standard_audit/cleanup_job.rb
|
|
@@ -105,6 +105,7 @@ files:
|
|
|
105
105
|
- lib/standard_audit.rb
|
|
106
106
|
- lib/standard_audit/audit_scope.rb
|
|
107
107
|
- lib/standard_audit/auditable.rb
|
|
108
|
+
- lib/standard_audit/checks/retention.rb
|
|
108
109
|
- lib/standard_audit/configuration.rb
|
|
109
110
|
- lib/standard_audit/engine.rb
|
|
110
111
|
- lib/standard_audit/event_subscriber.rb
|