CloudLAPS is a community developed solution, maintained by Nickolaj Andersen from MSEndpointMgr including community members Thomas Kurth (@ThomasKurth_ch), Maurice Daly (@modaly_it) and Simon Wåhlin (@SimonWahlin), aiming at providing an end-to-end local administrator password solution (LAPS) for cloud managed devices, e.g. Azure AD joined devices.
This solution provides the functionality of rotating the password for a given local administrator account on trusted devices using Proactive Remediation in Microsoft Intune. A trusted device in this sense means a device that is managed by Intune and joined to the organizations Azure AD tenant. Apart from other community solutions similar to this solution, CloudLAPS provides access to retrieve the local administrator passwords through a web-based portal. Delegated access to the web portal is supported through the means of native Azure AD enterprise application management. Password retrieval through the web portal is automatically logged in a Log Analytics workspace for auditing purposes.
CloudLAPS Community Edition is based upon a set of services hosted in Azure. The service components that make up the solution consists of the following:
- Azure Function App
- Azure Key Vault
- Azure App Service Plan
- Azure App Service
- Azure Monitor (Log Analytics workspace)
- Azure Application Insights
- Storage Accounts
Apart from the above mentioned Azure resources, Proactive Remediations of Endpoint Analytics in Microsoft Endpoint Manager is used on the client-side, being responsible for scheduling and executing the call towards the Function App API running in Azure.
While CloudLAPS Community Edition as a solution is free of charge and licensed under the MIT license, deploying CloudLAPS Community Edition in an Azure subscription might incur associated costs. See the link below for additional details.
Pricing Overview—How Azure Pricing Works | Microsoft Azure
For more information about CloudLAPS Community Edition and its features, refer to the docs section below. For how to get started with CloudLAPS Community Edition, follow the instructions under Setup.
Table of content
Prerequisites
In order to setup CloudLAPS Community Edition, the following permissions are required:
- Azure Active Directory
- Minimum Application Administrator or Cloud Application Administrator for creating an Azure AD app registration. Setting up the permissions for the Managed System Identity of the Function App to access device details requires Global Admin permissions.
- Azure Subscription
- Contributor access to subscription or Contributor to a specific Resource Group that will be used during setup.
Create Azure AD app registration
Before deploying the CloudLAPS Community Edition resources in Azure, an app registration in Azure AD is required. This app registration will be the principal used on behalf of delegating access to the CloudLAPS Portal, ensuring that only allowed identities can access the passwords from the devices. Helping you comply with the principle of least privileged.
From within the Azure portal, go to Azure Active Directory and select App registrations.
Click on New registration.
Provide the app registration with a name that implies CloudLAPS Portal and follows your internal naming convention. Leave the supported account types with it’s default value. As for Redirect Uri, it will be configured in the post-deploy section, but for simplicity, select Web and enter the following as shown in the picture below:
Click Register.
Copy the Application (client) ID from the Overview blade, it will be used as parameter input in the next section when deploying the resources in Azure.
Deploy CloudLAPS to Azure
Click the button below to deploy the required Azure resources for the CloudLAPS solution. You’ll be forwarded to the Azure portal, where you’re asked to fill in the required fields necessary for a successful deployment.
Begin by either selecting an existing Resource group or Create a new.
Continue the deployment by filling in the remaining parameters:
- Region
- Select the desired region where all the resources will be deployed in.
- Application ID
- Specify the Application (client) ID value from the newly created app registration in the Application ID field.
- Function App Name
- Specify a name that’s unique in Azure for the Function App (dash character will automatically be removed as it’s not supported).
- Function App Service Plan SKU
- Select a plan in the Function App Service Plan SKU. Recommended plan value is selected by default, but will endure a cost associated with the selection.
- Portal Web App Name
- Specify a name that’s unique in Azure for the App Service where the portal will be hosted (dash character will automatically be removed as it’s not supported).
- Portal App Service Plan SKU
- Select a plan in the Portal App Service Plan SKU. Recommended plan value is selected by default, but will endure a cost associated with the selection.
- Key Vault Name
- Specify a name that’s unique in Azure for the Key Vault where all passwords will be kept.
- Log Analytics Workspace Name
- Specify a name for the Log Analytics workspace where audit logs from the portal are kept.
- Tag
- Provide any required tags necessary in your organization in a list such as:
{“FirstTag”: “FirstValue”, “SecondTag”: “SecondValue”}
- Provide any required tags necessary in your organization in a list such as:
IMPORTANT: Do not use the above examples when entering values into the name fields where it’s stated that they clearly require a unique name in Azure, or the deployment will fail. A recommendation is to combine ‘CloudLAPS’ + ‘<CompanyName>’ or similar, e.g. CloudLAPSMSEndpointMgrFunction or CloudLAPSMSEndpointMgrVault to ensure unique names are used. Another recommendation could be to add a company specific pre- or suffix in the names.
Click Review + Create.
Click Create and allow for a couple of minutes for the deployment to complete. Once completed, a message similar to below will be shown, meaning the deployment successfully completed for the Azure resources related to CloudLAPS Community Edition.
Post-deploy configuration
Once the Azure resources are successfully deployed, complete the post-deploy configuration outlined in the following section
Update Azure AD app registration
Click on the Go to resource group button after the Azure resource deployment is completed (or search for the Resource Group from within the Azure portal).
Look for the App Service resource and click on it.
Under Essentials, copy the URL.
Browse to the Azure AD app registration created earlier before the Azure resource deployment, in the Authentication blade replace the value for Redirect URIs with the following:
https://<URL_value_copied_above>/signin-oidc
Underneath the Web – Redirect URIs, in the field for Front-channel logout URL, enter the following:
https://<URL_value_copied_above>/signout-oidc
In the Implicit grant and hybrid flows section, put a checkmark next to the ID token (used for implicit and hybrid flows).
Click Save.
Delegate access for Function App Managed System Identity
The Function App Managed System Identity requires permissions to be delegated for it to read device attributes used for validating an incoming request to the Function App API. Open a PowerShell console and ensure to install the following module, if it’s not already present:
Install-Module -Name AzureAD
CloudLAPS Community Edition source code repository contains a PowerShell script that simplifies the delegation of the correct permissions. Get the script from the following URL:
CloudLAPS/Add-MSIAppRoleAssignment.ps1 at main · MSEndpointMgr/CloudLAPS (github.com)
Before the script can be executed, two values are to be retrieved. First, the Tenant ID and then the Object ID of the Function App Managed System Identity. Browse the Resource Group where CloudLAPS Community Edition was deployed and click on the Function App.
In the Settings section to the left, select the Identity blade and copy the value in the Object ID field.
Go to Azure Active Directory in the Azure portal and from the Overview blade, copy the Tenant ID value.
Update the first two rows in the PowerShell script with the corresponding values that were just copied.
# Assign static variables $TenantID = "<Enter Tenant ID>" $MSIObjectID = "<Enter Managed System Identity Object ID>"
Save the script and invoke the PowerShell script. When asked to authenticate, provide the Global Admin credentials.
After a successful login, the script outputs the new app assignment it has created, providing the Managed System Identity with Device.Read.All permissions for Microsoft Graph.
Validate CloudLAPS Portal can be accessed
Try browsing to the CloudLAPS Portal URL to verify that it’s running and accessible. The URL can be found from within the App Service resource, in the Overview blade under Essentials.
Click on the URL, which takes you to the portal as shown below:
On rare occasions, it may be required to restart the app service for the portal to initialize at first startup. It can be done from the App Service object in the Overview blade:
Configure Proactive Remediation script
CloudLAPS Community Edition contains a set of client-side scripts that are invoked on a device by a Proactive Remediation from Intune. These scripts can be found in the repository from the URL below:
CloudLAPS/Proactive Remediation at main · MSEndpointMgr/CloudLAPS (github.com)
Download the two scripts named:
- Detect.ps1
- Remediate.ps1
Remediate.ps1 will need to be modified slightly, to include the Function App URL in order for the client-side script to know which API endpoint to communicate with.
Go to the Resource Group that contains the deployed Azure resources for CloudLAPS Community Edition. Click on the Function App resource.
Scroll down to Functions and click on SetSecret.
In the Overview blade, click on Get Function Url, ensure default (function key) is selected and click on the Copy button.
Perform the same copy operation of the Get Function Url for the SendClientEvent function.
Edit the Remediation.ps1 script and locate the $SetSecretURI and $SendClientEventURI variables.
$SetSecretURI = "<Enter Azure Functions URI for SetSecret function>" $SendClientEventURI = "<Enter Azure Functions URI for SendClientEvent function>"
Update these two variables with the copied function URL’s from above, so that they look similar to the following:
$SetSecretURI = "https://msecloudlapsfunction.azurewebsites.net/api/SetSecret?code=<function_key_redacted>" $SendClientEventURI = "https://msecloudlapsfunction.azurewebsites.net/api/SendClientEvent?code=<function_key_redacted>"
Locate the $LocalAdministratorName variable. This variable controls the name of the local administrator account that the client-side script will update the password for. If the given account doesn’t exist, a new local administrator account with the provided name will be created automatically.
$LocalAdministratorName = "<Enter the name of the local administrator account>"
Set the variable value to the desired account name, e.g. LocalAdmin:
$LocalAdministratorName = "LocalAdmin"
Locate the $SendClientEvent variable. This variable controls whether the client-side scripts will call the SendClientEvent function within the Function App and relay password rotation events to the Log Analytics workspace for reporting capabilities. Default the variable is set to $false, which disables the password rotation events sending capability. Change the value to $true if you wish to enable it.
$SendClientEvent = $false
Save the modified Remediation.ps1 script.
From within the Microsoft Endpoint Manager portal (endpoint.microsoft.com), click on Reports and then Endpoint Analytics.
Click on Proactive Remediations.
Click on Create script package.
Provide a name, e.g. CloudLAPS-Client.
Click Next.
For Detection script file, browse and select Detection.ps1. For Remediation script file, browse and select Remediation.ps1. Ensure Run script in 64-bit PowerShell is set to Yes.
Click Next.
Define any required Scope tags and click Next. Assign the new script package to your devices. It’s recommended that a set of UAT devices are targeted in a pilot group, before moving into a production state. From a scheduling perspective, make sure that the schedule is set to Daily.
Click Next and finally Create.
Delegate access for administrators to portal
By default, when creating an app registration in Azure AD, it’s configured for allowing any identity to use for retrieving an authentication token. For CloudLAPS Community Edition, the first step in the Setup guide was to create an app registration. Later when deploying the Azure resources, the Application (client) ID was provided as parameter input and automatically configured for the CloudLAPS portal, to ensure access to the portal are authenticated using Azure AD.
In a scenario where only a few users or administrators should be given access to the CloudLAPS Portal, which is highly recommended, a few additional configuration steps are required. Follow the steps below in a scenario where you want to restrict access to the CloudLAPS Portal within the organization.
From within the Azure portal, browse Azure Active Directory and select Enterprise Applications.
Search for the name of the app registration created earlier, e.g. CloudLAPS Portal and click on it.
In the Properties blade, ensure User assignment required is set to Yes and click Save.
With that configured, only users and/or groups that are defined in the Users and groups blade from the application will be allowed to access the CloudLAPS Portal. By default, the user who created the app registration is automatically added as shown below.
Click Add user/group to delegate any desired access to the CloudLAPS Portal within the organization.
Table of content
Solution overview and in-depth details
The following documentation section goes into detail regarding how the CloudLAPS Community Edition solution works end-to-end. Each item in the numbered list correlates to the matching number from the image above.
- Microsoft Intune delivers the client-side CloudLAPS proactive remediation script to the device, where the Intune Management Extension is responsible for scheduling and running the client-side script on a daily basis.
- Upon client-side script execution, the script gathers a set of required properties from the device such as SerialNumber, DeviceName, DeviceID, PublicKey (from the Azure AD device registration certificate) and others. A signature hash is calculated using the Private Key portion (from the Azure AD device registration certificate) based on the DeviceID property. These properties are then embedded in the request sent by the client-side script to the CloudLAPS-API function app in Azure.
- Function App retrieves the client-side script request and performs a series of validation checks for the incoming request. Validations checks are performed in order as described below. In case where a validation check fails, subsequent checks are dismissed and the request is discarded by the API. Function App uses its Managed System Identity to query Graph API during the validation checks when required.
- Request Header check
Ensures the request contains the expected properties of a valid request. - Known Azure AD device check
DeviceID property is validated that the inbound request comes from an Azure AD joined device (validating that the device is registered in Azure AD). - Thumbprint check
The thumbprint of the device registration certificate gets validated, by decoding the Azure AD device record attribute named ’alternativeSecurityIds.Key’ value, which contains the hash of the thumbprint of the certificate used when the device registered with Azure AD. The decoded thumbprint is then matched against the Thumbprint property from the inbound request. - Public Key check
The Public Key from the device registration certificate gets validated, by decoding the Azure AD device record attribute named ’alternativeSecurityIds.Key’ value, which contains the hash of the Public Key from the certificate used when the device registered with Azure AD. The decoded Public Key hash is then matched against the PublicKey property from the inbound request. - Signature check
To validate the Signature property hash value, the Public Key from the device registration certificate is again decoded from the ’alternativeSecurityIds.Key’ attribute value in order for a reconstruction of the Public Key, then used to call the VerifyHash method from the object, to ensure the calculated signature from the inbound request can be validated. - DeviceEnabled check
Function App queries for the accountEnabled attribute of the device record, to ensure the device record is not disabled.
- Request Header check
- After all validation checks have passed, Function App queries the Key Vault to retrieve an existing secret from the vault for the device, if any exist. The Type property from the inbound request controls which property will be used to retrieve an existing secret. For physical devices, the SerialNumber property is used in the query and for virtual machines the DeviceName property is used. If no secret exists for the device of the inbound request, Function App skips to the next step (step 5). If an existing secret does exist for the device, a new password will be created and updated for the secret in the Key Vault. This process is referred to as password rotation. Password rotation will only be allowed if the last password rotation occurred in the past, more than the specified amount of days configured in the Function App application setting named UpdateFrequencyDays. The value of the UpdateFrequencyDays application setting is by default set to 3, which only allows the password rotation to happen every 3 days. When password rotation is not allowed, step 5 in the solution overview is skipped and step 6 returns a status message to the client-side script that the password rotation was not allowed, instead of the rotated password. When password rotation is allowed, the secret for the device in the Key Vault is updated, step 5 skipped and the rotated password is returned in step 6 to the client-side script, that updates the local administrator account with the new password.
- When a secret for the device of the inbound request to Function App doesn’t exist in the Key Vault, a new secret will be created with a new password. This process is referred to as password creation. For password creation, restrictions that are in place for password rotation have no effect, a new password creation action will always be allowed after the validation checks have passed. The Type property from the inbound request controls which property will be used to create a new secret. For physical devices, the SerialNumber property is used in the query and for virtual machines the DeviceName property is used.
- Depending on which action was determined based on the existence of a secret or not for the device of the inbound request, this step acts differently. For password creation, the password is simply returned to the client-side script. For password rotation, that was not restricted due to when the last password rotation occurred, the rotated password is returned. For password rotation, when the rotation was in fact restricted and not allowed, only a status message is returned.
Function App documentation
As stated in the solution overview section above, the Function App is one of the core components of the CloudLAPS solution. The Function App acts as the communication endpoint (API) that retrieves the inbound requests from devices where the client-side script is executed on. It’s also responsible for validating the inbound request comes a trusted device.
The Function App has an Application Settings section, where the required settings are automatically configured during the Azure resource deployment (performed as a step in the Setup phase of CloudLAPS Community Edition). Some of these application settings should not be altered, however the ones documented below can be changed for the solution to operate differently, more specifically to an organizations requirements.
These application settings can be found under Settings – Configuration – Application Settings of the Function App from within the Azure portal.
- KeyVaultName
- This application settings is used by the SetSecret function to know which Key Vault in Azure to access when interacting with retrieving or setting up new secrets (also referred to as Passwords in the aspect of CloudLAPS Community Edition). Use this setting value to provide the name of a Key Vault, in a scenario where another existing Key Vault should be used.
- UpdateFrequencyDays
- Password rotation (described more in detail in the solution overview documentation above) will only be allowed if the most recent password rotation occurred in the past, more than the specified amount of days configured in this application setting. The default value is 3, which for instance only allows the password rotation process from a device to happen every 3 days. Change this value to a desired amount of days that meets the organization requirements. A value of 0 is not supported.
- PasswordLength
- Define the length of the password that will be generated for the local administrator account. Default value is 16.
- PasswordAllowedCharacters
- Define the allowed characters to be picked from when randomly generating the local administrator account password. Default value is: ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz.:;,-_!?$%*=+&<>@#()23456789
- DebugLogging
- When debug logging is enabled, output from the Function App contains additional data useful for troubleshooting. Debug logging is by default set to ‘false’, meaning it’s disabled. Set to ‘true’ to enable it.
CloudLAPS Portal details
Accessing the CloudLAPS Portal requires one to successfully authenticate using Azure AD. If user assignment required has been enabled, only the specified users or groups have access to the portal. The portal URL can be found on the App Service resource deployed during the Setup section.
It’s recommended that a custom domain is mapped for the portal, rather than simply using the provided URL. Follow these instructions for more information:
Tutorial: Map existing custom DNS name – Azure App Service | Microsoft Docs
When a user is automatically signed in to the CloudLAPS Portal, the start page is displayed.
Search page should be used to find passwords for device.
Below resembles how a search made for the computer name of a virtual machine was performed, detailing the properties returned. Use the serial number instead when searching for a physical device.
Every search performed in the portal is automatically audited, which is also stated on the Privacy page.
Client-side script details
All communication from the Proactive Remediation scripts running on devices are encrypted using TLS 1.2. When the Proactive Remediation script Detection.ps1 is executed, a dedicated event log is created on the device if it doesn’t exist.
Refer to the CloudLAPS-Client event log for additional information on the password creation and password rotation processes. Below is a flow chart that describes the password creation and rotation processes more in details.
Viewing auditing data from Log Analytics
Auditing events from the CloudLAPS Portal is written to the Log Analytics workspace, every time there’s a search made by any user. The Audit events can be queried from within the Log Analytics workspace in a custom log named CloudLAPSAudit_CL.
CloudLAPS Analytics and monitoring
Looking for a centralized summary including analytics to monitor the state of devices where CloudLAPS is deployed? Setup the CloudLAPS Analytics and monitoring Log Analytics workbook using the setup instructions from the page below:
CloudLAPS Analytics and monitoring – MSEndpointMgr
Setup and educational YouTube videos
Dean Ellerby from CloudManagement.Community has created excellent educational videos on how to get started with CloudLAPS, set it all up and demos the admin experience:
Getting Started with CloudLAPS (youtube.com)
Source code repositories
CloudLAPS Community Edition source code can be found at the following locations:
- Is CloudLAPS Community Edition free?
- Yes, it’s licensed under the MIT license and it’s associated software and code is free to use. Deploying CloudLAPS Community Edition in an Azure subscription might incur associated costs. See Azure pricing for more information.
- Will there be updates made available in the future?
- Whenever a bug is found or new features are added, a new release will be added under the Releases tab containing a link to the release specific update instructions.
- How will CloudLAPS Community Edition be updated?
- For issues related to the Function App and App Service, new ARM templates will be made available for re-deployment of the affected component. For the Proactive Remediation script, an update will be merged in the CloudLAPS repository. Visit the Releases section frequently for updates to CloudLAPS Community Edition. New releases will have specific update instructions depending on what components of CloudLAPS require an update.
- Is there any support for CloudLAPS Community Edition provided by the developers?
- As the name suggests, it’s a community edition with no support attached. However, if a bug is reported we intend to address whenever time permits.
- Can I change the MSEndpointMgr logo in the CloudLAPS Portal?
- It’s currently not supported with the Azure deployment method utilized. A manual setup of the portal is possible. That requires a new App Service to be created and Visual Studio (for easiest replacement of the logo file and publishing the changed solution).
- Can I use an existing Log Analytics workspace?
- It’s possible yes, but it requires re-configuring the Application Settings of the CloudLAPS Portal, to point towards the existing workspace. Re-configure the LogAnalytics:SharedKey and LogAnalytics:WorkspaceId application settings. If running CloudLAPS version 1.1.0 or above, locate the Key Vault resource that has ‘-as’ at the end of the name and update the LogAnalyticsWorkspaceId and LogAnalyticsWorkspaceSharedKey secrets with the corresponding values.
- How do I report an issue with CloudLAPS Community Edition?
- We prefer that bugs are reported on the official repository. Links are provided in the Source section.
Be sure to explore the capabilities of the CloudLAPS Analytics and monitoring Log Analytics workbook released with version 1.1.0 for a complete auditing, analytics and monitoring solution for CloudLAPS.