hiera-eyaml-age 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.
- checksums.yaml +4 -4
- data/.gitignore +7 -0
- data/CHANGELOG.md +29 -0
- data/Makefile +29 -0
- data/README.md +4 -0
- data/hiera-eyaml-age.gemspec +1 -1
- data/lib/hiera/backend/eyaml/encryptors/age/version.rb +1 -1
- data/lib/hiera/backend/eyaml/encryptors/age.rb +53 -17
- metadata +13 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 705b8add5ef02f0dded07812e427e71e66bb8d9fb232d5caa0a479408186f2b3
|
|
4
|
+
data.tar.gz: dceba351e19d85bc85a716beb1a6cc765bdc343bc1ad33d6113a47d39537ae1c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eabe1f74179e9013b2d6f410a1e92d76a01990a23bd067a6c637e68394e65bda7061f5272c091a1581de741af2631e842877b80ee81f85540202cdb3b5074cc4
|
|
7
|
+
data.tar.gz: 062a51fa6e8ab4212f6cf1134be570abaf8229d15c3e67c22a723516701afbf9cf910b657d47401f10d49df7838ff91b8cd91dcc3f5729f1273c1ed2aa5453eb
|
data/.gitignore
CHANGED
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.2.1] - 2026-05-27
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Widen hiera-eyaml dependency range to `>= 4.2.0, < 6.0` to work with both Debian packaging and current gem releases
|
|
13
|
+
|
|
14
|
+
## [0.2.0] - 2026-05-26
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- Manage packaging (gem, deb)
|
|
19
|
+
- Add options to take identity and/or recipients from environment variables instead of files
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- Handle errors without dumping age's stderr unless asked for
|
|
24
|
+
|
|
25
|
+
## [0.1.0]
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- init
|
data/Makefile
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
VERSION := $(shell ruby -r ./lib/hiera/backend/eyaml/encryptors/age/version \
|
|
2
|
+
-e 'puts Hiera::Backend::Eyaml::Encryptors::AgeVersion::VERSION')
|
|
3
|
+
export DEBEMAIL:=network@ias.edu
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
.PHONY: gem
|
|
7
|
+
gem: hiera-eyaml-age-$(VERSION).gem
|
|
8
|
+
|
|
9
|
+
.PHONY: deb
|
|
10
|
+
deb: hiera-eyaml-age-$(VERSION).gem
|
|
11
|
+
gem2deb --package hiera-eyaml-age hiera-eyaml-age-$(VERSION).gem
|
|
12
|
+
|
|
13
|
+
targz:
|
|
14
|
+
git archive --output hiera-eyaml-age_$(VERSION).tar.gz --prefix hiera-eyaml-age main
|
|
15
|
+
|
|
16
|
+
.PHONY: packages
|
|
17
|
+
packages: deb gem targz
|
|
18
|
+
|
|
19
|
+
hiera-eyaml-age-$(VERSION).gem:
|
|
20
|
+
gem build hiera-eyaml-age.gemspec
|
|
21
|
+
|
|
22
|
+
.PHONY: clean
|
|
23
|
+
clean:
|
|
24
|
+
rm -rf \
|
|
25
|
+
gem2deb* \
|
|
26
|
+
hiera-eyaml-age-* \
|
|
27
|
+
ruby* \
|
|
28
|
+
hiera-eyaml-age-* \
|
|
29
|
+
hiera-eyaml-age_*
|
data/README.md
CHANGED
|
@@ -61,6 +61,10 @@ age recipients can be native age public keys (`age1...`) or SSH public keys (`ss
|
|
|
61
61
|
|
|
62
62
|
Use `eyaml --help` for more, or see the [hiera-eyaml] docs.
|
|
63
63
|
|
|
64
|
+
## Hardware keys and PKCS#11 tokens
|
|
65
|
+
|
|
66
|
+
If your age identity is protected by another factor (e.g. encrypted with a password, or an identity stored with touch required on a hardware security key) be aware that `hiera-eyaml` calls the encryptor once per encrypted value per file. Each call spawns a separate `age` process, which could mean one authorization interaction per encrypted value., depending on your setup. This is a limitation of `hiera-eyaml`'s design, not of `age`.
|
|
67
|
+
|
|
64
68
|
### Configuring hiera
|
|
65
69
|
|
|
66
70
|
```yaml
|
data/hiera-eyaml-age.gemspec
CHANGED
|
@@ -14,7 +14,7 @@ class Hiera
|
|
|
14
14
|
|
|
15
15
|
self.options = {
|
|
16
16
|
age_binary_path: {
|
|
17
|
-
desc: "Full path to the age executable",
|
|
17
|
+
desc: "Full path to the age executable (use an absolute path in production to avoid PATH-based substitution)",
|
|
18
18
|
type: :string,
|
|
19
19
|
default: "age"
|
|
20
20
|
},
|
|
@@ -22,6 +22,10 @@ class Hiera
|
|
|
22
22
|
desc: "Path to age identity file for decryption",
|
|
23
23
|
type: :string
|
|
24
24
|
},
|
|
25
|
+
identity_env_var: {
|
|
26
|
+
desc: "Name of environment variable containing age identity for decryption",
|
|
27
|
+
type: :string
|
|
28
|
+
},
|
|
25
29
|
recipients: {
|
|
26
30
|
desc: "List of recipients (comma separated)",
|
|
27
31
|
type: :string
|
|
@@ -29,6 +33,10 @@ class Hiera
|
|
|
29
33
|
recipients_file: {
|
|
30
34
|
desc: "File containing a list of recipients (one on each line)",
|
|
31
35
|
type: :string
|
|
36
|
+
},
|
|
37
|
+
recipients_env_var: {
|
|
38
|
+
desc: "Name of environment variable containing age recipients (comma separated)",
|
|
39
|
+
type: :string
|
|
32
40
|
}
|
|
33
41
|
}
|
|
34
42
|
|
|
@@ -53,22 +61,40 @@ class Hiera
|
|
|
53
61
|
binmode: true
|
|
54
62
|
)
|
|
55
63
|
unless status.success?
|
|
56
|
-
|
|
64
|
+
warn("age encrypt failed (run with --trace for details, including errors from age which may be sensitive)")
|
|
65
|
+
debug("age encrypt stderr: #{stderr.strip}")
|
|
66
|
+
raise RecoverableError, "age encrypt failed"
|
|
57
67
|
end
|
|
58
68
|
|
|
59
69
|
stdout
|
|
60
70
|
end
|
|
61
71
|
|
|
62
72
|
def self.decrypt(ciphertext)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
73
|
+
env_var = option(:identity_env_var)
|
|
74
|
+
|
|
75
|
+
if env_var
|
|
76
|
+
raise ArgumentError, "env #{env_var} is not set" unless ENV[env_var]
|
|
77
|
+
|
|
78
|
+
# Pass the identity via a pipe rather than a temp file so the key
|
|
79
|
+
# material never touches disk. age's --identity accepts /dev/fd/N.
|
|
80
|
+
# Ruby 2.0+ opens FDs with O_CLOEXEC by default, so we must
|
|
81
|
+
# explicitly preserve the read end across the exec boundary.
|
|
82
|
+
r_fd, w_fd = IO.pipe
|
|
83
|
+
w_fd.write(ENV[env_var])
|
|
84
|
+
w_fd.close
|
|
85
|
+
identity_arg = "/dev/fd/#{r_fd.fileno}"
|
|
86
|
+
extra_opts = { r_fd.fileno => r_fd }
|
|
87
|
+
else
|
|
88
|
+
identity_file = option(:identity_file)
|
|
89
|
+
debug("age identity file is #{identity_file}")
|
|
90
|
+
|
|
91
|
+
if identity_file.nil? || identity_file.empty?
|
|
92
|
+
raise ArgumentError,
|
|
93
|
+
"No age identity file configured, check age_identity_file configuration value is correct"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
identity_arg = identity_file
|
|
97
|
+
extra_opts = {}
|
|
72
98
|
end
|
|
73
99
|
|
|
74
100
|
stdout, stderr, status =
|
|
@@ -76,16 +102,18 @@ class Hiera
|
|
|
76
102
|
option(:age_binary_path),
|
|
77
103
|
"--decrypt",
|
|
78
104
|
"--identity",
|
|
79
|
-
|
|
105
|
+
identity_arg,
|
|
80
106
|
stdin_data: ciphertext,
|
|
81
|
-
binmode: true
|
|
107
|
+
binmode: true,
|
|
108
|
+
**extra_opts
|
|
82
109
|
)
|
|
83
110
|
|
|
111
|
+
r_fd&.close
|
|
112
|
+
|
|
84
113
|
unless status.success?
|
|
85
|
-
warn(
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
raise StandardError, "age decrypt failed: #{stderr.strip}"
|
|
114
|
+
warn("age decrypt failed (run with --trace for details, including errors from age which may be sensitive)")
|
|
115
|
+
debug("age decrypt stderr: #{stderr.strip}")
|
|
116
|
+
raise StandardError, "age decrypt failed"
|
|
89
117
|
end
|
|
90
118
|
|
|
91
119
|
stdout
|
|
@@ -99,6 +127,14 @@ class Hiera
|
|
|
99
127
|
private
|
|
100
128
|
|
|
101
129
|
def determine_recipients
|
|
130
|
+
env_var = option(:recipients_env_var)
|
|
131
|
+
if env_var
|
|
132
|
+
raise ArgumentError, "env #{env_var} is not set" unless ENV[env_var]
|
|
133
|
+
|
|
134
|
+
debug("Using --recipients-env-var option")
|
|
135
|
+
return ENV[env_var].split(",").map(&:strip)
|
|
136
|
+
end
|
|
137
|
+
|
|
102
138
|
recipient_option = option :recipients
|
|
103
139
|
|
|
104
140
|
unless recipient_option.nil?
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hiera-eyaml-age
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1
|
|
4
|
+
version: 0.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- IAS Network
|
|
@@ -13,16 +13,22 @@ dependencies:
|
|
|
13
13
|
name: hiera-eyaml
|
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
|
15
15
|
requirements:
|
|
16
|
-
- - "
|
|
16
|
+
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version:
|
|
18
|
+
version: 4.2.0
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '6.0'
|
|
19
22
|
type: :runtime
|
|
20
23
|
prerelease: false
|
|
21
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
25
|
requirements:
|
|
23
|
-
- - "
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
version: 4.2.0
|
|
29
|
+
- - "<"
|
|
24
30
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: '
|
|
31
|
+
version: '6.0'
|
|
26
32
|
description: age encryptor for use with hiera-eyaml
|
|
27
33
|
executables: []
|
|
28
34
|
extensions: []
|
|
@@ -30,8 +36,10 @@ extra_rdoc_files: []
|
|
|
30
36
|
files:
|
|
31
37
|
- ".gitignore"
|
|
32
38
|
- ".rubocop.yml"
|
|
39
|
+
- CHANGELOG.md
|
|
33
40
|
- Gemfile
|
|
34
41
|
- Gemfile.lock
|
|
42
|
+
- Makefile
|
|
35
43
|
- README.md
|
|
36
44
|
- Rakefile
|
|
37
45
|
- hiera-eyaml-age.gemspec
|