November 27th, 2024

Properly cycling domain passwords with the JSonADDomain extension

Joseph Calev
Principal Software Engineer, Azure Core Compute

For those familiar with the JsonAdDomain extension, it provides an easy way to join VMs to your domain. However, one aspect that customers have been less crazy about is that the domain password must be shared in the protected settings (where it is at least encrypted) and, more importantly, the functionality of the extension doesn’t work well with standard security practices.

There are several basic security practices involving something like a domain password:

  • Store them in keyvault
  • Use managed identities to access the keyvault
  • Change the password every six months are so

The standard procedure for cycling passwords is to actually have two keyvaults. Each contains a password, but only one is valid. When a new password is set, the oldest keyvault changes.

The JSonADDomain extension now has this capability. Two keyvaults are supported – primary and secondary. If the primary password fails, we’ll try again with the secondary. This now gives you total control over the password storage and allows you to follow modern security practices.

The settings to accomplish this are as follows:

{
  "apiVersion": "2015-06-15",
  "type": "Microsoft.Compute/virtualMachines/extensions",
  "name": "[concat(parameters('dnsLabelPrefix'),'/joindomain')]",
  "location": "[parameters('location')]",
  "dependsOn": [
    "[concat('Microsoft.Compute/virtualMachines/', parameters('dnsLabelPrefix'))]"
  ],
  "properties": {
    "publisher": "Microsoft.Compute",
    "type": "JsonADDomainExtension",
    "typeHandlerVersion": "1.3",
    "autoUpgradeMinorVersion": true,
    "settings": {
      "Name": "[parameters('domainToJoin')]",
      "OUPath": "[parameters('ouPath')]",
      "User": "[concat(parameters('domainToJoin'), '\\', parameters('domainUsername'))]",
      "Restart": "true",
      "Options": "[parameters('domainJoinOptions')]"
    },
    "protectedSettings": {
      "PrimaryPasswordKeyVault": {
        "KeyVaultUri": "[parameters('primaryKeyvaultUri')]",
        "ManagedIdentityClientId": "[parameters('managedIdentityClientId')]"
      },
      "SecondaryPasswordKeyVault": {
        "KeyVaultUri": "[parameters('secondaryKeyvaultUri')]",
        "ManagedIdentityObjectId": "[parameters('managedIdentityObjectId')]"
      }
    }
  }
}

The SecondaryPasswordKeyvault is of course optional, but recommended. For each, either a ManagedIdentityClientId or a ManagedIdentityObjectId (not both) must be specified in order to access it.

 

Author

Joseph Calev
Principal Software Engineer, Azure Core Compute

Software Engineer Lead at Microsoft. Focusing on enabling customer scenarios for VM extensions and applications.

0 comments