Attestation policies

To help protect data from an untrusted workload operator, Confidential Space implements an attestation process that detects modifications to a workload image or its TEE. The process is based on Shielded VM measured boot and extended runtime measurements, and captures boot sequence measurements in a protected, extend-only register in the virtual Trusted Platform Module (vTPM) device.

The Confidential Space attestation service generates OpenID Connect (OIDC) tokens that include these vTPM attestations in a form that can be validated by a workload identity pool, which checks them against policies added as attribute conditions to a provider. These tokens are signed by Google, last one hour, and are automatically refreshed.

Create an attestation policy

After you create a workload identity pool, attestation policies are added as attribute conditions to a provider. Policies are written in Common Expression Language (CEL), and are made up of a series of assertions that can be chained together with the && operator.

Here's an example of adding a provider to a workload identity pool using the gcloud CLI, along with the attribute-condition option that defines the policies:

gcloud iam workload-identity-pools providers create-oidc attestation-verifier \
    --location=global \
    --workload-identity-pool=user-pool-name \
    --issuer-uri="https://confidentialcomputing.googleapis.com/" \
    --allowed-audiences="https://sts.googleapis.com" \
    --attribute-mapping="google.subject=assertion.sub" \
    --attribute-condition="assertion.submods.container.image_digest =='sha256:837ccb607e312b170fac7383d7ccfd61fa5072793f19a25e75fbacb56539b86b' \
&& 'service-account@my-project.iam.gserviceaccount.com' in assertion.google_service_accounts \
&& assertion.swname == 'CONFIDENTIAL_SPACE' \
&& 'STABLE' in assertion.submods.confidential_space.support_attributes"

In this example, an external identity attempting to impersonate a service account attached to the workload identity pool must attest the following details and have their values match the policy values in order to authenticate successfully:

  • The workload container's image digest

  • The address of the service account attached to the workload VM

  • The Confidential Space image name

  • The production Confidential Space image support attribute

The available assertions to construct an attestation policy are detailed in the following table.

Attestation assertions

Assertions Type Description
Confidential Space image assertions
assertion.dbgstat String

Use to verify that the Confidential Space image is the debug or production version.

There are two valid values:

  • enable. Check that the debug image is being used.
  • disabled-since-boot. Check that the production image is being used.

Examples:

assertion.dbgstat == "enable"

Verifies that the debug version of the Confidential Space image is being used.

assertion.dbgstat == "disabled-since-boot"

Verifies that the production version of the Confidential Space image is being used.

assertion.submods.confidential_space.support_attributes Array[String]

Use to verify the security version of the TEE in a production Confidential Space image. Debug Confidential Space images have no support attribute set.

There are three support attributes:

  • USABLE. An image with only this attribute is out of support and no longer monitored for vulnerabilities. Use at your own risk.
  • STABLE. This version of the image is supported and monitored for vulnerabilities. A STABLE image is also USABLE.
  • LATEST. This is the latest version of the image, and is supported. The LATEST image is also STABLE and USABLE.

Example:

"LATEST" in assertion.submods.confidential_space.support_attributes

Verifies that the latest version of the Confidential Space image is being used.

assertion.swname String

Use to verify the software running on the attesting entity. The value is always CONFIDENTIAL_SPACE.

Example:

assertion.swname == "CONFIDENTIAL_SPACE"
assertion.swversion Array[String]

Use to verify the software version of the Confidential Space image. We recommend using assertion.submods.confidential_space.support_attributes to target the latest version of an image, instead of a specific version.

Example:

int(assertion.swversion[0]) == 230103
Workload container assertions
assertion.submods.container.cmd_override Array[String]

Use to verify CMD commands and parameters used in the workload image.

Examples:

size(assertion.submods.container.cmd_override) == 0

Verifies the CMD of the workload image hasn't been overwritten.

assertion.submods.container.cmd_override == ['program']

Verifies that 'program' is the only content in the CMD overrides.

assertion.submods.container.env JSON object

Use to verify environment variables and their values have been explicitly passed to the container.

Example:

{"example-env-1": "value-1", "example-env-2": "value-2"}

Verifies that the environment variable example-env-1 is set to value-1, and example-env-2 is set to value-2.

assertion.submods.container.env_override JSON object

Use to verify if the user has overwritten environment variables in the container.

Examples:

!has(assertion.submods.container.env_override.example)

