Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,11 @@ Azure Storage currently allows setting **Minimum TLS Version = TLS 1.0, 1.1, or

### Azure Portal steps
#### Require secure transfer for a new storage account
1. Open the **Create storage account** pane in the Azure portal.
2. In the **Advanced** page, select the **Enable secure transfer** checkbox.
3. Create storage account blade
1. In the top center search bar in the Azure portal, search for **Storage accounts**
1. Click on **Create**
1. Select your own resource group, provide a unique name for the **Storage account name** and select "**Azure Blob Storage or Azure Data Lake Storage Gen2** for the **Preferred storage type** parameter
1. Click next and in the **Advanced** page, select the **Require secure transfer for REST API operations** checkbox if not already enabled.
1. Leave the rest of the parameters as-is and click **Review + create**

![desc](./images/storage_01.png)

Expand All @@ -86,12 +88,13 @@ Goal: ensure all storage accounts enforce **Minimum TLS Version = TLS 1.2**.

### Azure Portal steps

1. Open **Azure Policy** in the Portal.
1. In the Azure Portal, navigate to **Policy**
2. Select **Definitions**, search for **"Storage accounts should have the specified minimum TLS version"** (Policy ID `fe83a0eb-a853-422d-aac2-1bffd182c5d0`).
3. Choose **Assign**.
4. Set **Scope** to the subscription or resource group.
5. Under **Parameters**, set **Minimum TLS version** to `TLS 1.2` and (optionally) effect to `Deny`.
6. Complete **Review + Create**, then select **Create**.
4. Set **Scope** to the subscription and your **Labuser-xxx** resource group.
5. Uncheck the box: **Only show parameters that need input or review**
6. Under **Parameters**, set **Minimum TLS version** to `TLS 1.2` and (optionally) effect to `Deny`.
7. Complete **Review + Create**, then select **Create**.

![Azure Policy](./images/policy_01.png)

Expand Down Expand Up @@ -186,6 +189,8 @@ az role assignment create \

#### Create a Container

Use the Azure Portal to create a new container or use CLI below

```bash
# Create a blob storage container
# Create a container named "test-container"
Expand Down Expand Up @@ -221,6 +226,8 @@ StorageBlobLogs

![Log Analytics](./images/log_analytics_02.png)

Look for TLS 1.0/1.1 usage.

> **Tip:** If you observe TLS 1.0/1.1 usage, upgrade client frameworks (e.g., .NET, Java, Python SDKs), avoid hardcoded protocol versions, and rely on OS defaults that negotiate TLS 1.2+ ([learn.microsoft.com](https://learn.microsoft.com/azure/storage/common/transport-layer-security-configure-minimum-version)).

## Results & acceptance criteria
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -151,16 +151,11 @@ ATTESTATION_NAME="attest${HASH_SUFFIX}"
> [!WARNING]
> If your Azure Cloud Shell session times out (e.g. during a break), the variables defined above will be lost and must be re-defined before continuing. We recommend saving them in a local text file on your machine so you can quickly copy and paste them back into a new session.

### Step 2: Create Resource Group and Key Vault
### Step 2: Create Key Vault

Create the resource group and Key Vault with RBAC-based permissions:
Create a Key Vault with RBAC-based permissions:

```bash
# Create Resource Group
az group create \
--name $RESOURCE_GROUP \
--location $LOCATION

# Create Key Vault with Azure RBAC permission model
az keyvault create \
--name $KEYVAULT_NAME \
Expand Down Expand Up @@ -263,12 +258,12 @@ az network vnet subnet create \
Create the Confidential VM with AMD SEV-SNP hardware encryption:

```bash
# Create Confidential VM (North Europe) - No public IP
# Create Confidential VM - No public IP
az vm create \
--resource-group $RESOURCE_GROUP \
--name "vm-ubuntu-cvm" \
--location $LOCATION \
--size "Standard_DC2as_v5" \
--size "Standard_DC2as_v6" \
--admin-username $ADMIN_USERNAME \
--ssh-key-value "$SSH_PUBLIC_KEY" \
--authentication-type ssh \
Expand All @@ -288,6 +283,7 @@ az vm identity assign \
```

