Skip to content

Commit

Permalink
Add Confidential Space documentation and example
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 575952813
Change-Id: I0437bb00973340b87f71e12f11983bf58f900513
  • Loading branch information
jessieqliu authored and copybara-github committed Oct 23, 2023
1 parent 57939ef commit 3e2ecb6
Show file tree
Hide file tree
Showing 5 changed files with 226 additions and 0 deletions.
140 changes: 140 additions & 0 deletions docs/confidential_space.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# Confidential Space

Integration with Confidential Space enables added security and convenience for
both products. This doc covers the features enabled by this combination.

## CloudKMS Attestation

With Confidential Space, STET can use the Attestation Token as attestation
evidence when accessing a CloudKMS KEK.

By default, STET uses Application Default Credentials when performing CloudKMS
operations. This feature allows STET to determine whether it needs to configure
a different set of credentials (through Workload Identity Federation) to use a
particular KEK.

### Setup

You can find additional information and examples on how to use Confidential
Space
[here](https://cloud.google.com/confidential-computing/confidential-vm/docs/analyze-with-confidential-space).

To enable STET to provide Confidential Space attestation to Cloud KMS, (aside
from existing setup) you will need to (A) write STET configs containing your KEK
and credential information, and (B)
[install and run STET](../README.md#prebuilt-binaries) in your workload.

To use CloudKMS Attestation in STET, add a `confidential_space_configs` section
to your STET config file. This contains one or more `kek_credentials`, each of
which contains information about credentials needed to access a Confidential
Space WIP-protected KEK: * `kek_uri_pattern` is a regex pattern indicating the
URIs of KEKs that should be this set of credentials. * `wip_name` is the
identifier of the WIP, which should be of the format
`projects/*/locations/*/workloadIdentityPools/*/providers/*`. *
`service_account` is the trusted service account that will be used to access the
KEK. * `mode` refers to whether these credentials are used for encrypt and/or
decrypt. Defaults to `DEFAULT_ENCRYPT_AND_DECRYPT_MODE`.

#### Example

```yaml#
encrypt_config:
key_config:
kek_infos:
- kek_uri: "gcp-kms://projects/foo-project/locations/us-east1/keyRings/my-keyring/cryptoKeys/my-key"
dek_algorithm: AES256_GCM0
no_split: true
decrypt_config:
key_configs:
- kek_infos:
- kek_uri: "gcp-kms://projects/foo-project/locations/us-east1/keyRings/my-keyring/cryptoKeys/my-key"
dek_algorithm: AES256_GCM
no_split: true
confidential_space_configs:
kek_credentials:
# These credentials will be used in both `encrypt` and `decrypt`.
- kek_uri_pattern: "gcp-kms://projects/foo-project/.*"
wip_name: "projects/1234/locations/global/workloadIdentityPools/foo-wip/providers/foo-provider"
service_account: "[email protected]"
# These credentials will only be used in `encrypt`.
- kek_uri_pattern: "gcp-kms://projects/bar-project/.*"
wip_name: "projects/5678/locations/global/workloadIdentityPools/bar-wip/providers/bar-provider"
service_account: "[email protected]"
mode: ENCRYPT_ONLY
# These credentials will only be used in `decrypt`.
- kek_uri_pattern: "gcp-kms://projects/bar-project/.*"
wip_name: "projects/5678/locations/global/workloadIdentityPools/bar-wip/providers/bar-provider"
service_account: "[email protected]"
mode: DECRYPT_ONLY
```

When a STET is run from a workload in a Confidential Space VM, it will
automatically detect that it is in Confidential Space and look for corresponding
credentials to use when contacting CloudKMS.

* If STET detects it is in Confidential Space and `confidential_space_configs`
is provided, it will search `kek_credentials` for the first one where
`kek_uri_pattern` and `mode` match the current KEK URI and STET command,
respectively.
* If a match is found, `wip_name` and `service_account` will be used to
configure credentials for CloudKMS.
* If a match is not found, Application Default Credentials will be used.
* Defining `confidential_space_configs` is **optional**. If not provided, STET
will default to Application Default Credentials for CloudKMS Operations.

### Usage

Once you have configured Confidential Space and your STET configs accordingly,
you can execute `stet encrypt` or `decrypt` like normal.

### Additional Considerations

#### Grant CloudKMS Viewer Permissions

If STET detects a KEK has Confidential Space credentials, it will also use those
credentials to retrieve its `CryptoKey` metadata.

**What does this mean?** Ensure that any service accounts used to encrypt or
decrypt with a KEK also have the `CloudKMS Viewer` role on that KEK.

#### First Match Only

STET will only try the first set of credentials that matches the KEK URI and
encrypt/decrypt command.

**What does this mean?** To avoid confusion, ensure only one `kek_uri_pattern`
matches the KEK you want to use, or pay careful attention to the ordering of
`kek_credentials`.

In the below config, STET will use the credentials with the `foo@` service
account, despite the `kek_uri_pattern` for `bar@` matching more specifically.

```yaml#
encrypt_config:
key_config:
kek_infos:
- kek_uri: "gcp-kms://projects/foo-project/locations/us-east1/keyRings/my-keyring/cryptoKeys/my-key"
dek_algorithm: AES256_GCM
no_split: true
confidential_space_configs:
kek_credentials:
- kek_uri_pattern: "gcp-kms://.*"
wip_name: "projects/1234/locations/global/workloadIdentityPools/foo-wip/providers/foo-provider"
service_account: "[email protected]"
- kek_uri_pattern: "gcp-kms://projects/foo-project/locations/us-east1/keyRings/my-keyring/cryptoKeys/my-key"
wip_name: "projects/5678/locations/global/workloadIdentityPools/bar-wip/providers/bar-provider"
service_account: "[email protected]"
```

#### Only Include Required Credentials

If STET finds a set of credentials that matches the KEK and command, it assumes
that KEK/command can only be accessed in Confidential Space by that set of
credentials. If that fails, STET will not (A) try another set of credentials, or
(B) try Application Default Credentials.

**What does this mean?** Ensure you only include credentials that are necessary
to access the KEKs.
16 changes: 16 additions & 0 deletions examples/confidential_space/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM google/cloud-sdk:latest

WORKDIR /test

LABEL "tee.launch_policy.allow_env_override"="CIPHERTEXT_OBJECT,PLAINTEXT_OBJECT"

# Assuming stet binary is built/present in the current directory.
ADD stet /usr/local/bin
RUN chown root /usr/local/bin/stet
RUN chmod u+sx,a+rx /usr/local/bin/stet

COPY config.yaml .

COPY --chown=1001 simple_workload.sh ./
RUN chmod +x ./simple_workload.sh
CMD ["./simple_workload.sh"]
20 changes: 20 additions & 0 deletions examples/confidential_space/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
encrypt_config:
key_config:
kek_infos:
- kek_uri: "gcp-kms://projects/my-project/locations/us-east1/keyRings/my-key-ring/cryptoKeys/confspace-key"
dek_algorithm: AES256_GCM
no_split: true

decrypt_config:
key_configs:
- kek_infos: # Note the extra hyphen here, because key_configs is a repeated field.
- kek_uri: "gcp-kms://projects/my-project/locations/us-east1/keyRings/my-key-ring/cryptoKeys/confspace-key"
dek_algorithm: AES256_GCM
no_split: true

confidential_space_configs:
kek_credentials:
- kek_uri_pattern: "gcp-kms://projects/my-project/locations/us-east1/keyRings/my-key-ring/cryptoKeys/confspace-key"
wip_name: "projects/123456789/locations/global/workloadIdentityPools/trusted-workload-pool/providers/attestation-verifier"
service_account: "[email protected]"
mode: DECRYPT_ONLY_MODE
38 changes: 38 additions & 0 deletions examples/confidential_space/info.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
This document briefly describes how to use the example code in this directory,
consisting of the following files: * `config.yaml` is an example STET config
that uses Confidential Space. It is configured to use Confidential Space in the
decrypt workflow. * `simple_workload.sh` is a basic workload meant to be used in
a Confidential Space VM. It downloads data from GCS and executes `stet decrypt`
on it with `config.yaml`. * `Dockerfile` is an example dockerfile to build an
image with `simple_workload`.

## Encrypt Workflow

For this example, Confidential Space is not needed for the encryption workflow.
Execute `stet encrypt` and upload the ciphertext to your GCS bucket as you
normally would for
[Cloud Data Ingress](https://github.com/GoogleCloudPlatform/stet/blob/main/docs/workflows.md#cloud-data-ingress).

## Decrypt Workflow

For this example, the decryption workflow requires setting up a Confidential
Space VM. Follow the instructions
[here](https://codelabs.developers.google.com/codelabs/confidential-space#0) for
a codelab on how to set up Confidential Space - including building and uploading
the workload as a Docker image.

To use the provided example `config.yaml`: * Replace the `kek_uri` and
`kek_uri_pattern` fields with your KEK URI * Replace `wip_name` with the name of
your WIP * Replace `service_account` with the trusted service account attached
to your WIP * This is the same service account that should have `decrypt`
permissions on your KEK

When you create your Confidential VM instance, make sure to include the
following metadata values: * `tee-env-CIPHERTEXT_OBJECT=$CIPHER_URI`, where
`$CIPHER_URI` is the gsutil URI where your ciphertext was uploaded to. *
`tee-env-PLAINTEXT_OBJECT=$PLAIN_URI`, where `$PLAIN_URI` is the gsutil URI for
the workload to upload the deciphered data to.

Once the VM is created and started, it will automatically run the workload and
upload the decrypted data to the URI you specified. You can also inspect the VM
logs to see the exit code of the workload to confirm it ran correctly.
12 changes: 12 additions & 0 deletions examples/confidential_space/simple_workload.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash

# This is a simple Confidential Space workload that downloads an object from
# GCS, decrypts it with STET, and uploads the result to GCS.

gsutil cp $CIPHERTEXT_OBJECT /test/ciphertext

# Decrypt with STET.
stet decrypt --config-file=config.yaml /test/ciphertext /test/plaintext

# Print decrypted data.
gsutil cp /test/plaintext $PLAINTEXT_OBJECT

0 comments on commit 3e2ecb6

Please sign in to comment.