Configure Azure IoT Operations Broker Authorization

The azure-native:iotoperations:BrokerAuthorization resource, part of the Pulumi Azure Native provider, defines authorization policies for an IoT Operations MQTT broker: which clients can connect, which topics they can access, and which state store keys they can read or write. This guide focuses on three capabilities: client identification via IDs, usernames, and attributes; MQTT operation permissions (Connect, Publish, Subscribe); and state store access control.

Authorization resources belong to a broker within an IoT Operations instance, both of which must exist. They also reference an Azure Arc CustomLocation for edge deployment. The examples are intentionally small. Combine them with your own broker configuration and client authentication setup.

Allow clients to connect and subscribe to topics

Most broker deployments start by defining which clients can connect and which topics they can subscribe to.

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

const brokerAuthorization = new azure_native.iotoperations.BrokerAuthorization("brokerAuthorization", {
    authorizationName: "resource-name123",
    brokerName: "resource-name123",
    extendedLocation: {
        name: "qmbrfwcpwwhggszhrdjv",
        type: azure_native.iotoperations.ExtendedLocationType.CustomLocation,
    },
    instanceName: "resource-name123",
    properties: {
        authorizationPolicies: {
            cache: azure_native.iotoperations.OperationalMode.Enabled,
            rules: [{
                brokerResources: [
                    {
                        method: azure_native.iotoperations.BrokerResourceDefinitionMethods.Connect,
                    },
                    {
                        method: azure_native.iotoperations.BrokerResourceDefinitionMethods.Subscribe,
                        topics: [
                            "topic",
                            "topic/with/wildcard/#",
                        ],
                    },
                ],
                principals: {
                    attributes: [{
                        floor: "floor1",
                        site: "site1",
                    }],
                    clientIds: ["my-client-id"],
                },
                stateStoreResources: [{
                    keyType: azure_native.iotoperations.StateStoreResourceKeyTypes.Pattern,
                    keys: ["*"],
                    method: azure_native.iotoperations.StateStoreResourceDefinitionMethods.ReadWrite,
                }],
            }],
        },
    },
    resourceGroupName: "rgiotoperations",
});
import pulumi
import pulumi_azure_native as azure_native