💡 **Key Configuration Details**:

- `--security-type "ConfidentialVM"` - Enables hardware-based confidential computing
- `--os-disk-security-encryption-type "VMGuestStateOnly"` - Encrypts VM guest state with platform-managed keys
- `--enable-secure-boot true` - Protects boot integrity
Expand All @@ -299,24 +295,25 @@ az vm identity assign \
Create Azure Bastion for secure remote access:

```bash
# Create Public IP for Bastion (North Europe)
# Create Public IP for Bastion
az network public-ip create \
--resource-group $RESOURCE_GROUP \
--name "bastion-northeurope-ip" \
--name "bastion-ip" \
--location $LOCATION \
--sku "Standard" \
--allocation-method "Static"

# Create Azure Bastion (Basic SKU) for North Europe
# Create Azure Bastion (Basic SKU)

echo "Bastion deployment initiated (this may take 5-10 minutes)"

az network bastion create \
--resource-group $RESOURCE_GROUP \
--name "bastion-northeurope" \
--name "bastion" \
--location $LOCATION \
--vnet-name "vm-ubuntu-cvm-vnet" \
--public-ip-address "bastion-northeurope-ip" \
--public-ip-address "bastion-ip" \
--sku "Basic"

echo "Bastion deployment in North Europe initiated (this may take 5-10 minutes)"
```

⏱️ **Deployment Time**: Azure Bastion typically takes 5-10 minutes to deploy. You can proceed with reviewing the next sections while waiting.
Expand All @@ -329,10 +326,10 @@ echo "Bastion deployment in North Europe initiated (this may take 5-10 minutes)"

### Step 1: Connect via Azure Bastion

> **📝 Note: These commands run ON the Linux VM itself after connecting via Bastion (not on your local machine)**
> **📝 Note: These commands run ON the Linux VM itself after connecting via Bastion (not on your local machine or in Azure Cloud Shell)**

1. Navigate to the Azure Portal
2. Go to **Virtual Machines** > **vm-ubuntu-cvm**
2. Go to **Virtual Machines** > **vm-ubuntu-cvm** (select the one in your resource group)
3. Click **Connect** > **Connect via Bastion**
4. **Authentication Type**: SSH Private Key from Azure Key Vault
5. **Username**: `azureuser`
Expand Down Expand Up @@ -391,14 +388,29 @@ sudo dpkg -i azguestattestation1_1.1.2_amd64.deb

### Step 1: Build the Attestation Client

Install prerequisites by running these commands:

```bash
sudo apt install cmake

sudo apt-get update -y && sudo apt-get install -y build-essential

sudo apt-get install -y libcurl4-openssl-dev libjsoncpp-dev libboost-all-dev nlohmann-json3-dev jq
```

### Generate build files

```bash
# Navigate to the sample app directory
cd confidential-computing-cvm-guest-attestation/cvm-attestation-sample-app/

# Generate build files with CMake
cmake .
```

# Compile the application
### Compile the application

```bash
make
```

Expand All @@ -408,7 +420,7 @@ make

To use the dedicated Attestation Provider you created in Task 2 Step 4, you need to pass its URI using the `-a` argument.

**Retrieve Your Attestation URI via Azure CLI**
#### Retrieve Your Attestation URI via Azure CLI from your Azure CLI session in Cloud Shell or your local machine

```bash
# Retrieve your attestation provider URI
Expand All @@ -417,7 +429,17 @@ ATTESTATION_URI=$(az attestation show \
--resource-group $RESOURCE_GROUP \
--query "attestUri" \
-o tsv)
echo $ATTESTATION_URI
```

Alternatively, you may also retrieve the URL from the Azure portal (navigate to your resource group and click on the Attestation provider resource):

![Attestation Client - Specified Provider](./images/attestation-provider.png)

#### Run attestation with your custom provider (inside the Linux VM)

