3 Schema structure
This section defines the structure of an OSIRIS document at the JSON schema level. It describes the top-level object, required fields and the organization of topology data.
OSIRIS documents are JSON objects that conform to RFC 8259. The schema is formally defined using JSON Schema (see Appendix A).
3.1 Top-Level object
3.1.1 Structure
An OSIRIS document MUST be a JSON object containing at least the following top-level fields:
{
"version": "1.0.0",
"metadata": { ... },
"topology": { ... }
}
3.1.2 Required fields
The following fields are REQUIRED at the top level:
version(string): The OSIRIS specification version to which this document conforms. See section 3.2 for version string format and semantics.metadata(object): Contextual information about the document’s origin, scope and generation. See section 3.3 for metadata object structure.topology(object): The infrastructure topology data, including resources, connections and groups. See section 3.4 for topology object structure.
3.1.3 Additional top-level fields
OSIRIS v1.0 defines only version, metadata and topology at the top level.
Producers MAY include $schema. Other top-level fields SHOULD NOT be emitted.
Consumers MUST ignore unknown top-level fields and MAY emit warnings about unrecognized fields. This ensures forward compatibility if future OSIRIS versions introduce additional top-level constructs (e.g. signatures, links, fragments).
3.1.4 Document size considerations
OSIRIS does not impose a maximum document size, but producers SHOULD consider practical limits:
- Large topologies (thousands of resources) may benefit from splitting across multiple documents.
- Consumers may have memory or processing constraints that limit document size.
- Network transmission and storage efficiency favor reasonably-sized documents.
Producers generating large topologies MAY split infrastructure across multiple OSIRIS documents based on logical boundaries (e.g. per region, per environment, per account) and document the scope in metadata.
3.2 Version
3.2.1 Field definition
The version field is a REQUIRED string at the top level of every OSIRIS document. It declares which version of the OSIRIS specification the document conforms to.
3.2.2 Version string format
The version string MUST follow semantic versioning principles as defined in Semantic Versioning 2.0.0.
Version strings MUST use the format: MAJOR.MINOR.PATCH
Examples:
1.0.0- OSIRIS version 1.0.01.1.0- OSIRIS version 1.1.0 (minor update, backward compatible)2.0.0- OSIRIS version 2.0.0 (major update, may contain breaking changes)
3.2.3 Version semantics
Version numbers convey compatibility guarantees:
-
MAJOR version increments indicate breaking changes that are not backward compatible. Documents with different MAJOR versions may use incompatible schema structures or semantics.
-
MINOR version increments indicate backward-compatible additions or enhancements. New optional fields, resource types or connection types may be introduced. Existing fields and semantics remain unchanged.
-
PATCH version increments indicate backward-compatible fixes or clarifications to the specification that may affect interpretation or validation behavior, but do not change schema structure.
3.2.4 Consumer version handling
Consumers MUST check the version field before processing an OSIRIS document.
Consumers SHOULD implement the following compatibility logic:
-
Different MAJOR version: Document is unsupported. Consumer SHOULD reject the document or emit an error.
-
Same MAJOR version: Document is supported.
- If the document has a higher MINOR version than the consumer supports, the consumer MUST ignore unknown fields and MAY emit informational warnings.
- If the document has the same MINOR version and a higher PATCH version, the consumer MUST accept the document.
Example:
- Consumer supports OSIRIS
1.0.0 - Document version
1.0.5> Accept (same major.minor, higher patch) - Document version
1.2.0> Accept, ignore unknown fields, MAY warn (same major, higher minor) - Document version
2.0.0> Reject or error (different major)
3.2.5 Version field placement
The version field appears at the document’s top level only. It does not appear in nested objects (metadata, resources, connections, groups).
Metadata MAY include generator or tool version information, but this is distinct from the OSIRIS specification version declared in the top-level version field.
3.3 Metadata Object
3.3.1 Structure
The metadata field is a REQUIRED object at the top level of every OSIRIS document. It provides contextual information about the document’s generation, scope and provenance as described in section 2.4.
A minimal metadata object:
{
"timestamp": "2025-12-18T14:30:00Z"
}
3.3.2 Required fields
The following field is REQUIRED within the metadata object:
timestamp(string): An ISO 8601 formatted timestamp indicating when the topology snapshot was generated. The timestamp MUST include date and time and MUST include a timezone designator (eitherZfor UTC or an offset such as+02:00or-05:00).
[!NOTE] OSIRIS recommends using RFC 3339 compatible timestamps for maximum interoperability.
Examples of valid timestamps:
2025-12-18T14:30:00Z(UTC)2025-12-18T14:30:00+00:00(UTC with offset notation)2025-12-18T09:30:00-05:00(Eastern Time with offset)
[!WARNING] Timestamps without timezone designators (e.g.
2025-12-18T14:30:00) are NOT VALID.
3.3.3 Optional fields
The following fields are OPTIONAL but RECOMMENDED:
generator(object): Information about the tool or system that produced the document. If present, the generator object SHOULD contain:name(string): Name of the generating tool or systemversion(string): Version of the generating toolurl(string, optional): Reference URL for the generator
Example:
{
"name": "osiris-aws-parser",
"version": "1.0.0",
"url": "https://github.com/osirisjson/osiris-producers/hyperscalers/aws/"
}
scope(object): Description of what infrastructure is represented in this document. The scope object MAY contain:name(string): Human readable name for this topologydescription(string): Textual description of the scopeproviders(array of strings): List of infrastructure providers included (e.g.["aws", "azure"])regions(array of strings): Geographic regions or zones includedaccounts(array of strings): Account, subscription or project identifiersenvironments(array of strings): Environment designations (e.g.["production", "staging"])sites(array of strings): On-premises sites or facility identifiers (e.g.["MXP-DC-1", "AGP-DC-2"])clusters(array of strings): Cluster identifiers (e.g.["proxmox-prod"],["vsphere-cluster-a"])intended_audience(array of strings): Indicate the intended teams or an external auditor (e.g.["compliance-team", "infrastructure-team", "SGS", "BSI"])purpose(string): Indicate the purpose of the document (e.g."compliance")
[!NOTE] Detailed physical hierarchy (building/floor/room/row/rack) SHOULD be represented using groups in the topology.
Hyperscaler example:
{
"name": "Production Infrastructure - US East",
"providers": ["aws"],
"regions": ["us-east-1", "us-east-2"],
"accounts": ["1234567890"],
"environments": ["production"]
}
3.3.4 Extension fields
The metadata object MAY contain additional fields beyond those defined above. These extension fields enable producers to include:
- Custom organizational metadata (cost centers, ownership, compliance tags)
- Source system references (API endpoints, query parameters)
- Validation or processing hints
- Vendor-specific context
Consumers MUST ignore unrecognized metadata fields. Consumers MAY preserve unknown fields when transforming or re-exporting OSIRIS documents, provided such fields do not violate security or redaction requirements.
3.3.5 Metadata object size
Metadata objects SHOULD be concise. Large amounts of auxiliary data (e.g. full audit logs, detailed cost breakdowns) SHOULD be stored externally and referenced via URL or identifier rather than embedded directly in metadata.
3.3.6 Complete metadata example
Hyperscaler example
{
"timestamp": "2025-12-18T14:30:00Z",
"generator": {
"name": "osiris-aws-parser",
"version": "1.0.0"
},
"scope": {
"name": "Production multi Hyperscalers topology",
"description": "Primary production workloads across AWS and Azure",
"providers": ["aws", "azure"],
"regions": ["us-east-1", "eastus"],
"environments": ["production"]
},
"tags": {
"cost_center": "sw-development",
"compliance": "sox"
}
}
On-premise example
{
"timestamp": "2025-12-18T14:30:00Z",
"generator": {
"name": "osiris-aws-parser",
"version": "1.0.0"
},
"scope": {
"name": "Hybrid production topology",
"description": "AWS workloads including on-prem DCs fabric with Proxmox cluster",
"providers": ["aws", "arista", "dell", "proxmox"],
"regions": ["eu-west-1"],
"sites": ["MXP-DC-1"],
"clusters": ["proxmox-prod-1"],
"environments": ["production"]
},
"tags": {
"owner": "it-systems-services",
"compliance": "iso27001"
}
}
3.4 Topology object
3.4.1 Structure
The topology field is a REQUIRED object at the top level of every OSIRIS document. It contains the infrastructure topology data: resources, connections between resources and logical or physical groupings.
A minimal valid topology object:
{
"resources": []
}
3.4.2 Required fields
The following field is REQUIRED within the topology object:
-
resources(array): An array of resource objects representing infrastructure components. Each resource object is defined in Chapter 4 (Resource Model).The resources array MAY be empty (representing a topology with no resources), but the field itself MUST be present.
3.4.3 Optional fields
The following fields are OPTIONAL:
-
connections(array): An array of connection objects representing relationships between resources. Each connection object is defined in Chapter 5 (Connection model).If omitted, the topology contains resources but no explicit relationships. Consumers SHOULD treat an absent
connectionsfield as equivalent to an empty array. -
groups(array): An array of group objects representing logical or physical collections of resources. Each group object is defined in Chapter 6 (Group model).
If omitted, the topology contains resources but no explicit grouping structure. Consumers SHOULD treat an absent groups field as equivalent to an empty array.
3.4.4 Field ordering
The order of resources, connections and groups arrays within the topology object is not semantically significant. Producers MAY emit these fields in any order.
However, for human readability and diff-friendliness, producers SHOULD use a consistent field order. The RECOMMENDED order is: resources, connections, groups.
3.4.5 Array element ordering
The order of elements within resources, connections and groups arrays is not semantically significant unless otherwise specified by consumer requirements.
Producers SHOULD consider stable, deterministic ordering (e.g. sorted by ID) to produce diff-friendly outputs when the same infrastructure is exported multiple times.
3.4.6 Referential integrity
Resources, connections and groups reference each other by identifier:
- Connections reference resources via
sourceandtargetfields - Groups reference resources via
membersarrays - Groups may reference other groups for hierarchical nesting
All identifier references MUST point to objects that exist within the same OSIRIS document. Cross-document references are not supported in OSIRIS v1.0.
Producers SHOULD validate referential integrity before emitting documents. Consumers MUST handle referential integrity violations gracefully (see chapter 9, section 9.3 for validation rules). Consumers MAY ignore invalid connections or groups while still processing valid resources.
3.4.7 Topology object example
Hyperscaler example
{
"resources": [
{
"id": "aws::i-0abc123def4567890",
"name": "production-web-server-01",
"type": "compute.vm",
"provider": {
"name": "aws",
"type": "AWS::EC2::Instance",
"native_id": "i-0abc123def4567890",
"region": "us-east-1",
"account": "123456789012"
},
"status": "active"
},
{
"id": "aws::myapp-prod-db",
"name": "production-postgresql-primary",
"type": "application.database",
"provider": {
"name": "aws",
"type": "AWS::RDS::DBInstance",
"native_id": "myapp-prod-db",
"region": "us-east-1",
"account": "123456789012"
},
"status": "active"
}
],
"connections": [
{
"id": "conn-web-to-db",
"source": "aws::i-0abc123def4567890",
"target": "aws::myapp-prod-db",
"type": "dependency",
"direction": "forward"
}
],
"groups": [
{
"id": "aws::vpc-0abc123def4567890",
"type": "network.vpc",
"members": ["aws::i-0abc123def4567890", "aws::myapp-prod-db"]
}
]
}
On-premise example
{
"resources": [
{
"id": "arista::MXP-SW-LEAF-01",
"name": "mxp-leaf-switch-01",
"type": "network.switch",
"provider": {
"name": "arista",
"type": "DCS-7050SX3-48YC12",
"native_id": "MXP-SW-LEAF-01"
},
"properties": {
"rack_unit_start": 12,
"rack_unit_height": 1,
"face": "front"
},
"location": {
"datacenter": "MXP",
"building": "01",
"floor": "F1",
"room": "105",
"rack": "R01",
"unit": 12
},
"status": "active"
},
{
"id": "dell::MXP-SRV-R98-001",
"name": "mxp-proxmox-host-01",
"type": "compute.server",
"provider": {
"name": "dell",
"type": "PowerEdge R770",
"native_id": "MXP-SRV-R98-001"
},
"properties": {
"rack_unit_start": 30,
"rack_unit_height": 2,
"face": "front",
"service_tag": "ABC1234"
},
"location": {
"datacenter": "MXP",
"building": "01",
"floor": "F1",
"room": "105",
"rack": "R98",
"unit": 30
},
"status": "active"
},
{
"id": "proxmox::vm-100",
"name": "mxp-production-web-01",
"type": "compute.vm",
"provider": {
"name": "proxmox",
"type": "VirtualMachine",
"native_id": "vm-100",
"cluster": "proxmox-prod-cluster"
},
"location": {
"datacenter": "MXP"
},
"status": "active"
}
],
"connections": [
{
"id": "conn-switch-to-server",
"source": "arista::MXP-SW-LEAF-01",
"target": "dell::MXP-SRV-R98-001",
"type": "network",
"properties": {
"source_interface": "Ethernet48",
"target_interface": "eno1",
"speed_gbps": 25
}
},
{
"id": "conn-vm-runs-on-host",
"source": "proxmox::vm-100",
"target": "dell::MXP-SRV-R98-001",
"type": "compute.runs.on",
"direction": "forward"
}
],
"groups": [
{
"id": "grp-mxp-dc1",
"type": "physical.datacenter",
"members": [],
"children": ["grp-mxp-f1"]
},
{
"id": "grp-mxp-f1",
"type": "physical.floor",
"members": [],
"children": ["grp-mxp-f1-row-a"]
},
{
"id": "grp-mxp-f1-row-a",
"type": "physical.row",
"members": [],
"children": ["grp-mxp-r01", "grp-mxp-r98"]
},
{
"id": "grp-mxp-r01",
"type": "physical.rack",
"members": ["arista::MXP-SW-LEAF-01"]
},
{
"id": "grp-mxp-r98",
"type": "physical.rack",
"members": ["dell::MXP-SRV-R98-001", "proxmox::vm-100"]
}
]
}
[!NOTE] Resource types and group types in this example (e.g.
application.database,network.vpc) are illustrative. The complete type taxonomy is defined in Chapter 7 (Resource type taxonomy) and section 6.2 (Group types). Identifiers are opaque strings and producers MAY use structured IDs based on specific naming conventions.
3.4.8 Empty topologies
A topology with no resources, connections or groups is valid:
{
"resources": []
}
When the resources array is empty, producers SHOULD either emit connections and groups as empty arrays or omit them entirely. Producers MUST NOT emit connections or groups that reference non-existent resources.
Empty topologies may represent:
- Newly provisioned environments awaiting resource deployment
- Filtered exports where no resources matched selection criteria
- Placeholder documents for testing or validation purposes
Consumers MUST handle empty topologies without error.