Skip to content

Node Manifest Tenancy v0.2.0

This document is the normative description of the Node Manifest tenancy block for schemaVersion 0.2.0. The tenancy block is an optional structure that allows producers to declare which tenants a given manifest is intended to serve. In this version it is a naming construct only; it does not yet drive runtime enforcement or access control. Its purpose is to give all parties a stable way to answer the question "who was this node working for?" without having to infer that from mission prose or out-of-band metadata.

The JSON Schema at schema/node-manifest.v0.schema.json describes the shape of the tenancy block. This document defines the meaning and expected behaviour of the fields exposed there. If there is any ambiguity in how to interpret a field, this text is definitive.

Tenancy object

When present, the top-level tenancy field of a Node Manifest is an object with a single required field, tenants. The tenants array must contain at least one entry and each entry must be a well-formed tenant lane as described below. Producers must not emit a tenancy object with an empty tenants array. Consumers that encounter such a manifest may treat it as if the tenancy field were absent.

The absence of a tenancy object means that the producer has not declared tenants for this manifest. Consumers must not attempt to guess or invent tenant information in that case; they may attach their own deployment-specific metadata alongside the manifest if needed, but that metadata is outside the scope of this specification.

Tenant lanes

Each element of the tenancy.tenants array is a tenant lane object. In schemaVersion 0.2.0 the tenant lane has one required field, tenantId, and optional descriptive fields, displayName and notes. Producers may attach additional fields, but those have no defined semantics in this version.

The tenantId field is a stable identifier for a mission principal. It is an opaque string from the schema's point of view; it may be a URN, an internal registry key, or any other naming scheme chosen by the deployment. Producers must ensure that tenantId values are unique within the tenancy.tenants array of a manifest. They should also strive to keep tenantId stable over time for a given real-world principal so that different manifests referring to the same tenant can be correlated. For example, if a particular maritime security operations centre is treated as a tenant, producers should not alternate between two different identifiers for it across manifests.

Consumers must treat tenantId as an opaque token. They may use it as a key in their own databases, correlate receipts or mission products against it, and display it in user interfaces, but they must not assume any structure or semantics beyond uniqueness within the manifest.

The displayName field, when present, is a human-readable label for the tenant lane. It is intended for displays, logs, and briefing products. Producers may set it to any useful description; common patterns include the organisation name or a short code. Consumers must not rely on displayName for identity; it is descriptive only.

The notes field, when present, is free-text intended for operators and planners. It can capture additional context such as "DFO fisheries enforcement only" or "NATO coalition lane for Op NANOOK 2025". This field has no runtime semantics. Producers are free to omit it. Consumers must not attach any behavioural meaning to its contents.

Additional fields on the tenant lane object are allowed to support experimentation and deployment-specific metadata. Consumers that do not explicitly implement such extensions must ignore them rather than rejecting the manifest.

Relationship to envelope and selection

The tenancy block does not change how manifests are selected or considered eligible at a given time. The reference helper selectActiveManifestForNode ignores tenancy and uses only the envelope fields defined in spec/ENVELOPE-v0.2.0.md. Producers and consumers must not allow tenancy to influence selection; two manifests that are identical in their envelope but differ only in tenancy are considered equally eligible and the usual issuedAt and manifestId tie-breakers apply.

This separation is intentional. The envelope defines when a manifest applies to a node; tenancy simply records who it is for. Later revisions of the specification will introduce richer semantics on top of tenant lanes (such as per-tenant policies and evidence), but those will build on this basic naming construct rather than changing it.

Although the tenancy block is optional and descriptive in this version, producers are strongly encouraged to populate it whenever a manifest is clearly being issued on behalf of identifiable principals. Over time this will create a consistent, queryable record of which sorties served which tenants, even before the full mission fabric semantics are in place.

In particular, multi-agency and coalition missions should declare each major stakeholder as a tenant lane. For example, a single patrol manifest might name the joint operations command, the coast guard, and a transport ministry as tenants. Doing so does not change runtime behaviour today, but it prepares the ground for later, more expressive contracts and receipts that can be keyed off the same tenantId values.