Configure Azure Synapse Workspace SQL Vulnerability Assessment

The azure-native:synapse:WorkspaceManagedSqlServerVulnerabilityAssessment resource, part of the Pulumi Azure Native provider, configures vulnerability assessment for a Synapse workspace’s managed SQL server: where scan results are stored and how often scans run. This guide focuses on three capabilities: storage authentication methods (access keys vs SAS tokens), recurring scan configuration, and email notification setup.

Vulnerability assessments require an existing Synapse workspace and Azure Storage account with a blob container for scan results. The examples are intentionally small. Combine them with your own workspace and storage infrastructure.

Store scan results using storage account access key

Most vulnerability assessment deployments start with the minimal configuration: a storage location for scan results and credentials to write to that location.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const workspaceManagedSqlServerVulnerabilityAssessment = new azure_native.synapse.WorkspaceManagedSqlServerVulnerabilityAssessment("workspaceManagedSqlServerVulnerabilityAssessment", {
    resourceGroupName: "wsg-7398",
    storageAccountAccessKey: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    storageContainerPath: "https://myStorage.blob.core.windows.net/vulnerability-assessment/",
    vulnerabilityAssessmentName: "default",
    workspaceName: "testWorkspace",
});
import pulumi
import pulumi_azure_native as azure_native

workspace_managed_sql_server_vulnerability_assessment = azure_native.synapse.WorkspaceManagedSqlServerVulnerabilityAssessment("workspaceManagedSqlServerVulnerabilityAssessment",
    resource_group_name="wsg-7398",
    storage_account_access_key="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    storage_container_path="https://myStorage.blob.core.windows.net/vulnerability-assessment/",
    vulnerability_assessment_name="default",
    workspace_name="testWorkspace")
package main