broker_authorization = azure_native.iotoperations.BrokerAuthorization("brokerAuthorization",
    authorization_name="resource-name123",
    broker_name="resource-name123",
    extended_location={
        "name": "qmbrfwcpwwhggszhrdjv",
        "type": azure_native.iotoperations.ExtendedLocationType.CUSTOM_LOCATION,
    },
    instance_name="resource-name123",
    properties={
        "authorization_policies": {
            "cache": azure_native.iotoperations.OperationalMode.ENABLED,
            "rules": [{
                "broker_resources": [
                    {
                        "method": azure_native.iotoperations.BrokerResourceDefinitionMethods.CONNECT,
                    },
                    {
                        "method": azure_native.iotoperations.BrokerResourceDefinitionMethods.SUBSCRIBE,
                        "topics": [
                            "topic",
                            "topic/with/wildcard/#",
                        ],
                    },
                ],
                "principals": {
                    "attributes": [{
                        "floor": "floor1",
                        "site": "site1",
                    }],
                    "client_ids": ["my-client-id"],
                },
                "state_store_resources": [{
                    "key_type": azure_native.iotoperations.StateStoreResourceKeyTypes.PATTERN,
                    "keys": ["*"],
                    "method": azure_native.iotoperations.StateStoreResourceDefinitionMethods.READ_WRITE,
                }],
            }],
        },
    },
    resource_group_name="rgiotoperations")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := iotoperations.NewBrokerAuthorization(ctx, "brokerAuthorization", &iotoperations.BrokerAuthorizationArgs{
			AuthorizationName: pulumi.String("resource-name123"),
			BrokerName:        pulumi.String("resource-name123"),
			ExtendedLocation: &iotoperations.ExtendedLocationArgs{
				Name: pulumi.String("qmbrfwcpwwhggszhrdjv"),
				Type: pulumi.String(iotoperations.ExtendedLocationTypeCustomLocation),
			},
			InstanceName: pulumi.String("resource-name123"),
			Properties: &iotoperations.BrokerAuthorizationPropertiesArgs{
				AuthorizationPolicies: &iotoperations.AuthorizationConfigArgs{
					Cache: pulumi.String(iotoperations.OperationalModeEnabled),
					Rules: iotoperations.AuthorizationRuleArray{
						&iotoperations.AuthorizationRuleArgs{
							BrokerResources: iotoperations.BrokerResourceRuleArray{
								&iotoperations.BrokerResourceRuleArgs{
									Method: pulumi.String(iotoperations.BrokerResourceDefinitionMethodsConnect),
								},
								&iotoperations.BrokerResourceRuleArgs{
									Method: pulumi.String(iotoperations.BrokerResourceDefinitionMethodsSubscribe),
									Topics: pulumi.StringArray{
										pulumi.String("topic"),
										pulumi.String("topic/with/wildcard/#"),
									},
								},
							},
							Principals: &iotoperations.PrincipalDefinitionArgs{
								Attributes: pulumi.StringMapArray{
									pulumi.StringMap{
										"floor": pulumi.String("floor1"),
										"site":  pulumi.String("site1"),
									},
								},
								ClientIds: pulumi.StringArray{
									pulumi.String("my-client-id"),
								},
							},
							StateStoreResources: iotoperations.StateStoreResourceRuleArray{
								&iotoperations.StateStoreResourceRuleArgs{
									KeyType: pulumi.String(iotoperations.StateStoreResourceKeyTypesPattern),
									Keys: pulumi.StringArray{
										pulumi.String("*"),
									},
									Method: pulumi.String(iotoperations.StateStoreResourceDefinitionMethodsReadWrite),
								},
							},
						},
					},
				},
			},
			ResourceGroupName: pulumi.String("rgiotoperations"),
		})
		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 brokerAuthorization = new AzureNative.IoTOperations.BrokerAuthorization("brokerAuthorization", new()
    {
        AuthorizationName = "resource-name123",
        BrokerName = "resource-name123",
        ExtendedLocation = new AzureNative.IoTOperations.Inputs.ExtendedLocationArgs
        {
            Name = "qmbrfwcpwwhggszhrdjv",
            Type = AzureNative.IoTOperations.ExtendedLocationType.CustomLocation,
        },
        InstanceName = "resource-name123",
        Properties = new AzureNative.IoTOperations.Inputs.BrokerAuthorizationPropertiesArgs
        {
            AuthorizationPolicies = new AzureNative.IoTOperations.Inputs.AuthorizationConfigArgs
            {
                Cache = AzureNative.IoTOperations.OperationalMode.Enabled,
                Rules = new[]
                {
                    new AzureNative.IoTOperations.Inputs.AuthorizationRuleArgs
                    {
                        BrokerResources = new[]
                        {
                            new AzureNative.IoTOperations.Inputs.BrokerResourceRuleArgs
                            {
                                Method = AzureNative.IoTOperations.BrokerResourceDefinitionMethods.Connect,
                            },
                            new AzureNative.IoTOperations.Inputs.BrokerResourceRuleArgs
                            {
                                Method = AzureNative.IoTOperations.BrokerResourceDefinitionMethods.Subscribe,
                                Topics = new[]
                                {
                                    "topic",
                                    "topic/with/wildcard/#",
                                },
                            },
                        },
                        Principals = new AzureNative.IoTOperations.Inputs.PrincipalDefinitionArgs
                        {
                            Attributes = new[]
                            {
                                
                                {
                                    { "floor", "floor1" },
                                    { "site", "site1" },
                                },
                            },
                            ClientIds = new[]
                            {
                                "my-client-id",
                            },
                        },
                        StateStoreResources = new[]
                        {
                            new AzureNative.IoTOperations.Inputs.StateStoreResourceRuleArgs
                            {
                                KeyType = AzureNative.IoTOperations.StateStoreResourceKeyTypes.Pattern,
                                Keys = new[]
                                {
                                    "*",
                                },
                                Method = AzureNative.IoTOperations.StateStoreResourceDefinitionMethods.ReadWrite,
                            },
                        },
                    },
                },
            },
        },
        ResourceGroupName = "rgiotoperations",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.iotoperations.BrokerAuthorization;
import com.pulumi.azurenative.iotoperations.BrokerAuthorizationArgs;
import com.pulumi.azurenative.iotoperations.inputs.ExtendedLocationArgs;
import com.pulumi.azurenative.iotoperations.inputs.BrokerAuthorizationPropertiesArgs;
import com.pulumi.azurenative.iotoperations.inputs.AuthorizationConfigArgs;
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 brokerAuthorization = new BrokerAuthorization("brokerAuthorization", BrokerAuthorizationArgs.builder()
            .authorizationName("resource-name123")
            .brokerName("resource-name123")
            .extendedLocation(ExtendedLocationArgs.builder()
                .name("qmbrfwcpwwhggszhrdjv")
                .type("CustomLocation")
                .build())
            .instanceName("resource-name123")
            .properties(BrokerAuthorizationPropertiesArgs.builder()
                .authorizationPolicies(AuthorizationConfigArgs.builder()
                    .cache("Enabled")
                    .rules(AuthorizationRuleArgs.builder()
                        .brokerResources(                        
                            BrokerResourceRuleArgs.builder()
                                .method("Connect")
                                .build(),
                            BrokerResourceRuleArgs.builder()
                                .method("Subscribe")
                                .topics(                                
                                    "topic",
                                    "topic/with/wildcard/#")
                                .build())
                        .principals(PrincipalDefinitionArgs.builder()
                            .attributes(Map.ofEntries(
                                Map.entry("floor", "floor1"),
                                Map.entry("site", "site1")
                            ))
                            .clientIds("my-client-id")
                            .build())
                        .stateStoreResources(StateStoreResourceRuleArgs.builder()
                            .keyType("Pattern")
                            .keys("*")
                            .method("ReadWrite")
                            .build())
                        .build())
                    .build())
                .build())
            .resourceGroupName("rgiotoperations")
            .build());

    }
}
resources:
  brokerAuthorization:
    type: azure-native:iotoperations:BrokerAuthorization
    properties:
      authorizationName: resource-name123
      brokerName: resource-name123
      extendedLocation:
        name: qmbrfwcpwwhggszhrdjv
        type: CustomLocation
      instanceName: resource-name123
      properties:
        authorizationPolicies:
          cache: Enabled
          rules:
            - brokerResources:
                - method: Connect
                - method: Subscribe
                  topics:
                    - topic
                    - topic/with/wildcard/#
              principals:
                attributes:
                  - floor: floor1
                    site: site1
                clientIds:
                  - my-client-id
              stateStoreResources:
                - keyType: Pattern
                  keys:
                    - '*'
                  method: ReadWrite
      resourceGroupName: rgiotoperations

