standard_audit 0.5.0 → 0.7.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.
@@ -1,10 +1,14 @@
1
1
  require "standard_audit/version"
2
2
  require "standard_audit/engine"
3
3
  require "standard_audit/configuration"
4
+ require "standard_audit/metadata_filter"
5
+ require "standard_audit/sensitive_keys_dry_run"
4
6
  require "standard_audit/subscriber"
5
7
  require "standard_audit/event_subscriber"
8
+ require "standard_audit/reference_preloading"
6
9
  require "standard_audit/auditable"
7
10
  require "standard_audit/audit_scope"
11
+ require "standard_audit/checks/retention"
8
12
 
9
13
  module StandardAudit
10
14
  # Metadata keys owned internally by StandardAudit. Never filtered by
@@ -12,8 +16,30 @@ module StandardAudit
12
16
  RESERVED_METADATA_KEYS = %w[_tags _source].freeze
13
17
 
14
18
  class << self
15
- def configure
16
- yield(config) if block_given?
19
+ # Applies configuration to the single mutable Configuration instance.
20
+ #
21
+ # `baseline: true` also *remembers* the block, so `reset_configuration!`
22
+ # replays it. That matters because the config object holds behaviour, not
23
+ # just data — `before_checksum_hooks` in particular. Without a baseline, a
24
+ # suite that installs the rspec plugin (which calls `reset_configuration!`
25
+ # before every example) silently loses write-time hooks after the first
26
+ # example, and the specs that would notice pass vacuously.
27
+ #
28
+ # Idiomatic host usage, in config/initializers/standard_audit.rb:
29
+ #
30
+ # StandardAudit.configure(baseline: true) do |config|
31
+ # config.subscribe_to "myapp.**"
32
+ # config.before_checksum :backfill_scope
33
+ # end
34
+ #
35
+ # Only the most recent `baseline: true` block is remembered; call it once,
36
+ # from the initializer.
37
+ def configure(baseline: false, &block)
38
+ return config unless block
39
+
40
+ @baseline_configuration = block if baseline
41
+ block.call(config)
42
+ config
17
43
  end
18
44
 
19
45
  def config
@@ -25,10 +51,9 @@ module StandardAudit
25
51
 
26
52
  actor ||= config.current_actor_resolver.call
27
53
 
28
- # Filter sensitive keys. `_tags` and `_source` are reserved internal
29
- # metadata keys owned by EventSubscriber and are never stripped.
30
- sensitive = config.sensitive_keys.map(&:to_s) - RESERVED_METADATA_KEYS
31
- filtered_metadata = metadata.reject { |k, _| sensitive.include?(k.to_s) }
54
+ # Redaction lives in MetadataFilter, shared with Subscriber, so the two
55
+ # write paths cannot drift apart.
56
+ filtered_metadata = MetadataFilter.call(metadata, config: config)
32
57
 
33
58
  attrs = {
34
59
  event_type: event_type,
@@ -100,8 +125,24 @@ module StandardAudit
100
125
  @event_subscriber ||= EventSubscriber.new
101
126
  end
102
127
 
103
- def reset_configuration!
128
+ # Drops the memoized Configuration. Any block registered with
129
+ # `configure(baseline: true)` is replayed onto the fresh instance, so a
130
+ # per-example reset restores the app's real configuration rather than the
131
+ # gem defaults.
132
+ def reset_configuration!(replay_baseline: true)
104
133
  @configuration = nil
134
+ @baseline_configuration&.call(config) if replay_baseline
135
+ config
136
+ end
137
+
138
+ # Forgets the `configure(baseline: true)` block. Mainly for the gem's own
139
+ # specs and for a host that needs a genuinely pristine configuration.
140
+ def clear_baseline_configuration!
141
+ @baseline_configuration = nil
142
+ end
143
+
144
+ def baseline_configured?
145
+ !@baseline_configuration.nil?
105
146
  end
106
147
 
107
148
  private
@@ -79,6 +79,47 @@ namespace :standard_audit do
79
79
  puts "Backfilled checksums for #{count} audit log records"
80
80
  end
81
81
 
82
+ namespace :sensitive_keys do
83
+ desc "Report which historical metadata keys a redaction rule would strip (read-only)"
84
+ task :dry_run, [:pattern] => :environment do |_t, args|
85
+ # Audit rows are append-only, so a redaction rule that swallows real
86
+ # content cannot be undone. This reads the rows you already have and
87
+ # reports, per key, what the rule would have stripped.
88
+ #
89
+ # rake standard_audit:sensitive_keys:dry_run
90
+ # rake "standard_audit:sensitive_keys:dry_run[secret]"
91
+ # NESTED=1 rake "standard_audit:sensitive_keys:dry_run[secret|token]"
92
+ #
93
+ # The argument is a Regexp source, matched case-insensitively, and is
94
+ # applied *in addition to* the app's configured sensitive_keys.
95
+ # NESTED=1/0 overrides config.filter_nested_metadata for the run.
96
+ pattern = args[:pattern].presence || ENV["PATTERN"].presence
97
+ patterns = StandardAudit.config.sensitive_key_patterns.dup
98
+ patterns << Regexp.new(pattern, Regexp::IGNORECASE) if pattern
99
+
100
+ nested =
101
+ case ENV["NESTED"]
102
+ when nil, "" then nil
103
+ when "0", "false" then false
104
+ else true
105
+ end
106
+
107
+ report = StandardAudit::SensitiveKeysDryRun.call(
108
+ sensitive_key_patterns: patterns,
109
+ nested: nested,
110
+ batch_size: (ENV["BATCH_SIZE"] || 1000).to_i
111
+ )
112
+
113
+ puts "StandardAudit sensitive-key dry run"
114
+ puts "==================================="
115
+ puts "Candidate pattern: #{pattern ? Regexp.new(pattern, Regexp::IGNORECASE).inspect : '(none — reporting current config)'}"
116
+ puts ""
117
+ puts report
118
+ puts ""
119
+ puts "Nothing was written. Rows are append-only; a rule you enable applies only to future writes."
120
+ end
121
+ end
122
+
82
123
  desc "Export audit logs for a specific actor (GDPR right to access)"
83
124
  task :export_actor, [:actor_gid, :output] => :environment do |_t, args|
84
125
  raise "actor_gid is required" unless args[:actor_gid].present?
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.5.0
4
+ version: 0.7.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
- - MIT-LICENSE
92
+ - LICENSE
93
93
  - README.md
94
94
  - Rakefile
95
95
  - app/jobs/standard_audit/cleanup_job.rb
@@ -105,10 +105,14 @@ 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
112
+ - lib/standard_audit/metadata_filter.rb
113
+ - lib/standard_audit/reference_preloading.rb
111
114
  - lib/standard_audit/rspec.rb
115
+ - lib/standard_audit/sensitive_keys_dry_run.rb
112
116
  - lib/standard_audit/subscriber.rb
113
117
  - lib/standard_audit/version.rb
114
118
  - lib/tasks/standard_audit_tasks.rake