import (
	synapse "github.com/pulumi/pulumi-azure-native-sdk/synapse/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := synapse.NewWorkspaceManagedSqlServerVulnerabilityAssessment(ctx, "workspaceManagedSqlServerVulnerabilityAssessment", &synapse.WorkspaceManagedSqlServerVulnerabilityAssessmentArgs{
			ResourceGroupName:           pulumi.String("wsg-7398"),
			StorageAccountAccessKey:     pulumi.String("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"),
			StorageContainerPath:        pulumi.String("https://myStorage.blob.core.windows.net/vulnerability-assessment/"),
			VulnerabilityAssessmentName: pulumi.String("default"),
			WorkspaceName:               pulumi.String("testWorkspace"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var workspaceManagedSqlServerVulnerabilityAssessment = new AzureNative.Synapse.WorkspaceManagedSqlServerVulnerabilityAssessment("workspaceManagedSqlServerVulnerabilityAssessment", new()
    {
        ResourceGroupName = "wsg-7398",
        StorageAccountAccessKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
        StorageContainerPath = "https://myStorage.blob.core.windows.net/vulnerability-assessment/",
        VulnerabilityAssessmentName = "default",
        WorkspaceName = "testWorkspace",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.synapse.WorkspaceManagedSqlServerVulnerabilityAssessment;
import com.pulumi.azurenative.synapse.WorkspaceManagedSqlServerVulnerabilityAssessmentArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var workspaceManagedSqlServerVulnerabilityAssessment = new WorkspaceManagedSqlServerVulnerabilityAssessment("workspaceManagedSqlServerVulnerabilityAssessment", WorkspaceManagedSqlServerVulnerabilityAssessmentArgs.builder()
            .resourceGroupName("wsg-7398")
            .storageAccountAccessKey("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
            .storageContainerPath("https://myStorage.blob.core.windows.net/vulnerability-assessment/")
            .vulnerabilityAssessmentName("default")
            .workspaceName("testWorkspace")
            .build());

    }
}
resources:
  workspaceManagedSqlServerVulnerabilityAssessment:
    type: azure-native:synapse:WorkspaceManagedSqlServerVulnerabilityAssessment
    properties:
      resourceGroupName: wsg-7398
      storageAccountAccessKey: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      storageContainerPath: https://myStorage.blob.core.windows.net/vulnerability-assessment/
      vulnerabilityAssessmentName: default
      workspaceName: testWorkspace

The storageContainerPath property points to a blob container where Azure stores scan results. The storageAccountAccessKey provides write access to that container. The vulnerabilityAssessmentName is typically “default” (Azure supports only one assessment per workspace).

Store scan results using SAS token authentication

When storage account keys aren’t available or you want time-limited access, SAS tokens provide an alternative authentication method.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const workspaceManagedSqlServerVulnerabilityAssessment = new azure_native.synapse.WorkspaceManagedSqlServerVulnerabilityAssessment("workspaceManagedSqlServerVulnerabilityAssessment", {
    resourceGroupName: "wsg-7398",
    storageContainerPath: "https://myStorage.blob.core.windows.net/vulnerability-assessment/",
    storageContainerSasKey: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    vulnerabilityAssessmentName: "default",
    workspaceName: "testWorkspace",
});
import pulumi
import pulumi_azure_native as azure_native

workspace_managed_sql_server_vulnerability_assessment = azure_native.synapse.WorkspaceManagedSqlServerVulnerabilityAssessment("workspaceManagedSqlServerVulnerabilityAssessment",
    resource_group_name="wsg-7398",
    storage_container_path="https://myStorage.blob.core.windows.net/vulnerability-assessment/",
    storage_container_sas_key="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    vulnerability_assessment_name="default",
    workspace_name="testWorkspace")
package main

import (
	synapse "github.com/pulumi/pulumi-azure-native-sdk/synapse/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := synapse.NewWorkspaceManagedSqlServerVulnerabilityAssessment(ctx, "workspaceManagedSqlServerVulnerabilityAssessment", &synapse.WorkspaceManagedSqlServerVulnerabilityAssessmentArgs{
			ResourceGroupName:           pulumi.String("wsg-7398"),
			StorageContainerPath:        pulumi.String("https://myStorage.blob.core.windows.net/vulnerability-assessment/"),
			StorageContainerSasKey:      pulumi.String("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"),
			VulnerabilityAssessmentName: pulumi.String("default"),
			WorkspaceName:               pulumi.String("testWorkspace"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var workspaceManagedSqlServerVulnerabilityAssessment = new AzureNative.Synapse.WorkspaceManagedSqlServerVulnerabilityAssessment("workspaceManagedSqlServerVulnerabilityAssessment", new()
    {
        ResourceGroupName = "wsg-7398",
        StorageContainerPath = "https://myStorage.blob.core.windows.net/vulnerability-assessment/",
        StorageContainerSasKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
        VulnerabilityAssessmentName = "default",
        WorkspaceName = "testWorkspace",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.synapse.WorkspaceManagedSqlServerVulnerabilityAssessment;
import com.pulumi.azurenative.synapse.WorkspaceManagedSqlServerVulnerabilityAssessmentArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var workspaceManagedSqlServerVulnerabilityAssessment = new WorkspaceManagedSqlServerVulnerabilityAssessment("workspaceManagedSqlServerVulnerabilityAssessment", WorkspaceManagedSqlServerVulnerabilityAssessmentArgs.builder()
            .resourceGroupName("wsg-7398")
            .storageContainerPath("https://myStorage.blob.core.windows.net/vulnerability-assessment/")
            .storageContainerSasKey("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
            .vulnerabilityAssessmentName("default")
            .workspaceName("testWorkspace")
            .build());

    }
}
resources:
  workspaceManagedSqlServerVulnerabilityAssessment:
    type: azure-native:synapse:WorkspaceManagedSqlServerVulnerabilityAssessment
    properties:
      resourceGroupName: wsg-7398
      storageContainerPath: https://myStorage.blob.core.windows.net/vulnerability-assessment/
      storageContainerSasKey: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      vulnerabilityAssessmentName: default
      workspaceName: testWorkspace

This configuration replaces storageAccountAccessKey with storageContainerSasKey. The SAS token must grant read and write permissions to the specified container. This approach lets you limit access duration and scope without sharing the full storage account key.

Configure recurring scans with email notifications

Production deployments typically enable recurring scans and configure email notifications to alert security teams when vulnerabilities are detected.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const workspaceManagedSqlServerVulnerabilityAssessment = new azure_native.synapse.WorkspaceManagedSqlServerVulnerabilityAssessment("workspaceManagedSqlServerVulnerabilityAssessment", {
    recurringScans: {
        emailSubscriptionAdmins: true,
        emails: [
            "email1@mail.com",
            "email2@mail.com",
        ],
        isEnabled: true,
    },
    resourceGroupName: "wsg-7398",
    storageAccountAccessKey: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    storageContainerPath: "https://myStorage.blob.core.windows.net/vulnerability-assessment/",
    storageContainerSasKey: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    vulnerabilityAssessmentName: "default",
    workspaceName: "testWorkspace",
});
import pulumi
import pulumi_azure_native as azure_native

workspace_managed_sql_server_vulnerability_assessment = azure_native.synapse.WorkspaceManagedSqlServerVulnerabilityAssessment("workspaceManagedSqlServerVulnerabilityAssessment",
    recurring_scans={
        "email_subscription_admins": True,
        "emails": [
            "email1@mail.com",
            "email2@mail.com",
        ],
        "is_enabled": True,
    },
    resource_group_name="wsg-7398",
    storage_account_access_key="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    storage_container_path="https://myStorage.blob.core.windows.net/vulnerability-assessment/",
    storage_container_sas_key="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    vulnerability_assessment_name="default",
    workspace_name="testWorkspace")
package main

import (
	synapse "github.com/pulumi/pulumi-azure-native-sdk/synapse/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := synapse.NewWorkspaceManagedSqlServerVulnerabilityAssessment(ctx, "workspaceManagedSqlServerVulnerabilityAssessment", &synapse.WorkspaceManagedSqlServerVulnerabilityAssessmentArgs{
			RecurringScans: &synapse.VulnerabilityAssessmentRecurringScansPropertiesArgs{
				EmailSubscriptionAdmins: pulumi.Bool(true),
				Emails: pulumi.StringArray{
					pulumi.String("email1@mail.com"),
					pulumi.String("email2@mail.com"),
				},
				IsEnabled: pulumi.Bool(true),
			},
			ResourceGroupName:           pulumi.String("wsg-7398"),
			StorageAccountAccessKey:     pulumi.String("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"),
			StorageContainerPath:        pulumi.String("https://myStorage.blob.core.windows.net/vulnerability-assessment/"),
			StorageContainerSasKey:      pulumi.String("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"),
			VulnerabilityAssessmentName: pulumi.String("default"),
			WorkspaceName:               pulumi.String("testWorkspace"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var workspaceManagedSqlServerVulnerabilityAssessment = new AzureNative.Synapse.WorkspaceManagedSqlServerVulnerabilityAssessment("workspaceManagedSqlServerVulnerabilityAssessment", new()
    {
        RecurringScans = new AzureNative.Synapse.Inputs.VulnerabilityAssessmentRecurringScansPropertiesArgs
        {
            EmailSubscriptionAdmins = true,
            Emails = new[]
            {
                "email1@mail.com",
                "email2@mail.com",
            },
            IsEnabled = true,
        },
        ResourceGroupName = "wsg-7398",
        StorageAccountAccessKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
        StorageContainerPath = "https://myStorage.blob.core.windows.net/vulnerability-assessment/",
        StorageContainerSasKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
        VulnerabilityAssessmentName = "default",
        WorkspaceName = "testWorkspace",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.synapse.WorkspaceManagedSqlServerVulnerabilityAssessment;
import com.pulumi.azurenative.synapse.WorkspaceManagedSqlServerVulnerabilityAssessmentArgs;
import com.pulumi.azurenative.synapse.inputs.VulnerabilityAssessmentRecurringScansPropertiesArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var workspaceManagedSqlServerVulnerabilityAssessment = new WorkspaceManagedSqlServerVulnerabilityAssessment("workspaceManagedSqlServerVulnerabilityAssessment", WorkspaceManagedSqlServerVulnerabilityAssessmentArgs.builder()
            .recurringScans(VulnerabilityAssessmentRecurringScansPropertiesArgs.builder()
                .emailSubscriptionAdmins(true)
                .emails(                
                    "email1@mail.com",
                    "email2@mail.com")
                .isEnabled(true)
                .build())
            .resourceGroupName("wsg-7398")
            .storageAccountAccessKey("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
            .storageContainerPath("https://myStorage.blob.core.windows.net/vulnerability-assessment/")
            .storageContainerSasKey("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
            .vulnerabilityAssessmentName("default")
            .workspaceName("testWorkspace")
            .build());

    }
}
resources:
  workspaceManagedSqlServerVulnerabilityAssessment:
    type: azure-native:synapse:WorkspaceManagedSqlServerVulnerabilityAssessment
    properties:
      recurringScans:
        emailSubscriptionAdmins: true
        emails:
          - email1@mail.com
          - email2@mail.com
        isEnabled: true
      resourceGroupName: wsg-7398
      storageAccountAccessKey: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      storageContainerPath: https://myStorage.blob.core.windows.net/vulnerability-assessment/
      storageContainerSasKey: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      vulnerabilityAssessmentName: default
      workspaceName: testWorkspace

The recurringScans block enables automated scanning. Set isEnabled to true to activate recurring scans. The emails array specifies recipients for scan reports, and emailSubscriptionAdmins sends notifications to Azure subscription administrators. This configuration extends the minimal setup from earlier examples by adding automation and alerting.

Beyond these examples

These snippets focus on specific vulnerability assessment features: storage authentication (access keys and SAS tokens), recurring scan scheduling, and email notification configuration. They’re intentionally minimal rather than full security monitoring solutions.

The examples reference pre-existing infrastructure such as Synapse workspaces and Azure Storage accounts with blob containers. They focus on configuring the assessment rather than provisioning the surrounding infrastructure.

To keep things focused, common assessment patterns are omitted, including:

  • Storage account and container provisioning
  • Workspace creation and configuration
  • IAM permissions for storage access
  • Scan result analysis and remediation workflows

These omissions are intentional: the goal is to illustrate how each assessment feature is wired, not provide drop-in security modules. See the WorkspaceManagedSqlServerVulnerabilityAssessment resource reference for all available configuration options.

Let's configure Azure Synapse Workspace SQL Vulnerability Assessment

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Storage Configuration
How do I authenticate to the storage account for vulnerability scans?
You must provide either storageAccountAccessKey or storageContainerSasKey. If using a SAS key, ensure it has read and write access to the blob container specified in storageContainerPath.
Can I provide both storageAccountAccessKey and storageContainerSasKey?
Yes, you can specify both authentication methods as shown in the first example, though only one is required.
What format should the storage container path use?
Use the format https://[storageAccountName].blob.core.windows.net/[containerName]/, for example https://myStorage.blob.core.windows.net/vulnerability-assessment/.
Recurring Scans & Notifications
Is recurringScans required to create a vulnerability assessment?
No, recurringScans is optional. You can create a vulnerability assessment with just storage configuration, as shown in the minimal examples.
How do I enable automated vulnerability scans with email notifications?
Configure recurringScans with isEnabled set to true. Optionally specify an emails array and set emailSubscriptionAdmins to true to notify subscription administrators.
Resource Management
What properties can't be changed after creating the vulnerability assessment?
The following properties are immutable: storageContainerPath, vulnerabilityAssessmentName, workspaceName, and resourceGroupName. Changing any of these requires recreating the resource.

Using a different cloud?

Explore security guides for other cloud providers: