The azure-native:iotoperations:BrokerAuthorization resource, part of the Pulumi Azure Native provider, defines authorization policies for an Azure 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 and topic authorization, attribute-based access control, and state store key patterns.
Authorization resources belong to a broker within an IoT Operations instance. 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 principals block identifies clients by clientIds or attributes (key-value pairs like site and floor). The brokerResources array defines what those clients can do: the method property specifies MQTT operations (Connect, Subscribe, Publish), and the topics array lists allowed topic patterns. Wildcards like # match multiple topic levels. The stateStoreResources block grants read-write access to all state store keys using the * pattern.
Use attribute-based rules with dynamic topic patterns
IoT deployments often need rules that scale across device fleets without hardcoding every client ID.
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 reference client properties at runtime using template syntax like {principal.attributes.building} and {principal.clientId}. The principals block defines required attributes (building: “17”, organization: “contoso”) and usernames (temperature-sensor, humidity-sensor). The brokerResources array uses these attributes in topic patterns, so each client publishes to a unique path based on its identity. The stateStoreResources block demonstrates two access patterns: pattern-based keys using wildcards and character classes ([0-9]), and binary keys encoded as base64 strings.
Grant state store access with pattern matching
Applications using the broker’s state store need rules that control which keys clients can access.
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
The stateStoreResources block defines access rules for the broker’s state store. The keyType property determines how keys are matched: Pattern uses wildcards and literals, while Binary expects base64-encoded key names. The keys array lists patterns or exact keys, and the method property specifies Read, Write, or ReadWrite permissions. Pattern matching lets you grant access to key families without listing every key individually.
Beyond these examples
These snippets focus on specific authorization features: client authentication and topic authorization, attribute-based access control with dynamic patterns, and state store key access rules. They’re intentionally minimal rather than full broker deployments.
The examples reference pre-existing infrastructure such as Azure IoT Operations instance and broker, and Azure Arc custom location for edge deployment. They focus on configuring authorization policies rather than provisioning the broker itself.
To keep things focused, common authorization patterns are omitted, including:
- Username-based principal matching (usernames property)
- Multiple authorization rules per policy
- Cache configuration tuning beyond enabled/disabled
- Binary key types for state store access
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 FREEFrequently Asked Questions
Authorization Rules & Principals
{principal.attributes.attributeName} or {principal.clientId} in clientIds, topics, or state store keys. For example, sensors/{principal.attributes.building}/{principal.clientId}/telemetry/* creates dynamic topic patterns based on the principal’s building attribute and client ID.authorizationPolicies.rules property accepts an array of authorization rules. Each rule can specify different principals (by attributes, clientIds, or usernames) and their allowed broker resources and state store access.principals property with attributes (key-value pairs like building: “17”), clientIds (MQTT client IDs), or usernames. Principals matching any of these criteria will be subject to the rule.State Store Access Control
keyType: Pattern, you can use * (matches any characters), ? (matches single character), and [0-9] (matches character ranges). Examples: myotherkey?, mynumerickeysuffix[0-9], clients:{principal.clientId}:*.Pattern keyType uses string patterns with wildcards (like mykey* or key[0-9]). Binary keyType uses base64-encoded binary keys (like MTE2IDEwMSAxMTUgMTE2).method property to Read for read-only access or ReadWrite for full access. You can define multiple state store resource rules with different methods for different key patterns.MQTT Broker Operations
brokerResources with the appropriate method: Connect for client connections, Publish for publishing to topics, or Subscribe for subscribing to topics. Specify topics for Publish and Subscribe methods, and optionally clientIds for Connect.# for multi-level wildcards in topic patterns, such as topic/with/wildcard/#. You can also combine wildcards with dynamic principal attributes like sensors/{principal.attributes.building}/#.Resource Configuration
extendedLocation, authorizationName, brokerName, instanceName, and resourceGroupName.