The authorizationPolicies property contains rules that match clients and grant permissions. Each rule has a principals section that identifies clients by clientIds or attributes, and a brokerResources section that specifies allowed MQTT operations. The method property controls whether clients can Connect, Publish, or Subscribe; the topics array restricts access to specific topic patterns using MQTT wildcards.

Use attribute-based rules with dynamic topic patterns

IoT deployments often need rules that scale across device fleets without hardcoding each client.

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

const brokerAuthorization = new azure_native.iotoperations.BrokerAuthorization("brokerAuthorization", {
    authorizationName: "resource-name123",
    brokerName: "resource-name123",
    extendedLocation: {
        name: "qmbrfwcpwwhggszhrdjv",
        type: azure_native.iotoperations.ExtendedLocationType.CustomLocation,
    },
    instanceName: "resource-name123",
    properties: {
        authorizationPolicies: {
            cache: azure_native.iotoperations.OperationalMode.Enabled,
            rules: [{
                brokerResources: [
                    {
                        clientIds: ["{principal.attributes.building}*"],
                        method: azure_native.iotoperations.BrokerResourceDefinitionMethods.Connect,
                    },
                    {
                        method: azure_native.iotoperations.BrokerResourceDefinitionMethods.Publish,
                        topics: ["sensors/{principal.attributes.building}/{principal.clientId}/telemetry/*"],
                    },
                    {
                        method: azure_native.iotoperations.BrokerResourceDefinitionMethods.Subscribe,
                        topics: ["commands/{principal.attributes.organization}"],
                    },
                ],
                principals: {
                    attributes: [{
                        building: "17",
                        organization: "contoso",
                    }],
                    usernames: [
                        "temperature-sensor",
                        "humidity-sensor",
                    ],
                },
                stateStoreResources: [
                    {
                        keyType: azure_native.iotoperations.StateStoreResourceKeyTypes.Pattern,
                        keys: [
                            "myreadkey",
                            "myotherkey?",
                            "mynumerickeysuffix[0-9]",
                            "clients:{principal.clientId}:*",
                        ],
                        method: azure_native.iotoperations.StateStoreResourceDefinitionMethods.Read,
                    },
                    {
                        keyType: azure_native.iotoperations.StateStoreResourceKeyTypes.Binary,
                        keys: ["MTE2IDEwMSAxMTUgMTE2"],
                        method: azure_native.iotoperations.StateStoreResourceDefinitionMethods.ReadWrite,
                    },
                ],
            }],
        },
    },
    resourceGroupName: "rgiotoperations",
});
import pulumi
import pulumi_azure_native as azure_native

