Blog Post

Microsoft Sentinel Blog
7 MIN READ

Use Azure DevOps to manage Sentinel for MSSPs and Multi-tenant Environments

timurengin's avatar
timurengin
Icon for Microsoft rankMicrosoft
Jan 08, 2024

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:

  1. 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.
  2. Project Administrator access to your Azure DevOps repository.
  3. Pipelines enabled for Azure DevOps.
  4. 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 

 

Directory setup

 

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.

 

Next steps

 

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.

 

Updated Dec 15, 2023
Version 1.0

6 Comments

  • john66571's avatar
    john66571
    Iron Contributor

    Ive gotten a few PM's regarding my post above, ive not been able to reply to them as the PM's dont have reply to them, im also not able to tag any of you sorry!

    But yes, i have resolved the issue by rewriting the powershellscript (*.ps1) file and also modifying the *.yml . Most work was done in the ps1 however which is to big to post anywhere here. But i had to introduce a variable and steps in the ps1 that stored the tracking_table before the next step in workflow picked it up and loaded it. But basicly something like this:

    function MergeTrackingTables
    function ReadCsvToTable
    function PushCsvToRepo($trackingTableExists)

    • Yvhi's avatar
      Yvhi
      Copper Contributor

      Hi john66571,

      I'm glad to stumble upon your case as I'm in the same situation and I couldn't figure out why it was redeploying the whole thing for no reason :-)...

      Would you mind sharing your updated PowerShell script? That would be much appreciated!

      Thanks,

      Yvhan

  • john66571's avatar
    john66571
    Iron Contributor

    timurengin 
    Hello kind sir,

    Adding additional tasks (more then 1) in the yml file where you specifiy workingDirectory causes DevOps pipeline to overwrite each tasks tracking_table_<id>.csv. This is with the default powershellscript created by connecting Sentinel out the box.

    Example issue:
    Task 1 creates a tracking table entry, holds it in "memory".

    Task 2 creates a tracking table entry, holds it in "memory". 

    When its time to write to the repo, the actual file tracking_table_<id>.csv it cleans out Task 1s jobb as Task 2 lands after.

     

    This causes unwanted massive runtimes and redeployments if anything within the task1 workingDirectory. Task 1 in my case is the default repos with 200 analytic rules and configs while task 2 is custom deployments. I could revert the order to cut down on the runtime and let the largest workingDirectory be the last task in the pipe, but the issue would remain.

    Any solutions from your end? (to the default ps1 script that is created).

     


    As additional input:
    I tried adding the functionality myself to the ps1 script, but im at best novice at both powershell and devops.

    Greatly appreciated.

  • Taabojo0's avatar
    Taabojo0
    Copper Contributor

    Hi timurengin 
    If you use Github sentinel is installing this 

    In your organisation/user account. With that comes a Github (Bot) User which has read and write rights. 
    In some way (didn't found it in the microsoft docs) the customer service principle has access to that git user atleast to make the inital commits. Is there any blockade between the customer service principle and that speicifc git user?
    otherwise it could be possible if you hijack the service priniple user to make commits and changes to other customers if you have an shared repo.

    Hope that claryfies your questions. 

  • Hi Taabojo0, can you clarify what you mean by "Sentinel Application"? If you mean the Sentinel service, then it does not have any read/write rights on the repo. Once the Sentinel repository connection is set up a service principal is created in Azure, and this service principal is the one which will modify/create resources in Sentinel based on the changes in the Azure DevOps repo.

  • Taabojo0's avatar
    Taabojo0
    Copper Contributor

    timurengin 

    Thanks for that artical, very helpfull just tried it myself. 

    However i have one question. The Sentinel Application has read/write rights to your repo. Do you know if it is possible to access that user from azure? 
    I ask because how can you be sure that one customer is not looking into the repo and changing stuff for other customers or something like that. 
    Isn't that a big concern if you have write rights to a repo?

     

    greetings 

    Johannes