Skip to content

Commit 7d4644e

Browse files
[confcom] adding fragment support (#8238)
* read only logic for some mount types (#62) * offloading error checking and updating tests * Gracefully handle broken base64 policies in non-diff mode (#64) * handle broken base64 * address style fixes * adding flag to omit ID from policy * adding ability to not use sidecars via ARM tag * adding workload identity support for vn2 * Add user prompt to confirm policy overwrite for VN2 YAMLs * support for image attached fragments * updating locations where executables are found * updating version to 1.1.0 * updating test value * taking out unused dependency * fixing errors in docs and types * getting rid of whitespace * updating kata tests for linux * updating kata tests for windows * can't have binary files --------- Co-authored-by: Khalil Sayid <[email protected]> Co-authored-by: Khalil Sayid <[email protected]>
1 parent a719b25 commit 7d4644e

39 files changed

+3414
-376
lines changed

src/confcom/HISTORY.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,20 @@
22
33
Release History
44
===============
5+
1.1.0
6+
++++++
7+
* adding support for image-attached fragments via `acifragmentgen`
8+
* adding workload identity support for VN2
9+
* adding `--exclude-default-fragments` to disallow sidecars from policy
10+
* adding `--omit-id` for policy stability across multiple image registries
11+
* better handle broken base64 policies in templates
12+
* improve error handling structure
13+
* make some mount types in VN2 required readonly
14+
* prompt users if they want to overwrite their policy in VN2
15+
* changing where dmverity-vhd and sign1util binaries are fetched from. This includes a significant speedup in dmverity-vhd hashing
16+
517
1.0.1
18+
++++++
619
* getting rid of msrestazure dependency in _validators.py
720

821
1.0.0

src/confcom/azext_confcom/README.md

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@
2929
- [allow_environment_variable_dropping](#allow_environment_variable_dropping)
3030
- [allow_unencrypted_scratch](#allow_unencrypted_scratch)
3131
- [allow_capabilities_dropping](#allow_capabilities_dropping)
32+
- [Microsoft Azure CLI 'confcom acifragmentgen' Extension Examples](#microsoft-azure-cli-confcom-acifragmentgen-extension-examples)
3233
- [Microsoft Azure CLI 'confcom katapolicygen' Extension Examples](#microsoft-azure-cli-confcom-katapolicygen-extension-examples)
33-
- [Microsoft Azure CLI 'confcom katapolicygen' Extension Examples]
3434

3535
## Microsoft Azure CLI 'confcom acipolicygen' Extension Examples
3636

@@ -279,16 +279,16 @@ Mixed-mode policy generation is available in the `confcom` tooling, meaning imag
279279

280280
## AKS Virtual Node
281281

282-
Azure Kubernetes Service (AKS) allows pods to be scheduled on Azure Container Instances (ACI)
283-
using the [AKS Virtual Node](https://learn.microsoft.com/en-us/azure/aks/virtual-nodes) feature. The `confcom` tooling can generate security policies for these ACI-based pods in the same way as for standalone ACI container groups. The key difference is that the `confcom` tooling will ingest an AKS pod specification (`pod.yaml`) instead of an ARM Template.
282+
Azure Kubernetes Service (AKS) allows pods to be scheduled on Azure Container Instances (ACI)
283+
using the [AKS Virtual Node](https://learn.microsoft.com/en-us/azure/aks/virtual-nodes) feature. The `confcom` tooling can generate security policies for these ACI-based pods in the same way as for standalone ACI container groups. The key difference is that the `confcom` tooling will ingest an AKS pod specification (`pod.yaml`) instead of an ARM Template.
284284

285285
Use the following command to generate and print a security policy for an AKS pod running on ACI:
286286

287287
```bash
288288
az confcom acipolicygen --virtual-node-yaml ./pod.yaml --print-policy
289289
```
290290

291-
> [!NOTE]
291+
> [!NOTE]
292292
> The `acipolicygen` command is specific to generating policies for ACI-based containers. For generating security policies for the [Confidential Containers on AKS](https://learn.microsoft.com/en-us/azure/aks/confidential-containers-overview) feature, use the `katapolicygen` command.
293293
294294
## Security Policy Information Sources
@@ -659,6 +659,81 @@ This rule determines whether unencrypted writable storage from the UVM to the co
659659

660660
Whether to allow capabilities to be dropped in the same manner as allow_environment_variable_dropping.
661661

662+
## Microsoft Azure CLI 'confcom acifragmentgen' Extension Examples
663+
664+
Run `az confcom acifragmentgen --help` to see a list of supported arguments along with explanations. The following commands demonstrate the usage of different arguments to generate confidential computing security fragments.
665+
666+
For information on what a policy fragment is, see [policy fragments](#policy-fragments). For a full walkthrough on how to generate a policy fragment and use it in a policy, see [Create a Key and Cert for Signing](../samples/certs/README.md).
667+
668+
**Examples:**
669+
670+
Example 1: The following command creates a security fragment and prints it to stdout as well as saving it to a file `contoso.rego`:
671+
672+
```bash
673+
az confcom acifragmentgen --config ./fragment_config.json --svn 1 --namespace contoso
674+
```
675+
676+
The config file is a JSON file that contains the following information:
677+
678+
```json
679+
{
680+
"containers": [
681+
{
682+
"name": "my-image",
683+
"properties": {
684+
"image": "mcr.microsoft.com/acc/samples/aci/helloworld:2.8",
685+
"environmentVariables": [
686+
{
687+
"name": "PATH",
688+
"value": "/customized/path/value"
689+
},
690+
{
691+
"name": "TEST_REGEXP_ENV",
692+
"value": "test_regexp_env(.*)",
693+
"regex": true
694+
}
695+
],
696+
"command": [
697+
"python3",
698+
"main.py"
699+
]
700+
}
701+
}
702+
]
703+
}
704+
```
705+
706+
The `--svn` argument is used to specify the security version number of the fragment and should be an integer. The `--namespace` argument is used to specify the namespace of the fragment and cannot conflict with some built-in names. If a conflicting name occurs, there will be an error message. [This list of reserved names can be found here under 'reserved_fragment_namespaces'](./data/internal_config.json). The format of the config file generally follows that of the [ACI resource in an ARM template](https://learn.microsoft.com/en-us/azure/templates/microsoft.containerinstance/containergroups?pivots=deployment-language-arm-template).
707+
708+
Example 2: This command creates a signed security fragment and attaches it to a container image in an ORAS-compliant registry:
709+
710+
```bash
711+
az confcom acifragmentgen --chain ./samples/certs/intermediateCA/certs/www.contoso.com.chain.cert.pem --key ./samples/certs/intermediateCA/private/ec_p384_private.pem --svn 1 --namespace contoso --config ./samples/config.json --upload-fragment
712+
```
713+
714+
Example 3: This command creates a file to be used by `acipolicygen` that says which fragments should be included in the policy. Note that the policy must be [COSE](https://www.iana.org/assignments/cose/cose.xhtml) signed:
715+
716+
```bash
717+
az confcom acifragmentgen --generate-import -p ./contoso.rego.cose --minimum-svn 1 --fragments-json fragments.json
718+
```
719+
720+
This outputs a file `fragments.json` that contains the following information:
721+
722+
```json
723+
{
724+
"path": "./contoso.rego.cose",
725+
"feed": "contoso.azurecr.io/example",
726+
"includes": [
727+
"containers",
728+
"fragments"
729+
],
730+
"issuer": "did:x509:0:sha256:mLzv0uyBNQvC6hi4y9qy8hr6NSZuYFv6gfCwAEWBNqc::subject:CN:Contoso",
731+
"minimum_svn": "1"
732+
}
733+
```
734+
735+
This file is then used by `acipolicygen` to generate a policy that includes custom fragments.
736+
662737
## Microsoft Azure CLI 'confcom katapolicygen' Extension Examples
663738

664739
Run `az confcom katapolicygen --help` to see a list of supported arguments along with explanations. The following commands demonstrate the usage of different arguments to generate confidential computing security policies.

src/confcom/azext_confcom/_help.py

Lines changed: 113 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# --------------------------------------------------------------------------------------------
66

77
from knack.help_files import helps # pylint: disable=unused-import
8-
8+
from azext_confcom.config import SUPPORTED_ALGOS
99

1010
helps[
1111
"confcom"
@@ -51,23 +51,23 @@
5151
5252
- name: --debug-mode
5353
type: boolean
54-
short-summary: 'When enabled, the generated security policy adds the ability to use /bin/sh or /bin/bash to debug the container. It also enabled stdio access, ability to dump stack traces, and enables runtime logging. It is recommended to only use this option for debugging purposes.'
54+
short-summary: 'When enabled, the generated security policy adds the ability to use /bin/sh or /bin/bash to debug the container. It also enabled stdio access, ability to dump stack traces, and enables runtime logging. It is recommended to only use this option for debugging purposes'
5555
5656
- name: --approve-wildcards -y
5757
type: boolean
58-
short-summary: 'When enabled, all prompts for using wildcards in environment variables are automatically approved.'
58+
short-summary: 'When enabled, all prompts for using wildcards in environment variables are automatically approved'
5959
6060
- name: --disable-stdio
6161
type: boolean
62-
short-summary: 'When enabled, the containers in the container group do not have access to stdio.'
62+
short-summary: 'When enabled, the containers in the container group do not have access to stdio'
6363
6464
- name: --print-existing-policy
6565
type: boolean
66-
short-summary: 'When enabled, the existing security policy that is present in the ARM Template is printed to the command line, and no new security policy is generated.'
66+
short-summary: 'When enabled, the existing security policy that is present in the ARM Template is printed to the command line, and no new security policy is generated'
6767
6868
- name: --diff -d
6969
type: boolean
70-
short-summary: 'When combined with an input ARM Template, verifies the policy present in the ARM Template under "ccePolicy" and the containers within the ARM Template are compatible. If they are incompatible, a list of reasons is given and the exit status code will be 2.'
70+
short-summary: 'When combined with an input ARM Template file (or YAML file for Virtual Node policy generation), verifies the policy present in the ARM Template under "ccePolicy" and the containers within the file are compatible. If they are incompatible, a list of reasons is given and the exit status code will be 2'
7171
7272
- name: --outraw
7373
type: boolean
@@ -79,7 +79,7 @@
7979
8080
- name: --save-to-file -s
8181
type: string
82-
short-summary: 'Save output policy to given file path.'
82+
short-summary: 'Save output policy to given file path'
8383
8484
- name: --print-policy
8585
type: boolean
@@ -89,6 +89,22 @@
8989
type: boolean
9090
short-summary: 'When enabled, the hashing algorithm used to generate the policy is faster but less memory efficient'
9191
92+
- name: --omit-id
93+
type: boolean
94+
short-summary: 'When enabled, the generated policy will not contain the ID field. This will keep the policy from being tied to a specific image name and tag'
95+
96+
- name: --include-fragments -f
97+
type: boolean
98+
short-summary: 'When enabled, the path specified by --fragments-json will be used to pull fragments from an OCI registry or locally and include them in the generated policy'
99+
100+
- name: --fragments-json -j
101+
type: string
102+
short-summary: 'Path to JSON file containing fragment information to use for generating a policy. This requires --include-fragments to be enabled'
103+
104+
- name: --exclude-default-fragments -e
105+
type: boolean
106+
short-summary: 'When enabled, the default fragments are not included in the generated policy. This includes containers needed to mount azure files, mount secrets, mount git repos, and other common ACI features'
107+
92108
examples:
93109
- name: Input an ARM Template file to inject a base64 encoded Confidential Container Security Policy into the ARM Template
94110
text: az confcom acipolicygen --template-file "./template.json"
@@ -98,6 +114,96 @@
98114
text: az confcom acipolicygen --template-file "./template.json" -s "./output-file.txt" --print-policy
99115
- name: Input an ARM Template file and use a tar file as the image source instead of the Docker daemon
100116
text: az confcom acipolicygen --template-file "./template.json" --tar "./image.tar"
117+
- name: Input an ARM Template file and use a fragments JSON file to generate a policy
118+
text: az confcom acipolicygen --template-file "./template.json" --fragments-json "./fragments.json" --include-fragments
119+
"""
120+
121+
helps[
122+
"confcom acifragmentgen"
123+
] = f"""
124+
type: command
125+
short-summary: Create a Confidential Container Policy Fragment for ACI.
126+
127+
parameters:
128+
- name: --image
129+
type: string
130+
short-summary: 'Image to use for the generated policy fragment'
131+
132+
- name: --input -i
133+
type: string
134+
short-summary: 'Path to a JSON file containing the configuration for the generated policy fragment'
135+
136+
- name: --tar
137+
type: string
138+
short-summary: 'Path to either a tarball containing image layers or a JSON file containing paths to tarballs of image layers'
139+
140+
- name: --namespace -n
141+
type: string
142+
short-summary: 'Namespace to use for the generated policy fragment'
143+
144+
- name: --svn
145+
type: string
146+
short-summary: 'Minimum Allowed Software Version Number for the generated policy fragment. This should be a monotonically increasing integer'
147+
148+
- name: --feed -f
149+
type: string
150+
short-summary: 'Feed to use for the generated policy fragment. This is typically the same as the image name when using image-attached fragments. It is the location in the remote repository where the fragment will be stored'
151+
152+
- name: --key -k
153+
type: string
154+
short-summary: 'Path to .pem formatted key file to use for signing the generated policy fragment. This must be used with --chain'
155+
156+
- name: --chain
157+
type: string
158+
short-summary: 'Path to .pem formatted certificate chain file to use for signing the generated policy fragment. This must be used with --key'
159+
160+
- name: --algo
161+
type: string
162+
short-summary: |
163+
Algorithm used for signing the generated policy fragment. This must be used with --key and --chain.
164+
Supported algorithms are {SUPPORTED_ALGOS}
165+
166+
- name: --fragment-path -p
167+
type: string
168+
short-summary: 'Path to an existing policy fragment file to be used with --generate-import. This option allows you to create import statements for the specified fragment without needing to pull it from an OCI registry'
169+
170+
- name: --generate-import -g
171+
type: boolean
172+
short-summary: 'Generate an import statement for a policy fragment'
173+
174+
- name: --disable-stdio
175+
type: boolean
176+
short-summary: 'When enabled, the containers in the container group do not have access to stdio'
177+
178+
- name: --debug-mode
179+
type: boolean
180+
short-summary: 'When enabled, the generated security policy adds the ability to use /bin/sh or /bin/bash to debug the container. It also enabled stdio access, ability to dump stack traces, and enables runtime logging. It is recommended to only use this option for debugging purposes'
181+
182+
- name: --output-filename
183+
type: string
184+
short-summary: 'Save output policy to given file path'
185+
186+
- name: --outraw
187+
type: boolean
188+
short-summary: 'Output policy in clear text compact JSON instead of default pretty print format'
189+
190+
- name: --upload-fragment -u
191+
type: boolean
192+
short-summary: 'When enabled, the generated policy fragment will be uploaded to the registry of the image being used'
193+
194+
- name: --fragments-json -j
195+
type: string
196+
short-summary: 'Path to a JSON file that will store the fragment import information generated when using --generate-import. This file can later be fed into the policy generation command (acipolicygen) to include the fragment in a new or existing policy. If not specified, the import statement will be printed to the console instead of being saved to a file'
197+
198+
examples:
199+
- name: Input an image name to generate a simple fragment
200+
text: az confcom acifragmentgen --image mcr.microsoft.com/azuredocs/aci-helloworld
201+
- name: Input a config file to generate a fragment with a custom namespace and debug mode enabled
202+
text: az confcom acifragmentgen --input "./config.json" --namespace "my-namespace" --debug-mode
203+
- name: Generate an import statement for a signed local fragment
204+
text: az confcom acifragmentgen --fragment-path "./fragment.json" --generate-import --minimum-svn 1
205+
- name: Generate a fragment and COSE sign it with a key and chain
206+
text: az confcom acifragmentgen --image mcr.microsoft.com/azuredocs/aci-helloworld --key "./key.pem" --chain "./chain.pem" --svn 1 --namespace contoso --no-print
101207
"""
102208

103209
helps[

0 commit comments

Comments
 (0)