bard-backup 0.14.0 → 0.15.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 500bd736142fc1765b02fdbee4923a35dd4d09bd3cabd825706d7b64b9ad3fff
4
- data.tar.gz: 07c8d6686725ebd36364da96df0e8f66d80c87ddbf3751e1a86f0e12ead8a78c
3
+ metadata.gz: d27a5d0b3ccda89bf0b15345414f6143ba1ef13e2b388545f32bbe980f36eb2f
4
+ data.tar.gz: 7ac24670444a407c21b9ce062feed27580da64d6f62f02326db65882a14d86b4
5
5
  SHA512:
6
- metadata.gz: f1893706b187e49ad3a16b5fc8fa5a2de0644e522041f7d7a1d4bf9f54054ca8094956a3f26c7a83f7e598097af94726fbbb5d3dc876a5fad90e47e71a2d460d
7
- data.tar.gz: eb744cd047d227b37de6b723b5e5ec027b8f1c03dd663fc735abfad2165370536a2b727c068b3d5624b64ce9e3ff79b54fc1ea925cfbb30aa6e85ba2ae0cc598
6
+ metadata.gz: 1adf405bb06825fe7fd2e176dc1bd4565a2200977a5dead6e2d3c92bb7415b7144a9c2f08bd6995e60afa6b0069c77428bd6e509ddbca1a470b04cfd2708f0de
7
+ data.tar.gz: f5870aa10fcb9df65c920c8b7516ab9f82577ad263cd5578002cec49d19c2ae223837441f1b3ec7cd71ab1df85cea5cf7fd5f46f87be62b57d41fd58edbbbee5
data/CLAUDE.md CHANGED
@@ -47,17 +47,18 @@ Tests require AWS credentials at `spec/support/credentials.json`. In CI, this is
47
47
  - `Bard::Backup::FileTree.create!` syncs configured data directories to S3.
48
48
  - `Bard::Backup.restore!(at:)` downloads the backup nearest `at` (or the latest when omitted), decrypts it if necessary, and loads it into the local database via `backhoe` (drop-and-create). `Bard::Backup.available` lists the available backups (as `Bard::Backup` objects carrying timestamp and size).
49
49
 
50
- **Destination strategy pattern**: `Destination.build(config)` is a factory that picks the right class based on `:type`. `Destination.resolve(hashes)` is the single entry point both `Database.create!` and `Finder` use — it falls back to the configured destinations, normalizes a lone Hash/Array, and builds them. Each destination resolves its own `encryption_key` (explicit config, falling back to `Bard::Config.current.backup.encryption_key`), so callers never inject it.
50
+ **Destination strategy pattern**: `Destination.build(config)` is a factory that picks the right class based on `:type`. `Destination.resolve(hashes)` is the single entry point both `Database.create!` and `Finder` use — it falls back to the configured destinations, normalizes a lone Hash/Array, and builds them. A destination's `encryption_key` comes from its config, which `tasks.rake` merges from the `bard_backup` Rails credentials entry; there is no other source.
51
51
  - `S3Destination` — dumps DB locally via backhoe, uploads to S3, runs `Deleter` for retention, verifies previous hour's backup
52
52
  - `UploadDestination` — dumps DB and uploads to presigned URLs (multi-threaded)
53
53
 
54
- **Config DSL** (loaded via `bard/plugins/backup` and `bard/plugins/encrypt`; `backup` extends `Bard::Config`, `encrypt` extends `Bard::BackupConfig`):
54
+ **Config DSL** (loaded via `bard/plugins/backup`; `backup` extends `Bard::Config`):
55
55
  ```ruby
56
56
  backup do
57
57
  s3 "primary", path: "bucket/subfolder", region: "us-west-2"
58
- encrypt true # reads key from config/master.key
59
58
  end
60
59
  ```
60
+ Encryption at rest is opt-in per destination via an `encryption_key` in the `bard_backup`
61
+ credentials entry — there is no DSL toggle.
61
62
 
62
63
  **Key classes**:
63
64
  - `S3Tree` — `Data.define`-based S3 wrapper used by both `S3Destination` and `FileTree`. Methods: `list_objects`, `put_file`, `put_body`, `get`, `delete_keys`, `mv`, `empty!`. Supports encryption via `Encryptor` and STS `session_token`.
data/README.md CHANGED
@@ -22,7 +22,6 @@ In a Rails app, configure destinations in `config/bard.rb` using the `Bard::Conf
22
22
  ```ruby
23
23
  backup do
24
24
  s3 "primary", path: "my-bucket/my-project", region: "us-west-2"
25
- encrypt true # optional: encrypt payloads at rest. Reads key from config/master.key.
26
25
  end
