Skip to content

Commit

Permalink
Merge pull request #23 from SethHollandsworth/feature/sha256_hash
Browse files Browse the repository at this point in the history
Feature/sha256 hash, removing --json flag
  • Loading branch information
SethHollandsworth authored Apr 18, 2023
2 parents db1efe0 + 9e841d5 commit fd14dfc
Show file tree
Hide file tree
Showing 12 changed files with 64 additions and 135 deletions.
1 change: 1 addition & 0 deletions src/confcom/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ The `confcom` extension does not currently support:

- [ARM Template functions](https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/template-functions) other than `variables` and `parameters`.
- Variables and Parameters with non-primitive data types e.g. objects and arrays
- Nested and Linked ARM Templates

## Trademarks

Expand Down
6 changes: 3 additions & 3 deletions src/confcom/azext_confcom/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,15 @@ Example 2: This command injects a CCE policy into [ARM-template](arm.template.md

az confcom acipolicygen -a .\arm-template.json -p .\template.parameters.json

This is mainly for decoupling purposes so that an ARM template can remain the same and evolving variables can go into a different file.
This is mainly for decoupling purposes so that an ARM template can remain the same and evolving variables can go into a different file. When a security policy gets injected into the ARM Template, the corresponding sha256 hash of the decoded security policy gets printed to the command line. This sha256 hash can be used for verifying the hostdata field of the SEV-SNP Attestation Report and/or used for key release policies using MAA (Microsoft Azure Attestation) or mHSM (managed Hardware Security Module)

Example 3: This command takes the input of an ARM template to create a human-readable CCE policy in pretty print JSON format and output the result to the console.
NOTE: Generating JSON policy is for use by the customer only, and is not used by ACI In most cases. The default REGO format security policy is required. <br />

az confcom acipolicygen -a ".\arm_template" --outraw-pretty-print --json
az confcom acipolicygen -a ".\arm_template" --outraw-pretty-print

The default output of `acipolicygen` command is base64 encoded REGO format.
This example uses the `--json` argument to generate output in JSON format, use `--outraw-pretty-print` to indicate decoding policy in clear text and in pretty print format and print result to console.
This example uses `--outraw-pretty-print` to indicate decoding policy in clear text and in pretty print format and print result to console.

Example 4: The following command takes the input of an ARM template to create a human-readable CCE policy in clear text and print to console: <br />

Expand Down
4 changes: 0 additions & 4 deletions src/confcom/azext_confcom/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,6 @@
type: boolean
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.'
- name: --json -j
type: string
short-summary: 'Outputs in JSON format instead of Rego'
- name: --outraw
type: boolean
short-summary: 'Output policy in clear text compact JSON instead of default base64 format'
Expand Down
6 changes: 0 additions & 6 deletions src/confcom/azext_confcom/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,6 @@ def load_arguments(self, _):
required=False,
help="Disabling container stdio will disable the ability to see the output of the container in the terminal for Confidential ACI",
)
c.argument(
"use_json",
options_list=("--json", "-j"),
required=False,
help="Output in JSON format",
)
c.argument(
"diff",
options_list=("--diff", "-d"),
Expand Down
14 changes: 8 additions & 6 deletions src/confcom/azext_confcom/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@
from knack.log import get_logger
from azext_confcom.config import DEFAULT_REGO_FRAGMENTS
from azext_confcom import os_util
from azext_confcom.template_util import pretty_print_func, print_func
from azext_confcom.template_util import pretty_print_func, print_func, str_to_sha256
from azext_confcom.init_checks import run_initial_docker_checks
from azext_confcom.template_util import inject_policy_into_template, print_existing_policy_from_arm_template
from azext_confcom import security_policy
from azext_confcom.security_policy import OutputType


logger = get_logger(__name__)
Expand All @@ -27,7 +28,6 @@ def acipolicygen_confcom(
infrastructure_svn: str,
tar_mapping_location: str,
approve_wildcards: str = False,
use_json: bool = False,
outraw: bool = False,
outraw_pretty_print: bool = False,
diff: bool = False,
Expand Down Expand Up @@ -124,15 +124,17 @@ def acipolicygen_confcom(
exit_code = get_diff_outputs(policy, output_type == security_policy.OutputType.PRETTY_PRINT)
elif arm_template and (not print_policy_to_terminal and not outraw and not outraw_pretty_print):
result = inject_policy_into_template(arm_template, arm_template_parameters,
policy.get_serialized_output(output_type, use_json), count)
policy.get_serialized_output(), count)
if result:
print("CCE Policy successfully injected into ARM Template")
# this is always going to be the unencoded policy
print(str_to_sha256(policy.get_serialized_output(OutputType.RAW)))
logger.info("CCE Policy successfully injected into ARM Template")
else:
# output to terminal
print(f"{policy.get_serialized_output(output_type, use_json)}\n\n")
print(f"{policy.get_serialized_output(output_type)}\n\n")
# output to file
if save_to_file:
policy.save_to_file(save_to_file, output_type, use_json)
policy.save_to_file(save_to_file, output_type)

sys.exit(exit_code)

Expand Down
3 changes: 2 additions & 1 deletion src/confcom/azext_confcom/data/internal_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@
"feed": "mcr.microsoft.com/aci/aci-cc-infra-fragment",
"minimum_svn": "1",
"includes": [
"containers"
"containers",
"fragments"
]
}
],
Expand Down
28 changes: 4 additions & 24 deletions src/confcom/azext_confcom/security_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,21 +150,18 @@ def close(self) -> None:
def get_serialized_output(
self,
output_type: OutputType = OutputType.DEFAULT,
use_json=False,
rego_boilerplate=True,
) -> str:
# error check the output type
if not isinstance(output_type, Enum) or output_type.value not in [item.value for item in OutputType]:
eprint("Unknown output type for serialization.")

