@@ -6,6 +6,7 @@ use anyhow::Result;
6
6
use opentelemetry:: global:: shutdown_tracer_provider;
7
7
use policy_evaluator:: callback_handler:: CallbackHandlerBuilder ;
8
8
use policy_evaluator:: policy_metadata:: Metadata ;
9
+ use settings:: VerificationSettings ;
9
10
use std:: path:: PathBuf ;
10
11
use std:: { process, thread} ;
11
12
use tokio:: { runtime:: Runtime , sync:: mpsc, sync:: oneshot} ;
@@ -40,6 +41,35 @@ fn main() -> Result<()> {
40
41
. expect ( "error parsing the number of workers" )
41
42
} ) ;
42
43
44
+ // As of clap version 2, we have to do this check in separate
45
+ // steps.
46
+ //
47
+ // `--enable-metrics` does not take a value. However, using
48
+ // `env` from clap to link the `KUBEWARDEN_ENABLE_METRICS`
49
+ // envvar to this flag forcefully sets `takes_value` on the
50
+ // flag, making the usage of `--enable-metrics` argument weird
51
+ // (this should not take a value).
52
+ //
53
+ // The answer is therefore, to just set up the
54
+ // `--enable-metrics` flag in clap, and check manually whether
55
+ // the environment variable is set.
56
+ //
57
+ // The same is true for `--verify-policies` flag, and
58
+ // KUBEWARDEN_ENABLE_VERIFICATION env var.
59
+ //
60
+ // Check https://github.com/clap-rs/clap/issues/1476 for
61
+ // further details.
62
+ let metrics_enabled = matches. is_present ( "enable-metrics" )
63
+ || std:: env:: var_os ( "KUBEWARDEN_ENABLE_METRICS" ) . is_some ( ) ;
64
+ let verify_enabled = matches. is_present ( "enable-verification" )
65
+ || std:: env:: var_os ( "KUBEWARDEN_ENABLE_VERIFICATION" ) . is_some ( ) ;
66
+
67
+ let verification_settings: Option < VerificationSettings > = if verify_enabled {
68
+ Some ( cli:: verification_settings ( & matches) ?)
69
+ } else {
70
+ None
71
+ } ;
72
+
43
73
////////////////////////////////////////////////////////////////////////////
44
74
// //
45
75
// Phase 1: setup the CallbackHandler. This is used by the synchronous //
@@ -149,24 +179,6 @@ fn main() -> Result<()> {
149
179
fatal_error ( err. to_string ( ) ) ;
150
180
}
151
181
152
- // As of clap version 2, we have to do this check in separate
153
- // steps.
154
- //
155
- // `--enable-metrics` does not take a value. However, using
156
- // `env` from clap to link the `KUBEWARDEN_ENABLE_METRICS`
157
- // envvar to this flag forcefully sets `takes_value` on the
158
- // flag, making the usage of `--enable-metrics` argument weird
159
- // (this should not take a value).
160
- //
161
- // The answer is therefore, to just set up the
162
- // `--enable-metrics` flag in clap, and check manually whether
163
- // the environment variable is set.
164
- //
165
- // Check https://github.com/clap-rs/clap/issues/1476 for
166
- // further details.
167
- let metrics_enabled = matches. is_present ( "enable-metrics" )
168
- || std:: env:: var_os ( "KUBEWARDEN_ENABLE_METRICS" ) . is_some ( ) ;
169
-
170
182
// The unused variable is required so the meter is not dropped early and
171
183
// lives for the whole block lifetime, exporting metrics
172
184
let _meter = if metrics_enabled {
@@ -186,6 +198,48 @@ fn main() -> Result<()> {
186
198
) ;
187
199
for ( name, policy) in policies. iter_mut ( ) {
188
200
debug ! ( policy = name. as_str( ) , "download" ) ;
201
+
202
+ let mut verifier = policy_fetcher:: verify:: Verifier :: new ( sources. clone ( ) ) ;
203
+ let mut verified_manifest_digest: Option < String > = None ;
204
+
205
+ if verify_enabled {
206
+ // verify policy prior to pulling for all keys, and keep the
207
+ // verified manifest digest of last iteration, even if all are
208
+ // the same:
209
+ for key_value in verification_settings
210
+ . as_ref ( )
211
+ . unwrap ( )
212
+ . verification_keys
213
+ . values ( )
214
+ {
215
+ verified_manifest_digest = Some (
216
+ verifier
217
+ . verify (
218
+ & policy. url ,
219
+ docker_config. clone ( ) ,
220
+ verification_settings
221
+ . as_ref ( )
222
+ . unwrap ( )
223
+ . verification_annotations
224
+ . clone ( ) ,
225
+ key_value,
226
+ )
227
+ . await
228
+ . map_err ( |e| fatal_error ( e. to_string ( ) ) )
229
+ . unwrap ( ) ,
230
+ ) ;
231
+ }
232
+ info ! (
233
+ name = name. as_str( ) ,
234
+ sha256sum = verified_manifest_digest
235
+ . as_ref( )
236
+ . unwrap_or( & "unknown" . to_string( ) )
237
+ . as_str( ) ,
238
+ status = "verified-signatures" ,
239
+ "policy download" ,
240
+ ) ;
241
+ }
242
+
189
243
match policy_fetcher:: fetch_policy (
190
244
& policy. url ,
191
245
policy_fetcher:: PullDestination :: Store ( PathBuf :: from ( policies_download_dir) ) ,
@@ -195,6 +249,33 @@ fn main() -> Result<()> {
195
249
. await
196
250
{
197
251
Ok ( fetched_policy) => {
252
+ if verify_enabled {
253
+ if verified_manifest_digest. is_none ( ) {
254
+ // when deserializing keys we check that have keys to
255
+ // verify. We will always have a digest manifest
256
+ fatal_error ( "Verification of policy failed" . to_string ( ) ) ;
257
+ unreachable ! ( ) ;
258
+ }
259
+ verifier
260
+ . verify_local_file_checksum (
261
+ & fetched_policy. uri ,
262
+ docker_config. clone ( ) ,
263
+ verified_manifest_digest. as_ref ( ) . unwrap ( ) ,
264
+ )
265
+ . await
266
+ . map_err ( |e| fatal_error ( e. to_string ( ) ) )
267
+ . unwrap ( ) ;
268
+ info ! (
269
+ name = name. as_str( ) ,
270
+ sha256sum = verified_manifest_digest
271
+ . as_ref( )
272
+ . unwrap_or( & "unknown" . to_string( ) )
273
+ . as_str( ) ,
274
+ status = "verified-local-checksum" ,
275
+ "policy download" ,
276
+ ) ;
277
+ }
278
+
198
279
if let Ok ( Some ( policy_metadata) ) =
199
280
Metadata :: from_path ( & fetched_policy. local_path )
200
281
{
0 commit comments