cfn-guardian 0.13.2 → 0.13.3

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: f0cc2724cc132d8d63320389df91b3c10a5f03c20ee7268196c97849e5be65c1
4
- data.tar.gz: 75a0a157d81de0b56cf70736c899d902a08836bb5d8a8375854dbaca28fa531a
3
+ metadata.gz: 6499c49242499318fb5e91766a52219a941f2993bc6d8236734a95c47c67f392
4
+ data.tar.gz: 6caf244eeb6ffbf88fa299fd9c908f84f4c4866fac81a470141aa971f5a6d461
5
5
  SHA512:
6
- metadata.gz: 0f512b00589c8448d1ec5cdb1f4fe9946637a13392808e22897fa4e814dc54d5b0fa6ff907283e99666115dbe4ff57d3fd3e8a18574f41cd08131e26b00d50f0
7
- data.tar.gz: 32677e892cb44a0e2fab340fb2e69bae3695bb801b1d2e990d2ed4fc3f8bec46e0802f3bf844eb5a36fa7d04dd8cb8a91ff66f88d8bd0249c3c4404b2347add0
6
+ metadata.gz: ffbcd0281d97cc3b4ff01e4dd4de1f5cd5f3db76759a9e2b93a831d346acbd3849702d450039bd54e1031bb9782d7a3ff9109ebda738a4c18a39a425ab728fe5
7
+ data.tar.gz: 679154efbf9054ffabde0511df35e7b618cd602e170b687f496f6e8ec0710219badcc050a2ea5562914f5ce11e8e09eca74522ac048c200dd0b1feb2e081b670
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cfn-guardian (0.13.2)
4
+ cfn-guardian (0.13.3)
5
5
  aws-sdk-cloudformation (~> 1.76, < 2)
6
6
  aws-sdk-cloudwatch (~> 1.72, < 2)
7
7
  aws-sdk-codecommit (~> 1.53, < 2)