policy_str = self._policy_serialization(
use_json, output_type == OutputType.PRETTY_PRINT
output_type == OutputType.PRETTY_PRINT
)

if not use_json and rego_boilerplate:
if rego_boilerplate:
policy_str = self._add_rego_boilerplate(policy_str)
elif use_json and output_type == OutputType.PRETTY_PRINT:
policy_str = json.dumps(json.loads(policy_str), indent=2, sort_keys=True)

# if we're not outputting base64
if output_type in (OutputType.RAW, OutputType.PRETTY_PRINT):
Expand Down Expand Up @@ -217,19 +214,6 @@ def _add_elements(self, dictionary) -> Dict:

return dictionary

def _convert_to_json(self, dictionary) -> Dict:
# need to make a deep copy so we can change the underlying config data
# dicts
editable = copy.deepcopy(dictionary)
out = {"length": len(editable), "elements": {}}

for i, container in enumerate(editable):
out["elements"][str(i)] = container

self._add_elements(out)

return {config.POLICY_FIELD_CONTAINERS: out}

def validate_cce_policy(self) -> Tuple[bool, Dict]:
"""Utility method: check to see if the existing policy
that instantiates this function would allow the policy created by the input ARM Template"""
Expand Down Expand Up @@ -361,12 +345,11 @@ def save_to_file(
self,
file_path: str,
output_type: OutputType = OutputType.DEFAULT,
use_json=False,
) -> None:
output = self.get_serialized_output(output_type, use_json=use_json)
output = self.get_serialized_output(output_type)
os_util.write_str_to_file(file_path, output)

def _policy_serialization(self, use_json, pretty_print=False) -> str:
def _policy_serialization(self, pretty_print=False) -> str:
policy = []
regular_container_images = self.get_images()

Expand All @@ -383,9 +366,6 @@ def _policy_serialization(self, use_json, pretty_print=False) -> str:
for container in policy:
container[config.POLICY_FIELD_CONTAINERS_ALLOW_STDIO_ACCESS] = False

# default output is rego policy
if use_json:
policy = self._convert_to_json(policy)
if pretty_print:
return pretty_print_func(policy)
return print_func(policy)
Expand Down
5 changes: 5 additions & 0 deletions src/confcom/azext_confcom/template_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import copy
import tarfile
from typing import Any, Tuple, Dict, List
from hashlib import sha256
import deepdiff
import yaml
import docker
Expand Down Expand Up @@ -570,6 +571,10 @@ def pretty_print_func(x: dict) -> str:
return json.dumps(x, indent=2, sort_keys=True)


def str_to_sha256(x: str) -> str:
return sha256(x.encode('utf-8')).hexdigest()


def is_sidecar(image_name: str) -> bool:
return image_name.split(":")[0] in config.BASELINE_SIDECAR_CONTAINERS

Expand Down
60 changes: 18 additions & 42 deletions src/confcom/azext_confcom/tests/latest/test_confcom_arm.py

Large diffs are not rendered by default.

Loading

0 comments on commit fd14dfc

Please sign in to comment.