broker_authorization = azure_native.iotoperations.BrokerAuthorization("brokerAuthorization",
    authorization_name="resource-name123",
    broker_name="resource-name123",
    extended_location={
        "name": "qmbrfwcpwwhggszhrdjv",
        "type": azure_native.iotoperations.ExtendedLocationType.CUSTOM_LOCATION,
    },
    instance_name="resource-name123",
    properties={
        "authorization_policies": {
            "cache": azure_native.iotoperations.OperationalMode.ENABLED,
            "rules": [{
                "broker_resources": [
                    {
                        "client_ids": ["{principal.attributes.building}*"],
                        "method": azure_native.iotoperations.BrokerResourceDefinitionMethods.CONNECT,
                    },
                    {
                        "method": azure_native.iotoperations.BrokerResourceDefinitionMethods.PUBLISH,
                        "topics": ["sensors/{principal.attributes.building}/{principal.clientId}/telemetry/*"],
                    },
                    {
                        "method": azure_native.iotoperations.BrokerResourceDefinitionMethods.SUBSCRIBE,
                        "topics": ["commands/{principal.attributes.organization}"],
                    },
                ],
                "principals": {
                    "attributes": [{
                        "building": "17",
                        "organization": "contoso",
                    }],
                    "usernames": [
                        "temperature-sensor",
                        "humidity-sensor",
                    ],
                },
                "state_store_resources": [
                    {
                        "key_type": azure_native.iotoperations.StateStoreResourceKeyTypes.PATTERN,
                        "keys": [
                            "myreadkey",
                            "myotherkey?",
                            "mynumerickeysuffix[0-9]",
                            "clients:{principal.clientId}:*",
                        ],
                        "method": azure_native.iotoperations.StateStoreResourceDefinitionMethods.READ,
                    },
                    {
                        "key_type": azure_native.iotoperations.StateStoreResourceKeyTypes.BINARY,
                        "keys": ["MTE2IDEwMSAxMTUgMTE2"],
                        "method": azure_native.iotoperations.StateStoreResourceDefinitionMethods.READ_WRITE,
                    },
                ],
            }],
        },
    },
    resource_group_name="rgiotoperations")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := iotoperations.NewBrokerAuthorization(ctx, "brokerAuthorization", &iotoperations.BrokerAuthorizationArgs{
			AuthorizationName: pulumi.String("resource-name123"),
			BrokerName:        pulumi.String("resource-name123"),
			ExtendedLocation: &iotoperations.ExtendedLocationArgs{
				Name: pulumi.String("qmbrfwcpwwhggszhrdjv"),
				Type: pulumi.String(iotoperations.ExtendedLocationTypeCustomLocation),
			},
			InstanceName: pulumi.String("resource-name123"),
			Properties: &iotoperations.BrokerAuthorizationPropertiesArgs{
				AuthorizationPolicies: &iotoperations.AuthorizationConfigArgs{
					Cache: pulumi.String(iotoperations.OperationalModeEnabled),
					Rules: iotoperations.AuthorizationRuleArray{
						&iotoperations.AuthorizationRuleArgs{
							BrokerResources: iotoperations.BrokerResourceRuleArray{
								&iotoperations.BrokerResourceRuleArgs{
									ClientIds: pulumi.StringArray{
										pulumi.String("{principal.attributes.building}*"),
									},
									Method: pulumi.String(iotoperations.BrokerResourceDefinitionMethodsConnect),
								},
								&iotoperations.BrokerResourceRuleArgs{
									Method: pulumi.String(iotoperations.BrokerResourceDefinitionMethodsPublish),
									Topics: pulumi.StringArray{
										pulumi.String("sensors/{principal.attributes.building}/{principal.clientId}/telemetry/*"),
									},
								},
								&iotoperations.BrokerResourceRuleArgs{
									Method: pulumi.String(iotoperations.BrokerResourceDefinitionMethodsSubscribe),
									Topics: pulumi.StringArray{
										pulumi.String("commands/{principal.attributes.organization}"),
									},
								},
							},
							Principals: &iotoperations.PrincipalDefinitionArgs{
								Attributes: pulumi.StringMapArray{
									pulumi.StringMap{
										"building":     pulumi.String("17"),
										"organization": pulumi.String("contoso"),
									},
								},
								Usernames: pulumi.StringArray{
									pulumi.String("temperature-sensor"),
									pulumi.String("humidity-sensor"),
								},
							},
							StateStoreResources: iotoperations.StateStoreResourceRuleArray{
								&iotoperations.StateStoreResourceRuleArgs{
									KeyType: pulumi.String(iotoperations.StateStoreResourceKeyTypesPattern),
									Keys: pulumi.StringArray{
										pulumi.String("myreadkey"),
										pulumi.String("myotherkey?"),
										pulumi.String("mynumerickeysuffix[0-9]"),
										pulumi.String("clients:{principal.clientId}:*"),
									},
									Method: pulumi.String(iotoperations.StateStoreResourceDefinitionMethodsRead),
								},
								&iotoperations.StateStoreResourceRuleArgs{
									KeyType: pulumi.String(iotoperations.StateStoreResourceKeyTypesBinary),
									Keys: pulumi.StringArray{
										pulumi.String("MTE2IDEwMSAxMTUgMTE2"),
									},
									Method: pulumi.String(iotoperations.StateStoreResourceDefinitionMethodsReadWrite),
								},
							},
						},
					},
				},
			},
			ResourceGroupName: pulumi.String("rgiotoperations"),
		})
		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 brokerAuthorization = new AzureNative.IoTOperations.BrokerAuthorization("brokerAuthorization", new()
    {
        AuthorizationName = "resource-name123",
        BrokerName = "resource-name123",
        ExtendedLocation = new AzureNative.IoTOperations.Inputs.ExtendedLocationArgs
        {
            Name = "qmbrfwcpwwhggszhrdjv",
            Type = AzureNative.IoTOperations.ExtendedLocationType.CustomLocation,
        },
        InstanceName = "resource-name123",
        Properties = new AzureNative.IoTOperations.Inputs.BrokerAuthorizationPropertiesArgs
        {
            AuthorizationPolicies = new AzureNative.IoTOperations.Inputs.AuthorizationConfigArgs
            {
                Cache = AzureNative.IoTOperations.OperationalMode.Enabled,
                Rules = new[]
                {
                    new AzureNative.IoTOperations.Inputs.AuthorizationRuleArgs
                    {
                        BrokerResources = new[]
                        {
                            new AzureNative.IoTOperations.Inputs.BrokerResourceRuleArgs
                            {
                                ClientIds = new[]
                                {
                                    "{principal.attributes.building}*",
                                },
                                Method = AzureNative.IoTOperations.BrokerResourceDefinitionMethods.Connect,
                            },
                            new AzureNative.IoTOperations.Inputs.BrokerResourceRuleArgs
                            {
                                Method = AzureNative.IoTOperations.BrokerResourceDefinitionMethods.Publish,
                                Topics = new[]
                                {
                                    "sensors/{principal.attributes.building}/{principal.clientId}/telemetry/*",
                                },
                            },
                            new AzureNative.IoTOperations.Inputs.BrokerResourceRuleArgs
                            {
                                Method = AzureNative.IoTOperations.BrokerResourceDefinitionMethods.Subscribe,
                                Topics = new[]
                                {
                                    "commands/{principal.attributes.organization}",
                                },
                            },
                        },
                        Principals = new AzureNative.IoTOperations.Inputs.PrincipalDefinitionArgs
                        {
                            Attributes = new[]
                            {
                                
                                {
                                    { "building", "17" },
                                    { "organization", "contoso" },
                                },
                            },
                            Usernames = new[]
                            {
                                "temperature-sensor",
                                "humidity-sensor",
                            },
                        },
                        StateStoreResources = new[]
                        {
                            new AzureNative.IoTOperations.Inputs.StateStoreResourceRuleArgs
                            {
                                KeyType = AzureNative.IoTOperations.StateStoreResourceKeyTypes.Pattern,
                                Keys = new[]
                                {
                                    "myreadkey",
                                    "myotherkey?",
                                    "mynumerickeysuffix[0-9]",
                                    "clients:{principal.clientId}:*",
                                },
                                Method = AzureNative.IoTOperations.StateStoreResourceDefinitionMethods.Read,
                            },
                            new AzureNative.IoTOperations.Inputs.StateStoreResourceRuleArgs
                            {
                                KeyType = AzureNative.IoTOperations.StateStoreResourceKeyTypes.Binary,
                                Keys = new[]
                                {
                                    "MTE2IDEwMSAxMTUgMTE2",
                                },
                                Method = AzureNative.IoTOperations.StateStoreResourceDefinitionMethods.ReadWrite,
                            },
                        },
                    },
                },
            },
        },
        ResourceGroupName = "rgiotoperations",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.iotoperations.BrokerAuthorization;
import com.pulumi.azurenative.iotoperations.BrokerAuthorizationArgs;
import com.pulumi.azurenative.iotoperations.inputs.ExtendedLocationArgs;
import com.pulumi.azurenative.iotoperations.inputs.BrokerAuthorizationPropertiesArgs;
import com.pulumi.azurenative.iotoperations.inputs.AuthorizationConfigArgs;
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 brokerAuthorization = new BrokerAuthorization("brokerAuthorization", BrokerAuthorizationArgs.builder()
            .authorizationName("resource-name123")
            .brokerName("resource-name123")
            .extendedLocation(ExtendedLocationArgs.builder()
                .name("qmbrfwcpwwhggszhrdjv")
                .type("CustomLocation")
                .build())
            .instanceName("resource-name123")
            .properties(BrokerAuthorizationPropertiesArgs.builder()
                .authorizationPolicies(AuthorizationConfigArgs.builder()
                    .cache("Enabled")
                    .rules(AuthorizationRuleArgs.builder()
                        .brokerResources(                        
                            BrokerResourceRuleArgs.builder()
                                .clientIds("{principal.attributes.building}*")
                                .method("Connect")
                                .build(),
                            BrokerResourceRuleArgs.builder()
                                .method("Publish")
                                .topics("sensors/{principal.attributes.building}/{principal.clientId}/telemetry/*")
                                .build(),
                            BrokerResourceRuleArgs.builder()
                                .method("Subscribe")
                                .topics("commands/{principal.attributes.organization}")
                                .build())
                        .principals(PrincipalDefinitionArgs.builder()
                            .attributes(Map.ofEntries(
                                Map.entry("building", "17"),
                                Map.entry("organization", "contoso")
                            ))
                            .usernames(                            
                                "temperature-sensor",
                                "humidity-sensor")
                            .build())
                        .stateStoreResources(                        
                            StateStoreResourceRuleArgs.builder()
                                .keyType("Pattern")
                                .keys(                                
                                    "myreadkey",
                                    "myotherkey?",
                                    "mynumerickeysuffix[0-9]",
                                    "clients:{principal.clientId}:*")
                                .method("Read")
                                .build(),
                            StateStoreResourceRuleArgs.builder()
                                .keyType("Binary")
                                .keys("MTE2IDEwMSAxMTUgMTE2")
                                .method("ReadWrite")
                                .build())
                        .build())
                    .build())
                .build())
            .resourceGroupName("rgiotoperations")
            .build());

    }
}
resources:
  brokerAuthorization:
    type: azure-native:iotoperations:BrokerAuthorization
    properties:
      authorizationName: resource-name123
      brokerName: resource-name123
      extendedLocation:
        name: qmbrfwcpwwhggszhrdjv
        type: CustomLocation
      instanceName: resource-name123
      properties:
        authorizationPolicies:
          cache: Enabled
          rules:
            - brokerResources:
                - clientIds:
                    - '{principal.attributes.building}*'
                  method: Connect
                - method: Publish
                  topics:
                    - sensors/{principal.attributes.building}/{principal.clientId}/telemetry/*
                - method: Subscribe
                  topics:
                    - commands/{principal.attributes.organization}
              principals:
                attributes:
                  - building: '17'
                    organization: contoso
                usernames:
                  - temperature-sensor
                  - humidity-sensor
              stateStoreResources:
                - keyType: Pattern
                  keys:
                    - myreadkey
                    - myotherkey?
                    - mynumerickeysuffix[0-9]
                    - clients:{principal.clientId}:*
                  method: Read
                - keyType: Binary
                  keys:
                    - MTE2IDEwMSAxMTUgMTE2
                  method: ReadWrite
      resourceGroupName: rgiotoperations

Attribute-based rules embed client metadata into topic patterns using {principal.attributes.name} syntax. When a client with building: "17" publishes, the broker evaluates the pattern sensors/{principal.attributes.building}/{principal.clientId}/telemetry/* to determine access. The stateStoreResources section uses the same interpolation for key patterns, letting you scope state store access per client or attribute.

Grant access to broker and state store resources

Applications that use both MQTT messaging and state store need rules covering both resource types.

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

const brokerAuthorization = new azure_native.iotoperations.BrokerAuthorization("brokerAuthorization", {
    authorizationName: "resource-name123",
    brokerName: "resource-name123",
    extendedLocation: {
        name: "qmbrfwcpwwhggszhrdjv",
        type: azure_native.iotoperations.ExtendedLocationType.CustomLocation,
    },
    instanceName: "resource-name123",
    properties: {
        authorizationPolicies: {
            cache: azure_native.iotoperations.OperationalMode.Enabled,
            rules: [{
                brokerResources: [{
                    clientIds: ["nlc"],
                    method: azure_native.iotoperations.BrokerResourceDefinitionMethods.Connect,
                    topics: ["wvuca"],
                }],
                principals: {
                    attributes: [{
                        key5526: "nydhzdhbldygqcn",
                    }],
                    clientIds: ["smopeaeddsygz"],
                    usernames: ["iozngyqndrteikszkbasinzdjtm"],
                },
                stateStoreResources: [{
                    keyType: azure_native.iotoperations.StateStoreResourceKeyTypes.Pattern,
                    keys: ["tkounsqtwvzyaklxjqoerpu"],
                    method: azure_native.iotoperations.StateStoreResourceDefinitionMethods.Read,
                }],
            }],
        },
    },
    resourceGroupName: "rgiotoperations",
});
import pulumi
import pulumi_azure_native as azure_native

broker_authorization = azure_native.iotoperations.BrokerAuthorization("brokerAuthorization",
    authorization_name="resource-name123",
    broker_name="resource-name123",
    extended_location={
        "name": "qmbrfwcpwwhggszhrdjv",
        "type": azure_native.iotoperations.ExtendedLocationType.CUSTOM_LOCATION,
    },
    instance_name="resource-name123",
    properties={
        "authorization_policies": {
            "cache": azure_native.iotoperations.OperationalMode.ENABLED,
            "rules": [{
                "broker_resources": [{
                    "client_ids": ["nlc"],
                    "method": azure_native.iotoperations.BrokerResourceDefinitionMethods.CONNECT,
                    "topics": ["wvuca"],
                }],
                "principals": {
                    "attributes": [{
                        "key5526": "nydhzdhbldygqcn",
                    }],
                    "client_ids": ["smopeaeddsygz"],
                    "usernames": ["iozngyqndrteikszkbasinzdjtm"],
                },
                "state_store_resources": [{
                    "key_type": azure_native.iotoperations.StateStoreResourceKeyTypes.PATTERN,
                    "keys": ["tkounsqtwvzyaklxjqoerpu"],
                    "method": azure_native.iotoperations.StateStoreResourceDefinitionMethods.READ,
                }],
            }],
        },
    },
    resource_group_name="rgiotoperations")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := iotoperations.NewBrokerAuthorization(ctx, "brokerAuthorization", &iotoperations.BrokerAuthorizationArgs{
			AuthorizationName: pulumi.String("resource-name123"),
			BrokerName:        pulumi.String("resource-name123"),
			ExtendedLocation: &iotoperations.ExtendedLocationArgs{
				Name: pulumi.String("qmbrfwcpwwhggszhrdjv"),
				Type: pulumi.String(iotoperations.ExtendedLocationTypeCustomLocation),
			},
			InstanceName: pulumi.String("resource-name123"),
			Properties: &iotoperations.BrokerAuthorizationPropertiesArgs{
				AuthorizationPolicies: &iotoperations.AuthorizationConfigArgs{
					Cache: pulumi.String(iotoperations.OperationalModeEnabled),
					Rules: iotoperations.AuthorizationRuleArray{
						&iotoperations.AuthorizationRuleArgs{
							BrokerResources: iotoperations.BrokerResourceRuleArray{
								&iotoperations.BrokerResourceRuleArgs{
									ClientIds: pulumi.StringArray{
										pulumi.String("nlc"),
									},
									Method: pulumi.String(iotoperations.BrokerResourceDefinitionMethodsConnect),
									Topics: pulumi.StringArray{
										pulumi.String("wvuca"),
									},
								},
							},
							Principals: &iotoperations.PrincipalDefinitionArgs{
								Attributes: pulumi.StringMapArray{
									pulumi.StringMap{
										"key5526": pulumi.String("nydhzdhbldygqcn"),
									},
								},
								ClientIds: pulumi.StringArray{
									pulumi.String("smopeaeddsygz"),
								},
								Usernames: pulumi.StringArray{
									pulumi.String("iozngyqndrteikszkbasinzdjtm"),
								},
							},
							StateStoreResources: iotoperations.StateStoreResourceRuleArray{
								&iotoperations.StateStoreResourceRuleArgs{
									KeyType: pulumi.String(iotoperations.StateStoreResourceKeyTypesPattern),
									Keys: pulumi.StringArray{
										pulumi.String("tkounsqtwvzyaklxjqoerpu"),
									},
									Method: pulumi.String(iotoperations.StateStoreResourceDefinitionMethodsRead),
								},
							},
						},
					},
				},
			},
			ResourceGroupName: pulumi.String("rgiotoperations"),
		})
		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 brokerAuthorization = new AzureNative.IoTOperations.BrokerAuthorization("brokerAuthorization", new()
    {
        AuthorizationName = "resource-name123",
        BrokerName = "resource-name123",
        ExtendedLocation = new AzureNative.IoTOperations.Inputs.ExtendedLocationArgs
        {
            Name = "qmbrfwcpwwhggszhrdjv",
            Type = AzureNative.IoTOperations.ExtendedLocationType.CustomLocation,
        },
        InstanceName = "resource-name123",
        Properties = new AzureNative.IoTOperations.Inputs.BrokerAuthorizationPropertiesArgs
        {
            AuthorizationPolicies = new AzureNative.IoTOperations.Inputs.AuthorizationConfigArgs
            {
                Cache = AzureNative.IoTOperations.OperationalMode.Enabled,
                Rules = new[]
                {
                    new AzureNative.IoTOperations.Inputs.AuthorizationRuleArgs
                    {
                        BrokerResources = new[]
                        {
                            new AzureNative.IoTOperations.Inputs.BrokerResourceRuleArgs
                            {
                                ClientIds = new[]
                                {
                                    "nlc",
                                },
                                Method = AzureNative.IoTOperations.BrokerResourceDefinitionMethods.Connect,
                                Topics = new[]
                                {
                                    "wvuca",
                                },
                            },
                        },
                        Principals = new AzureNative.IoTOperations.Inputs.PrincipalDefinitionArgs
                        {
                            Attributes = new[]
                            {
                                
                                {
                                    { "key5526", "nydhzdhbldygqcn" },
                                },
                            },
                            ClientIds = new[]
                            {
                                "smopeaeddsygz",
                            },
                            Usernames = new[]
                            {
                                "iozngyqndrteikszkbasinzdjtm",
                            },
                        },
                        StateStoreResources = new[]
                        {
                            new AzureNative.IoTOperations.Inputs.StateStoreResourceRuleArgs
                            {
                                KeyType = AzureNative.IoTOperations.StateStoreResourceKeyTypes.Pattern,
                                Keys = new[]
                                {
                                    "tkounsqtwvzyaklxjqoerpu",
                                },
                                Method = AzureNative.IoTOperations.StateStoreResourceDefinitionMethods.Read,
                            },
                        },
                    },
                },
            },
        },
        ResourceGroupName = "rgiotoperations",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.iotoperations.BrokerAuthorization;
import com.pulumi.azurenative.iotoperations.BrokerAuthorizationArgs;
import com.pulumi.azurenative.iotoperations.inputs.ExtendedLocationArgs;
import com.pulumi.azurenative.iotoperations.inputs.BrokerAuthorizationPropertiesArgs;
import com.pulumi.azurenative.iotoperations.inputs.AuthorizationConfigArgs;
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 brokerAuthorization = new BrokerAuthorization("brokerAuthorization", BrokerAuthorizationArgs.builder()
            .authorizationName("resource-name123")
            .brokerName("resource-name123")
            .extendedLocation(ExtendedLocationArgs.builder()
                .name("qmbrfwcpwwhggszhrdjv")
                .type("CustomLocation")
                .build())
            .instanceName("resource-name123")
            .properties(BrokerAuthorizationPropertiesArgs.builder()
                .authorizationPolicies(AuthorizationConfigArgs.builder()
                    .cache("Enabled")
                    .rules(AuthorizationRuleArgs.builder()
                        .brokerResources(BrokerResourceRuleArgs.builder()
                            .clientIds("nlc")
                            .method("Connect")
                            .topics("wvuca")
                            .build())
                        .principals(PrincipalDefinitionArgs.builder()
                            .attributes(Map.of("key5526", "nydhzdhbldygqcn"))
                            .clientIds("smopeaeddsygz")
                            .usernames("iozngyqndrteikszkbasinzdjtm")
                            .build())
                        .stateStoreResources(StateStoreResourceRuleArgs.builder()
                            .keyType("Pattern")
                            .keys("tkounsqtwvzyaklxjqoerpu")
                            .method("Read")
                            .build())
                        .build())
                    .build())
                .build())
            .resourceGroupName("rgiotoperations")
            .build());

    }
}
resources:
  brokerAuthorization:
    type: azure-native:iotoperations:BrokerAuthorization
    properties:
      authorizationName: resource-name123
      brokerName: resource-name123
      extendedLocation:
        name: qmbrfwcpwwhggszhrdjv
        type: CustomLocation
      instanceName: resource-name123
      properties:
        authorizationPolicies:
          cache: Enabled
          rules:
            - brokerResources:
                - clientIds:
                    - nlc
                  method: Connect
                  topics:
                    - wvuca
              principals:
                attributes:
                  - key5526: nydhzdhbldygqcn
                clientIds:
                  - smopeaeddsygz
                usernames:
                  - iozngyqndrteikszkbasinzdjtm
              stateStoreResources:
                - keyType: Pattern
                  keys:
                    - tkounsqtwvzyaklxjqoerpu
                  method: Read
      resourceGroupName: rgiotoperations

A single rule can define permissions for broker operations and state store key access. The brokerResources section controls MQTT operations; the stateStoreResources section controls state store access. The keyType property determines how keys are matched: Pattern uses wildcards, Binary uses base64-encoded keys. The method property sets whether clients can Read, Write, or ReadWrite.

Beyond these examples

These snippets focus on specific authorization features: client identification (IDs, usernames, attributes), MQTT operation permissions (Connect, Publish, Subscribe), and state store access control (pattern and binary keys). They’re intentionally minimal rather than full broker deployments.

The examples reference pre-existing infrastructure such as IoT Operations instance and broker, Azure Arc CustomLocation, and state store configuration (for relevant examples). They focus on authorization policy configuration rather than provisioning the broker itself.

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

  • Cache configuration tuning (cache property defaults to Enabled)
  • Multiple authorization rules per policy
  • Client certificate-based authentication
  • Wildcard patterns in clientIds and usernames

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

Let's configure Azure IoT Operations Broker Authorization

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Authorization Rules & Permissions
What authorization methods are available for broker resources?
Broker resources support three methods: Connect (for client connections), Publish (for publishing messages), and Subscribe (for subscribing to topics).
What authorization methods are available for state store resources?
State store resources support Read (read-only access) and ReadWrite (full access) methods.
How do I use principal attributes in authorization rules?
Use substitution syntax like {principal.attributes.building}, {principal.clientId}, or {principal.attributes.organization} in topics, clientIds, or state store keys. For example, sensors/{principal.attributes.building}/{principal.clientId}/telemetry/* dynamically includes the principal’s building attribute and client ID.
How does authorization policy caching work?
Set authorizationPolicies.cache to Enabled to cache authorization decisions for improved performance, or Disabled to evaluate every request.
Pattern Matching & Wildcards
What wildcard patterns can I use in topics?
Topics support MQTT-style wildcards, including # for multi-level wildcards (e.g., topic/with/wildcard/#).
What wildcard patterns can I use for state store keys?
When using keyType: Pattern, you can use * (multi-character wildcard), ? (single-character wildcard), and character classes like [0-9]. Examples include myotherkey?, mynumerickeysuffix[0-9], and clients:{principal.clientId}:*.
What's the difference between Pattern and Binary key types for state store?
Pattern uses string matching with wildcards for flexible key matching, while Binary uses base64-encoded keys for exact binary matching (e.g., MTE2IDEwMSAxMTUgMTE2).
Configuration & Lifecycle
What properties can't be changed after creating a broker authorization?
The following properties are immutable: authorizationName, brokerName, instanceName, resourceGroupName, and extendedLocation. You must recreate the resource to change these values.
How do I use a different API version for this resource?
Run pulumi package add azure-native iotoperations [ApiVersion] to generate a local SDK package for versions like 2024-07-01-preview, 2024-08-15-preview, 2024-09-15-preview, 2025-04-01, 2025-07-01-preview, or 2025-10-01.

Using a different cloud?

Explore security guides for other cloud providers: