person Tia Zanella
calendar_add_on Created April 5, 2026
update Updated April 26, 2026
Share
download Download MD

OSIRIS JSON Producer for Microsoft Azure

The OSIRIS JSON Azure producer connects to Microsoft Azure via the Azure CLI (az) and generates OSIRIS JSON snapshots of your subscription topology. As of v0.4.0 the producer covers networking, compute, storage, identity, databases, containers, integration, observability and backup tiers, including their cross-resource dependency edges (Private Endpoint to PaaS targets, App Service to App Insights, Log Analytics, RSV, Backup Vault to protected items, AKS to subnets and node pools, etc.).

To begin using OSIRIS JSON for Microsoft Azure, install the core dispatcher and the Microsoft Azure OSIRIS JSON producer:

go install go.osirisjson.org/producers/cmd/osirisjson-producer@latest
go install go.osirisjson.org/producers/cmd/osirisjson-producer-azure@latest

The core dispatcher lets you run osirisjson-producer azure .... Without it, invoke the vendor binary directly as osirisjson-producer-azure ....

Make sure $GOPATH/bin (or $HOME/go/bin) is in your PATH. See the getting started page for more install options.

Prerequisites

  1. Install the Azure CLI
  2. Authenticate: az login
  3. The authenticated user must have Reader role (or equivalent read permission) on the target subscription(s). For full data collection including effective routes, the user also needs Microsoft.Network/networkInterfaces/effectiveRouteTable/action permission (included in Network Contributor and above). If this permission is absent, the producer skips effective route collection with an INFO log and continues normally.

You can execute the producer on your local machine or invoke it using a scheduled job with a service account on your preferred platform.

CLI usage

osirisjson-producer azure [flags]
osirisjson-producer azure template --generate

Single mode

Start by collecting one subscription that will be automatically saved as microsoft-azure-<timestamp>-<name>.json:

osirisjson-producer azure -S a1b2c3d4-e5f6-7890-abcd-ef1234567890

Interactive mode

Run without flags to get an interactive subscription picker:

osirisjson-producer azure

The producer discovers all accessible subscriptions and presents a numbered list. Select using individual numbers (1,3,5), ranges (30-55), combinations (1,3,30-55), or type all.

Multi-subscription mode

Collect multiple subscriptions to an output directory:

# Specific subscriptions
osirisjson-producer azure -S sub-id-1,sub-id-2,sub-id-3 -o ./output

# All accessible subscriptions (auto-discover)
osirisjson-producer azure --all -o ./output

# All subscriptions in a specific tenant
osirisjson-producer azure --all --tenant f1e2d3c4-b5a6-9078-fedc-ba9876543210 -o ./output

Batch mode (CSV)

Generate a CSV template:

osirisjson-producer azure template --generate

Collect from a CSV file:

osirisjson-producer azure -s subscriptions.csv -o ./output

The CSV template uses these columns:

ColumnRequiredDescription
subscription_idyesAzure subscription UUID
subscription_nameyesHuman-readable label (used as output filename)
tenant_idAzure AD / Entra ID tenant UUID
environmentDeployment stage: dv, np, pr (development, non-production, production)
regionFilter to Azure region (empty = all regions)
notesFree-text notes (ignored by producer)

Output hierarchy

Single mode: saves to microsoft-azure-<timestamp>-<name>.json in the current directory.

Multi/batch/all modes: organized by tenant and timestamp:

output/
  <TenantID>/
    <timestamp>/
      <SubscriptionName>.json

Each subscription produces a self-contained OSIRIS document. Cross-subscription references (e.g. VNet peerings or ExpressRoute connections to remote subscriptions) are emitted as stub resources with provider.subscription set to the remote subscription ID, so the topology edge survives the boundary while the document remains valid.

Multi-tenant environments

Run the producer once per tenant. Each az login authenticates to one tenant. Use az login --tenant <tenant-id> to switch. The output hierarchy groups documents by tenant automatically.

Flags reference

