One of the challenges of managing Sentinel instances in multi-tenant scenarios is ensuring consistent and secure deployment of Sentinel resources (connectors, analytics rules, playbooks, workbooks, etc.) across different Sentinel instances. Manually configuring these components for each tenant can be time-consuming, error-prone, and difficult to scale. Using Azure DevOps to automate and streamline the deployment and configuration of Sentinel components can address these challenges.
A feature in Sentinel that enables this automation and streamlining is Sentinel Repositories. Sentinel Repositories create connections to repositories that store Sentinel resources as code (ARM files) and allow version control, branching, merging, and collaboration.. Sentinel Repositories connections can be to either a GitHub repo or an Azure DevOps repo. Sentinel Repositories can also be integrated with Azure DevOps pipelines to automatically deploy and update Sentinel resources across different environments (e.g., development, testing, production) and tenants. If the Sentinel Repository connection is made to a GitHub repo, then the automation is handled using GitHub Actions.
The aim of this article is to outline how Azure DevOps can be used for multi-tenant scenarios. To set up a Sentinel repository connection follow the steps in this article. The end goal here is to have a CI/CD setup which can accommodate multiple tenants (customers) and deployment requirements.
This article will use Azure DevOps as the medium for the Sentinel repository connection. For more information about Sentinel Repositories please read this article.
Prerequisites for setting up multi-tenant scenarios in Azure DevOps:
- An Owner role in the resource group that contains your Microsoft Sentinel workspace or a combination of User Access Administrator and Sentinel Contributor roles to create the connection.
- Project Administrator access to your Azure DevOps repository.
- Pipelines enabled for Azure DevOps.
- Third-party application access via OAuth enabled for Azure DevOps application connection policies.
Once these prerequisites are met, please follow these steps:
Set up a Sentinel repository connection
Setting up the Sentinel repository connection in another tenant or Sentinel instance is only slightly different. When setting up the repository connection, the account creating the connection (by clicking on Add new in the Repositories tab of Sentinel) should be an Owner or Sentinel Contributor + User Access Administrator on the resource group Sentinel is in.
When authenticating to DevOps, the authentication must happen with the account that has permissions in the tenant where the Azure DevOps instance is. This action only happens once per Sentinel instance. Both accounts permissions can be removed afterwards without issue.
Figure 1: Adding a new DevOps connection to Sentinel
Figure 2: Interrupting the automatic authentication to sign-in with account from tenant which has the Azure DevOps instance
Once the correct account has been authenticated, add the details of the Azure DevOps instance. This includes the correct organization, project, and branch.
Set up the DevOps structure
There are several ways that DevOps can be set up to accommodate multiple tenants (customers) and deployment requirements. Tenants may have different requirements such as:
- Tenant-specific Sentinel resources
- Tenant-specific detection logic
- Tenant-specific exclusions
- Tenant-specific permissions
It is possible to set up multiple DevOps repositories and create multiple connections across Sentinel instances as well. However, this article will only focus on setups involving a single DevOps instance.
When using a single repository, organising branches and directory structures will determine how resources are deployed.
There are two main setups when using a single repo; one is based on having dedicated directories for tenants in the directory structure, and the other makes use of dedicated branches for tenants. The setup suited for most organizations involves organising the directory structure rather than having separate branches for each Sentinel instance (customer). This article outlines how to set up and configure a single repository when using the directory structure to manage Sentinel resource deployment across multiple Sentinel instances.
Architectural views for setting up both dedicated directories and dedicated branches:
Figure 3: Azure DevOps repository directory structure for managing multiple Sentinel instances
Figure 4: Using branches to manage Sentinel resource deployment
This setup uses custom deployment configurations for each tenant, which in turn determines which folders and files are used for Sentinel deployments to those tenants. The setup requires both a custom directory structure and custom deployment files. Note that in this case all deployments to the multiple Sentinel instances are coming from the same branch.
Setting up the directory structure is simple, and it can be done manually in the DevOps site or locally and then pushed to the repository. There is no specific rule to follow here, as the configuration files (see below) can be modified down to specific file/folder exclusions. For operational purposes it is highly recommended that the directory structure is kept as simple as possible.
For example, if there are two Sentinel instances that resources will be deployed to, it is a good idea to have a folder in the root for each instance. If many of the resources will be the same and shared across the Sentinel instances, then a separate folder can be created that will contain Sentinel resources deployed to both Sentinel instances. This means that there will be fewer ARM files in the instance specific folders, and only unique Sentinel resources' ARM files will exist in those folders.
Once the directory structure is set up, the pipelines must be configured to only deploy files within certain folders, based on the Sentinel instance the pipeline is running for. When a Sentinel repository connection is created, three files are created in the DevOps repo under the folder .sentinel:
Figure 5: Files created once the Sentinel repository connection is set up
The file of importance in this case is the .yml file, which is the pipeline file, and which defines the actions a pipeline will take. The .yml file needs to be edited so that it only covers the directories in scope for the Sentinel instance it is running for. When modifying pipeline files it is important that the correct file is being edited.
In order to view which sentinel instance the pipeline file is for, check the Sentinel instance name on the top line of the pipeline file.
Figure 6: The top line of the pipeline file indicating the Sentinel instance name
Configure the pipeline file
There are two changes that need to be made to the pipeline file. Every time there is a change to a file within the scope of the config file, the pipeline will be triggered to run. Therefore, the first modification to the pipeline file is to configure the folders where changes are monitored and the pipeline runs when a change takes place. The second change is to configure the deployment steps, to ensure the correct folders will be deployed.
To configure the pipeline to run when changes happen in specific folders, the include section needs to be changed under the paths item. The “'*'” needs to be removed and the folders that should be in scope need to be added.
In the example below, the folders “Baseline” and “Subsidiary” in the root are added as folders the pipeline should trigger for when there is a change in one of the files.
Figure 7: trigger section in the pipeline file before modifications
Figure 8: trigger section in the pipeline file after modifications
The second change is to add an additional task to the pipeline file and change the working directories. The tasks are found under the steps section. Each directory/folder that should be deployed for this Sentinel instance should have its own task added and configured in the pipeline file. It is important to note that when a directory is added to the task, all subfolders and files within them will be deployed.
Following from the example above, there are two folders that should be deployed to the specific Sentinel instance. These are ‘Baseline' and ‘Subsidiary'. Therefore, there needs to be two tasks in the pipeline file. By default, the pipeline contains one task and the working directory is the root of the repository. In the example being used this would mean that an additional task needs to be added and the original task needs to be amended so that the working directory is one of the folders instead of the root. Doing so ensures that not everything in the repository is pushed to Sentinel.
In the example below, the yellow boxes indicate the working directories – ‘Baseline' and ‘Subsidiary'. The red box shows the newly added task. Note, that apart from the workingDirectory value, the content for the tasks are identical. When adding a task, copying and pasting the default task and then changing the workingDirectory value is sufficient.
Figure 8: task section in the pipeline file after modifications
For further information about custom deployments and the parameters in the pipeline file, view the documentation for custom repository deployments.
Deploy the content
Now that the pipeline file has been configured, the pipeline can be triggered to run manually or via a change to the configured folders, which will also trigger it.
Assuming that the ARM files in the repository are in the correct format, then resources in the folders configured in the pipeline file for the Sentinel instance should have been deployed to Sentinel. If there are missing or additional resources, review the ARM files to ensure they are in the correct format and validate that the pipeline file has been configured correctly.
Now that the pipelines have been verified to be working correctly, DevOps processes can be added into the overall procedure. This can include pull request reviews, project management elements, and other features the Azure DevOps offers.
You should now know how to use Azure DevOps to deploy resources to Sentinel. This method allows for version control, automation, and consistency of Sentinel resources across different environments. By following the steps outlined, you can create a Sentinel repositories connections, a pipeline file, configure the pipeline file with the desired folders and parameters, and trigger the deployment of Sentinel resources from a repository.
More information about using Sentinel for Managed Security Services Provider can be found here.