forked from confidential-containers/trustee
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathear_default_policy_cpu.rego
More file actions
391 lines (317 loc) · 12.1 KB
/
Copy pathear_default_policy_cpu.rego
File metadata and controls
391 lines (317 loc) · 12.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
package policy
import rego.v1
# This policy validates multiple TEE platforms
# The policy is meant to capture the TCB requirements
# for confidential containers.
# This policy is used to generate an EAR Appraisal.
# Specifically it generates an AR4SI result.
# More informatino on AR4SI can be found at
# <https://datatracker.ietf.org/doc/draft-ietf-rats-ar4si/>
# For the `executables` trust claim, the value 33 stands for
# "Runtime memory includes executables, scripts, files, and/or
# objects which are not recognized."
default executables := 33
# For the `hardware` trust claim, the value 97 stands for
# "A Verifier does not recognize an Attester's hardware or
# firmware, but it should be recognized."
default hardware := 97
# For the `configuration` trust claim the value 36 stands for
# "Elements of the configuration relevant to security are
# unavailable to the Verifier."
default configuration := 36
# For the `filesystem` trust claim, the value 0 stands for
# "No assertion."
default file_system := 0
# For the `instance_identity` trust claim, the value 0 stands for
# "No assertion."
default instance_identity := 0
# For the `runtime_opaque` trust claim, the value 0 stands for
# "No assertion."
default runtime_opaque := 0
# For the `storage_opaque` trust claim, the value 0 stands for
# "No assertion."
default storage_opaque := 0
# For the `sourced_data` trust claim, the value 0 stands for
# "No assertion."
default sourced_data := 0
trust_claims := {
"executables": executables,
"hardware": hardware,
"configuration": configuration,
"file-system": file_system,
"instance-identity": instance_identity,
"runtime-opaque": runtime_opaque,
"storage-opaque": storage_opaque,
"sourced-data": sourced_data,
}
##### Sample
# For the `executables` trust claim, the value 3 stands for
# "Only a recognized genuine set of approved executables have
# been loaded during the boot process."
executables := 3 if {
# Short circuit the rest of the conditions, if the platform is not set.
# Creating a simple entry like this will skip executing the first
# extension in the block.
input.sample
# The sample attester does not report any launch digest.
# This is an example of how a real platform might validate executables.
input.sample.launch_digest in query_reference_value("launch_digest")
}
# For the `hardware` trust claim, the value 2 stands for
# "An Attester has passed its hardware and/or firmware
# verifications needed to demonstrate that these are genuine/
# supported.
hardware := 2 if {
input.sample
input.sample.svn in query_reference_value("svn")
input.sample.platform_version.major == query_reference_value("major_version")
input.sample.platform_version.minor >= query_reference_value("minimum_minor_version")
}
# For the 'configuration' trust claim 2 stands for
# "The configuration is a known and approved config."
#
# In this case, check that debug mode isn't turned on.
# The sample platform is just an example.
# For the sample platform, the debug claim is always false.
# The sample platform should only be used for testing.
configuration := 2 if {
input.sample
input.sample.debug == false
}
##### SNP
executables := 3 if {
input.snp
# In the future, we might calculate this measurement here various components
input.snp.measurement in query_reference_value("snp_launch_measurement")
}
hardware := 2 if {
input.snp
# Check the reported TCB to validate the ASP FW
input.snp.reported_tcb_bootloader in query_reference_value("snp_bootloader")
input.snp.reported_tcb_microcode in query_reference_value("snp_microcode")
input.snp.reported_tcb_snp in query_reference_value("snp_snp_svn")
input.snp.reported_tcb_tee in query_reference_value("snp_tee_svn")
}
# For the 'configuration' trust claim 2 stands for
# "The configuration is a known and approved config."
#
# For this, we compare all the configuration fields.
configuration := 2 if {
input.snp
input.snp.policy_debug_allowed == false
input.snp.policy_migrate_ma == false
input.snp.platform_smt_enabled == query_reference_value("snp_smt_enabled")
input.snp.platform_tsme_enabled == query_reference_value("snp_tsme_enabled")
input.snp.policy_abi_major == query_reference_value("snp_guest_abi_major")
input.snp.policy_abi_minor == query_reference_value("snp_guest_abi_minor")
input.snp.policy_single_socket == query_reference_value("snp_single_socket")
input.snp.policy_smt_allowed == query_reference_value("snp_smt_allowed")
}
# For the `configuration` trust claim 3 stands for
# "The configuration includes or exposes no known
# vulnerabilities."
#
# In this check, we do not specifically check every
# configuration value, but we make sure that some key
# configurations (like debug_allowed) are set correctly.
else := 3 if {
input.snp
input.snp.policy_debug_allowed == false
input.snp.policy_migrate_ma == false
}
##### TDX
executables := 3 if {
input.tdx
# Check the kernel, initrd, and cmdline (including dmverity parameters) measurements
input.tdx.quote.body.rtmr_1 in query_reference_value("rtmr_1")
input.tdx.quote.body.rtmr_2 in query_reference_value("rtmr_2")
tdx_uefi_event_tdvfkernel_ok
tdx_uefi_event_tdvfkernelparams_ok
}
# Support for Grub boot used by GKE
else := 4 if {
input.tdx
# Check the kernel, initrd, and cmdline (including dmverity parameters) measurements
input.tdx.quote.body.rtmr_1 in query_reference_value("rtmr_1")
input.tdx.quote.body.rtmr_2 in query_reference_value("rtmr_2")
}
hardware := 2 if {
input.tdx
# Check the quote is a TDX quote signed by Intel SGX Quoting Enclave
input.tdx.quote.header.tee_type == "81000000"
input.tdx.quote.header.vendor_id == "939a7233f79c4ca9940a0db3957f0607"
# Check TDX Module hash
# input.tdx.quote.body.mr_seam in query_reference_value("mr_seam")
#
# Check OVMF code hash
input.tdx.quote.body.mr_td in query_reference_value("mr_td")
# Check TCB status (covers quote.body.tcb_svn claim check)
input.tdx.tcb_status == "UpToDate"
# Check minimum TCB date
# An alternative check to tcb_status is to define a minimum acceptable
# TCB date. TCB dates are associated with TCB Recovery events to which
# the platforms are certified.
#
# Available TCB dates can be checked using:
# curl -s https://api.trustedservices.intel.com/tdx/certification/v4/tcbevaluationdatanumbers | jq
#
# Example: in some cases, "OutOfDate" tcb_status can be accepted as long as
# the tcb_date is not older than a given date from a past TCB Recovery event:
# min_tcb_date := "2025-08-13T00:00:00Z"
# attester_tcb_date_ns := time.parse_rfc3339_ns(input.tdx.tcb_date)
# min_tcb_date_ns := time.parse_rfc3339_ns(min_tcb_date)
# attester_tcb_date_ns >= min_tcb_date_ns
# Check collateral expiration status
input.tdx.collateral_expiration_status == "0"
# Check against allowed advisory ids
# allowed_advisory_ids := {"INTEL-SA-00837"}
# attester_advisory_ids := {id | id := input.attester_advisory_ids[_]}
# object.subset(allowed_advisory_ids, attester_advisory_ids)
# Check against disallowed advisory ids
# disallowed_advisory_ids := {"INTEL-SA-00837"}
# attester_advisory_ids := {id | id := input.tdx.advisory_ids[_]} # convert array to set
# intersection := attester_advisory_ids & disallowed_advisory_ids
# count(intersection) == 0
}
configuration := 2 if {
input.tdx
# Check the TD has the expected attributes (e.g., debug not enabled) and features.
input.tdx.td_attributes.debug == false
input.tdx.quote.body.xfam in query_reference_value("xfam")
}
tdx_uefi_event_tdvfkernel_ok if {
event := input.tdx.uefi_event_logs[_]
event.type_name == "EV_EFI_BOOT_SERVICES_APPLICATION"
"File(kernel)" in event.details.device_paths
digest := event.digests[_]
digest.digest == query_reference_value("tdvfkernel")
}
tdx_uefi_event_tdvfkernelparams_ok if {
event := input.tdx.uefi_event_logs[_]
event.type_name == "EV_EVENT_TAG"
event.details.string == "LOADED_IMAGE::LoadOptions"
digest := event.digests[_]
digest.digest == query_reference_value("tdvfkernelparams")
}
##### Azure vTPM SNP
executables := 3 if {
input["az-snp-vtpm"]
input["az-snp-vtpm"].measurement in query_reference_value("measurement")
input["az-snp-vtpm"].tpm.pcr11 in query_reference_value("snp_pcr11")
}
hardware := 2 if {
input["az-snp-vtpm"]
# Check the reported TCB to validate the ASP FW
input["az-snp-vtpm"].reported_tcb_bootloader in query_reference_value("tcb_bootloader")
input["az-snp-vtpm"].reported_tcb_microcode in query_reference_value("tcb_microcode")
input["az-snp-vtpm"].reported_tcb_snp in query_reference_value("tcb_snp")
input["az-snp-vtpm"].reported_tcb_tee in query_reference_value("tcb_tee")
}
# For the 'configuration' trust claim 2 stands for
# "The configuration is a known and approved config."
#
# For this, we compare all the configuration fields.
configuration := 2 if {
input["az-snp-vtpm"]
input["az-snp-vtpm"].platform_smt_enabled in query_reference_value("smt_enabled")
input["az-snp-vtpm"].platform_tsme_enabled in query_reference_value("tsme_enabled")
input["az-snp-vtpm"].policy_abi_major in query_reference_value("abi_major")
input["az-snp-vtpm"].policy_abi_minor in query_reference_value("abi_minor")
input["az-snp-vtpm"].policy_single_socket in query_reference_value("single_socket")
input["az-snp-vtpm"].policy_smt_allowed in query_reference_value("smt_allowed")
}
##### Azure vTPM TDX
executables := 3 if {
input["az-tdx-vtpm"]
input["az-tdx-vtpm"].tpm.pcr11 in query_reference_value("tdx_pcr11")
}
hardware := 2 if {
input["az-tdx-vtpm"]
# Check the quote is a TDX quote signed by Intel SGX Quoting Enclave
input["az-tdx-vtpm"].quote.header.tee_type == "81000000"
input["az-tdx-vtpm"].quote.header.vendor_id == "939a7233f79c4ca9940a0db3957f0607"
# Check TDX Module hash
# input.tdx.quote.body.mr_seam in query_reference_value("mr_seam")
#
# Check OVMF code hash
input["az-tdx-vtpm"].quote.body.mr_td in query_reference_value("mr_td")
# Check TCB status (covers quote.body.tcb_svn claim check)
input["az-tdx-vtpm"].tcb_status == "UpToDate"
# Check minimum TCB date (See TDX section for details.)
}
configuration := 2 if {
input["az-tdx-vtpm"]
input["az-tdx-vtpm"].quote.body.xfam in query_reference_value("xfam")
}
##### TPM
hardware := 2 if {
input.tpm
}
executables := 3 if {
input.tpm
input.tpm.pcr11 in query_reference_value("tpm_pcr11")
input.tpm.ak_public in query_reference_value("trusted_aks")
}
configuration := 0 if {
input.tpm
}
##### IBM Secure Execution for Linux (SEL)
# Only field existence is checked. No value check is necessary.
# The SE verifier performs cryptographic verification including
# measurements, signatures, and user_data binding.
# If the field exists, it means the verifaction is successful.
# This is a 'trust-the-verifier' approach.
executables := 3 if {
input.se
}
hardware := 2 if {
input.se
}
configuration := 2 if {
input.se
}
#################################
# EXTENSIONS
#
# Extensions are added to the EAR Appraisal
#
# The identifiers extension contains information that
# describes the workload.
#
# In Confidential Containers many of these identifiers
# are bootstrapped from the Kata Agent Policy or some
# other config provided in the InitData.
#
# Other runtimes may provide identifiers in other ways,
# such as via the event log.
extensions := [
{"name": "ear.trustee.identifiers",
"key": -18,
"value": {
"validated": validated_identifiers
}
}
]
# Validated identifiers are information that describes a workload
# that are bound to the hardware evidence via attesation
# and bound to the workload by the guest runtime.
validated_identifiers := object.union_n([
container_images_id,
container_uids_id,
])
# Use list comprehension to parse all of the images specified in the policy.
container_images := [img |
container := input["init_data_claims"]["agent_policy_claims"]["containers"][_]
img := container["OCI"]["Annotations"]["io.kubernetes.cri.image-name"]
]
container_images_id := {"container_images": container_images} if {
count(container_images) > 0
} else := {}
# UIDs
container_uids := [img |
container := input["init_data_claims"]["agent_policy_claims"]["containers"][_]
img := container["OCI"]["Process"]["User"]["UID"]
]
container_uids_id := {"container_uids": container_uids} if {
count(container_uids) > 0
} else := {}