FlagShortDescription
--subscription-SAzure subscription ID(s), comma-separated
--allAuto-discover all accessible subscriptions
--source-sCSV file with subscription targets
--output-oOutput directory (required for multi/all/CSV mode)
--tenantAzure AD / Entra ID tenant ID (optional)
--regionFilter to a specific Azure region (optional)
--purposeOutput detail grade: documentation (default) or audit. See Purpose below
--safe-failure-modeSecret handling: fail-closed (default), log-and-redact, off
--version / -vDisplay version and exit
--helpDisplay help and exit

Purpose

The --purpose flag implements OSIRIS JSON specification chapter 13.1.3 (data minimization). Collection is always exhaustive; emission is shaped by the declared purpose so the same producer run can serve both lightweight visualization use cases and audit / compliance use cases.

ValueBehavior
documentation (default)Minimal fields: identity, type, provider traceability, names, tags and high-level relationships. Per-resource properties and extensions maps are stripped. Suited for diagrams, inventory dashboards and high-level documentation.
auditEvery readable field, after sensitive-field redaction. Full properties and extensions maps for every resource, connection and group. Suited for compliance reviews, audits, configuration drift or deep documentation and accurate topology design.

The selected value is recorded in the document under metadata.scope.purpose so consumers can tell which grade of detail they are reading.

[!IMPORTANT] Secrets are always redacted regardless of purpose. The audit projection adds detail (IP addresses, NSG rules, SKU subfields, BGP details, etc.); it never adds authentication material. Database admin passwords, Cosmos / Redis / Service Bus / Event Hubs access keys, App Insights instrumentation keys and Log Analytics shared keys are never collected.

# Default: documentation (minimal projection)
osirisjson-producer azure -S a1b2c3d4-e5f6-7890-abcd-ef1234567890

# Audit: full ARM fidelity
osirisjson-producer azure -S a1b2c3d4-e5f6-7890-abcd-ef1234567890 --purpose audit

What OSIRIS JSON producer for Microsoft Azure collects

The OSIRIS JSON producer for Microsoft Azure collects a complete inventory of supported resource types via the Azure CLI on every run. The following table groups what is queried.

Networking

Microsoft Azure resourceOSIRIS JSON type
Virtual Networksnetwork.vpc
Subnetsnetwork.subnet
Network Interfacesnetwork.interface
Network Security Groupsnetwork.security.group
Application Security Groupsosiris.azure.asg
Route Tablesosiris.azure.routetable
Public IP Addressesosiris.azure.publicip
Load Balancers (L4)network.loadbalancer
Application Gateways (L7)network.loadbalancer
Azure Firewallsnetwork.firewall
NAT Gatewaysosiris.azure.gateway.nat
VNet Gateways (VPN / ExpressRoute)osiris.azure.gateway.vnet
ExpressRoute Circuitsosiris.azure.expressroute
Private Endpointsosiris.azure.privateendpoint
DNS Zonesosiris.azure.dns.zone
Private DNS Zonesosiris.azure.dns.privatezone

Compute and storage

Microsoft Azure resourceOSIRIS JSON type
Virtual Machinescompute.vm
Managed Disksosiris.azure.disk
Managed Snapshotsosiris.azure.snapshot
Storage Accountsosiris.azure.storageaccount

App Service / web tier

Microsoft Azure resourceOSIRIS JSON type
App Service Planosiris.azure.appserviceplan
Web Apposiris.azure.webapp
Function Apposiris.azure.functionapp

App Service routing: sites whose kind contains functionapp are emitted as osiris.azure.functionapp; all other sites are emitted as osiris.azure.webapp.

Identity and security

Microsoft Azure resourceOSIRIS JSON type
Key Vaultosiris.azure.keyvault
Container Registryosiris.azure.containerregistry
User-Assigned Managed Identityosiris.azure.managedidentity

Backup and disaster recovery

Microsoft Azure resourceOSIRIS JSON type
Recovery Services Vaultosiris.azure.recoveryvault
Backup Vault (Azure Backup)osiris.azure.backupvault

Databases

Microsoft Azure resourceOSIRIS JSON type
SQL Serverosiris.azure.sqlserver
SQL Databaseosiris.azure.sqldatabase
PostgreSQL Flexible Serverosiris.azure.postgresqlserver
MySQL Flexible Serverosiris.azure.mysqlserver
Cosmos DB accountosiris.azure.cosmosaccount
Redis Cacheosiris.azure.redis