Verifies that the user has not overridden the example environment variable.

size(assertion.submods.container.env_override) == 0

Verifies that the user hasn't overwritten any environment variables.

assertion.submods.container.image_digest String

Use to verify the image digest of the workload container. Specifying this condition lets multiple parties agree on an authorized workload that is allowed to access their data.

Example:

assertion.submods.container.image_digest == "sha256:837ccb607e312b170fac7383d7ccfd61fa5072793f19a25e75fbacb56539b86b"
assertion.submods.container.image_id String

Use to verify the image ID of the workload container.

Example:

assertion.submods.container.image_id == "sha256:652a44b0e911271ba07cf2915cd700fdfa50abd62a98f87a57fdebc59843d93f"
assertion.submods.container.image_reference String

Use to verify the location of the workload container running in Confidential Space.

Example:

assertion.submods.container.image_reference == "us-docker.pkg.dev/PROJECT_ID/WORKLOAD_CONTAINER:latest"
assertion.submods.container.image_signatures JSON object

Use to verify that the image has a certain signature or is signed by a public key and signing algorithm. It can include the following elements:

  • key_id: The hexadecimal fingerprint of the public key. To get the fingerprint, you can run the following command:

    openssl pkey -pubin -in public_key.pem -outform DER | openssl sha256

    public_key.pem is your public key in PEM format.

  • signature: The signature over a payload that's associated with the signed container and that follows the Simple Signing format.
  • signature_algorithm: The algorithm used to sign the key. One of the following:

    • RSASSA_PSS_SHA256 (RSASSA-PSS with a SHA-256 digest)
    • RSASSA_PKCS1V15_SHA256 (RSASSA-PKCS1 v1_5 with a SHA-256 digest)
    • ECDSA_P256_SHA256 (ECDSA on the P-256 Curve with a SHA-256 digest)

Example:

assertion.swname == 'CONFIDENTIAL_SPACE' && ['ECDSA_P256_SHA256:FINGERPRINT_OF_PUBLIC_KEY'].exists(fingerprint, fingerprint in assertion.submods.container.image_signatures.map(sig, sig.signature_algorithm+':'+sig.key_id)) && 'serviceaccount.iam.gserviceaccount.com' in assertion.google_service_accounts"
assertion.submods.container.restart_policy String

Use to verify the restart policy of the container launcher when the workload stops. Valid values are Always, OnFailure, and Never. Default is Never.

Example:

assertion.submods.container.restart_policy == "Never"
VM assertions
assertion.google_service_accounts Array[String]

Use to verify that a specified service account is attached to the VM running the workload, or has been listed using tee-impersonate-service-account in the VM metadata.

Example:

workload-service-account@my-project.iam.gserviceaccount.com in assertion.google_service_accounts
assertion.hwmodel String

Use to verify the underlying Confidential Computing hardware protection and specifics of the platform operating system. The only supported platform is GCP_AMD_SEV.

Example:

assertion.hwmodel == "GCP_AMD_SEV"
assertion.submods.gce.instance_id String

Use to verify the VM instance ID.

Example:

assertion.submods.gce.instance_id == "0000000000000000000"
assertion.submods.gce.instance_name String

Use to verify the name of the VM instance.

Example:

assertion.submods.gce.instance_name == "workload-vm"
assertion.submods.gce.project_id String

Use to verify the VM is running a Google Cloud project with the specified project ID.

Example:

assertion.submods.gce.project_id == "project-id"
assertion.submods.gce.project_number String

Use to verify the VM is running in a Google Cloud project with the specified project number.

Example:

assertion.submods.gce.project_number == "00000000000"
assertion.submods.gce.zone String

Use to verify the VM is running in the specified zone.

Example:

assertion.submods.gce.zone == "us-central1-a"

Troubleshooting policy failures

If the service account attached to your Confidential Space VM has been granted the logging.logWriter role, you can troubleshoot errors by viewing the VM's logs:

  1. Go to Logging in the workload operator's project in the Google Cloud console.

    Go to Logging

  2. Click Edit time to set a start time and end time for the logs you want to view.

  3. Filter by the following log fields if they're available:

    • Resource type: VM Instance

    • Instance ID: The instance ID of the VM

    • Log name: confidential-space-launcher

  4. Read the failure message to find out what the problem is. A resource might not have been set up properly, or the attribute conditions in your workload identity pool providers might not match the claims made by the Confidential Space workload.