Connect Azure VMs
This guide shows you how to connect Azure virtual machines to Riptides using the AzureIMDS (Azure Instance Metadata Service) verifier. With AzureIMDS, daemons authenticate automatically using the signed identity token provided by the Azure IMDS — no manual tokens required.
Choose the installation method that matches your infrastructure:
- Kubernetes — deploy the daemon as a Helm chart into an existing cluster
- Virtual Machines — configure the daemon installed via the install script on Azure Linux VMs
Prerequisites
Section titled “Prerequisites”- A running Riptides control plane (see Getting Started)
kubectlconfigured to access the Riptides API- One or more Azure Linux VMs you want to connect
- The VMs must be able to reach the control plane endpoint over the network
- A managed identity attached to each VM — this is required and must be done before installing the daemon (see below)
How It Works
Section titled “How It Works”Every Azure VM with a managed identity can request a signed identity token from the Azure Instance Metadata Service (IMDS) at http://169.254.169.254/metadata/identity/oauth2/token. The Riptides daemon retrieves this token and presents it to the control plane during registration. The control plane verifies the token signature using Microsoft’s public OIDC certificates and checks that the instance metadata (subscription ID, resource group, etc.) matches the Verifier’s requiredMetadata constraints.
Step 1: Create an AzureIMDS Verifier
Section titled “Step 1: Create an AzureIMDS Verifier”Create a Verifier that accepts daemons presenting a valid Azure managed identity token. Use requiredMetadata to restrict which Azure subscriptions are allowed to register:
apiVersion: auth.riptides.io/v1alpha1kind: Verifiermetadata: name: azureimds namespace: riptides-systemspec: AzureIMDS: {} requiredMetadata: - azureimds:subscription:id: "00000000-0000-0000-0000-000000000000"Apply it:
riptides-cli ctl apply -f verifier-azureimds.yamlConfirm the Verifier is available:
riptides-cli ctl get verifiersExpected output:
NAME STATEazureimds AvailableSecurity note: Always set
requiredMetadatawith your Azure subscription ID to prevent VMs from unauthorized subscriptions from registering daemons. You can add multiple entries to allow several subscriptions.
Filtering by Multiple Subscriptions
Section titled “Filtering by Multiple Subscriptions”To allow VMs from more than one Azure subscription:
spec: AzureIMDS: {} requiredMetadata: - azureimds:subscription:id: "00000000-0000-0000-0000-000000000000" - azureimds:subscription:id: "11111111-1111-1111-1111-111111111111"Step 2: Create a DaemonGroup (Optional)
Section titled “Step 2: Create a DaemonGroup (Optional)”A DaemonGroup lets you organize daemons into logical groups based on OS or other metadata, useful for scoping WorkloadIdentity assignments to your Azure fleet:
apiVersion: core.riptides.io/v1alpha1kind: DaemonGroupmetadata: name: azure-linux-nodes namespace: riptides-systemspec: workloadID: riptides/daemongroup/azure-linux-nodes selectors: - linuxos:name: ubuntu - linuxos:name: debian - linuxos:name: fedoraApply it:
riptides-cli ctl apply -f daemongroup-azure.yamlThis group will automatically include any connected daemon running Ubuntu, Debian, or Fedora. You can later scope WorkloadIdentity resources to this group using the scope.daemonGroup.id field.
Kubernetes
Section titled “Kubernetes”Additional prerequisites for Kubernetes:
- Kubernetes cluster v1.26 or later
- Helm v3.12 or later
Daemon Configuration
Section titled “Daemon Configuration”When installing the daemon via Helm, set authPlugin.type to AzureIMDS and enable the azure metadata collector so the daemon can retrieve the identity token from the Azure IMDS. Use the following values.yaml in place of the one shown in the getting-started guide:
config: daemon: metadataCollectors: procfs: enabled: true linuxos: enabled: true azure: enabled: true kubernetes: enabled: true kubeletHost: localhost kubeletPort: 10250 kubeletCA: /etc/kubernetes/pki/ca.crt skipKubeletVerification: true credentials: /var/run/secrets/kubernetes.io/serviceaccount/token controlPlane: enabled: true url: https://<your-env-id>.console.riptides.io authPlugin: type: AzureIMDS dataDir: /data/riptidesNote: The
azuremetadata collector must be enabled — the daemon requests the identity token fromhttp://169.254.169.254/metadata/identity/oauth2/tokento authenticate with the control plane. The managed identity must be attached to the VM or node pool. ThetrustDomainmust match the value configured on the control plane.
Custom Resource
Section titled “Custom Resource”By default the daemon requests an identity token for the resource https://management.azure.com/, which must match the resource configured in your AzureIMDS Verifier. To use a different resource URI, set authPlugin.resource in your values.yaml:
authPlugin: type: AzureIMDS resource: https://my-custom-resource.example.com/Verify the Daemon Connected
Section titled “Verify the Daemon Connected”After deploying the daemon, check that your Azure nodes have registered:
riptides-cli ctl get daemonsYou should see entries like:
NAME WORKLOAD-ID STATEa1b2c3d4-e5f6-7890-abcd-e01234567890 riptides/daemon/my-subscription/my-resource-group/my-vm ConnectedVirtual Machines
Section titled “Virtual Machines”Step 1: Run the Installer
Section titled “Step 1: Run the Installer”Run the install script with --azureimds. The script auto-detects Azure VMs, but you can pass the flag explicitly:
curl -fsSL https://docs.riptides.io/install.sh | sudo bash -s -- \ --controlplane-url https://<your-env-id>.console.riptides.io \ --azureimdsThe script installs the kernel driver and daemon, writes /etc/riptides/config.yaml with authPlugin.type: AzureIMDS, and starts the riptides systemd service. The daemon authenticates automatically using the VM’s managed identity on first start.
Note: The managed identity must be attached to the VM before running the installer. The
azuremetadata collector is enabled automatically by the daemon whenauthPlugin.typeisAzureIMDS.
To follow live logs and confirm a successful AzureIMDS handshake:
sudo journalctl -u riptides -fCustom Resource
Section titled “Custom Resource”By default the daemon requests an identity token for the resource https://management.azure.com/, which must match the resource configured in your AzureIMDS Verifier. If you configured your Verifier with a different resource URI, pass it as an argument to --azureimds:
curl -fsSL https://docs.riptides.io/install.sh | sudo bash -s -- \ --controlplane-url https://<your-env-id>.console.riptides.io \ --azureimds https://my-custom-resource.example.com/Verify the Daemon Connected
Section titled “Verify the Daemon Connected”Confirm the daemon has registered with the control plane:
riptides-cli ctl get daemonsYou should see an entry like:
NAME WORKLOAD-ID STATEa1b2c3d4-e5f6-7890-abcd-e01234567890 riptides/daemon/my-subscription/my-resource-group/my-vm ConnectedHow Authentication Happens
Section titled “How Authentication Happens”When the daemon starts on an Azure VM, it:
- Requests a signed identity token from the Azure IMDS (
http://169.254.169.254/metadata/identity/oauth2/token) - Sends the token to the Riptides control plane
- The control plane verifies the token signature using Microsoft’s public OIDC certificates
- The control plane checks that the instance’s subscription ID matches the Verifier’s
requiredMetadata - On success, the daemon is registered and receives a workload ID in the format
riptides/daemon/<subscription-id>/<resource-group>/<vm-name>(for example,riptides/daemon/my-subscription/my-resource-group/my-vm)
No tokens to distribute, no secrets to manage — the VM’s managed identity is the credential.
Step 3: Assign Workload Identities
Section titled “Step 3: Assign Workload Identities”Now that your Azure nodes are connected, create WorkloadIdentity resources to assign SPIFFE identities to workloads running on those VMs. Scope identities to your DaemonGroup so they only apply to your Azure fleet:
apiVersion: core.riptides.io/v1alpha1kind: WorkloadIdentitymetadata: name: my-backend-service namespace: riptides-systemspec: workloadID: my-app/backend-service scope: daemonGroup: id: riptides/daemongroup/azure-linux-nodes selectors: - process:name: backend-service connection: tls: mode: PERMISSIVEApply it:
riptides-cli ctl apply -f workload-identity-azure.yamlAny process named backend-service running on a node in the azure-linux-nodes daemon group will receive the SPIFFE ID spiffe://example.com/my-app/backend-service.
For full details on WorkloadIdentity configuration, see the WorkloadIdentity reference.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Possible Cause | Resolution |
|---|---|---|
riptides-modules fails to load | Trusted Launch / Secure Boot enabled | Disable Secure Boot in the VM’s security configuration, or switch to a standard Generation 2 VM |
Daemon does not appear in riptides-cli ctl get daemons | Daemon cannot reach control plane | Verify network connectivity and firewall rules between the Azure VM and the control plane endpoint |
| Daemon shows authentication error | Subscription ID mismatch | Check that the Verifier’s requiredMetadata includes the correct Azure subscription ID |
| Daemon shows authentication error | No managed identity attached | Ensure the VM has a system-assigned or user-assigned managed identity configured in the Azure portal |
| Daemon shows authentication error | IMDS not accessible | Confirm the VM can reach http://169.254.169.254 (this is available by default on Azure VMs) |
| DaemonGroup shows no daemons | Selector mismatch | Verify the linuxos:name selector matches the OS running on your instances |
| VM daemon fails after config change | Stale process | Run sudo systemctl restart riptides and check journalctl -u riptides |
Next Steps
Section titled “Next Steps”- Connect AWS EC2 Nodes — connect Amazon EC2 instances using the AWSIID verifier
- Connect GCP Instances — connect Google Cloud VMs using the GCPIIT verifier
- WorkloadIdentity Reference — full selector and TLS mode documentation
- Verifier Reference — all verifier types and metadata filtering options