Containers and integration

Microsoft Azure resourceOSIRIS JSON type
AKS Clusterosiris.azure.aks.cluster
AKS Agent Poolosiris.azure.aks.nodepool
Container App Managed Environmentosiris.azure.containerapp.environment
Container Apposiris.azure.containerapp
Container Group / ACIosiris.azure.containergroup
Service Bus Namespaceosiris.azure.servicebus.namespace
Event Hubs Namespaceosiris.azure.eventhubs.namespace
API Management Serviceosiris.azure.apim
Front Door (Standard / Premium)osiris.azure.frontdoor.profile

Observability

Microsoft Azure resourceOSIRIS JSON type
Application Insightsosiris.azure.applicationinsights
Log Analytics Workspaceosiris.azure.loganalytics

Containment

Microsoft Azure resourceOSIRIS JSON type
Resource Groupscontainer.resourcegroup

What is intentionally not collected

OSIRIS JSON defines a vendor-neutral JSON format for describing infrastructure resources, their properties and their topological relationships it is not an Infrastructure-as-Code or similar format you cen read more here What is OSIRIS JSON. The following are intentionally out of scope:

  • Monitoring policy: alert rules, action groups, metric alerts, scheduled query rules.
  • Backup / retention policies under Recovery Services Vault and Backup Vault (the vaults and protected-item edges are emitted; the policy bodies are not).
  • Database-tier policy: SQL auditing, threat-detection, TDE, firewall rules, security-alert-policy.
  • API Management policies, products, operations, named values.
  • Front Door routes, rule sets, endpoints, WAF policy associations (the profile is emitted; the routing is not).
  • Container App secrets and ACI environment variables.
  • Per-resource diagnostic-setting enumeration (would add one az call per resource).
  • Classic Azure Front Door (Microsoft.Network/frontDoors, deprecated).
  • Legacy Microsoft.DBforPostgreSQL/servers (single server, end-of-life on Azure’s roadmap).

OSIRIS JSON output structure for Microsoft Azure

{
  "$schema": "https://osirisjson.org/schema/v1.0/osiris.schema.json",
  "version": "1.0.0",
  "metadata": {
    "generator": {
      "name": "osirisjson-producer-azure",
      "version": "0.4.0",
      "url": "https://osirisjson.org"
    },
    "scope": {
      "name": "<subscription-id> - <subscription-name>",
      "purpose": "documentation",
      "providers": ["azure"],
      "accounts": ["<tenant-id>"],
      "subscriptions": ["<subscription-id>"],
      "regions": ["westeurope", "eastus2"]
    }
  },
  "topology": {
    "resources": [ ... ],
    "connections": [ ... ],
    "groups": [ ... ]
  }
}

Connection types

Connection edges use OSIRIS JSON v1.0 standard subtypes per specification chapter 5.2.3 so consumers can tell topology layers apart.

OSIRIS JSON connection typeUsed for
containsContainment (Subnet within VNet, App Service Plan within site, AKS Cluster within node pool, RG within Subscription, SQL Server within SQL Database, source Disk within Snapshot, VM within attached Disk)
networkGeneric network connectivity (NIC to subnet, NSG associations, DNS links, gateway connections, App Insights to workspace, Web App to App Insights, AKS / Redis / ACI to subnet, APIM to subnet)
network.peeringVNet peerings
network.vpnVPN gateway connections
network.bgpExpressRoute circuit connections
dependencyPrivate Endpoint to PaaS target (Web App, Function App, Key Vault, Container Registry, Recovery Services Vault, AKS cluster, Service Bus, Event Hubs, APIM)
dependency.storagePrivate Endpoint to Storage Account
dependency.databasePrivate Endpoint to database (SQL Server, Cosmos DB, Redis)

Group types

OSIRIS JSON group typeUsed for
logical.subscriptionTop-level subscription group
logical.resourcegroupResource group groups (children of the subscription)
container.regionOne group per distinct provider.region observed in the subscription, membering every resource in that region. Region global and empty-region resources are skipped (they are not geographically scoped). The boundary token is <subscription-id>/<region>, so groups never collide across subscriptions.

