Skip to content

Commit

Permalink
skopeo: programatically start/stop keyprovider
Browse files Browse the repository at this point in the history
  • Loading branch information
csegarragonz committed Oct 10, 2023
1 parent e2d2933 commit db5378b
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 8 deletions.
4 changes: 4 additions & 0 deletions docs/helloworld_knative_attestation.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ signatures, consume encrypted container images.

After that, you may jump to [running the application](#run-the-application).

> Note that, if you are running different attestation types one after the other
> you may want to clear the contents of the KBS between runs using:
> `inv kbs.clear-db`
## Firmware Digest

Before running the application, we need to generate the expected launch digest
Expand Down
14 changes: 9 additions & 5 deletions tasks/skopeo.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
SKOPEO_VERSION = "1.13.0"
SKOPEO_IMAGE = "quay.io/skopeo/stable:v{}".format(SKOPEO_VERSION)
SKOPEO_ENCRYPTION_KEY = join(K8S_CONFIG_DIR, "image_enc.key")
# SKOPEO_CTR_ENCRYPTION_KEY = "/tmp/image_enc.key"
AA_CTR_ENCRYPTION_KEY = "/tmp/image_enc.key"


Expand All @@ -31,7 +30,6 @@ def run_skopeo_cmd(cmd, capture_stdout=False):
cmd,
]
skopeo_cmd = " ".join(skopeo_cmd)
print(skopeo_cmd)
if capture_stdout:
return run(skopeo_cmd, shell=True, capture_output=True).stdout.decode("utf-8").strip()
else:
Expand All @@ -50,13 +48,16 @@ def encrypt_container_image(ctx, image_tag, sign=False):
The image tag must be provided in the format: docker.io/<repo>/<name>:tag
"""
# start_coco_keyprovider()

# Encrypt image
encryption_key_resource_id = "default/image-encryption-key/1"
if not exists(SKOPEO_ENCRYPTION_KEY):
create_encryption_key()

# We use CoCo's keyprovider server (that implements the ocicrypt protocol)
# to encrypt the OCI image. To that extent, we need to mount the encryption
# key somewhere that the attestation agent (in the keyprovider) can find
# it
start_coco_keyprovider(SKOPEO_ENCRYPTION_KEY, AA_CTR_ENCRYPTION_KEY)

encrypted_image_tag = image_tag.split(":")[0] + ":encrypted"
skopeo_cmd = [
"copy --insecure-policy",
Expand All @@ -75,6 +76,7 @@ def encrypt_container_image(ctx, image_tag, sign=False):
layers = [layer["MIMEType"].endswith("tar+gzip+encrypted") for layer in inspect_json["LayersData"]]
if not all(layers):
print("Some layers in image {} are not encrypted!".format(encrypted_image_tag))
stop_coco_keyprovider()
raise RuntimeError("Image encryption failed!")

# Create a secret in KBS with the encryption key. Skopeo needs it as raw
Expand All @@ -89,3 +91,5 @@ def encrypt_container_image(ctx, image_tag, sign=False):

if sign:
sign_container_image(encrypted_image_tag)

stop_coco_keyprovider()
22 changes: 19 additions & 3 deletions tasks/util/guest_components.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from os.path import join
from subprocess import run
from tasks.util.env import PROJ_ROOT
from time import sleep

GUEST_COMPONENTS_DIR = join(PROJ_ROOT, "..", "guest-components")
COCO_KEYPROVIDER_DIR = join(GUEST_COMPONENTS_DIR, "attestation-agent", "coco_keyprovider")
Expand All @@ -9,22 +10,37 @@
COCO_KEYPROVIDER_CTR_PORT = 50000


def start_coco_keyprovider():
def start_coco_keyprovider(host_key_path, guest_key_path):
"""
Start the CoCo key-provider to encrypt a docker image using Skopeo
"""
docker_cmd = [
"docker run -d",
"--net host",
"--name {}".format(COCO_KEYPROVIDER_CTR_NAME),
"-p {port}:{port}".format(port=COCO_KEYPROVIDER_CTR_PORT),
"-v {}:/usr/src/guest-components".format(GUEST_COMPONENTS_DIR),
"-v {}:{}".format(host_key_path, guest_key_path),
"-w /usr/src/guest-components/attestation-agent/coco-keyprovider",
"rust:1.72",
"bash -c 'rustup component add rustfmt && cargo run --release -- --socket 127.0.0.1:{}'".format(COCO_KEYPROVIDER_CTR_PORT),
"bash -c 'rustup component add rustfmt && cargo run --release --bin coco_keyprovider -- --socket 127.0.0.1:{}'".format(COCO_KEYPROVIDER_CTR_PORT),
]
docker_cmd = " ".join(docker_cmd)
print(docker_cmd)
run(docker_cmd, shell=True, check=True)

# Wait for the gRPC server to be ready
poll_period = 2
string_to_check = "listening to socket addr"
while True:
sleep(poll_period)
logs_cmd = "docker logs {}".format(COCO_KEYPROVIDER_CTR_NAME)
ctr_logs = run(logs_cmd, shell=True, capture_output=True).stderr.decode("utf-8")
if string_to_check in ctr_logs:
print("gRPC server ready!")
break

print("Waiting for keyprovider's gRPC server to be ready...")


def stop_coco_keyprovider():
"""
Expand Down

0 comments on commit db5378b

Please sign in to comment.