This blog post details a method for securely deploying applications to on-premises IIS servers from Azure Pipelines without exposing credentials. The author leverages a self-hosted agent running on the target server, combined with a pre-configured deployment group. Instead of storing sensitive information directly in the pipeline, the approach uses Azure Key Vault to securely store the application pool password. The pipeline then retrieves this password during the deployment process and utilizes it with the powershell
task in Azure Pipelines to update the application pool, ensuring credentials are not exposed in plain text within the pipeline or agent's environment. This setup enables automated deployments while mitigating the security risks associated with managing credentials for on-premises deployments.
This blog post details a method for implementing reasonably secure deployments from Azure Pipelines to on-premises IIS servers, focusing on minimizing the attack surface and adhering to the principle of least privilege. The author outlines a process that avoids storing sensitive credentials like passwords directly within the pipeline definition, leveraging Azure Key Vault for secure secret management and Managed Identities for authentication.
The core strategy revolves around establishing a dedicated deployment user account on the target IIS server. This account is granted only the necessary permissions to deploy and manage the specific application, adhering to the principle of least privilege. It explicitly does not have administrative privileges. This minimizes the potential damage if the account is compromised.
The deployment process utilizes a self-hosted agent running on the on-premises server, which is registered with the Azure DevOps project. Critically, the agent itself doesn't hold any secrets. Instead, it leverages a Managed Identity assigned to the Azure DevOps project. This Managed Identity has permissions to access the necessary secrets stored in Azure Key Vault. During the deployment process, the pipeline instructs the agent to retrieve the deployment user's credentials from Key Vault using its Managed Identity. These credentials are then used to authenticate with the IIS server and perform the deployment tasks.
The actual deployment steps involve using the msdeploy.exe
utility. The retrieved credentials are passed securely to msdeploy.exe
to authenticate with the target IIS server. The pipeline script then uses msdeploy.exe
to sync the application files from the build artifact to the IIS server and configure the application within IIS. The author emphasizes the importance of using the -declareParamFile
option with msdeploy.exe
to avoid exposing sensitive information in the pipeline logs. This approach stores the sensitive deployment parameters in a separate file that is accessed securely during the deployment process.
The author also touches on securing the web.config
file. They recommend excluding the web.config
from the initial deployment and instead using a separate, dedicated step to deploy a transformed web.config
file. This transformed configuration file contains environment-specific settings retrieved securely from Azure Key Vault, ensuring sensitive information like connection strings isn't embedded in the application's source code. This approach separates configuration from code and allows for environment-specific configurations without compromising security.
Finally, the post briefly discusses the option of using deployment groups as an alternative to individual self-hosted agents. However, the core principles of using Managed Identities, Azure Key Vault, and least privilege remain the same regardless of the chosen deployment method. The author advocates for this approach as a more secure and manageable way to handle deployments to on-premises IIS servers compared to traditional methods relying on stored credentials.
Summary of Comments ( 32 )
https://news.ycombinator.com/item?id=43256802
The Hacker News comments generally praise the article for its practical approach to a complex problem (deploying to on-premise IIS from Azure DevOps). Several commenters appreciate the focus on simplicity and avoiding over-engineering, highlighting the use of built-in Azure DevOps features and PowerShell over more complex solutions. One commenter suggests using deployment groups instead of self-hosted agents for better security and manageability. Another emphasizes the importance of robust rollback procedures, which the article acknowledges but doesn't delve into deeply. A few commenters discuss alternative approaches, like using containers or configuration management tools, but acknowledge the validity of the author's simpler method for specific scenarios. Overall, the comments agree that the article provides a useful, real-world example of secure-enough deployments.
The Hacker News post titled "(Reasonably) secure Azure Pipelines on-prem deployments" discussing the linked blog post about secure deployments to IIS using Azure DevOps has generated a small but focused discussion thread. Several commenters engage with the specific technical details and offer alternative approaches or raise potential concerns.
One commenter points out a potential vulnerability if the deployment agent's machine account, which has write access to the web application directory, is compromised. They suggest an alternative where the build agent packages the application, and a separate deployment process, running under a more restricted account, handles the extraction and deployment to IIS. This separation of duties limits the potential damage from a compromised build agent.
Another commenter discusses the complexity and challenges associated with using tools like Ansible for deployments, particularly in Windows environments. They acknowledge the benefits of such tools but highlight the effort required to learn and maintain them, contrasting it with the relative simplicity of the approach presented in the blog post. This commenter suggests that while more sophisticated tools exist, the author's method might be a pragmatic solution for those prioritizing simplicity and ease of implementation.
A third commenter questions the security of storing deployment credentials within Azure DevOps, even if encrypted. They propose using a dedicated secrets management solution like Azure Key Vault for storing sensitive information and retrieving it during the deployment process. This approach enhances security by decoupling the secrets from the deployment pipeline itself.
The overall sentiment in the comments is one of cautious appreciation for the author's approach. Commenters acknowledge the practicality of the solution while also highlighting potential security concerns and suggesting alternative, more secure, albeit potentially more complex, methods. The discussion revolves around the trade-off between simplicity and security in real-world deployment scenarios. No one outright criticizes the author's method but instead offer constructive feedback and alternative perspectives for achieving secure deployments.