Resource types

Resource types follow the OSIRIS JSON v1.0 specification. Standard types are used where defined; Azure-specific types use the osiris.azure.* namespace.

Standard types:

  • container.resourcegroup - Resource groups
  • network.vpc - Virtual networks
  • network.subnet - Subnets
  • network.interface - Network interfaces
  • network.security.group - Network security groups
  • network.loadbalancer - Load balancers (L4 and L7 / Application Gateway)
  • network.firewall - Azure Firewalls
  • compute.vm - Virtual machines

Extensions (osiris.azure)

Azure-specific data that does not map to portable OSIRIS JSON properties is emitted under the osiris.azure extension namespace. This follows the OSIRIS JSON spec: properties holds common / portable data, extensions holds vendor-specific deep data. Extensions are only emitted under --purpose audit.

Representative extensions include:

OSIRIS JSON Resource typeSelected extension fields
network.interfaceenable_accelerated_networking, effective_routes[]
network.security.groupsecurity_rules[], default_security_rules[]
osiris.azure.expressroutesku, sku_tier, service_provider, peerings[] (BGP peering type, state, peer ASN, VLAN ID, address prefixes)
osiris.azure.webapp / osiris.azure.functionappmanaged_identity, outbound_vnet_routing, private_endpoint_connection_ids[], app_insights_id
osiris.azure.storageaccount / osiris.azure.keyvault / osiris.azure.containerregistry / osiris.azure.recoveryvault / osiris.azure.sqlserver / osiris.azure.cosmosaccountprivate_endpoint_connection_ids[]
osiris.azure.applicationinsightsworkspace_resource_id (bound Log Analytics workspace)
osiris.azure.loganalyticscustomer_id (workspace UUID used by KQL; not a secret)

Provider metadata

Every resource includes provider.type with the native ARM resource type (e.g. Microsoft.Network/virtualNetworks, Microsoft.Compute/virtualMachines). Cross-subscription stubs include provider.subscription with the remote subscription ID. All resources include provider.source set to azure-cli.

Resource IDs

Azure resource IDs follow the pattern azure::<ARM-resource-id>, using the full ARM resource ID as the native identifier. This ensures globally unique, deterministic IDs that survive cross-subscription correlation.

Region canonicalization

provider.region and metadata.scope.regions are canonicalized to Azure’s slug form (lowercase, no spaces). The az CLI returns location inconsistently across resource types: most ARM resources use westeurope / eastus2, while App Service Plans and Web Apps surface the display form (West Europe). The producer normalizes to the slug so a single-region subscription does not appear as two regions in metadata.scope.regions.

RBAC requirements

Permission levelWhat gets collected
ReaderAll resource types, properties, extensions (NSG rules, ER peerings, gateway connections, VNet peerings, DNS links, Private Endpoint to target edges, App Service to App Insights, AKS, container, database, messaging and observability resources)
Reader + effectiveRouteTable/actionEverything above + NIC effective routes
Network Contributor / OwnerFull dataset without restrictions

The producer tests permission on the first NIC and gracefully skips effective route collection if the permission is denied. All other data is collected regardless.

Examples

Single subscription

We are going to explore a single subscription in our tenant and generate from Microsoft Azure an OSIRIS JSON document.

osirisjson-producer azure -S a1b2c3d4-e5f6-7890-abcd-ef1234567890 --purpose audit

OSIRIS JSON output document (trimmed, --purpose audit):

