Skip to content

Scenario: MQ-9B Multi-Tenant Tenancy v0.2.0

This scenario illustrates how the Node Manifest tenancy block in schemaVersion 0.2.0 is used for a realistic multi-tenant mission. It uses the manifest fixture examples/mq9b-multitenant.node-manifest.0.2.0.json and describes an RCAF MQ-9B-style remotely piloted aircraft operating over the Canadian Arctic on behalf of several federal principals at once.

In this schema line the tenancy block is descriptive only. It records who the manifest is intended to serve without changing how manifests are selected or when they are considered valid. The envelope semantics from ENVELOPE-v0.2.0.md still fully determine which manifest is in force at any given instant. Tenancy simply answers the question "who was this node working for?" in a stable, machine-readable way.

Context: a multi-agency Arctic patrol

Canada's northern and Arctic approaches are routinely patrolled by joint task forces that serve more than one departmental master at a time. A single long-endurance sortie may need to satisfy defence sovereignty tasks for the Canadian Joint Operations Command, civil surveillance and pollution monitoring tasks for Transport Canada's National Aerial Surveillance Program, and safety and ice-awareness tasks for the Canadian Coast Guard. These missions are already planned and briefed as "whole-of-government" patrols; the tenancy block makes that structure explicit in the manifest.

In this scenario, the node identified as ca.rpas.mq9b-001 is an MQ-9B-style RPAS assigned to an Arctic maritime domain awareness patrol in the eastern approaches. The sortie is led as a national task under CJOC, but it is expected to collect data and deliver products for multiple federal partners during the same flight window.

The manifest

The manifest below is the multitenant variant of the earlier envelope-only example. It binds the contract to the specific node and time window via the envelope fields and declares three tenant lanes in the tenancy block:

{
  "schemaVersion": "0.2.0",
  "kind": "node-manifest",
  "manifestId": "urn:example:manifest:ca.rpas.mq9b-001:2025-01-10T12:00:00Z:multitenant",
  "nodeId": "ca.rpas.mq9b-001",
  "issuedAt": "2025-01-10T12:00:00Z",
  "validity": {
    "notBefore": "2025-01-10T12:15:00Z",
    "notAfter": "2025-01-10T16:15:00Z",
    "graceSeconds": 300
  },
  "tenancy": {
    "tenants": [
      {
        "tenantId": "ca.dnd.cjoc",
        "displayName": "Canadian Joint Operations Command",
        "notes": "Lead defence tenant for Arctic patrol."
      },
      {
        "tenantId": "ca.tc.nasp",
        "displayName": "Transport Canada NASP",
        "notes": "Pollution and shipping surveillance."
      },
      {
        "tenantId": "ca.ccg",
        "displayName": "Canadian Coast Guard",
        "notes": "Ice, SAR, and environmental response."
      }
    ]
  }
}

The envelope fields (schemaVersion, kind, manifestId, nodeId, issuedAt, and validity) behave exactly as in the envelope scenario. At any time between notBefore and the effective expiry defined by notAfter and graceSeconds, this manifest is eligible to be selected for node ca.rpas.mq9b-001. Outside that window, the node has no active manifest unless another manifest for the same node is also present and eligible.

The tenancy block does not affect this selection logic. Whether or not tenancy is present, the reference helper selectActiveManifestForNode chooses the in-force manifest based solely on envelope fields.

Tenant lanes and their meaning

Each entry in tenancy.tenants is a tenant lane object. In this version the only required field is tenantId. It is an opaque, stable identifier for a mission principal. The manifest above uses three illustrative tenantIds:

ca.dnd.cjoc identifies the Canadian Joint Operations Command as the lead defence tenant. In practice this lane stands for national defence objectives such as air and maritime sovereignty, detection of foreign military activity, and contributions to NORAD or allied surveillance. The notes field reminds operators and auditors that this is the primary defence lane for the sortie.

ca.tc.nasp identifies Transport Canada's National Aerial Surveillance Program as a civil surveillance tenant. This lane captures tasks such as spotting oil pollution, monitoring shipping patterns, and verifying vessel behaviour against regulations. It signals that some portion of the sortie's sensing and reporting is intended to fulfil NASP's mandate.

ca.ccg identifies the Canadian Coast Guard as a safety and response tenant. This lane covers objectives like ice reconnaissance, search-and-rescue overwatch, and environmental response support. It reflects the Coast Guard's role in Arctic safety and presence, even though the platform itself is operated by the air force.

From the manifest's point of view, all three lanes are peers. The schema does not treat one as "primary" and others as "secondary"; that distinction, if needed, would be expressed in later mission content and policy blocks. The key guarantee at this stage is that if a receiver sees a manifest with these tenantIds, it can unambiguously say that the sortie was flown on behalf of each of these principals.

Relationship to runtime behaviour

In schemaVersion 0.2.0, tenancy is deliberately semantics-light. Runtimes and planners may use the tenancy block to annotate logs, UIs, or receipts with tenant context, but they must not allow it to change manifest selection, validity, or safety behaviour. Two manifests that are identical in their envelope and differ only in tenancy are considered equally eligible; the usual issuedAt and manifestId rules break any ties.

This separation keeps the core rules simple and deterministic. The envelope defines when a manifest applies to a node. Tenancy simply records the declared tenant set for that contract. Later schema versions will introduce richer per-tenant semantics - such as separate policy digests, classification ceilings, and evidence lanes keyed by tenantId - building on this basic naming construct rather than modifying it.

How to read and use this scenario

This scenario is intended as a worked example for implementers and reviewers. It shows how a single manifest in the 0.2.0 schema line can describe a multi-agency patrol on a single node, using the tenancy block to make the multi-tenant nature explicit without changing any of the envelope mechanics.

Producers can use this pattern whenever a sortie clearly serves multiple identifiable principals. They mint a unique manifestId for the node and time window, bind it to the node via nodeId, set an issuedAt and optional validity window, and then populate tenancy.tenants with one entry per mission principal, each with a stable tenantId and optional descriptive fields. Consumers that care about tenancy can use these lanes as keys in their own systems; consumers that do not can safely ignore the tenancy block entirely.