27
26
  ```
28
27
 
@@ -33,8 +32,13 @@ bard_backup:
33
32
  - name: primary
34
33
  access_key_id: ...
35
34
  secret_access_key: ...
35
+ encryption_key: ... # optional: encrypts payloads at rest with AES-256-GCM
36
36
  ```
37
37
 
38
+ Adding `encryption_key` is what turns on encryption at rest; omit it and payloads are stored
39
+ in the clear. Changing its value makes existing backups undecryptable, so treat it as
40
+ permanent unless you re-key deliberately.
41
+
38
42
  Then run via the rake tasks provided by the bundled Railtie:
39
43
 
40
44
  ```bash
@@ -21,16 +21,20 @@ module Bard
21
21
  resolved_config.slice(:name, :type, :path, :region)
22
22
  end
23
23
 
24
+ # Credentials can supply the key, so resolve rather than reading raw config.
25
+ def encryption_key
26
+ resolved_config[:encryption_key]
27
+ end
28
+
24
29
  private
25
30
 
26
- # The raw config enriched with Rails credentials (by name), defaults, the
27
- # computed endpoint, and the resolved encryption key.
31
+ # The raw config enriched with Rails credentials (by name), defaults, and
32
+ # the computed endpoint.
28
33
  def resolved_config
29
34
  @resolved_config ||= begin
30
35
  credentials = RailsCredentials.find(name: config[:name])
31
36
  resolved = { type: :s3, region: "us-west-2" }.merge(credentials).merge(config)
32
37
  resolved[:endpoint] ||= "https://s3.#{resolved[:region]}.amazonaws.com"
33
- resolved[:encryption_key] ||= Bard::Config.current.backup.encryption_key
34
38
  resolved
35
39
  end
36
40
  end
@@ -11,8 +11,7 @@ module Bard
11
11
  # Normalizes destination config into built destinations: falls back to the
12
12
  # configured destinations when none are given, and accepts a lone Hash or
13
13
  # an Array. A +now+ stamps every destination with one run timestamp (an
14
- # explicit per-destination +now+ still wins). Each destination resolves its
15
- # own encryption key (see #encryption_key), so callers don't have to inject it.
14
+ # explicit per-destination +now+ still wins).
16
15
  def self.resolve(destination_hashes = nil, now: nil)
17
16
  hashes = destination_hashes || Bard::Config.current.backup.destinations
18
17
  hashes = hashes.is_a?(Hash) ? [hashes] : Array(hashes)
@@ -24,12 +23,12 @@ module Bard
24
23
  raise NotImplementedError
25
24
  end
26
25
 
27
- private
28
-
29
26
  def encryption_key
30
- config[:encryption_key] || Bard::Config.current.backup.encryption_key
27
+ config[:encryption_key]
31
28
  end
32
29
 
30
+ private
31
+
33
32
  def now
34
33
  @now ||= config.fetch(:now, Time.now.utc)
35
34
  end
@@ -15,7 +15,6 @@ module Bard
15
15
  return if data_paths.empty?
16
16
 
17
17
  encryption_key = s3_config.delete(:encryption_key)
18
- encryption_key ||= bard_config&.backup&.encryption_key
19
18
 
20
19
  s3_tree = S3Tree.new(path: "#{bucket}/#{project_name}", encryption_key: encryption_key, **s3_config)
21
20
  new(s3_tree, data_paths).call
@@ -1,6 +1,6 @@
1
1
  module Bard
2
2
  class Backup
3
- VERSION = "0.14.0"
3
+ VERSION = "0.15.0"
4
4
  end
5
5
  end
6
6
 
data/lib/bard/backup.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require "bard"
2
2
  require "bard/plugins/backup"
3
- require "bard/plugins/encrypt"
4
3
  require "bard/backup/database"
5
4
  require "bard/backup/file_tree"
6
5
  require "bard/backup/finder"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bard-backup
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.0
4
+ version: 0.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Micah Geisel
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2026-07-13 00:00:00.000000000 Z
10
+ date: 2026-08-08 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: backhoe
@@ -113,7 +113,6 @@ files:
113
113
  - lib/bard/backup/version.rb
114
114
  - lib/bard/plugins/backup.rb
115
115
  - lib/bard/plugins/backup_restore.rb
116
- - lib/bard/plugins/encrypt.rb
117
116
  - sig/bard/backup.rbs
118
117
  homepage: https://github.com/botandrose/bard-backup
119
118
  licenses:
@@ -1,18 +0,0 @@
1
- require "bard/plugins/backup"
2
-
3
- module Bard
4
- class BackupConfig
5
- def encrypt(value = nil)
6
- if value.nil?
7
- @encrypt
8
- else
9
- @encrypt = value
10
- end
11
- end
12
-
13
- def encryption_key
14
- return nil unless encrypt
15
- File.read("config/master.key").strip
16
- end
17
- end
18
- end