{
  "$schema": "https://osirisjson.org/schema/v1.0/osiris.schema.json",
  "version": "1.0.0",
  "metadata": {
    "generator": {
      "name": "osirisjson-producer-azure",
      "version": "0.4.0",
      "url": "https://osirisjson.org"
    },
    "scope": {
      "name": "a1b2c3d4-e5f6-7890-abcd-ef1234567890 - my-nonprod-subscription",
      "purpose": "audit",
      "providers": ["azure"],
      "accounts": ["f1e2d3c4-b5a6-9078-fedc-ba9876543210"],
      "subscriptions": ["a1b2c3d4-e5f6-7890-abcd-ef1234567890"],
      "regions": ["westeurope"]
    }
  },
  "topology": {
    "resources": [
      {
        "id": "azure::/subscriptions/a1b2c3d4/resourceGroups/network-rg/providers/Microsoft.Network/virtualNetworks/hub-vnet",
        "type": "network.vpc",
        "name": "hub-vnet",
        "status": "active",
        "provider": {
          "name": "azure",
          "native_id": "/subscriptions/a1b2c3d4/resourceGroups/network-rg/providers/Microsoft.Network/virtualNetworks/hub-vnet",
          "type": "Microsoft.Network/virtualNetworks",
          "region": "westeurope",
          "source": "azure-cli",
          "subscription": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
          "tenant": "f1e2d3c4-b5a6-9078-fedc-ba9876543210"
        },
        "properties": {
          "resource_group": "network-rg",
          "address_space": ["10.0.0.0/16"],
          "dns_servers": ["10.0.0.4"],
          "subnet_count": 4,
          "enable_ddos_protection": false,
          "peerings": [
            {
              "name": "hub-to-spoke",
              "peering_state": "Connected",
              "remote_vnet_id": "/subscriptions/a1b2c3d4/.../spoke-vnet",
              "allow_gateway_transit": true,
              "allow_forwarded_traffic": true
            }
          ]
        }
      },
      {
        "id": "azure::/subscriptions/a1b2c3d4/resourceGroups/data-rg/providers/Microsoft.Storage/storageAccounts/mystg",
        "type": "osiris.azure.storageaccount",
        "name": "mystg",
        "status": "active",
        "provider": {
          "name": "azure",
          "native_id": "/subscriptions/a1b2c3d4/resourceGroups/data-rg/providers/Microsoft.Storage/storageAccounts/mystg",
          "type": "Microsoft.Storage/storageAccounts",
          "region": "westeurope",
          "source": "azure-cli",
          "subscription": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
          "tenant": "f1e2d3c4-b5a6-9078-fedc-ba9876543210"
        },
        "properties": {
          "resource_group": "data-rg",
          "sku_tier": "Standard",
          "sku_name": "Standard_LRS",
          "kind": "StorageV2",
          "access_tier": "Hot",
          "https_only": true,
          "min_tls_version": "TLS1_2",
          "public_network_access": "Disabled",
          "allow_blob_public_access": false
        },
        "extensions": {
          "osiris.azure": {
            "private_endpoint_connection_ids": [
              "/subscriptions/a1b2c3d4/.../privateEndpoints/pe-mystg"
            ]
          }
        }
      }
    ],
    "connections": [
      {
        "source": "azure::/subscriptions/a1b2c3d4/.../subnets/default",
        "target": "azure::/subscriptions/a1b2c3d4/.../virtualNetworks/hub-vnet",
        "type": "contains",
        "direction": "forward"
      },
      {
        "source": "azure::/subscriptions/a1b2c3d4/.../privateEndpoints/pe-mystg",
        "target": "azure::/subscriptions/a1b2c3d4/.../storageAccounts/mystg",
        "type": "dependency.storage",
        "direction": "forward"
      }
    ],
    "groups": [
      {
        "id": "azure::subscription::a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "type": "logical.subscription",
        "name": "my-nonprod-subscription",
        "children": [
          "azure::resourcegroup::network-rg",
          "azure::resourcegroup::data-rg"
        ]
      },
      {
        "id": "azure::region::a1b2c3d4-e5f6-7890-abcd-ef1234567890/westeurope",
        "type": "container.region",
        "name": "westeurope",
        "members": [
          "azure::/subscriptions/a1b2c3d4/.../virtualNetworks/hub-vnet",
          "azure::/subscriptions/a1b2c3d4/.../storageAccounts/mystg"
        ]
      }
    ]
  }
}

The same run with the default --purpose documentation returns the identical resource graph, but with the properties and extensions maps stripped from each resource, connection and group, suiting it for high-level topology views and documentation.

edit_note

Help improve this page

Found an issue or want to contribute? Open an issue.