diff --git a/dracut/30ignition/README-azure-provisioning.md b/dracut/30ignition/README-azure-provisioning.md
new file mode 100644
index 000000000..e1ca7921e
--- /dev/null
+++ b/dracut/30ignition/README-azure-provisioning.md
@@ -0,0 +1,156 @@
+ `# Azure Provisioning Integration - Proof of Concept
+
+## Overview
+
+This proof-of-concept demonstrates how to integrate Azure's provisioning metadata directly into Ignition's fetch stage. Instead of relying on external agents like WAAgent, this implementation reads user provisioning data from Azure's virtual CD-ROM during early boot and generates an Ignition configuration on-the-fly.
+
+## How It Works
+
+### Boot Flow
+
+1. **Early Boot** - System boots into initrd/initramfs environment
+2. **Media Mount** - Azure's virtual CD-ROM (`/dev/sr0`) is auto-mounted by the system
+3. **Fetch Stage** - `ignition-fetch.service` runs
+4. **Helper Script** - `ignition-fetch-userdata-helper` (ExecStartPre) executes:
+ - Locates the mounted CD-ROM using `findmnt`
+ - Reads and parses `ovf-env.xml`
+ - Extracts user provisioning data (username, password, SSH keys)
+ - Generates an Ignition 3.3.0 configuration
+ - Writes it to `/run/ignition.json`
+5. **Skip Normal Fetch** - The condition `ConditionPathExists=!/run/ignition.json` in the service file prevents the normal Ignition fetch from running since our helper already created the config
+6. **Subsequent Stages** - Later stages (disks, mount, files) process the generated config to create users and configure the system
+
+### Stage Order
+
+```
+fetch-offline -> fetch (with our helper) -> kargs -> disks -> mount -> files
+```
+
+## Files Modified/Created
+
+### New Files
+
+- **`ignition-fetch-userdata-helper.sh`** - Shell script that:
+ - Finds where `/dev/sr0` is mounted
+ - Parses Azure's `ovf-env.xml`
+ - Generates Ignition JSON configuration
+ - Writes to `/run/ignition.json`
+
+### Modified Files
+
+- **`ignition-fetch.service`** - Added `ExecStartPre` to run helper script before normal fetch
+- **`module-setup.sh`** - Added helper script installation and `findmnt` utility
+
+## Azure Provisioning Media Format
+
+On Azure, the provisioning media is:
+- **Device**: Virtual CD-ROM attached as `/dev/sr0` (also visible as `ata-Virtual_CD`)
+- **Filesystem**: UDF format
+- **Content**: Single XML file called `ovf-env.xml`
+
+### Expected ovf-env.xml Structure
+
+```xml
+
+
+
+ 1.0
+
+ LinuxProvisioningConfiguration
+ myhost
+ azureuser
+ $6$rounds=4096$abcdefgh$hashedpassword...
+ false
+
+
+
+ ...
+ /home/azureuser/.ssh/authorized_keys
+ ssh-rsa AAAAB3NzaC1yc2EAAAA... user@host
+
+
+
+
+
+
+```
+
+### Extracted Fields
+
+The helper script extracts only what it uses:
+- **UserName** - Linux username to create
+- **UserPassword** - Password hash (Azure typically provides pre-hashed)
+- **SSH Keys** - Public SSH keys from `` elements
+
+## Generated Ignition Configuration
+
+The helper generates an Ignition 3.3.0 config that:
+
+1. **Creates a user** with:
+ - Username from ``
+ - Password hash from ``
+ - SSH authorized keys from ``
+ - Home directory at `/home/`
+ - Shell set to `/bin/bash`
+ - Membership in `wheel` group
+
+2. **Configures sudo** via `/etc/sudoers.d/99_wheel_nopasswd`:
+ - Allows wheel group passwordless sudo
+
+3. **Configures SSH** via `/etc/ssh/sshd_config.d/10-custom.conf`:
+ - Enables password authentication
+ - Disables root login
+ - Sets custom SSHD settings
+
+### Sample Output
+
+```json
+{
+ "ignition": {
+ "version": "3.3.0"
+ },
+ "passwd": {
+ "users": [
+ {
+ "name": "azureuser",
+ "groups": ["wheel"],
+ "homeDir": "/home/azureuser",
+ "shell": "/bin/bash",
+ "passwordHash": "$6$rounds=4096$...",
+ "sshAuthorizedKeys": ["ssh-rsa AAAAB3..."]
+ }
+ ]
+ },
+ "storage": {
+ "files": [
+ {
+ "path": "/etc/sudoers.d/99_wheel_nopasswd",
+ "contents": {
+ "source": "data:,%25wheel%20ALL%3D(ALL)%20NOPASSWD%3AALL%0A"
+ },
+ "mode": 288
+ },
+ {
+ "path": "/etc/ssh/sshd_config.d/10-custom.conf",
+ "contents": {
+ "source": "data:,..."
+ },
+ "mode": 420
+ }
+ ]
+ }
+}
+```
+
+
+## References
+
+- [Ignition Documentation](https://coreos.github.io/ignition/)
+- [Ignition Configuration v3.3.0 Spec](https://coreos.github.io/ignition/configuration-v3_3/)
+- [Azure Linux Provisioning](https://learn.microsoft.com/en-us/azure/virtual-machines/linux/)
+- [OVF Environment Specification](http://schemas.dmtf.org/ovf/)
+
+
diff --git a/dracut/30ignition/ignition-fetch-userdata-helper.sh b/dracut/30ignition/ignition-fetch-userdata-helper.sh
new file mode 100644
index 000000000..8460337fd
--- /dev/null
+++ b/dracut/30ignition/ignition-fetch-userdata-helper.sh
@@ -0,0 +1,154 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+#
+# ignition-fetch-userdata-helper.sh
+# Reads Azure provisioning media (ovf-env.xml) and generates Ignition config
+
+set -euo pipefail
+
+CDROM_DEV="/dev/sr0"
+OVF_FILE="ovf-env.xml"
+OUTPUT_CONFIG="/run/ignition.json"
+
+log() {
+ echo "ignition-fetch-userdata-helper: $*" >&2
+}
+
+# Function to extract value from XML using basic text processing
+# Usage: extract_xml_value "ElementName"
+extract_xml_value() {
+ local element="$1"
+ local xml_content="$2"
+ echo "$xml_content" | grep -oP "(?<=<${element}>)[^<]+" | head -1 || echo ""
+}
+
+# Function to extract value with namespace prefix
+extract_ns_xml_value() {
+ local element="$1"
+ local xml_content="$2"
+ echo "$xml_content" | grep -oP "(?<=<[^:]*:${element}>)[^<]+" | head -1 || echo ""
+}
+
+main() {
+ log "Starting Azure provisioning media fetch..."
+
+ if [[ ! -b "$CDROM_DEV" ]]; then
+ log "CD-ROM device $CDROM_DEV not found, skipping..."
+ exit 0
+ fi
+
+ # Find where /dev/sr0 is mounted (assume it's already mounted)
+ mount_dir=$(findmnt -n -o TARGET --source "$CDROM_DEV" 2>/dev/null | head -1)
+
+ if [[ -z "$mount_dir" ]]; then
+ log "CD-ROM device $CDROM_DEV is not mounted, skipping..."
+ exit 0
+ fi
+
+ log "CD-ROM mounted at $mount_dir"
+
+ # Check if ovf-env.xml exists
+ if [[ ! -f "$mount_dir/$OVF_FILE" ]]; then
+ log "ovf-env.xml not found at $mount_dir/$OVF_FILE, skipping..."
+ exit 0
+ fi
+
+ log "Found $OVF_FILE, parsing..."
+
+ xml_content=$(cat "$mount_dir/$OVF_FILE")
+
+ # Extract user data from LinuxProvisioningConfigurationSet
+ username=$(extract_ns_xml_value "UserName" "$xml_content")
+ userpassword=$(extract_ns_xml_value "UserPassword" "$xml_content")
+ ssh_keys=$(echo "$xml_content" | grep -oP '(?<=)[^<]+' | grep '^ssh-' || echo "")
+
+ log "Extracted username: ${username:-}"
+ log "Extracted password: ${userpassword:+}"
+ log "Extracted SSH keys: ${ssh_keys:+}"
+
+ if [[ -z "$username" ]]; then
+ log "No username found in provisioning data, skipping config generation..."
+ exit 0
+ fi
+
+ # Generate password hash if we have a plain password
+ password_hash="$userpassword"
+
+ # Build SSH authorized keys JSON array
+ ssh_keys_json="[]"
+ if [[ -n "$ssh_keys" ]]; then
+ ssh_keys_json="["
+ first=true
+ while IFS= read -r key; do
+ [[ -z "$key" ]] && continue
+ if [[ "$first" == "true" ]]; then
+ first=false
+ else
+ ssh_keys_json+=","
+ fi
+ escaped_key=$(echo "$key" | sed 's/"/\\"/g')
+ ssh_keys_json+="\"$escaped_key\""
+ done <<< "$ssh_keys"
+ ssh_keys_json+="]"
+ fi
+
+ log "Generating Ignition config..."
+
+ cat > "$OUTPUT_CONFIG" <