@@ -58,6 +58,7 @@ When enabled, the HTTP check Lambda (see [aws-lambda-http-check](https://github.
58
58
  | `HmacSecretSsm` | Yes | SSM Parameter Store path to the HMAC secret (SecureString). The Guardian-generated IAM role grants the Lambda `ssm:GetParameter` for this path. |
59
59
  | `HmacKeyId` | No | Key id sent in the `Key-Id` header. Default: `default`. |
60
60
  | `HmacHeaderPrefix` | No | Prefix for all HMAC header names. Default: `X-Health` (yields `X-Health-Signature`, `X-Health-Key-Id`, etc.). |
61
+ | `HealthConfigOverrides` | No | Request-scoped health check overrides sent as the `X-Health-Config-Overrides` header. Accepts a YAML object (serialized to JSON) or a raw JSON string. Included in the HMAC signature when `HmacSecretSsm` is set. |
61
62
 
62
63
  **Example:**
63
64
 
@@ -69,6 +70,12 @@ Resources:
69
70
  HmacSecretSsm: /guardian/myapp/hmac-secret
70
71
  HmacKeyId: default
71
72
  HmacHeaderPrefix: X-Health
73
+ HealthConfigOverrides:
74
+ roles:
75
+ my_service:
76
+ probes:
77
+ - id: my-probe
78
+ enabled: false
72
79
  ```
73
80
 
74
81
  Internal HTTP checks support the same keys under each host:
@@ -118,7 +125,7 @@ If you want Guardian to call a health endpoint that only accepts HMAC-authentica
118
125
  The Lambda signs this string (newline-separated, no trailing newline):
119
126
 
120
127
  ```
121
- METHOD\nPATH\nTIMESTAMP\nNONCE\nQUERY\nBODY_HASH
128
+ METHOD\nPATH\nTIMESTAMP\nNONCE\nQUERY\nBODY_HASH\nOVERRIDE_HEADER_HASH
122
129
  ```
123
130
 
124
131
  - `METHOD` – HTTP method (e.g. `GET`).
@@ -127,6 +134,7 @@ METHOD\nPATH\nTIMESTAMP\nNONCE\nQUERY\nBODY_HASH
127
134
  - `NONCE` – Same value as the `{prefix}-Nonce` header.
128
135
  - `QUERY` – Raw query string (e.g. `foo=bar` or empty).
129
136
  - `BODY_HASH` – SHA-256 hex digest of the raw request body (empty string for GET; for POST/PUT, hash the body as sent).
137
+ - `OVERRIDE_HEADER_HASH` – SHA-256 hex digest of the raw `X-Health-Config-Overrides` header value when sent, otherwise the SHA-256 digest of an empty string (`e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`).
130
138
 
131
139
  **Verification steps (pseudo code):**
132
140
 
@@ -175,6 +183,8 @@ def verify_health_request(request, secret_by_key_id, header_prefix="X-Health", m
175
183
  return False
176
184
 
177
185
  body_hash = hashlib.sha256(request.body or b"").hexdigest()
186
+ override_raw = request.headers.get("X-Health-Config-Overrides", "")
187
+ override_hash = hashlib.sha256(override_raw.encode()).hexdigest()
178
188
  canonical = "\n".join([
179
189
  request.method,
180
190
  request.path,
@@ -182,6 +192,7 @@ def verify_health_request(request, secret_by_key_id, header_prefix="X-Health", m
182
192
  nonce,
183
193
  request.query_string or "",
184
194
  body_hash,
195
+ override_hash,
185
196
  ])
186
197
  expected = hmac.new(secret.encode(), canonical.encode(), hashlib.sha256).hexdigest()
187
198
  return hmac.compare_digest(expected, signature)
@@ -42,7 +42,7 @@ module CfnGuardian
42
42
  @name = 'HttpCheck'
43
43
  @package = 'http-check'
44
44
  @handler = 'handler.http_check'
45
- @version = '685c17ced2429954fccbf8b8b8f2132b37b3f4ff'
45
+ @version = '3bd07fce99eaa560f2499673d4adc24cb4d72d2c'
46
46
  @runtime = 'python3.11'
47
47
  end
48
48
  end
@@ -1,3 +1,4 @@
1
+ require 'json'
1
2
  require 'cfnguardian/string'
2
3
 
3
4
  module CfnGuardian
@@ -58,8 +59,21 @@ module CfnGuardian
58
59
  @hmac_secret_ssm = resource.fetch('HmacSecretSsm',nil)
59
60
  @hmac_key_id = resource.fetch('HmacKeyId','default')
60
61
  @hmac_header_prefix = resource.fetch('HmacHeaderPrefix','X-Health')
62
+ @health_config_overrides = resource.fetch('HealthConfigOverrides',nil)
61
63
  @report_response_body = resource.fetch('ReportResponseBody',false)
62
64
  end
65
+
66
+ def http_headers
67
+ parts = []
68
+ parts << @headers unless @headers.nil? || @headers.empty?
69
+ unless @health_config_overrides.nil?
70
+ override_value = @health_config_overrides.is_a?(String) ?
71
+ @health_config_overrides :
72
+ JSON.generate(@health_config_overrides)
73
+ parts << "X-Health-Config-Overrides=#{override_value.gsub(' ', '%20')}"
74
+ end
75
+ parts.empty? ? nil : parts.join(' ')
76
+ end
63
77
 
64
78
  def payload
65
79
  payload = {
@@ -69,7 +83,8 @@ module CfnGuardian
69
83
  'STATUS_CODE_MATCH' => @status_code
70
84
  }
71
85
  payload['BODY_REGEX_MATCH'] = @body_regex unless @body_regex.nil?
72
- payload['HEADERS'] = @headers unless @headers.nil?
86
+ headers = http_headers
87
+ payload['HEADERS'] = headers unless headers.nil?
73
88
  payload['USER_AGENT'] = @user_agent unless @user_agent.nil?
74
89
  payload['PAYLOAD'] = @payload unless @payload.nil?
75
90
  payload['COMPRESSED'] = '1' if @compressed
@@ -1,4 +1,4 @@
1
1
  module CfnGuardian
2
- VERSION = "0.13.2"
2
+ VERSION = "0.13.3"
3
3
  CHANGE_SET_VERSION = VERSION.gsub('.', '-').freeze
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cfn-guardian
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.2
4
+ version: 0.13.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Guslington