Skip to content

Latest commit

 

History

History
156 lines (117 loc) · 9.26 KB

Confidential_ACI_SCHEME.md

File metadata and controls

156 lines (117 loc) · 9.26 KB

Confidential ACI scheme to support verification that a container group is genuine

Confidential ACI uses AMD SEV-SNP features to ensure the VM hosting running containers is secure against threats from the host operating system. The host starts a Utility VM (UVM) running a minimalist Linux in SNP mode for this purpose.

It is essential to check that sensitive workloads are indeed running in SNP VMs. This is done by obtaining an attestation report signed by the AMD hardware and passing that to a relying party to verify. You can also verify the attestation report manually.

Thus, a container must provide evidence to the relying party such that it can decide to release sensitive information to the container.

The evidence comprises the attestation report itself and three artefacts used to check it. These are:

  • Certificates issued by AMD to prove the particular CPU in the physical host is genuine and to verify the signed attestation report was generated by that CPU.
  • A COSE_Sign1 document signed by the Microsoft team which is responsible for the SNP VM image containing the expected hardware measurement of the SNP Utility VM and a SVN (Security Version Number).
  • The confidential computing enforcement policy, also known as security policy, supplied to the container runtime within the SNP Utility VM by the ACI infrastructure. This is the security policy provided by the customer to control what can be run within the VM, for example, which containers, environment variables, command lines and so forth.

These artefacts are provided as base64 encoded files in each container’s filesystem. The path to these files is generated to avoid colliding with existing files and made available via an environment variable UVM_SECURITY_CONTEXT_DIR (typically /security-context-*). Under that path are three files:

  • host-amd-cert-base64
  • reference-info-base64
  • security-policy-base64

host-amd-cert-base64

These are the AMD platform certificates, as per Trusted Hardware Identity Management Document - https://learn.microsoft.com/en-us/azure/security/fundamentals/trusted-hardware-identity-management#definitions, inlined in a JSON document encoded to base64. As JSON Schema:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "vcekCert": {
      "type": "string"
    },
    "tcbm": {
      "type": "string",
      "pattern": "^[0-9]+$"
    },
    "certificateChain": {
      "type": "string"
    },
    "cacheControl": {
      "type": "string"
    }
  },
  "required": [
    "vcekCert",
    "tcbm",
    "certificateChain",
    "cacheControl"
  ]
}

tcbm is CURRENT_TCB in Table 21 of SEV Secure Nested Paging Firmware ABI Specification. cacheControl is an implementation detail.

The following is an example of decoded JSON object:

{
    "vcekCert": "<PEM certificate>",
    "tcbm": "7308000000000003",
    "certificateChain": "<PEM certificate chain>",
    "cacheControl": "86400"
}

Example code that handles the JSON object can be found here:

https://github.com/microsoft/confidential-sidecar-containers/blob/main/pkg/common/info.go

reference-info-base64

This is a base64 encoded COSE_Sign1 document.

COSE_Sign1 envelopes are signed wrappers for arbitary data. See https://datatracker.ietf.org/doc/html/rfc8152. There is a header which contains the iss (issuer) and feed fields that must match Confidential ACI's signing identity and the certificate chain used to sign the whole bundle.

The COSE_Sign1 envelope has a JSON object as payload. The following is the JSON Schema:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "x-ms-sevsnpvm-guestsvn": {
      "type": "string",
      "pattern": "^[0-9]+$"
    },
    "x-ms-sevsnpvm-launchmeasurement": {
      "type": "string",
      "pattern": "^[0-9a-f]+$"
    }
  },
  "required": [
    "x-ms-sevsnpvm-guestsvn",
    "x-ms-sevsnpvm-launchmeasurement"
  ]
}

It contains the SVN of Confidential ACI as x-ms-sevsnpvm-guestsvn and hex encoded launch time measurement of UVM as x-ms-sevsnpvm-launchmeasurement.

The production SVN starts from 100.

There may be more fields in the JSON in future.

The following is an example payload:

{
  "x-ms-sevsnpvm-guestsvn": "100",
  "x-ms-sevsnpvm-launchmeasurement": "03fea02823189b25d0623a5c81f97c8ba4d2fbc48c914a55ce525f90454ddcec303743dac2fc013f0846912d1412f6df"
}

The field x-ms-sevsnpvm-launchmeasurement must match the launch measurement provided by the field MEASUREMENT of attestation report in Table 21 of SEV Secure Nested Paging Firmware ABI Specification. C code to obtain such a report can be found at https://github.com/microsoft/confidential-sidecar-containers/tree/main/tools/get-snp-report. Note that there are currently two versions - get-snp-report5.c for Linux Kernel version 5.15.* and get-snp-report6.c for kernels from 6.1 onwards.

To validate the COSE_Sign1 envelop you need to unpack it and check the iss and feed protected headers are as expected. iss is a did:x509 string and it can be used to check if it is properly signed by Microsoft. Confidential ACI Utility VMs are signed with a certificate chain which matches the DID:x509 did:x509:0:sha256:I__iuL25oXEVFdTP_aBLx_eT1RPHbCQ_ECBQfYZpt9s::eku:1.3.6.1.4.1.311.76.59.1.2. feed is a string ContainerPlat-AMD-UVM. These are stable identifiers, fixed for the lifetime of the root certificate which is more than 10 years. The DID:x509 string contains a hash of the root certificate and the eku (extended key usage) of the leaf certificate. COSE_Sign1 validation libraries (such as https://github.com/microsoft/cosesign1go, https://github.com/microsoft/cosesign1go/tree/main/cmd/sign1util#check) can be used to confirm that the document was signed by the expected issuing authority. In this case that is the team within Microsoft responsible for producing the UVM image (see https://github.com/microsoft/hcsshim).

These are examples that validate COSE_Sign1 envelope:

The first is the code that validates the similar security policy fragments, the second is code that validates these UVM reference information documents.

In Go, cosesign1go and didx509go are available to handle COSE_Sign1 and did:x509 respectively. In C++, t_cose and didx509cpp are available.

security-policy-base64

The Rego security policy is written by users or generated by Microsoft Azure CLI 'confcom' Extension. It is provided to the UVM at startup via the ACI configuration, and its SHA256 hash is used as HOST_DATA of attestation report. The following is an example:

https://github.com/Azure/azure-cli-extensions/blob/5362377ed1a674285dee0c3e4b517af8fbd1b26b/src/confcom/samples/sample-policy-output.rego

Relying party logic

It is essential that a container must not be given access to sensitive data before it is established that it is genuine. The container itself cannot do that as an attacker in charge of the host can easily load a modified container. There is a need for another entity to check that the container is genuine and running in a secure environment that respects the correct rules.

Container steps:

  • Create a key pair
  • Fetch an attestation report with REPORT_DATA == hash of public part of the key pair
  • Pass the attestation report and supporting documents to the relying party

Relying party steps:

  • Check that the attestation report is genuine and produced by real AMD SNP hardware by checking it is correctly signed, using the platform certificates in host-amd-cert-base64.
  • Check that the TEE is not in debug mode by inspecting the attestation report table 8.
  • Check that the Microsoft signed UVM reference info is genuine by checking the issuer and feed fields match the well known Confidential ACI values above and that the document is well formed.
  • Check that the launch measurement in the UVM reference info matches the launch measurement in the attestation report.
  • Check that the x-ms-sevsnpvm-guestsvn is the expected value.
  • Check that the HOST_DATA (sha256 over the security policy) is as expected. This is a customer specific value, for example it may be part of a mHSM key release policy.
  • Given all the above pass, encrypt the secret with the public part of the key from REPORT_DATA and return it to the container.