```bash
ATTESTATION_URI= <insert value from previous command>
# Run attestation with your custom provider
sudo ./AttestationClient -a $ATTESTATION_URI -o token | jq -R 'split(".") | .[0],.[1] | @base64d | fromjson'
```
Expand Down Expand Up @@ -453,7 +475,7 @@ The JWT token contains multiple claims that cryptographically prove the VM's sec

### Production Implementation Pattern

In a production scenario, your application would implement attestation checks before processing sensitive data:
In a production scenario, your application would implement attestation checks before processing sensitive data (this is just an example for inspiration, do not run this on the Linux server):

```python
# Pseudocode - Production attestation pattern
Expand Down Expand Up @@ -490,22 +512,6 @@ def process_sensitive_data(customer_data):

---

## Task 6: Clean Up Resources

💡 **Delete all resources to avoid ongoing charges.**

### Delete Resource Group

To delete all resources created in this challenge:

```bash
az group delete --name $RESOURCE_GROUP --yes --no-wait
```

⚠️ **Warning**: This command will permanently delete all resources in the resource group including the VM, Key Vault, Bastion, and all associated resources.

---

## Key Takeaways

In this challenge, you successfully implemented and validated Azure Confidential Computing with guest attestation. Here are the key concepts and best practices:
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -122,27 +122,29 @@ az feature show --namespace Microsoft.ContainerService --name AzureLinuxCVMPrevi
az provider register --namespace Microsoft.ContainerService
```

> [!WARNING]
> For all Microsoft-hosted events, these features and providers below are already registered. Ignore any error messages due to lack of permissions.

---

## Task 2: Create Resource Group and AKS Cluster
## Task 2: Create Azure Kubernetes Service cluster

💡 **Deploy the foundational AKS cluster with a standard system node pool. You'll add the Confidential VM node pool in the next task.**

### Step 1: Create Resource Group and AKS Cluster
### Step 1: Create AKS cluster

```bash
# Create Resource Group
az group create \
--name $RESOURCE_GROUP \
--location $LOCATION

# Create an AKS cluster
az aks create --resource-group $RESOURCE_GROUP --name $AKS_CLUSTER_NAME --node-count 1 --location $LOCATION --generate-ssh-keys

# Connect to the cluster
az aks get-credentials --resource-group $RESOURCE_GROUP --name $AKS_CLUSTER_NAME
```

At this point, you should see an AKS cluster in your resource group:

![AKS](./images//aks.png)

---

## Task 3: Add Confidential VM Node Pool
Expand All @@ -155,6 +157,10 @@ az aks get-credentials --resource-group $RESOURCE_GROUP --name $AKS_CLUSTER_NAME
az aks nodepool add --resource-group $RESOURCE_GROUP --cluster-name $AKS_CLUSTER_NAME --name cvmnodepool --node-count 1 --node-vm-size Standard_DC2as_v5
```

At this point, you should see another AKS node pool in your cluster:

![AKS](./images//aks-02.png)

---

## Task 4: Verify Confidential Node Pool Configuration
Expand All @@ -179,12 +185,12 @@ az aks nodepool list --resource-group $RESOURCE_GROUP --cluster-name $AKS_CLUSTE

### Step 1: Deploy the Attestation Pod

1. The attestation pod YAML file is located at `walkthrough/challenge-5/resources/cvm-attestation-pod.yaml` in this repository.
1. The attestation pod YAML file is located at `walkthrough/challenge-5/resources/cvm-attestation-pod.yaml` in this repository (if using Cloud Shell, upload the file via the **Manage files** menu option).

2. Apply the YAML file using the relative path from the repository root:
2. Apply the YAML file using the file from the repository:

```bash
kubectl apply -f walkthrough/challenge-5/resources/cvm-attestation-pod.yaml
kubectl apply -f cvm-attestation-pod.yaml
```

2. Check pod status:
Expand All @@ -193,6 +199,8 @@ kubectl apply -f walkthrough/challenge-5/resources/cvm-attestation-pod.yaml
kubectl get pods
```

![AKS](./images//aks-03.png)

3. Get the attestation report by checking logs:

```bash
Expand Down