Skip to content

Feature: [Ubuntu, no-CVM] CVM machines to not get UEFI and kek certificate updates#356

Open
rane-rajasi wants to merge 3 commits into
masterfrom
rarane/certupdate/nocvm
Open

Feature: [Ubuntu, no-CVM] CVM machines to not get UEFI and kek certificate updates#356
rane-rajasi wants to merge 3 commits into
masterfrom
rarane/certupdate/nocvm

Conversation

@rane-rajasi

@rane-rajasi rane-rajasi commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

These changes are for Canonical CVMs, the ask is, Canonical CVMs should not get UEFI and kek certificate updates.
There are 2 ways (imds and fde) of determining if a VM is a CVM, we are checking using both mechanisms and only applying certificate updates if both of these compute to false.

In VM tests:

  • Trusted VM that is NOT a CVM:
    1.core.log
    1.status.txt
  • Trusted VM that is CVM: Wasn't able to create a CVM in canary, no sizes available

@rane-rajasi rane-rajasi requested review from a team, kjohn-msft, michellemcdaniel and najams and removed request for a team June 22, 2026 17:20
@rane-rajasi rane-rajasi requested a review from kjohn-msft as a code owner June 22, 2026 17:20
@rane-rajasi rane-rajasi requested a review from najams as a code owner June 22, 2026 17:20
Comment thread src/core/src/bootstrap/EnvLayer.py Fixed
Comment thread src/core/src/core_logic/PatchInstaller.py Fixed
Comment thread src/core/src/core_logic/PatchInstaller.py Fixed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces Confidential VM (CVM) detection logic to prevent UEFI/KEK certificate updates from running on Canonical CVMs, while adding unit tests to validate the new behavior.

Changes:

  • Added CVM detection in EnvLayer using Azure IMDS and an FDE-based detection script.
  • Updated PatchInstaller to skip certificate updates when a CVM is detected.
  • Added/updated unit tests covering CVM detection and the certificate-update skip path.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/core/src/core_logic/PatchInstaller.py Skips update_certs() when CVM detection indicates the VM is confidential.
src/core/src/bootstrap/EnvLayer.py Implements CVM detection via IMDS and FDE-based script execution.
src/core/src/bootstrap/Constants.py Adds a constant path for the CVM detection script.
src/core/tests/Test_PatchInstaller.py Adds a test ensuring certificate updates are skipped on confidential VMs.
src/core/tests/Test_EnvLayer.py Adds tests for IMDS/FDE CVM detection and call ordering.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/core/src/core_logic/PatchInstaller.py
Comment thread src/core/src/bootstrap/EnvLayer.py Outdated
Comment thread src/core/tests/Test_EnvLayer.py
@codecov

codecov Bot commented Jun 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.04%. Comparing base (9608cd9) to head (ef8d554).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #356      +/-   ##
==========================================
+ Coverage   93.99%   94.04%   +0.04%     
==========================================
  Files         107      107              
  Lines       19810    19941     +131     
==========================================
+ Hits        18621    18753     +132     
+ Misses       1189     1188       -1     
Flag Coverage Δ
python27 94.04% <100.00%> (+0.04%) ⬆️
python312 94.00% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread src/core/src/bootstrap/EnvLayer.py Outdated

is_confidential_vm, detection_details = self.detect_confidential_vm_by_imds()
if is_confidential_vm:
return True, detection_details

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can't we just return is_confidential_vm here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to return is_confidential_vm

Comment thread src/core/src/bootstrap/EnvLayer.py Outdated
"""Runs the FDE-based CVM detection script and returns whether it detected a Confidential VM."""
script_path = Constants.AzGPSPaths.DETECT_CVM
command_output = str()
detection_script = """#!/usr/bin/env bash

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have anywhere else we do something like this? Is there no way that the script could be put in its own file and then run? It feels wrong to hard code a script like this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

def detect_confidential_vm_by_imds(self):
# type: () -> tuple
"""Queries Azure IMDS and returns whether the VM reports ConfidentialVM security type."""
command = 'curl -s --connect-timeout 2 --max-time 2 -H Metadata:true --noproxy "*" "http://169.254.169.254/metadata/instance?api-version=2025-04-07"'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a chance this IP address changes and could be spoofed/taken by a malicious actor?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have much insight on this one, simply used the command that was shared by partners to fetch from imds.

Here's Copilot's response:

✅ Short answer

No, the IP does not change
No, it cannot be externally spoofed or taken over by another tenant

🔎 Why this is safe

  1. Fixed, well-known platform endpoint

169.254.169.254 is a hard-coded Azure IMDS endpoint, not assigned from your VNet or subnet. [learn.microsoft.com]
It’s part of the link‑local range (169.254.0.0/16), reserved for host-local communication. [simonpainter.com]

➡️ This means:

It is not customer-controlled
It is not dynamically allocated
Azure guarantees its availability and consistency

  1. Not reachable from outside the VM

The endpoint is non-routable and only accessible from within the VM [learn.microsoft.com]
Traffic to IMDS never leaves the host [learn.microsoft.com]

➡️ So:

No external attacker can “impersonate” this endpoint over the network
It’s effectively a host-side service exposed into the VM

  1. Platform-injected routing

Azure automatically injects a route to 169.254.169.254 via the VM’s primary NIC (not via your VNet config) [simonpainter.com]

➡️ This prevents:

DNS spoofing
Route hijacking from within normal networking config

⚠️ What is a valid concern (and how to address it)
The only realistic risk is:

If an attacker already has root/admin access inside the VM, they could:

Intercept traffic locally
Modify iptables / routing
Run a fake service on that IP

✅ But:

At that point, the VM is already compromised
This is not specific to IMDS (applies to any local endpoint)

💡 Best-practice statement

The IMDS endpoint (169.254.169.254) is a well-known, platform-defined link-local address that is not part of the customer-controlled network and does not change across deployments. It is non-routable and only accessible from within the VM, with traffic handled entirely within the Azure host fabric.
This prevents external spoofing or takeover by other tenants. The only theoretical risk would require local root-level compromise of the VM, in which case any local endpoint (not just IMDS) could be intercepted.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants