diff --git a/doc/Agentic.xml b/doc/Agentic.xml new file mode 100644 index 000000000..b0fbf29ef --- /dev/null +++ b/doc/Agentic.xml @@ -0,0 +1,4347 @@ + + + + + ONVIF Agentic Service Specification + ONVIF Agentic Spec + 26.12 + + ONVIF™ + www.onvif.org + + December, 2026 + + + + + + + 2026 + ONVIF™ All rights reserved. + + + Recipients of this document may copy, distribute, publish, or display this document so + long as this copyright notice, license and disclaimer are retained with all copies of the + document. No license is granted to modify this document. + THIS DOCUMENT IS PROVIDED "AS IS," AND THE CORPORATION AND ITS MEMBERS AND THEIR + AFFILIATES, MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT + LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, + NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF THIS DOCUMENT ARE SUITABLE FOR ANY PURPOSE; + OR THAT THE IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS. + IN NO EVENT WILL THE CORPORATION OR ITS MEMBERS OR THEIR AFFILIATES BE LIABLE FOR ANY + DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR + RELATING TO ANY USE OR DISTRIBUTION OF THIS DOCUMENT, WHETHER OR NOT (1) THE CORPORATION, + MEMBERS OR THEIR AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR (2) + SUCH DAMAGES WERE REASONABLY FORESEEABLE, AND ARISING OUT OF OR RELATING TO ANY USE OR + DISTRIBUTION OF THIS DOCUMENT. THE FOREGOING DISCLAIMER AND LIMITATION ON LIABILITY DO NOT + APPLY TO, INVALIDATE, OR LIMIT REPRESENTATIONS AND WARRANTIES MADE BY THE MEMBERS AND THEIR + RESPECTIVE AFFILIATES TO THE CORPORATION AND OTHER MEMBERS IN CERTAIN WRITTEN POLICIES OF + THE CORPORATION. + + + + 26.12 + Dec-2026 + + Ottavio Campana + + Initial release of Agentic Service Specification. + + + + + + Scope + This specification defines an MCP-based interface for ONVIF devices, enabling AI agents + to discover and use device capabilities without relying on SOAP. MCP is natively supported + by agentic clients and provides a standard way to expose device functions and metadata. + The objective is to broaden the range of clients that can interoperate with ONVIF + devices and to expose advanced, ready-to-consume device functions for AI agents. + + + + Background and Motivation +
+ Background + Traditional physical-security systems are built around devices that expose predefined + services, events, metadata, and configuration interfaces. ONVIF clients, including video + management systems, use these interfaces to configure devices and ingest information into + a site-centric operational view. + AI-enabled and agentic systems introduce additional consumers and interaction patterns. + These systems need to discover available capabilities, retrieve contextual information, + interpret semantically described data, and invoke permitted actions across devices, + analytics services, and other site systems. + The ONVIF Agentic Service connects these environments. It complements existing ONVIF + services by providing common information models and discovery mechanisms that can be used by + both traditional clients and AI-native applications. Initial use cases include a VMS + ingesting standardised site-centric metadata and an authorised AI application using MCP to + discover and access device configuration capabilities. +
+
+ Motivation + Without standardisation, AI integrations depend on vendor-specific data models, + capability descriptions, and agent tools. This increases integration cost and limits + portability across manufacturers and system components. + This specification defines the interoperable boundary between information producers and + consumers. It enables consistent exchange of semantic metadata, provenance, confidence, + spatial and temporal context, and capability descriptions, while reusing existing ONVIF + services and security mechanisms where applicable. + The objective is not to prescribe a complete agentic architecture or replace established + VMS workflows. The objective is to allow traditional physical-security systems and AI-native + systems to share trusted information and expose controlled functionality through + standardised contracts. +
+
+ + + Normative references + IETF RFC 4648 The Base16, Base32, and Base64 Data Encodings + <http://www.ietf.org/rfc/rfc4648.txt> + IETF RFC 5280 Internet X.509 Public Key Infrastructure Certificate and CRL Profile + <http://www.ietf.org/rfc/rfc5280.txt> + IETF RFC 6750 OAuth 2.0 Bearer Token Usage + <http://www.ietf.org/rfc/rfc6750.txt> + IETF RFC 7517 JSON Web Key (JWK) + <http://www.ietf.org/rfc/rfc7517.txt> + IETF RFC 7519 JSON Web Token (JWT) + <http://www.ietf.org/rfc/rfc7519.txt> + IETF RFC 8414 OAuth 2.0 Authorization Server Metadata + <http://www.ietf.org/rfc/rfc8414.txt> + IETF RFC 8446 TLS 1.3 + <http://www.ietf.org/rfc/rfc8446.txt> + IETF RFC 8785 JSON Canonicalization Scheme (JCS) + <http://www.ietf.org/rfc/rfc8785.txt> + IETF RFC 9562 Universally Unique IDentifiers (UUIDs) + <http://www.ietf.org/rfc/rfc9562.txt> + ISO 8601 Date and time — Representations for information interchange + <https://www.iso.org/standard/70907.html> + JSON-LD 1.1 + <https://www.w3.org/TR/json-ld11/> + LinkML Specification + <https://linkml.io/linkml/> + Model Context Protocol, 2025-11-25 + <https://modelcontextprotocol.io/specification/2025-11-25> + Model Context Protocol, 2026-07-28 + <https://modelcontextprotocol.io/specification/2026-07-28> + Model Context Protocol Tasks Extension + <https://modelcontextprotocol.io/extensions/tasks/overview> + MCP Events Extension — Design Sketch Proposal + <https://github.com/modelcontextprotocol/experimental-ext-triggers-events/blob/main/docs/design-sketch-proposal.md> + ONVIF Core Specification + <https://www.onvif.org/specs/core/ONVIF-Core-Specification.pdf> + ONVIF Media Signing Specification + <https://www.onvif.org/specs/stream/ONVIF-MediaSigning-Spec.pdf> + ONVIF Schema + <https://www.onvif.org/onvif/ver10/schema/onvif.xsd> + ONVIF Security Baseline Specification + <https://www.onvif.org/specs/srv/security/ONVIF-SecurityBaseline-Spec.pdf> + ONVIF Security Service Specification + <https://www.onvif.org/specs/core/ONVIF-Security-Specification.pdf> + W3C JSON Schema Draft-07 + <https://json-schema.org/draft-07/schema> + + + + Terms and Definitions +
+ Definitions + + + + + + + + Event Delivery + + + The MCP mechanisms by which an ONVIF Device makes LinkML-structured + detection events available to the ONVIF Client, either on a long-lived + events/stream request carried over Streamable HTTP (push) or via a + client-supplied HTTPS callback (webhook), as defined by the MCP Events + extension. + + + + + Keep-Alive (Heartbeat) + + + A periodic notifications/events/heartbeat message sent by an + ONVIF Device on an open events/stream response so that the ONVIF + Client can distinguish an idle stream from a dead one, and so that the client's + persisted cursor advances during quiet periods. The default interval is 30 + seconds and is configurable through the set_event_stream_parameters + function (see ). + + + + + LinkML Schema + + + A YAML document that defines the data structures and enumerations used by an + ONVIF Device for both event payloads and skill input parameters. + + + + + MCP (Model Context Protocol) + + + An open protocol for agentic tool invocation and data resource access. + + + + + MCP Host / Client + + + An ONVIF Client or other orchestrator that connects to one or more MCP Servers + to discover and invoke tools. + + + + + MCP Server + + + An ONVIF Device endpoint that exposes Tools, Resources, and optionally Prompts + via the MCP protocol. + + + + + Metadata Event + + + A JSON-LD payload, conforming to a registered LinkML schema, that an ONVIF + Device makes available as an MCP event each time a detection occurs. + + + + + OIDC Server / Authorization Server + + + An OpenID Connect server that issues signed ES256 JWTs; acts as the trust + anchor for the whole stack. + + + + + ONVIF Client (Video Management System) + + + An ONVIF client that also acts as an MCP Host, managing cameras and consuming + agentic analytics events. + + + + + ONVIF Device + + + An MCP Server that wraps one or more agentic analytics models and exposes them + as Skills (MCP Tools), together with a schema announcement and a metadata + publisher. + + + + + Schema Registry + + + A component within the ONVIF Client that stores parsed LinkML schema bundles + and validates incoming metadata events against them. + + + + + Skill + + + An MCP Tool exposed by an ONVIF Device, representing a single callable + operation (e.g. set detection region, adjust sensitivity). + + + + + +
+
+ Abbreviations + + + + + + + ECDSA + Elliptic Curve Digital Signature Algorithm + + + ES256 + ECDSA with SHA-256 and the secp256r1 (P-256) curve + + + HTTP + Hypertext Transfer Protocol + + + HTTPS + Hypertext Transfer Protocol Secure + + + JCS + JSON Canonicalization Scheme + + + JSON + JavaScript Object Notation + + + JSON-LD + JSON-based Serialization for Linked Data + + + JWT + JSON Web Token + + + JWK + JSON Web Key + + + JWKS + JSON Web Key Set + + + LinkML + Linked data Modeling Language + + + MCP + Model Context Protocol + + + mDNS + Multicast DNS + + + OID + Object Identifier + + + OIDC + OpenID Connect + + + PEM + Privacy-Enhanced Mail, the base64 container format for certificates + + + RBAC + Role-Based Access Control + + + RTSP + Real Time Streaming Protocol + + + SDK + Software Development Kit + + + TLS + Transport Layer Security + + + URI + Uniform Resource Identifier + + + UUID + Universally Unique Identifier + + + ONVIF Client + Video Management System + + + WSDL + Web Services Description Language + + + XSD + XML Schema Definition + + + YAML + Yet Another Markup Language + + + + +
+
+ + + Overview + Agentic configurations are handled through the Agentic Service. Agentic configurations are + used to configure and control the intelligent functions as defined in this specification. YAML + for this service is specified in http://www.onvif.org/yaml/agentic.yaml. + + Referenced namespaces (with prefix) + + + + + + + Prefix + + + Namespace URI + + + + + + + env + + + http://www.w3.org/2003/05/soap-envelope + + + + + ter + + + http://www.onvif.org/ver10/error + + + + + xs + + + http://www.w3.org/2001/XMLSchema + + + + + tt + + + http://www.onvif.org/ver10/schema + + + + + tag + + + http://www.onvif.org/yaml/agentic + + + + + tns1 + + + http://www.onvif.org/ver10/topics + + + + + onvif + + + https://www.onvif.org/ver10/agentic/linkml/ + + + + +
+
+ + + Building Blocks + +
+ MCP — The Agentic Tool Interface + The Model Context Protocol (MCP) is an open, JSON-RPC 2.0 based protocol designed to + connect AI language models and agents to external tools and data sources. In the ONVIF + agentic stack, MCP serves as the standardised interface layer between the ONVIF Client + (acting as an MCP Host) and each ONVIF Device (acting as an MCP Server). Adopting MCP means + that any ONVIF Client can invoke any compliant ONVIF Device without requiring a + vendor-specific driver. + +
+ Protocol Primitives + MCP defines three categories of server-side object that a host may discover and + use: + + + Tools are callable operations with a named identifier, a human-readable + description, and an inputSchema (JSON Schema) that fully describes the + expected arguments. In the ONVIF agentic stack, Tools are called + Skills and represent ONVIF Device capabilities such as + configuring a detection region or querying service status. The ONVIF Client invokes a + Skill by sending a tools/call JSON-RPC request over the Control + Plane. + + + Resources are read-only data objects accessible via resources/list + and resources/read requests. In this specification, Resources carry the + LinkML schema bundles that describe the event payloads and skill input parameters of + the ONVIF Device. Each schema resource carries the MIME type + application/linkml+yaml. + + + Prompts are optional server-defined interaction templates. This specification does + not mandate Prompt support; ONVIF Devices MAY expose Prompts for human-in-the-loop + workflows. + + +
+ +
+ Transport Modes + This specification normatively uses the Streamable HTTP transport. The ONVIF Client + sends JSON-RPC requests as HTTP POST to the ONVIF Device's /mcp endpoint, and + the ONVIF Device returns each response on the same request/response exchange, as defined + by the Streamable HTTP transport in MCP 2026-07-28. Metadata events are delivered to the + ONVIF Client on the Server-Sent Events (SSE) response stream of a long-lived + events/stream POST request (push delivery), or delivered out-of-band via + the events/subscribe webhook mechanism (see ). The events/stream response + carries only notifications/events/* messages for the subscription it was + opened for; it is not a general server-to-client channel. An ONVIF Device conforming to + this specification shall support the Streamable HTTP transport and shall support + events/stream; support for events/subscribe webhook delivery + is OPTIONAL but RECOMMENDED for deployments where the ONVIF Client is not able to keep a + stream open, for example behind a proxy that terminates idle connections. +
+ +
+ Protocol Version + This specification normatively requires MCP 2026-07-28. Implementations conforming to + this specification shall not use the session-era MCP 2025-11-25 protocol. + MCP 2026-07-28 is a fully stateless protocol. There is no session establishment + handshake and no Mcp-Session-Id header. Every HTTP request is self-contained: + the ONVIF Client includes the MCP-Protocol-Version: 2026-07-28 request header + on each call, together with the Authorization: Bearer JWT header. The ONVIF + Device shall reject requests that carry a protocol version other than + 2026-07-28 with HTTP 400. + Service discovery uses the server/discover JSON-RPC method, which + replaces the initialize / initialized handshake of earlier + versions. The response carries the server's capability flags (tools, resources, prompts) + and its human-readable identity. As required by MCP 2026-07-28, the ONVIF Device shall + implement server/discover. The ONVIF Client may call + server/discover before issuing other requests to learn supported versions + and capabilities, but it is not required to call it first and may invoke any operation + directly and handle UnsupportedProtocolVersionError. + The stateless model is the correct choice for the ONVIF Agentic Service use case: + ONVIF Devices are deployed as horizontally-scalable endpoints behind load balancers, and + pinning a ONVIF Client to a specific server instance via a session identifier would + prevent transparent failover and scaling. With MCP 2026-07-28, every request can be routed + to any instance of the ONVIF Device without loss of state. + Push event delivery does not reintroduce session state. The state associated with an + events/stream request is scoped to the lifetime of that request only, and + the subscription is fully described by the request parameters (name, + arguments, cursor). If the stream is interrupted, the ONVIF + Client reopens it — possibly against a different instance of the ONVIF Device — passing + the last cursor it persisted, and delivery resumes from that position (see ). +
+
+ +
+ LinkML — Schema Definition Language + LinkML (Linked data Modeling Language) is an open schema definition language that + describes data structures in YAML. In the ONVIF agentic stack, LinkML is the normative + language for defining both the structure of metadata events (delivered via + events/stream or webhook) and the argument shapes of Skills invoked via + tools/call. LinkML defines the schema; JSON-LD (see + ) is the runtime wire format that carries instances of that + schema. + +
+ Schema Structure + A LinkML schema document is a YAML file with the following top-level keys: + + + id: a globally unique URI that identifies the schema module. Each + module of the bundle defined by this specification declares its own, for example + https://www.onvif.org/ver10/agentic/base/linkml/. It names a document, + and it is the identifier under which an ONVIF Client registers the compiled schema. It + is not the value carried by @context in a payload; the distinction is set + out in . + + + prefixes and default_prefix: the mapping from short + prefixes to namespace URIs, and the prefix under which the classes of the module are + placed. Every module of this specification declares + onvif: https://www.onvif.org/ver10/agentic/linkml/ and sets + default_prefix: onvif, so the classes of all modules share one + vocabulary namespace irrespective of which document declares them. The class + VehicleObservation is therefore identified by + https://www.onvif.org/ver10/agentic/linkml/VehicleObservation. This is + the mechanism on which the collision safety of vendor extensions rests, as described + in . + + + imports: a list of modules whose definitions are made available to + the importing document. The bundle defined by this specification is listed in + . An ONVIF Device shall not redefine a + class, a type or an enumeration that the bundle already declares. + + + classes: named data structures with typed attributes, optional + constraints (minimum_value, maximum_value, + minimum_cardinality), and documentation strings. Every class that + describes a unit of metadata derives, directly or indirectly, from + InformationItem (see ). + + + enums: closed value sets used for categorical fields, such as + VehicleType, VehicleUse and + DigestAlgorithm. A value set is closed in a stronger sense than it may + appear: an enumeration reached through imports cannot be extended with + further permissible values, so a vendor that needs a value the enumeration does not + provide cannot add one. This is why the enumerations of this specification that + classify an observed property provide both an Other value, for a property + that was determined but does not appear in the list, and an Unknown value, + for a property that could not be determined at all. + + +
+ +
+ The Four Roles of a URI + Four distinct kinds of URI appear in a metadata payload and in the schema documents + behind it. They look alike, and treating one as another leads an ONVIF Client to look up + an artefact that does not exist, so each is stated here once and used consistently + throughout this specification. + + + A schema identifier is the id of a LinkML module, + such as https://www.onvif.org/ver10/agentic/base/linkml/. It names a + document. + + + The vocabulary namespace is the expansion of + default_prefix, which is + https://www.onvif.org/ver10/agentic/linkml/ for every module of this + specification. It is the namespace in which a bare class name is interpreted, and it is + the value carried by @context in a payload, as specified in + . + + + A class identifier is a class name resolved within a + vocabulary namespace, such as + https://www.onvif.org/ver10/agentic/linkml/VehicleObservation. It is the + canonical identity of a metadata class, and therefore of an event type. + + + An MCP resource URI is the address at which an ONVIF Device + serves a schema document over MCP, and is the value an ONVIF Client passes to + resources/read, as shown in + . It is a property of the device that + serves the document, not of the schema the document defines: two devices may serve the + same schema at different resource URIs. + + +
+ +
+ Dual Role: Event Schema and Skill Input Schema + The same LinkML model serves two distinct purposes within the stack: + + + For metadata events, the compiled JSON Schema derived from the LinkML model is used by + the ONVIF Client LinkML Validator to check every incoming metadata event for + structural correctness — required fields, numeric ranges, and valid enum values. + + + For Skill invocation, the inputSchema field of each MCP Tool (Skill) + definition is also derived from the same LinkML model. This guarantees that the + coordinate spaces, unit definitions, and vocabulary used to configure the ONVIF Device + (e.g., a detection region polygon) are identical to those used to report events, + eliminating a class of integration errors that arise when configuration and reporting + use incompatible data models. + + +
+ +
+ Compilation to JSON Schema + The LinkML toolchain provides a generator that produces a JSON Schema document from a + LinkML YAML source. This compiled JSON Schema is used in two places: + + + First, it is embedded in the inputSchema field of each MCP Tool + definition returned by tools/list. The ONVIF Client can validate skill arguments + against this schema before sending a tools/call request, providing early + client-side error detection. + + + Second, a copy of the compiled schema is stored in the ONVIF Client Schema + Registry after schema discovery. The registry uses the compiled schema to validate + every incoming metadata event, whether delivered via events/stream or + delivered via webhook, before the ONVIF Client processes it. + + + ONVIF Devices shall pre-compile their LinkML schemas at build time and include the + compiled JSON Schema in Tool definitions. The source YAML shall also be exposed as a + schema Resource so that the ONVIF Client can re-compile or audit the schema + independently. +
+ +
+ ONVIF Agentic Schema Bundle + The ONVIF AI Working Group maintains one shared schema bundle, which every ONVIF Device + exposes and which no ONVIF Device modifies. It is organised as one module per concern: + + + agentic/common: the primitive types on which the rest of the bundle + rests — UUID, Likelihood, Base64Binary, + ReferenceToken, KeyID — together with the vendor extension + containers and the compound value structures such as + StringLikelihood and ColorDescriptor. + + + agentic/enums: the enumerations, such as VehicleType, + VehicleUse, PlateType, BarcodeType, + DigestAlgorithm and SignatureAlgorithm. + + + agentic/time: Time and its concrete forms, + ISO8601Timestamp and ISO8601Interval. + + + agentic/signature: the signing and integrity classes — + ItemDigest, KeyFingerprint, SigningKey and its + concrete forms, DevicePublicKey, and the OnvifSignature + profile. + + + agentic/base: the metadata model proper — + InformationItem, InformationEnvelope, + Observation and Assertion with their concrete subclasses, + Provenance, and Location. It is described in + . + + + agentic: the Skill interface — FunctionDescriptor, + ListFunctionsResult, the abstract bases that every function + specialises, and the classes of the reserved set_event_stream_parameters + function. + + + An ONVIF Device shall not redefine a class, a type or an enumeration that the bundle + declares. This ensures that an ONVIF Client that has already loaded the bundle does not + need to re-fetch it for each new ONVIF Device it connects to. + Because every module places its classes in the same vocabulary namespace, a class is + identified in the same way whichever module declares it. An ONVIF Client therefore resolves + a class name against the bundle as a whole, and not against the particular document in + which the class happens to appear; moving a class between modules in a future revision does + not change its identity. +
+
+ +
+ JSON-LD — Wire Format for Metadata Events + JSON-LD (JSON-based Linked Data) is the serialisation format used for all metadata + events delivered via events/stream or webhook. Where LinkML defines the schema at design time, + JSON-LD carries instances of that schema at runtime. The two technologies are + complementary: LinkML declares what data looks like; JSON-LD is the payload that + conforms to that declaration. + +
+ Context and Type Annotations + Every metadata payload emitted by an ONVIF Device shall carry two JSON-LD keywords. + @context shall be the vocabulary namespace defined in + , namely + https://www.onvif.org/ver10/agentic/linkml/. It appears once per + InformationEnvelope and its value is the same for every ONVIF Device, since + every device draws its types from the same bundle. It states which vocabulary the bare names + in the payload belong to. + This URI is not required to be dereferenceable, and an ONVIF Client shall not depend on + being able to retrieve a JSON-LD context document from it. The mapping from names to + identifiers is not fetched at runtime: it is derived from the LinkML modules the ONVIF + Device serves as resources, which an ONVIF Client has already loaded when it established the + session (see ). Where an ONVIF Client wishes to + perform full JSON-LD processing, it constructs the context itself from those modules, by the + rules below, and supplies it to its own processor. + A context derived from a LinkML module shall bind: + + + @vocab to the expansion of the default_prefix of the + module; + + + each class to its own local name within that namespace; + + + each prefix declared in prefixes to the namespace URI it is declared + with. + + + These three rules are stated normatively so that an ONVIF Device and an ONVIF Client + agree on the meaning of a payload without depending on any particular version of the LinkML + toolchain. A context produced by a LinkML context generator satisfies them; so does one + written by hand. + @type shall name the class of the node it appears on. For a class declared + by the ONVIF Agentic Schema Bundle the value is the bare local name, for example + VehicleObservation, which the vocabulary namespace resolves. For a class + declared by a vendor extension the value shall be a compact URI formed with a prefix that + the vendor module declares, for example acme:ThermalObservation; a bare name + shall not be used for a class outside the bundle. The reasoning is given in + . + The prefixes declared by the modules a single ONVIF Device serves shall be mutually + distinct. Where two independently authored extensions would claim the same prefix, the + device shall rename one of them before serving it, in the same way and for the same reason + that it arbitrates function names. + Together, @context and @type make each item + self-describing with respect to a bundle the ONVIF Client already + holds: the first says which vocabulary is in force, the second says which class in that + vocabulary the item instantiates, and the ONVIF Client routes and validates the item on the + strength of the two together. +
+ +
+ Self-Describing Events and Dynamic Schema Registration + An ONVIF Client loads the schema modules an ONVIF Device serves when it establishes the + session, by enumerating them with resources/list and reading each one, and it + keys its registry on the schema identifier of each module. In steady state, therefore, every + class an ONVIF Client encounters is already known to it. + The workflow below handles the case where it is not: an ONVIF Client receives an item + whose @type it cannot resolve, either because the bare name is not declared by + any module it holds or because the prefix of a compact URI is not bound by any of them. The + trigger is the unresolved @type and not the value of @context, + which is a constant and therefore never signals that anything new has appeared. An ONVIF + Client shall: + 1. Suspend validation of the triggering item. + 2. Re-enumerate the resources of the originating ONVIF Device with + resources/list and read any module it does not already hold. + 3. Register the new modules under their schema identifiers and rebuild the mapping from + class names to class identifiers. + 4. Re-validate and process the suspended item against the newly registered + module. + An ONVIF Client that still cannot resolve the @type after this shall treat + the item as being of an unknown type. It shall not discard the enclosing + InformationEnvelope on that ground alone, since the envelope may carry + further items it does understand, and an envelope that is signed remains verifiable + irrespective of whether every class in it is known. + This mechanism allows an ONVIF Device to introduce a new class — for instance a firmware + update that adds a vendor observation — without requiring a pre-coordinated ONVIF Client + update. The corresponding obligations on the ONVIF Device, which shall announce the change + rather than let it be discovered by a failure, are specified in + . +
+ +
+ Relationship to Linked Data + No part of this specification requires full JSON-LD processing. Nothing depends on + graph expansion, on RDF canonicalisation, or on @context being retrievable: the + payload is validated against a JSON Schema compiled from the LinkML bundle, the signature + profile of canonicalises plain JSON, and the + cross-references between information items are resolved by the rules of + . A conformant ONVIF Client shall treat + @context and @type as identifiers for schema lookup and item + routing. + An ONVIF Client may nonetheless perform full JSON-LD processing, for downstream + applications such as knowledge graph ingestion or cross-vendor correlation, and the payload + is shaped so that it can. Two consequences of the preceding sections apply to an ONVIF + Client that chooses to do so, and are stated here because they are easy to discover late. + First, a general-purpose JSON-LD processor cannot be pointed at an ONVIF payload as it + stands, because it would attempt to dereference @context and fail. An ONVIF + Client shall instead supply the context it derived from the LinkML modules of the device, by + the rules of , associating it with the + vocabulary namespace in the document loader of its processor. + Second, the identifiers of information items are plain UUID strings and are not JSON-LD + node identifiers, as stated in . The references that + one item makes to another — the supportedBy field of an + Assertion, the item field of an ItemDigest — are + therefore not edges of an RDF graph. An ONVIF Client that builds a graph from these payloads + shall construct those edges itself, minting node identifiers in a form of its own choosing; + it shall not expect a JSON-LD processor to produce them. +
+
+
+ + + Protocol Stack Architecture + +
+ Architecture Overview + The ONVIF agentic Protocol Stack is structured around the standard ONVIF roles of an + ONVIF Client and an ONVIF Device, with an OIDC Authorization Server acting as the shared + trust anchor that issues the tokens consumed by both. The figure below shows the top-level + relationships between these three components and the single MCP channel that carries all + interactions between them. +
+ ONVIF agentic Protocol Stack — Top-Level Architecture + + + + + + +
+ The OIDC Authorization Server is the trust anchor for the entire + stack. It issues signed ES256 JWTs to the ONVIF Client via the OAuth2 Client Credentials + grant, and exposes a JWKS endpoint that the ONVIF Device uses to validate every token it + receives. + The ONVIF Client combines the ONVIF Client role with the MCP Host + role. It manages connections to ONVIF Devices, invokes skills, and receives metadata + events. It also maintains the LinkML Schema Registry and validates every incoming event + before it is passed to business logic. + The ONVIF Device provides an MCP Server endpoint. Through this + endpoint, it exposes skills in the form of MCP Tools, pushes JSON-LD metadata events to the + ONVIF Client as MCP Events, and, when webhook delivery is supported, posts those events to a + client-supplied HTTPS callback. Moreover, it announces the LinkML schema via MCP + Resources. + All communication between the ONVIF Client and the ONVIF Device is bearer-token + authenticated and carried over a single MCP channel: every operation defined by this + specification — capability discovery, skill invocation, resource retrieval, and event + delivery — is a JSON-RPC exchange over MCP 2026-07-28 Streamable HTTP to the ONVIF Device's + /mcp endpoint. Event delivery uses the same endpoint: the ONVIF Client opens + an events/stream POST request per subscription and the ONVIF Device writes + event notifications and keep-alive heartbeats on the SSE response of that request. When + webhook delivery is used, the resulting event POSTs travel outside this MCP channel, + directly from the ONVIF Device to the HTTPS callback endpoint supplied by the ONVIF Client + (see ). +
+ +
+ Protocol Stack + The ONVIF agentic protocol stack uses a single MCP channel, protected by TLS and + bearer tokens issued by the OIDC Authorization Server, over which the ONVIF Client sends all + JSON-RPC requests to the ONVIF Device. + + + + + + + Direction + ONVIF Client to ONVIF Device (request/response, and the + long-lived events/stream request whose SSE response carries + server-initiated event notifications); ONVIF Device to a client-supplied HTTPS + callback endpoint for webhook event delivery. + + + Purpose + Discover capabilities, list and invoke skills, retrieve + resources, and stream or subscribe to metadata events. + + + Protocol + MCP 2026-07-28 over Streamable HTTP. + + + Message pattern + JSON-RPC 2.0 request/response; JSON-RPC 2.0 notifications + on the SSE response of an events/stream request. + + + Transport + HTTP POST to /mcp over HTTP/1.1 or HTTP/2. + HTTP/2 is RECOMMENDED so that concurrent events/stream requests are + multiplexed on a single connection. + + + Operations + server/discover, tools/list, + tools/call, resources/list, resources/read, + events/list, events/stream, events/subscribe, + and events/unsubscribe. + + + Security + TLS 1.3 with an Authorization: Bearer ES256 JWT on every request. + + + + + Each request is self-contained and shall be validated independently by the ONVIF Device + before execution. A response shall report either the requested result or an MCP error + indicating why the operation could not be completed. events/subscribe and + events/unsubscribe follow this same request/response pattern. + events/stream is a long-lived request: it is validated in the same way, but + on success its response remains open and carries a sequence of + notifications/events/* messages until it is cancelled. The detailed + behaviour of both delivery modes, including the out-of-band webhook delivery mechanism, is + defined in . +
+ +
+ Identity and Authorization Server + The ONVIF Agentic Service requires an OAuth 2.1 Authorization Server, as specified in + the ONVIF Security Service Specification. + This server acts as the trust anchor for the complete stack: it authenticates clients, + issues bearer access tokens, and exposes the metadata and key material needed by ONVIF + Devices to validate tokens before processing MCP requests. + In practice, the Authorization Server provides centralized identity and access control + for every operation. It ensures that only authorized ONVIF Clients can invoke Skills via + tools/call and receive protected metadata events via + events/stream or webhook delivery, according to the roles and + claims contained in the issued token. +
+
+ + + Service Discovery and Data Exchange + + + +
+ Network Discovery + MCP 2026-07-28 does not define network-level device discovery. Therefore, ONVIF Device + discovery remains dependent on the mechanisms specified by [ONVIF Core]. An ONVIF Client + shall discover ONVIF Devices and obtain their service endpoint using the ONVIF Core + discovery procedures before initiating MCP requests. +
+ +
+ Service Discovery + An ONVIF Device that supports the Agentic Service shall advertise the MCP service + endpoint URL through the ONVIF Core service discovery mechanism. In the ONVIF Core + GetServices response, the corresponding Agentic Service entry + (tds:GetServiceResponse) shall contain the service address used by the ONVIF + Client for MCP requests. +
+ +
+ Feature Discovery +
+ Session Initialization + An ONVIF Device implementing the Agentic Service shall implement the + server/discover JSON-RPC method as required by MCP 2026-07-28. The ONVIF + Client MAY call server/discover as its first request on a new connection to + obtain the device's protocol version, server identity, and capability flags. + Alternatively, the ONVIF Client MAY call any other operation directly and handle + UnsupportedProtocolVersionError (JSON-RPC error code -32022) + if the protocol version is not supported. In that case the ONVIF Device shall include a + supported list in the error response and the ONVIF Client shall retry using + one of the listed versions. + The server/discover response shall contain: protocolVersions + — the list of MCP protocol versions supported by the device; identity — the + server name and version; capabilities — the + declared capability flags (tools, resources, + prompts, and supported extensions). The ONVIF Client shall use the returned + capabilities flags to determine which subsequent operations are available + before invoking them. + To receive metadata events the ONVIF Client opens a long-lived + events/stream request per subscription, or subscribes for webhook + delivery via events/subscribe, as defined in . See for wire format examples. +
+
+ Schema Retrieval + The ONVIF Agentic Service exposes its LinkML metadata schema as one or more MCP + Resources. An ONVIF Client shall retrieve the schema bundle before processing any + metadata event delivered via events/stream or webhook. + The schema retrieval procedure is: + + The ONVIF Client calls resources/list. The response + includes one or more resources with mimeType: application/linkml+yaml + identifying the schema files. + The ONVIF Client calls resources/read for each schema + resource URI returned in step 1, in the order listed. A schema bundle may span + multiple resources when imported type definitions are split across files. + The ONVIF Client registers the complete schema bundle in its + validator. + + + An ONVIF Device shall advertise at least one resource with mimeType: + application/linkml+yaml describing the structure of every event type it emits. + The schema shall be self-contained — it shall not require the ONVIF Client to resolve + external URIs to validate event payloads. + See and for wire format examples. +
+
+ Tool Discovery + The ONVIF Device exposes its Skills — callable operations — as MCP Tools. The + ONVIF Client discovers the available Skills by calling tools/list. + Each Tool entry in the tools/list response shall contain: + + name — the Skill identifier used in subsequent + tools/call requests. + + + description — a human-readable description of the Skill's + function. + + + inputSchema — a JSON Schema object that fully describes the + expected arguments. This JSON Schema is compiled from the LinkML model retrieved in + and shall use the same coordinate spaces, + unit definitions, and vocabulary as the event payloads delivered via + events/stream or webhook delivery. + + + The ONVIF Client shall validate Skill arguments against the + inputSchema before sending a tools/call request. After + completing tool discovery the ONVIF Client has obtained, without any out-of-band + documentation: the complete catalogue of Skills supported by this device instance; the + argument types, valid ranges, and required/optional fields for each Skill; and + human-readable descriptions suitable for display or automated orchestration. This + catalogue covers the Skills only; the functions on which they operate are discovered + separately with list_functions (see ). + See for a wire format example. +
+
+ +
+ Skill Invocation + ONVIF Agentic Skills are invoked via the MCP tools/call JSON-RPC method. + The ONVIF Device shall validate the arguments object + against the inputSchema of the named Skill before executing it. If validation + fails, the ONVIF Device shall return a structured error response without executing the + Skill. + The ONVIF Device shall advertise support for the MCP Tasks extension in + server/discover. Before returning a task result, it shall verify that the + client declared io.modelcontextprotocol/tasks support for the request. A + supported Skill invocation may return either its normal result or a result with + resultType: "task". The returned task shall include a durable + taskId, a status, a ttlMs, and a recommended + pollIntervalMs. The client shall use tasks/get until the task + reaches completed, failed, or cancelled. + + This specification defines six mandatory Skills that every ONVIF agentic device shall + implement regardless of device type (camera, NVR, access control, or other). Additional + device-type-specific Skills may be defined in ONVIF profiles or vendor extensions. + + Skills and functions are distinct concepts and are discovered through distinct + operations. A Skill is an operation invocable via + tools/call; the six Skills defined here are the same on every conforming + device and are discovered with tools/list (see ). A function is an analytic + capability on which those Skills operate, such as vehicle_detection; functions + vary between device instances and over time, and are discovered with the + list_functions Skill (see ). A + function is not an MCP Tool and shall not be exposed as one: it is named in the + function argument of the generic Skills. Consequently + tools/list and list_functions are not redundant — the first + enumerates the operations an ONVIF Client may invoke, the second the subjects on which it + may invoke them. + +
+ get_status + The get_status Skill returns the current operational status of the + agentic analytics engine. It takes no arguments. The ONVIF Device shall always respond + successfully to this Skill unless the device is unreachable. + The response structuredContent shall include: + + state — one of running, stopped, + degraded, or error. + + + activeFunctions — list of active function executions. Each + execution shall include the function identifier and its + executionId. + + + engineVersion — version string of the agentic engine + firmware. + + + See for a wire format example. +
+ +
+ list_functions + The list_functions Skill returns the set of functions supported by this + device instance, together with their current configured/available state. It takes no + arguments. This is the authoritative machine-readable function catalogue of this device; + the ONVIF Client shall call list_functions before calling + configure_function, execute_function, or + stop_function. + Each entry in the response structuredContent.functions array shall + include: + + name — the local name of the function on this device (for example + vehicle_detection, license_plate_recognition, + set_event_stream_parameters). It is the value the ONVIF Client passes in the + function argument of configure_function, + execute_function, stop_function and + get_function_capabilities. + + + canonicalUri — the canonical identifier of the function, which is + the same on every ONVIF Device that implements it. + + + enabled — boolean indicating whether this function is configured + and available for execution. + + + configSchema — URI of the LinkML class in the schema bundle + (retrieved in ) that defines the structure of + the config argument accepted by configure_function for + this function. + + + executionSchema — OPTIONAL URI of the LinkML class in the schema + bundle that defines the structure of the parameters argument accepted + by execute_function for this function. It shall be present when the + function accepts execution parameters. + + + resultSchema — OPTIONAL URI of the LinkML class in the schema + bundle that defines the structure of the structuredContent returned by + execute_function for this function. It shall be present when the + function returns a structured result. + + + capabilitiesSchema — OPTIONAL URI of the LinkML class in the + schema bundle, derived from FunctionCapabilities, that defines the + structure of the capabilities returned by + get_function_capabilities for this function. It shall be present when + the function has capabilities that an ONVIF Client can read. + + + The structure of this response is defined by the ListFunctionsResult and + FunctionDescriptor classes of the Agentic Service LinkML schema. + + An ONVIF Device that exposes no local functions shall return an array containing only + the reserved functions defined by this specification. + The function identifier set_event_stream_parameters is reserved by this + specification. Every ONVIF Device implementing the Agentic Service shall include it in + the functions array with enabled: true, so that an ONVIF Client + can discover both the keep-alive control and the limits of the event stream without + out-of-band knowledge (see ). + See for a wire format example. + +
+ Function identity + A function carries two identifiers because the two questions an ONVIF Client asks + about a function are different. To call it, the client needs the + handle this device answers to; to recognise it, and to correlate it + with the same function on another device, the client needs an identifier that does not + depend on the device at all. + name is the handle. It shall be unique within a single + list_functions response, and it is arbitrated by the ONVIF Device: where two + independently defined functions would claim the same local name, the device shall rename + one of them. It is therefore not a global identifier, and an ONVIF Client shall not use it + as a key across devices, nor assume that a name it recognises on one device denotes the + same function on another. + canonicalUri is the identity. It shall be present on every entry, it + shall be the same on every ONVIF Device that implements the function, and it shall be + stable under any renaming of the local name. For a function reserved by this + specification the value shall be + https://www.onvif.org/ver10/agentic/function/ followed by the reserved name, + for example + https://www.onvif.org/ver10/agentic/function/set_event_stream_parameters. For any + other function the value shall lie in a namespace controlled by the party that defined + the function. + This is the same division of labour that applies to event types (see ), and for the same reason: a bare local name + cannot be made collision-free across parties who do not coordinate, while a URI in a + namespace its owner controls can. +
+
+ +
+ get_function_capabilities + The get_function_capabilities Skill returns the static capabilities of a + single function: the invariant properties that describe what this device instance + supports for that function, such as the ranges of values it accepts. Capabilities do not + depend on any particular invocation; they are the same before and after an execution and + are readable without performing one. + Capabilities shall not be returned in the structuredContent of + execute_function. An execute_function response reports the + outcome of the call it completes; the properties of the function itself are read through + this Skill. Keeping the two apart lets an ONVIF Client discover what a function accepts + before deciding what to ask for, and prevents invariant values from appearing as though + they were results of an action. + The Skill takes a single argument, as defined by the LinkML class + GetFunctionCapabilities: + + function (string, required) — the function identifier whose + capabilities are requested, as returned by list_functions. + + + The response structuredContent is defined by the LinkML class + GetFunctionCapabilitiesResponse and shall include the + function identifier and a capabilities object. The + capabilities object is an instance of the class derived from + FunctionCapabilities that list_functions names in the + capabilitiesSchema field of that function's descriptor. + An ONVIF Device shall reject a request naming a function it does not support with + -32011 NotFound. A function that has no readable capabilities shall omit + capabilitiesSchema from its descriptor; an ONVIF Device shall respond to + this Skill for such a function with an empty capabilities object rather than + with an error. + See for a wire format + example. +
+ +
+ configure_function + The configure_function Skill applies a configuration to a named + function. It is a generic wrapper: the structure of the config + argument is defined by the LinkML schema class identified by the + configSchema URI returned by list_functions for that function. + The ONVIF Client shall validate config against the compiled JSON Schema + (the inputSchema of the Skill) before sending the request. + The configure_function Skill arguments are: + + function (string, required) — the function identifier, as returned + by list_functions. + + + config (object, required) — the configuration object whose + structure is specific to function and defined by the + corresponding LinkML schema class. + + + configure_function shall not start the function. On success the ONVIF + Device shall confirm the applied configuration. If the operation is long-running and the + client has declared support for the MCP Tasks extension, the device may return a task + result instead of the final result. The client shall use tasks/get until the + task reaches a terminal state. On failure it shall return a structured error identifying + the failing field and the violated constraint. + See for a wire format example. +
+ +
+ execute_function + The execute_function Skill starts an execution of a configured function. + It shall not be used to provide the function's configuration. The arguments shall include + the function identifier and may include execution-specific parameters. The structure of + the parameters argument, when present, is defined by the LinkML class + derived from FunctionExecutionParameters that corresponds to the named + function. + On successful start, the device shall return an executionId. If starting + the function is asynchronous and the client has declared support for MCP Tasks, the device + may return a task result. The task represents only the start operation and shall reach a + terminal state when the execution is running or has failed. It shall not remain + permanently in working while a continuous function is active. + For continuous functions, subsequent output shall be made available as metadata + events, delivered on an open events/stream request or via webhook (see ). The execution remains active until stopped or + it terminates independently. + execute_function is also the mechanism through which the ONVIF Client + adjusts the keep-alive interval of push streams, by invoking the reserved + set_event_stream_parameters function (see ). +
+ +
+ stop_function + The stop_function Skill stops an active function execution identified by + its executionId. If stopping the execution is asynchronous and the client has + declared support for MCP Tasks, the device may return a task result. The task represents + only the stop operation and shall reach a terminal state when the execution is stopped or + the stop operation has failed. +
+
+ +
+ Event Delivery + Metadata events are exposed by the ONVIF Device as MCP event types, discovered via + events/list and delivered through one or both of the two delivery modes + defined by this specification: push (events/stream, over + the Streamable HTTP transport) and webhook + (events/subscribe / events/unsubscribe), as defined by the MCP + Events extension (see ). This specification does + not define, and an ONVIF Device conforming to it shall not require, a poll-based + (events/poll) delivery mode. +
+ Event Type Catalogue + An event type of this specification is a metadata class. An ONVIF Device that can + report vehicle observations declares an event type for + VehicleObservation, and an ONVIF Client that subscribes to it is asking to be + told when an item of that class is produced. There is no separate catalogue of event names + to be kept in step with the schema: the catalogue is a selection of the classes the ONVIF + Device is able to emit. + An ONVIF Device shall advertise its event types via events/list. Each + entry shall include: + + name — the local name of the event type on this ONVIF Device. It + shall be the same string that appears as the @type of an item of that + class in a delivered payload: the bare class name for a class of the ONVIF Agentic + Schema Bundle, for example VehicleObservation, and a compact URI for a + class introduced by a vendor extension, for example + acme:ThermalObservation. + Because the prefixes an ONVIF Device serves are mutually distinct (see ), this value is unique within the + device. It is not unique beyond it: two vendors may independently define a class of + the same local name, and an ONVIF Client shall therefore not use name as + a key across devices. + + + canonicalUri — the class identifier of the event type, as defined in + : an absolute URI such as + https://www.onvif.org/ver10/agentic/linkml/VehicleObservation. This is + the identity of the event type. It is the same on every ONVIF Device that emits the + class, it is unaffected by any renaming of a prefix, and it is the value an ONVIF + Client shall use to decide whether two devices report the same kind of thing. + The value is redundant, in that an ONVIF Client holding the schema modules of the + device can derive it from name. It is carried explicitly because it + appears once per catalogue entry rather than once per event, and because it allows a + catalogue to be interpreted before the modules have been read. + + + delivery — the non-empty subset of "push" and + "webhook" supported for this event type. An ONVIF Device shall + support "push" for every event type it declares; "webhook" + support is OPTIONAL. + + + inputSchema — a JSON Schema describing valid subscription + arguments (for example a sensor or zone filter). + + + payloadSchema — a JSON Schema describing the shape of the + event data field. Because data is always an + InformationEnvelope, as specified in + , the value is the same for every event + type an ONVIF Device declares, namely a reference to the compiled + InformationEnvelope class: + https://www.onvif.org/ver10/agentic/base/linkml/#/$defs/InformationEnvelope + What distinguishes one event type from another is therefore not the shape of the + payload but canonicalUri, which names the class an ONVIF Client is + subscribing to among the items the envelope carries. + + + An InformationEnvelope delivered for a subscription shall contain at least + one item of the subscribed class, and may contain further items that are needed to interpret + it. An Assertion that draws on an observation produced at the same moment is + the usual reason for the second case: the envelope carries both, so that an ONVIF Client + receives the claim and its immediate support together. Items whose production is separated + in time are not gathered into one envelope; they are linked by identifier, as specified in + . + One occurrence may satisfy several subscriptions — an envelope containing a + VehicleObservation and a VehicleReidentification matches a + subscription to either class. The ONVIF Device shall deliver it on each matching + subscription, and shall not withhold it from one because it was delivered on another. An + ONVIF Client holding several subscriptions shall therefore expect to receive the same items + more than once, and shall deduplicate on the identifiers of the items rather than on the + eventId of the occurrence, which is per-delivery. Item identifiers are unique + and never reused, as specified in , which makes this + deduplication exact. + If the set of event types, or the descriptor of any of them, changes at runtime, the + ONVIF Device shall send notifications/events/list_changed and the ONVIF + Client shall re-call events/list to refresh its registry. +
+
+ Push-Based Delivery + An ONVIF Device shall support events/stream for every declared event + type. The ONVIF Client opens one long-lived events/stream JSON-RPC request + per subscription, carrying the event name, the subscription + arguments, a cursor (null to start from now), + and optionally maxAgeMs to bound replay. On the Streamable HTTP transport + the request is an HTTP POST to the /mcp endpoint whose response is a + Server-Sent Events stream that remains open for the lifetime of the subscription. + If the subscription is invalid, the ONVIF Device shall reject the request with the + corresponding JSON-RPC error (see ) and shall not + open a stream. Otherwise the ONVIF Device shall first send + notifications/events/active, carrying the starting cursor and + the truncated flag, and shall then send one + notifications/events/event notification for each matching event as it + occurs. The params of every notifications/events/* message + shall carry the JSON-RPC id of the parent events/stream request + in _meta["io.modelcontextprotocol/subscriptionId"], so that an ONVIF Client + holding several concurrent streams can route each notification to the correct + subscription. + Each notifications/events/event notification is an + EventOccurrence carrying eventId, name, + timestamp, data (the JSON-LD event payload), and + cursor — the subscription position after that event. The ONVIF Client + shall persist the most recently received cursor and shall supply it when + reopening the stream, so that delivery resumes from that position. The ONVIF Device shall + set truncated: true in a fresh notifications/events/active + notification whenever events were skipped because the supplied cursor fell outside the + retention window or the maxAgeMs bound; a gap is not an error and the stream + shall remain open. + The ONVIF Device shall report a recoverable, per-occurrence failure using + notifications/events/error without closing the stream, and shall use + notifications/events/terminated only when the subscription can no longer + be honoured — for example when the event type has been removed or its schema has changed + incompatibly. On receipt of notifications/events/terminated the ONVIF Client + shall re-call events/list and resubscribe against the current + descriptor. + The ONVIF Client terminates a subscription by aborting the corresponding HTTP request + stream; no explicit cancellation message is required on Streamable HTTP. The ONVIF Device + shall stop delivering events and release the associated resources as soon as the request + stream is aborted. When the ONVIF Device itself closes the stream, it shall write the + StreamEventsResult as the final SSE data: frame. + An ONVIF Client MAY hold several concurrent events/stream requests open, + one per subscription; HTTP/2 is RECOMMENDED so that they are multiplexed on a single + connection. An ONVIF Device shall exempt events/stream from any general + request-concurrency limit it applies, and shall declare the maximum number of concurrent + streams it supports in maxConcurrentStreams of + EventStreamCapabilities, read with the + get_function_capabilities Skill for the reserved + set_event_stream_parameters function (see ); it shall reject a request exceeding that limit with + -32013 ResourceExhausted. An ONVIF Client that reads that value before + opening its streams need never provoke that error. + If the stream is interrupted, the ONVIF Client shall reopen an + events/stream request with the same name and + arguments and its last persisted cursor. +
+
+ Keep-Alive + An ONVIF Device shall send a periodic keep-alive on every open + events/stream response, so that an ONVIF Client can distinguish an idle + stream from a broken one and so that its persisted cursor advances during quiet periods. + The keep-alive is the notifications/events/heartbeat notification, whose + params carry the cursor the device has checked up to and the + _meta["io.modelcontextprotocol/subscriptionId"] of the stream. On + Streamable HTTP the keep-alive shall be sent as an SSE data: frame; the SSE + comment form (: keepalive) shall not be used, as it cannot carry cursor + state. + The default keep-alive interval is 30 seconds. An ONVIF Device shall send a + keep-alive at least once per keep-alive interval on every stream on which no event was + delivered during that interval. An ONVIF Client shall not apply its default request + timeout to an events/stream request; the keep-alive is the liveness signal. + An ONVIF Client that has received neither an event nor a keep-alive for more than twice + the current keep-alive interval shall treat the stream as dead and reopen it with its + last persisted cursor. + The keep-alive interval is configurable by the ONVIF Client through the reserved + set_event_stream_parameters function, invoked with the execute_function + Skill (see ). The structure of the + parameters argument is defined by the LinkML class + SetEventStreamParametersRequest in the schema bundle, which declares: + + + keepaliveIntervalMs (integer, optional, default + 30000) — the requested interval between two consecutive keep-alive + notifications, in milliseconds. + + + subscriptionId (integer, optional) — the JSON-RPC id + of a single events/stream request to which the new interval applies. + When omitted, the new interval applies to all streams opened by the authenticated + principal, including streams opened after the call. + + + An ONVIF Device shall apply the requested interval, clamped to the range it supports, + and shall report the value actually applied in the + structuredContent of the execute_function response, as + defined by the LinkML class SetEventStreamParametersResponse + (appliedKeepaliveIntervalMs, clamped, and + affectedStreams). Clamping is not an error: the ONVIF Client shall use the + returned appliedKeepaliveIntervalMs as the current keep-alive interval for + the affected streams, including for the dead-stream detection rule above, and + clamped shall be true when that value differs from the one + requested. An ONVIF Device + shall reject a request whose subscriptionId does not identify an open stream + of the authenticated principal with -32011 NotFound. + The supported range itself is not part of that result: it is a static property of the + ONVIF Device, not an outcome of the call. An ONVIF Client reads it with the + get_function_capabilities Skill (see ) for the + set_event_stream_parameters function, whose capabilities are defined by the + LinkML class EventStreamCapabilities: + defaultKeepaliveIntervalMs (30000), + minKeepaliveIntervalMs, maxKeepaliveIntervalMs, and + maxConcurrentStreams. An ONVIF + Client that reads the capabilities before calling the function can choose a value that + will not be clamped. + The class covers the event stream as a whole rather than the keep-alive mechanism + alone, which is why maxConcurrentStreams belongs to it. Capabilities in this + specification are always the capabilities of a function, and the reserved function that + configures the stream is the one place where a property of the stream itself has an owner. + The distinction the class draws is the general one of : the keep-alive interval is settable and + is therefore a parameter, whereas the interval range and the stream count are invariant for + a device instance and are therefore capabilities. + A change of keep-alive interval takes effect on the affected streams without + interrupting them, and shall not affect event delivery or cursor semantics. The interval + applied to a stream does not survive that stream: a stream reopened after an interruption + starts from the value most recently set for the principal, or from the 30 second default + if none was set. + The function as a whole — its identifier, the class of its input, and the class of its + output — is declared by the LinkML class SetEventStreamParametersInvocation, a + specialization of the abstract FunctionInvocation class. It fixes + function to the constant set_event_stream_parameters, narrows + parameters to SetEventStreamParametersRequest, and narrows + result to SetEventStreamParametersResponse. This binding is + normative: an execute_function call naming + set_event_stream_parameters and the response it produces shall together validate + against it. + See for a wire format example. +
+
+ Webhook-Based Delivery + Where declared for an event type, an ONVIF Device MAY additionally support webhook + delivery. The ONVIF Client registers an https callback URL and a + whsec_-prefixed signing secret by calling events/subscribe + with name, subscription arguments, + delivery: {"mode": "webhook", "url", "secret"}, a starting + cursor, and a suggested lifetime ttlMs. The ONVIF Device + returns a server-derived subscription id, the granted expiry + refreshBefore, and a safe-to-persist cursor. + The ONVIF Device shall then POST each matching EventOccurrence to the + registered callback URL, signed per Standard Webhooks (webhook-id, + webhook-timestamp, webhook-signature headers) and carrying + X-MCP-Subscription-Id. Unless the ONVIF Client requested, and the ONVIF + Device granted, no expiry (ttlMs: null / refreshBefore: null), + the ONVIF Client shall re-call events/subscribe with the same subscription + key before refreshBefore elapses to keep the subscription alive. The ONVIF + Client calls events/unsubscribe to explicitly terminate a webhook + subscription; otherwise it lapses at TTL expiry. + events/subscribe and events/unsubscribe shall only be + accepted from an authenticated principal; an ONVIF Device shall reject unauthenticated + calls to either method with -32012 Forbidden (see ). +
+
+ Error Codes + An ONVIF Device shall report error conditions on events/stream, + events/subscribe, and events/unsubscribe using the following + JSON-RPC error codes, as defined by the MCP Events extension. For + events/stream the error is returned as the response to the request and no + stream is opened: + + + + + + + + Code + Message + Meaning + + + + + -32602 + InvalidParams + The request is statically invalid — subscription arguments do not + match the event type's inputSchema, the callback + delivery.url is malformed or non-https, or + delivery.secret is not a valid whsec_ value. + + + -32011 + NotFound + An unknown event name, no subscription matching the + key on events/unsubscribe, a subscriptionId that + does not identify an open stream on + set_event_stream_parameters, or an unknown function on + get_function_capabilities. + + + -32012 + Forbidden + The authenticated principal is not permitted for this event/arguments + combination, or its access was revoked, or the call was unauthenticated. + + + -32013 + ResourceExhausted + A device-imposed limit or quota was reached (for example, the maximum + number of concurrent events/stream requests or webhook + subscriptions). + + + -32014 + Unsupported + The request is well-formed but a requested delivery mode is not + offered for this event type. + + + -32015 + CallbackEndpointError + A client-supplied callback endpoint failed verification or could not + be reached (webhook mode only). + + + + +
+
+ Event Payload Structure + A delivered event has two nested envelopes, belonging to two different specifications, + and the fields of one are not the fields of the other. Keeping them apart is necessary to + read the wire format at all. + The outer envelope is the EventOccurrence of the MCP Events extension. It + is a unit of delivery: it says that something was sent, on which + subscription, and where the subscription now stands. It carries eventId, + name, timestamp, cursor, the + _meta["io.modelcontextprotocol/subscriptionId"] of the parent stream, and + data. It is discarded once the delivery has been accounted for, and it is not + signed. + The inner envelope is the InformationEnvelope of this specification, defined + in . It is a unit of evidence: + it says what was observed or concluded, by whom, and — where a signature is present — that + the group of items has not been altered. It survives the delivery that carried it, it can be + stored, forwarded and re-verified, and it is the only level at which a signature is + defined. + The data field of every EventOccurrence — whether delivered as + a notifications/events/event notification on an events/stream + response or POSTed to a webhook callback — shall be a single + InformationEnvelope. There is no event class distinct from the metadata model: + an event is an InformationEnvelope in transit. The envelope shall carry + @context and @type as specified in + , and each of its items shall carry its own + @type. + The following correspondences hold, and an ONVIF Client shall not substitute one side for + the other: + + + EventOccurrence.name identifies the class an ONVIF Client subscribed to. + It shall equal the @type of at least one item in the envelope, but the + envelope may carry items of other classes as well (see + ). + + + EventOccurrence.eventId identifies a delivery and is scoped to the + subscription that produced it. The identity of the content is + InformationEnvelope.id, and the identity of each claim is the + id of the item. Two deliveries of the same envelope on two subscriptions + have two eventId values and one envelope identifier. + + + EventOccurrence.timestamp is when the occurrence was emitted for + delivery. It is not when the information was produced, which is the + productionTime of each item, nor when the observed situation obtained, + which is its observedTime. The three may differ by an amount an ONVIF Client + cannot bound, and it shall use productionTime and observedTime + for any reasoning about the world. + + + EventOccurrence.cursor is a position in a subscription. It is not part of + the evidence, it is not covered by any signature, and it shall not be stored as an + attribute of the information it accompanied. + + + See for a complete wire format example. +
+
+ Dynamic Schema Re-registration + An ONVIF Client holds the schema modules of a device from the moment the session was + established. The mechanism below covers the case where a class appears that those modules do + not define — typically after a firmware update that adds one. + The trigger is an @type the ONVIF Client cannot resolve: a bare name that no + module it holds declares, or a compact URI whose prefix no module it holds binds. It is not + the value of @context, which is a constant and therefore never changes when a new + class is introduced. If the ONVIF Client receives an item whose @type it cannot + resolve, it shall: + + Suspend validation of that item without discarding it, and without discarding the + enclosing InformationEnvelope, whose other items it may be able to + process. + + + Call resources/list on the ONVIF Device and resources/read + for each module it does not already hold, using the MCP resource URI the device + reports (see ). + + + Register the retrieved modules under their schema identifiers, and rebuild the + mapping from class names and prefixes to class identifiers over the whole set of + modules it now holds. + + + Resume validation of the suspended item and of all subsequent items of that + class. + + + This mechanism allows the ONVIF Device to introduce new classes without requiring the + ONVIF Client to have prior knowledge of them. It is a recovery path and not the normal one: + an ONVIF Device shall announce a change to its schema bundle with + notifications/events/list_changed, so that an ONVIF Client learns of it by + being told rather than by failing to interpret an item. An ONVIF Device shall keep every + module needed to interpret the classes it emits readable through + resources/read for as long as it emits them. + See for a wire format example. +
+
+ +
+ Post-Handshake ONVIF Client Knowledge + An ONVIF Agentic Service is self-describing: an ONVIF Client that has completed the + sequence defined in , , , , and is fully operational without any out-of-band + documentation, SDK, or static configuration. The table below summarises the knowledge + accumulated at each step. + + + + + + + + Section + Operation + Knowledge acquired + + + + + + server/discover + Device identity, supported protocol versions, declared capability + flags (resources, tools). + + + + resources/list + + resources/read + Complete LinkML schema bundle; JSON Schema for event validation and + skill argument validation. + + + + tools/list + Skill catalogue: name, human-readable description, and + inputSchema for each skill. + + + + list_functions + Which functions are currently enabled; + configSchema URI per function. + + + + get_function_capabilities + Static capabilities of a single function, such as the ranges of values + it accepts. + + + + events/list, events/stream, + events/subscribe + Event type catalogue; live metadata events pushed on an open stream or + delivered via webhook; @type for routing; @context for + dynamic schema re-registration. + + + + + An ONVIF Device implementing this specification shall ensure that an ONVIF Client + completing the above sequence is able to: validate all incoming event payloads against the + registered schema; invoke any available Skill with correctly structured arguments; and + interpret the full feature set of the device — all without consulting any resource external + to the ONVIF Device. +
+
+ + + Authentication and Authorization + The ONVIF Agentic Services delegates all authentication and token management to the + mechanisms defined in the ONVIF Core Specification and the ONVIF Security Service + Specification. Those documents govern JWT token format and required claims (iss, + aud, exp, nbf, roles), the mandatory + ES256 signing algorithm, token validation rules, the OAuth2 Client Credentials flow, + authorization server configuration, and TLS transport requirements. Implementations shall + comply with the ONVIF Core Specification and the ONVIF Security Service Specification. This + chapter defines only the ONVIF AI-specific normative mapping of MCP operations to ONVIF access + classes. + +
+ Role-to-MCP Operation Mapping + The ONVIF Security Service Specification defines three predefined JWT role values + carried in the roles claim of every access token: onvif:User, + onvif:Operator, and onvif:Administrator. These correspond to the + ONVIF user levels and cover the majority of deployments. For environments that require + finer-grained access control, the Security Service Specification defines a full user role + management model that allows custom roles to be assigned to individual users; refer to the + ONVIF Security Service Specification for details. The onvif: namespace prefix + is reserved; custom roles shall not use it. + Anonymous access to any MCP endpoint is not permitted. Every request to the ONVIF Device + shall carry a valid Authorization: Bearer JWT. The ONVIF Device maps the access + class required by each MCP operation against the roles claim in the presented + token and rejects requests that do not satisfy the minimum role requirement with HTTP 403. A + token carrying onvif:Administrator satisfies all lower access class + requirements; a token carrying onvif:Operator satisfies + READ_SYSTEM in addition to ACTUATE. + The table below is normative. Each Skill exposed via tools/list shall + include an annotation declaring its access class. The ONVIF Device shall enforce this + mapping at runtime. + + MCP Operation Access Class and Minimum Role Requirements + + + + + + + MCP Operation + Access Class + Minimum JWT Role + + + + + server/discover + READ_SYSTEM + onvif:User + + + resources/list + READ_SYSTEM + onvif:User + + + resources/read + READ_SYSTEM + onvif:User + + + tools/list + READ_SYSTEM + onvif:User + + + tools/callget_status, + list_functions, and + get_function_capabilities + READ_SYSTEM + onvif:User + + + tools/callconfigure_function, + execute_function, and stop_function + ACTUATE + onvif:Operator + + + tools/call — administrative Skills (e.g. model + management, device configuration) + WRITE_SYSTEM + onvif:Administrator + + + events/list and events/stream + READ_SYSTEM + onvif:User + + + events/subscribe and + events/unsubscribe + READ_SYSTEM + onvif:User + + + +
+
+
+ + + Metadata + This chapter defines the data model for structured metadata produced and consumed by + ONVIF AI-enabled devices. All metadata payloads are instances of, or derived from, the + abstract classes defined here. The normative schema is expressed in LinkML; JSON-LD is the + wire format (see ). + The following figure shows the class hierarchy structure from which specialised metadata + classes are derived. The remainder of this chapter defines and details the classes shown in + the figure. +
+ Metadata class hierarchy overview + + + + + + +
+ +
+ Object identifiers + Every object defined in this chapter carries an identifier. In the LinkML schema the + identifier is declared as a slot named id, and it appears on the wire under that + name as a plain string. + The value of every such identifier shall be a UUID as specified in RFC 9562, written in + the canonical lowercase hyphenated form, for example + 3f2b8c1e-6a4d-4f7b-9e21-5c8d0a1b2e3f. Uppercase forms, the URN form + urn:uuid:, and the braced Microsoft form shall not be used. + The id slot is deliberately not bound to the JSON-LD node identifier + @id. A bare UUID is not an IRI: a JSON-LD processor asked to read it as + @id would resolve it against a base URI and produce an identifier that means + nothing. Binding it properly would require every identifier in this model to be written in the + urn:uuid: form that the paragraph above forbids, on the wire and in every digest + computed over it, in exchange for a graph structure no part of this specification needs (see + ). + The consequence is that the references one object makes to another are resolved by the + rules of this specification, by comparing identifier strings, and are not RDF edges. An ONVIF + Client shall resolve them itself and shall not expect a JSON-LD processor to do so. + UUID version 4 or version 7 is recommended. Version 7 embeds a timestamp and is + therefore sortable by creation order, which can be convenient for storage and indexing; + version 4 discloses nothing about the device or the moment of creation. An ONVIF Device + may use any version that satisfies the uniqueness requirement. + Identifiers are opaque. An ONVIF Client shall not derive meaning from the content of a + UUID, shall not assume that lexicographic order reflects creation order unless it knows the + version in use, and shall treat two identifiers as designating the same object if and only + if they are equal as strings. + An ONVIF Device shall not reuse an identifier: once emitted, a UUID designates one + object for the lifetime of the deployment. This property is what makes identifier-based + references, such as the supporting items of an assertion (see ), and digest-to-item binding in a signed envelope (see ) unambiguous. +
+ +
+ InformationItem + InformationItem is the abstract base container for any single unit of + information exchanged in the metadata model. It is intentionally generic so that different + semantic categories can reuse the same trust and context fields. In this specification, + InformationItem is specialised by Observation and + Assertion. + Each InformationItem carries the following fields: an id + uniquely identifying the item, as specified in ; a + mandatory confidence value expressing the confidence level of the contained + information, whose range is Likelihood and which therefore lies between 0.0 and + 1.0 inclusive; a mandatory productionTime field giving the time at which the + information was produced, as specified in ; and a + provenance field describing the origin or producer of the + information. + An InformationItem does not carry a signature of its own. Integrity, + authenticity, and non-repudiation are provided at envelope level, as specified in : an item that requires such protection shall be + conveyed inside an InformationEnvelope. This does not mean that the item is + protected only collectively: when the envelope is signed with the profile defined in , each enclosed item is covered by its own digest, bound + to its id. What is signed once is the envelope; what is verifiable + individually is the item. +
+ +
+ InformationEnvelope + InformationEnvelope is an optional container used to group one or more + InformationItem instances and apply a single signature to the grouped + content. It is the only place in this model where a signature is applied: individual + information items are not signed. + The envelope-level signature is itself optional. Signing one envelope rather than each + enclosed item keeps the signing workload independent of the number of items, which matters + on devices with constrained cryptographic acceleration resources, while still providing + integrity, authenticity, and non-repudiation coverage for all enclosed + InformationItem instances. + An InformationEnvelope carries an id, as specified in , the mandatory list of enclosed items, an + optional list of hashes, and the optional signature. + The hashes field holds one ItemDigest per enclosed item, as + defined in . The entries shall be sorted by their + item field in ascending order, comparing the canonical lowercase UUID strings + lexicographically. The ordering is normative because the digest of the envelope is computed + over the sequence of entries: without a fixed order, two parties holding identical content + would compute different digests. Sorting by identifier, rather than preserving the order in + which the items were produced, makes the result independent of the order in which the + device happened to assemble the envelope. + The hashes field is optional even when a signature is present. The + envelope digest carried by the signature is sufficient to establish that the group of items + as a whole is intact; omitting the individual digests saves bandwidth and gives up only the + ability to determine which item was altered when verification fails. + The same trade-off is made by the Low Bitrate Mode of the ONVIF Media Signing + Specification. +
+ +
+ Observation + Observation is an abstract InformationItem that captures the + output of any generic sensor. Whether the source is a physical device such as a camera, a radar + or a thermometer, a person, or a virtual source such as a database, the observation packages + that output into a standardised format for consumption by downstream systems. The class is + abstract: an observation on the wire is always an instance of one of the concrete subclasses + below, or of a subclass introduced by a vendor extension. + Beyond the fields it inherits from InformationItem, an + Observation carries two optional context fields, which describe the situation + observed rather than the act of observing it: + + + observedTime — the time to which the observation refers, as specified in + . It is distinct from productionTime, which is + when the item was produced: a plate read from a recording refers to the moment of the + recording, not to the moment of the reading. + + + observedSpace — the place to which the observation refers, as specified in + . + + + An Observation states what a sensor produced. It is never revised: where an + ONVIF Device later has better information about the same subject, it emits a further + observation and, where it can, an Assertion relating the two, as described in + . An ONVIF Client shall not expect an + observation it has received to be superseded in place. + +
+ VehicleObservation + VehicleObservation reports a vehicle. Its only mandatory field beyond those + of InformationItem is type, drawn from the + VehicleType enumeration. + The enumeration provides Unknown precisely because type is + mandatory: an ONVIF Device that has detected a vehicle without classifying it reports + Unknown, and is never placed in the position of having to guess a type in order + to report a detection. It provides Other for a type that was determined but does + not appear in the enumeration, which an ONVIF Client shall not confuse with + Unknown: the first says the device knows and cannot express it, the second says + the device does not know. + The optional use field, drawn from the VehicleUse enumeration, + reports what the vehicle is used for. Use is orthogonal to type — an ambulance is a + Van, a Truck or a Car put to emergency medical service + — and the two fields shall not be conflated. Three states are distinguishable, and an ONVIF + Client shall distinguish them: the field is absent when the ONVIF Device does not classify + vehicle use at all; it is Unknown when the device does classify use but could + not determine it for this observation; and it names a value otherwise. + The optional brand, model and color fields report + further properties. brand and model are + StringLikelihood values, and therefore carry a likelihood of their own, + independent of the confidence of the item. +
+ +
+ LicensePlateObservation + LicensePlateObservation reports a licence plate. Its mandatory field is + plateNumber, a StringLikelihood. The optional + plateType, countryCode and issuingEntity fields report + the kind of plate, the country encoded as an ISO 3166-1:2013 Alpha-2 two-letter code, and the + authority that issued it. + A plate observation is a separate item from any vehicle observation made at the same + moment, and it is not nested inside one. The statement that a particular plate belongs to a + particular vehicle is a claim about two observations and is therefore an + Assertion, not a field. +
+ +
+ BarcodeObservation + BarcodeObservation reports information extracted from a barcode or 2D code. + Its mandatory field is data, a StringLikelihood carrying the + decoded content. The optional type field is a + BarcodeTypeLikelihood, which pairs a value of the BarcodeType + enumeration with a likelihood, and the optional ppm field reports the pixels per + module of the decoded symbol. +
+
+ +
+ Assertion + Assertion is a statement supported by one or more + InformationItem elements. Because an InformationItem can be an + Observation or Assertion, or a combination of both, Assertions + serve to convey richer, more complex information by synthesizing multiple supporting + items. + The supportedBy field holds the identifiers of the + supporting items, not copies of them. An assertion therefore states which items it relies + on without reproducing their content. This keeps an assertion small regardless of how much + evidence supports it, allows several assertions to cite the same item without duplicating + it, and ensures that an item covered by a signature is digested exactly once. + An Assertion is itself an InformationItem: it carries its own + id and, when conveyed in a signed envelope, is covered by its own digest. + Because the identifiers it cites are part of its canonical form, the signature over the + assertion also fixes the set of items it claims to be supported by. + +
+ Assertion sanity checks + To achieve robust and reliable parsers, the following sanity checks are required for + assertions: + + + Every identifier listed in supportedBy shall resolve to an + InformationItem the ONVIF Client has already received. + + + The productionTime of the assertion shall be more recent than the + productionTime of every supporting item. + + + The graph formed by taking information items as nodes and + supportedBy references as edges shall be directed and acyclic. + + + By traversing that graph, each assertion shall be traceable back to one or more + initial observations. + + + An ONVIF Client that receives an assertion citing an identifier it cannot resolve + shall not treat the assertion as invalid on that basis alone: the supporting item may + still be in transit, or may have been delivered on a stream the client did not subscribe + to. The client should defer evaluation until the reference can be resolved, and apply its + own policy if it never is. +
+ +
+ VehicleReidentification + VehicleReidentification is a concrete Assertion stating that two + or more vehicle observations, produced at different times, refer to the same physical vehicle. + It is the mechanism by which a later and better informed observation supersedes the + classification carried by an earlier one. + It exists because an Observation is never revised. A vehicle first seen at a + distance may be reported with type set to Unknown and a low + confidence; seen again, closer, it may be reported as a Van in + Ambulance use with a high confidence. Both observations are correct statements + about what the sensor produced at the time it produced them, and neither is withdrawn. What + was missing is the statement that they concern one vehicle, and that is what this class + carries. + Beyond the supportedBy field it inherits, of which at least two entries shall + be present since a single observation cannot be re-identified, the class carries: + + + vehicleId (mandatory) — a stable identifier of the physical vehicle to + which every observation listed in supportedBy refers. It designates a + physical entity and not an InformationItem, and is therefore the one + identifier in this model that is not subject to the resolution rule of + : an ONVIF Client shall not attempt to + resolve it to a received item. Successive re-identifications of the same vehicle shall + reuse the value, so that an ONVIF Client can accumulate what is known about one vehicle + across several assertions. + + + authoritativeObservation (optional) — the observation listed in + supportedBy whose classification an ONVIF Client should prefer. Where absent, + the observation with the most recent productionTime applies. The field exists + because recency is not always the right rule: an ONVIF Device that recognised a vehicle + clearly and then lost it to occlusion may consider the earlier reading the better + one. + + + The producer of a re-identification is typically not the producer of the observations it + cites. An observation comes from a video source; a re-identification comes from an algorithm, + whose provenance is an AnalyticsModule as described in + . The separation is deliberate and has a consequence an + ONVIF Client can act on: it may accept the observations and reject the assertion, because they + are distinct items with distinct provenance and distinct confidence. An ONVIF Client shall not + propagate the confidence of an observation to an assertion that cites it; an assertion may + well deserve less confidence than its evidence. +
+
+ +
+ Signature + Signature is an abstract class that describes a cryptographic attestation + bound to the content of an envelope. It is the type of the optional + signature field of InformationEnvelope. Different deployments can + require different signature formats and trust + frameworks; for this reason, the class is abstract and shall be specialised by concrete + signature profiles. + The presence of a Signature object on an envelope is optional. When + omitted, the enclosed items carry no integrity, authenticity, or non-repudiation claim; + signature is never applied to an individual InformationItem, as defined in + . + This specification defines one concrete profile, + OnvifSignature (see ). It is aligned with the + ONVIF Media Signing Specification, requires no JSON-LD processing, and allows a verifier to + determine which individual item was altered. + The class nevertheless remains abstract, and an ONVIF Client shall select the verification + procedure from the concrete type of the received object rather than assuming + OnvifSignature. This keeps a further profile addable in a later revision without + any change to InformationEnvelope, and it means that an ONVIF Client encountering + a profile it does not implement rejects that envelope rather than misreading it. + For any profile, the digest and signature algorithms that an ONVIF Device shall use, + and that an ONVIF Client shall accept, are those mandated by the current version of the + ONVIF Security Baseline Specification. Any algorithm enumeration appearing in the schema + fixes only how an algorithm is named on the wire; it is not a statement that the algorithm + is permitted. Where the schema and the ONVIF Security Baseline Specification disagree, the + latter prevails, and an ONVIF Client shall reject a signature that uses an algorithm the + baseline does not allow, even when the value is syntactically valid. + +
+ OnvifSignature + OnvifSignature is the concrete Signature profile defined by + this specification. It transposes to structured metadata the construction that the ONVIF + Media Signing Specification applies to video: there, each NAL Unit is hashed, the hashes + are collected in a list, a single hash of that list is computed, and only that hash is + signed. Here the same construction is applied with the InformationItem + taking the place of the NAL Unit and the InformationEnvelope taking the + place of the signed document. + The benefit is the same in both cases. One signing operation covers an arbitrary + number of elements, which keeps the cost on the device independent of the volume of + metadata produced, and the list of per-element hashes lets a verifier localise damage + instead of merely detecting it. + +
+ Canonicalisation + A signature is computed over octets, whereas the unit being protected here is a + JSON object. A deterministic serialisation is therefore required, so that the device + and the client hash exactly the same byte sequence. An ONVIF Device shall use the JSON + Canonicalization Scheme defined in RFC 8785. + RFC 8785 is used in preference to a canonicalisation defined over an expanded RDF + graph, which is what a proof format based on RDF would require, because it operates on + plain JSON: it requires neither JSON-LD expansion, nor context dereferencing, nor RDF + processing. This + keeps the profile implementable on a constrained device, consistently with the design + intent of the ONVIF Media Signing Specification. + It also keeps a signed envelope verifiable in isolation. A proof computed over an + expanded RDF graph can only be checked by a verifier that can still resolve the JSON-LD + context that was in force when the proof was made, which may be years later and on a + machine with no access to the originating device. Canonicalising the JSON as received + removes that dependency: the octets needed to verify an envelope are the octets of the + envelope. + The canonical form of an item is the JSON object representing that item exactly as + it appears in the items list of the envelope, including its + @type and its id. The digest of an item is therefore + inseparable both from the identifier that names it and from the class that gives it + meaning: an item cannot be moved under a different identifier, nor reinterpreted as a + different class, without invalidating the signature. +
+ +
+ Signing procedure + Let H denote the hash function selected by digestAlgorithm + and JCS(x) the canonical serialisation of the object x + according to . An ONVIF Device shall produce an + OnvifSignature as follows. + + + For every enclosed item item_i, compute + d_i = H(JCS(item_i)). + + + Emit one ItemDigest per item, carrying the item identifier and + d_i, and sort the resulting entries by identifier in ascending + order as required by . Let + d_1 … d_n denote the digests in that order. + + + Build the signature configuration: the + OnvifSignature object with the envelopeDigest and + signatureValue fields removed. It comprises the two algorithm fields, + created, and key. + + + Compute envelopeDigest = H( JCS(signatureConfiguration) || d_1 || … || + d_n ), where || denotes concatenation and each + d_i is contributed as its raw octets, not as its + base64 text. This mirrors the ONVIF Media Signing Specification, which concatenates + hashes as if they were aligned in memory. + + + Compute signatureValue by signing envelopeDigest with + the algorithm named by signatureAlgorithm and the key described by + key. + + + The signature configuration is included in the digest deliberately. Were the digest + computed over the item digests alone, the algorithm fields would lie outside the + signature, and an attacker could rewrite them to name a weaker algorithm while leaving + the signature formally verifiable. The ONVIF Media Signing Specification avoids this by + placing the cryptographic information inside the signed document; the step above + reproduces that property. Including key likewise prevents a signature from + being re-attributed to a different key, and including created binds the + declared signing time. +
+ +
+ Verification procedure + An ONVIF Client shall verify a signed envelope in two stages. + + + Reconstruct the signature configuration from the received object, recompute + envelopeDigest as specified above, and verify + signatureValue against it using the public key obtained from + key. If this succeeds, every enclosed item is authentic and + unmodified, and no further computation is required. + + + If it fails and the hashes list is present, recompute + H(JCS(item_i)) for each enclosed item and compare it with the + corresponding ItemDigest. Any entry that does not match identifies an + item that was altered; an entry present in hashes with no + corresponding item identifies one that was removed. + + + The second stage is diagnostic only. An envelope whose signature does not verify + shall be treated as unauthentic as a whole, irrespective of how many of its items + individually match. The purpose of the per-item comparison is to let an operator or a + downstream system know what was tampered with, not to salvage part of the + envelope. + When hashes is absent, only the first stage is possible; this is the + trade-off described in . +
+ +
+ ItemDigest + ItemDigest binds one digest to one information item. It carries the + following fields: + + + item (mandatory) — the UUID of the covered + InformationItem, equal to the id of that item. + + + digest (mandatory) — the digest of the canonical form of + that item, encoded in base64 as defined in RFC 4648. + + + The digest algorithm is not repeated in each entry: it is declared once, in the + digestAlgorithm field of the signature, and applies to every entry of the + list. +
+ +
+ SigningKey + SigningKey is an abstract class describing the key used to produce a + signature. It is abstract because the key material may either travel with every signed + envelope or be published once and subsequently referenced. The ONVIF Media Signing + Specification makes the same distinction, allowing the certificate chain to appear in + every signed unit or only in a dedicated certificate unit at stream start. + Two concrete subclasses are defined. + X509CertificateChain carries the certificate chain needed to verify + the signature, and has the following fields: + + + certificateChain (mandatory) — the chain in PEM format, + ordered from the leaf certificate towards the certification authority. The leaf + certificate contains the public key. As in the ONVIF Media Signing Specification, + the certification authority certificate itself shall not be included. + + + userProvisioned (optional, default false) — + set to true when the chain is a user provisioned chain rather than a + manufacturer provisioned one. + + + PublicKeyIdentifier references key material distributed out of band, + so that the chain need not be repeated in every envelope, and has the following + fields: + + + keyId (mandatory) — the identifier of the key, stable for + the lifetime of that key. It is drawn from the same identifier space as + tas:KeyID of the ONVIF Advanced Security Service, that is, the + keystore of the producing device. + + + verificationMethod (optional) — a URI from which the + corresponding public key or certificate chain can be retrieved. + + + fingerprints (optional) — zero or more + KeyFingerprint objects, at most one per digest algorithm, identifying + the key material the keyId is expected to designate (see ). + + + Because the identifier space is that of the device keystore, this value is directly + comparable with the identifiers a device declares in the publicKeys field + of its provenance (see ). An ONVIF Client can thus + detect an envelope signed with a key the producing device does not claim as its + own. + An ONVIF Client that receives a PublicKeyIdentifier for a key it does + not hold shall not accept the envelope until it has obtained and validated the + corresponding key material through a trusted path. +
+ +
+ Signature fields + OnvifSignature carries the following fields: + + + digestAlgorithm (mandatory) — the hash algorithm used both + for the per-item digests and for the envelope digest. + + + signatureAlgorithm (mandatory) — the algorithm used to + sign the envelope digest. + + + created (mandatory) — ISO 8601 UTC datetime at which the + signature was created. + + + key (mandatory) — the SigningKey describing + the key used. + + + envelopeDigest (mandatory) — the digest computed in step 4 + of , encoded in base64. + + + signatureValue (mandatory) — the digital signature over + envelopeDigest, encoded in base64. + + + Both algorithm fields name their algorithm by a symbolic value whose formal meaning + is the corresponding object identifier, so that an algorithm is designated here by the + same identifier the ONVIF Media Signing Specification uses. The permitted values remain + those of the ONVIF Security Baseline Specification. + Information identifying the product and the vendor is not repeated in the + signature. In the ONVIF Media Signing Specification such data is carried in a dedicated + field because the video stream has no other place for it; in this model it is already + expressed by the provenance field of each information item, and is + therefore covered by the item digest. +
+
+ +
+ Key fingerprints + A KeyID names an entry in the keystore of one device. It says nothing + about the material that entry holds: the same identifier designates different material + after a key rotation, and the same identifier on two devices designates unrelated + material. An ONVIF Client that matched a key on the strength of an identifier alone would + therefore be trusting a label, not a key. + KeyFingerprint closes that gap. It carries a digest of the key itself, + computed over the DER encoding of the SubjectPublicKeyInfo structure defined + in IETF RFC 5280, together with the digest algorithm used to compute it. The two fields + are: + + + algorithm (mandatory) — the digest algorithm, which shall be + one of those mandated by the current version of the ONVIF Security Baseline + Specification. + + + value (mandatory) — the digest of the DER encoded + SubjectPublicKeyInfo structure, encoded in base64. + + + The input is the key, not a certificate that carries it. Two certificates issued at + different times for the same key yield the same fingerprint, so a fingerprint survives a + certificate renewal, a firmware upgrade and a change of device, which the fingerprint of a + certificate does not. It is also the same octet sequence that the PEM form carried by + subjectPublicKeyInfo encodes, so a fingerprint can always be recomputed from + that field alone and an ONVIF Client never has to take a declared fingerprint on + trust. + Fingerprints appear in two places. In DevicePublicKey, they make the key + declaration of a provenance checkable (see ): an ONVIF + Client that holds a fingerprint obtained by an independent path considers the key matched + when that fingerprint equals one of those listed, and shall not consider a key matched on + the basis of keyId alone. In PublicKeyIdentifier, they state + which key material the signer claims to have used. + A fingerprint carried in PublicKeyIdentifier has a further property. The + key descriptor is part of the signature configuration, and the signature configuration is + covered by the envelope digest as computed in step 4 of . The fingerprint is therefore covered by the signature itself, which binds the + signature to key material rather than to the name of a keystore entry: an attacker cannot + substitute a different key for the same keyId without invalidating the + signature. + Because provenance is repeated on every information item, the + fingerprints field of DevicePublicKey is normally omitted from + items carried in a metadata stream, and is populated where an ONVIF Client is expected to + pin a key, such as in a signed InformationEnvelope. +
+ +
+ +
+ Location + Location is an abstract class that represents the spatial context of an + observation. It is the type of the optional observedSpace field of + Observation; when present it shall be an instance of a concrete + subclass. + The class is abstract because a place can be given in two irreducibly different ways. + It can be given by the function it serves — an ambulance drop-off, a loading bay, a + pedestrian crossing — which is a name assigned when the site is commissioned and which says + what happens there but not where it is. Or it can be given by its geometry: a polygon in + image coordinates, a point in a geographic reference system, a volume in a building model. + Neither form can be derived from the other, and a class that tried to carry both would leave + an ONVIF Client unable to tell which of the two it had actually been given. + This specification defines the functional form only. A geometric form may be added as a + further concrete subclass in a later revision without any change to + Observation, and an ONVIF Client shall therefore select its handling from the + concrete type of the received object rather than assuming + FunctionalLocation. + +
+ FunctionalLocation + FunctionalLocation is the concrete Location that names a + place by the function it serves. It carries the following fields: + + + name (mandatory) — the human readable name of the place as + configured on the ONVIF Device, for example Ambulance Drop-off. + + + token (optional) — a ReferenceToken identifying + the configured area the name refers to. It allows the place to be correlated across + information items even if its name is later changed, and to be looked up in the + analytics configuration of the device. + + + description (optional) — a longer description of the function + the place serves. + + + A functional location is meaningful only within the installation it belongs to. The + name is assigned by whoever commissioned the site and carries no meaning outside it: two + installations may both have a Main Gate, and the same gate may be renamed + without anything about the site having changed. An ONVIF Client shall therefore treat + name as a label for presentation, and token, where present, as + the key for correlation. + The description field is omitted from items carried in a metadata stream, + where the location is repeated on every item; it belongs to the configuration and + presentation paths instead. +
+
+ +
+ Time + Time is an abstract class that provides an authoritative time reference + for an information item, independent of the device system clock. Different kinds of + information + require different temporal representations — an instant for a discrete event, a span for a + condition that holds over a period — and for this reason the class is abstract and shall be + specialised by one of the concrete subclasses defined below. + Time is the type of two fields. Every InformationItem + carries a mandatory productionTime, the time at which the item itself was + produced. An Observation additionally carries an optional + observedTime, the temporal context of what was observed. The two are not + necessarily equal: an observation produced at one instant may describe a phenomenon that + occurred, or persisted, at another. + Both fields accept any concrete subclass of Time. An ONVIF Client shall + therefore determine the temporal representation from the instance it receives rather than + assume a single form. Like the other abstract classes in this chapter, Time + carries an optional vendor extension point (see ). + +
+ ISO8601Timestamp + ISO8601Timestamp is a concrete subclass of Time that + represents a single instant. It carries one field: + + + timestamp (mandatory) — the instant, formatted as an ISO + 8601 date and time (YYYY-MM-DDTHH:MM:SS, for example + 2026-09-09T15:54:00Z). The value shall carry the UTC designator or an + explicit offset, so that the instant it denotes is unambiguous for a recipient in + another time zone. + + + This is the representation to use when the information item refers to a point in + time, such as the moment at which a detection occurred. +
+ +
+ ISO8601Interval + ISO8601Interval is a concrete subclass of Time that + represents a span rather than an instant. It carries one field: + + + intervalString (mandatory) — the span, formatted as a single + ISO 8601 time interval string. + + + ISO 8601 admits several interval forms, all of which are carried in this one field: a + start and an end instant + (2026-09-09T15:00:00Z/2026-09-09T16:00:00Z); a start instant and a duration + (2026-09-09T15:00:00Z/P1M); and a repeating interval + (R5/2026-09-09T15:00:00Z/P1M). The instants appearing in the string are + subject to the same disambiguation requirement stated for + ISO8601Timestamp. + This is the representation to use when the information item refers to a condition + that holds over a period, such as a dwell time or an aggregation window, rather than to a + single instant. +
+
+ +
+ Provenance + Provenance is an abstract class that identifies the originator of an + information item. It is the type of the mandatory provenance field of + InformationItem, so every item states who is asserting it. Where + Time answers when the information was produced and Location where + the observed phenomenon was, Provenance answers who says so. + The class is abstract because producers of different natures are described by different + attributes, and shall be specialised by a concrete subclass. This specification defines two + such subclasses: ONVIFDevice, used when the producer is a device or one of its + sources, and AnalyticsModule, used when the producer is an algorithm running on + a device. Like the other abstract classes in this chapter, Provenance carries an + optional vendor extension point (see ). + The distinction between the two is what allows the two kinds of claim defined in this + chapter to be told apart. An Observation produced by a video source and an + Assertion derived from it by an algorithm running on the same device do not have + the same producer, even though they leave the device through the same interface and may + travel in the same envelope. An ONVIF Client may have reason to trust the sensor and not the + algorithm, or to trust one version of the algorithm and not another, and it can only act on + that distinction if the items state it. + Provenance is part of the content of an information item. When the item travels inside + a signed envelope it is therefore covered by the item digest, as specified in , and cannot be altered without invalidating the + signature. + +
+ ONVIFDevice + ONVIFDevice is the concrete Provenance subclass used when + the producer of an information item is an ONVIF Device. Rather than introduce a new way + of describing a device, it reuses the fields ONVIF already defines for that purpose: the + five descriptive fields are those returned by GetDeviceInformationResponse, + and the optional entity reference is the token of tt:DeviceEntity. The same + information is carried by the ONVIF Media Signing Specification alongside a signed video + stream, where it is likewise omissible. + All five descriptive fields are optional, and the only mandatory field is + publicKeys. This is deliberate, and it means that in this model + a device is identified by the keys it holds, not by how it describes + itself. The reason is given in . + ONVIFDevice carries the following fields: + + + manufacturer (optional) — the manufacturer of the + device. + + + model (optional) — the device model. + + + firmwareVersion (optional) — the firmware version in the + device. + + + serialNumber (optional) — the serial number of the + device. + + + hardwareId (optional) — the hardware ID of the + device. + + + entity (optional) — a DeviceEntity naming the + part of the device that produced the information. + + + publicKeys (mandatory) — one or more + DevicePublicKey entries. At least one entry shall be present. + + + These fields are optional here although + GetDeviceInformationResponse requires them. The context is different: there + they answer a question a client asked of the device, here they are attached to every + single information item the device produces. Making them optional lets a device avoid + repeating on each item what a client may already have obtained, and lets it withhold + serial number and hardware ID on streams where those are considered sensitive. + An ONVIF Device that exposes more than one source of information shall populate + entity. Without it, items originating from different channels or inputs of the + same device are indistinguishable from one another, and an ONVIF Client receiving two + contradictory observations from a multichannel encoder has no way of telling whether they + describe two different scenes or disagree about one. A device with a single source may omit + the field, since there is then nothing to distinguish. + +
+ DeviceEntity + DeviceEntity designates a physical or logical entity of a device, such + as an input, an output, or a channel. It carries one field: + + + token (mandatory) — a unique identifier referencing the + entity, drawn from the same identifier space as + tt:ReferenceToken of the ONVIF Schema and therefore at most 64 + characters long. + + + An ONVIF Device should use here the same token it uses for that entity in its other + ONVIF interfaces, so that an information item can be related to the video source, + input, or output it came from. +
+ +
+ Declared public keys + DevicePublicKey declares one public key the device claims as its own. + It carries the following fields: + + + keyId (mandatory) — the identifier of the key in the + keystore of the device, drawn from the same identifier space as + tas:KeyID of the ONVIF Advanced Security Service. It names an entry of + that keystore and not the key material the entry holds. + + + fingerprints (optional) — zero or more + KeyFingerprint objects, at most one per digest algorithm, identifying + the key material itself (see ). An ONVIF Client + that holds a fingerprint obtained by an independent path considers the key matched + when that fingerprint equals one of those listed, and shall not consider a key + matched on the basis of keyId alone. + + + subjectPublicKeyInfo (optional) — the public key in PEM + format. It is normally omitted: provenance is repeated on every information item, + and embedding key material on each one would be wasteful. It is included only when + the key has to travel with the item. + + + Using the keystore identifier space is what makes the declaration useful. The + signature of an envelope names the key that signed it (see ), the provenance names the keys the device holds, and the + two can be compared because both are identifiers of the same keystore. An ONVIF Client + can therefore tell whether an envelope was signed with a key the producing device + claims as its own, and can look that key up through the Advanced Security Service. + The comparison of identifiers alone establishes only that the two names agree. + Where the envelope and the provenance both carry a fingerprint, the comparison is one of + key material, and it is that comparison an ONVIF Client shall rely on. + No field states what a key is used for. The keystore of the device is the + authoritative source for that, and restating it here would only create a second place + able to contradict the first. + A declared key shall not be used to establish trust. The declaration lives inside + the information item, and is therefore only as trustworthy as the item that carries it: + an attacker who fabricates an envelope can name keys of their own and sign it with the + matching private key, producing a document that is internally consistent and entirely + false. An ONVIF Client shall establish trust in a key only through an independent + path — the keystore of the device queried over an authenticated channel, a certificate + chain leading to a trusted certification authority, or provisioning — and shall use the + declared keys only to discover which keys to look up, to follow a key rotation, or to + detect that an envelope was signed with a key the device does not claim. + This is also why publicKeys is the one mandatory field of + ONVIFDevice even though it is self-asserted. A key identifier is a + reference to material that can be verified by an independent path; + the descriptive fields reference nothing, and no procedure exists by which a client + could confirm them. The mandatory field is the one that can be + checked, not the one that already has been. + It follows that an ONVIF Client shall not base trust decisions or access control + decisions on manufacturer, model, + firmwareVersion, serialNumber, or hardwareId. + Those fields are for diagnostics, inventory, and presentation. +
+
+ +
+ AnalyticsModule + AnalyticsModule is the concrete Provenance subclass used when + the producer of an information item is an algorithm rather than a sensor. It is the + provenance that normally applies to an Assertion: an assertion is the product + of reasoning over items already produced, and what a client needs to know about it is which + algorithm reasoned, in which version, over the data of which source. + AnalyticsModule carries the following fields: + + + token (mandatory) — a unique identifier of the module within + the device, drawn from the same identifier space as the token of + tt:AnalyticsModule of the ONVIF Schema, so that a module named here can be + looked up in the analytics configuration of the device. + + + algorithm (optional) — an identifier of the algorithm the + module implements, for example vehicle-reidentification. + + + version (optional) — the version of the algorithm, or of the + model it runs. + + + entity (optional) — a DeviceEntity naming the + part of the device whose data the module consumed. + + + publicKeys (mandatory) — one or more + DevicePublicKey entries. At least one entry shall be present. + + + The version field is what makes a derived item reproducible. Two items + produced by the same algorithm in different versions are not comparable, and an ONVIF + Client that has qualified one version has not thereby qualified another. A device that + updates an analytics model without changing this field leaves a client unable to tell that + the basis of the claims it is receiving has changed. + entity is populated for the same reason as in ONVIFDevice, + and an ONVIF Device whose module consumes data from more than one source shall populate it. + The field is a reference to the source, not a claim about it: an assertion drawn from two + channels names the module that drew it, while the observations it cites name the channels + they came from. + As in ONVIFDevice, publicKeys is the only mandatory + descriptor, and for the same reason (see ): the key + identifier, together with any fingerprint accompanying it, is the one piece of information + in the class that refers to material an ONVIF Client can verify by an independent path. + algorithm and version are self-asserted and shall not be used as + the basis of a trust decision; they are the means by which a client decides how to + interpret a claim it has already decided to accept. +
+
+ +
+ Vendor Extensions + ONVIF follows the convention, established in its WSDL-based specifications, of + providing a generic extension point in every data structure to allow implementers to + carry vendor-specific information without breaking interoperability. This specification + carries that convention into the LinkML metadata model, and adds a second mechanism that + the WSDL-based specifications had no need for: a vendor may also define classes of its + own. + +
+ Extending a class with fields + A class that supports vendor-specific fields declares an optional slot named + extensible whose range is the abstract class Extensible. + Extensible is not inherited: a class that supports extension declares the slot + individually, and the classes of this specification that support it do so. The only + exceptions are VendorExtension and VendorExtensible, which are + themselves extension containers and derive from Extensible. + VendorExtension is a single extension entry. It pairs a mandatory vendor + namespace URI with a locally named, arbitrarily typed value; the namespace URI uniquely + identifies the vendor and prevents naming collisions between implementers. + VendorExtensible groups several such entries, and is the value to use where + more than one extension has to be carried on the same class. + An ONVIF Client that encounters a VendorExtension whose + vendor_namespace it does not recognise shall ignore that entry and shall not + treat its presence as an error. An ONVIF Device shall not use the extension point to carry + information that is required for correct interpretation of the normative fields of the + enclosing class: an extension is additional information, never a modifier of what is + already there. +
+ +
+ Extending the model with classes + A vendor may also define entirely new information item classes, by deriving them from + Observation, from Assertion, or from any concrete class of this + specification, and publishing them in a LinkML module of its own. This is how a device + reports information for which no class defined here is adequate, and it is the mechanism the + event type catalogue exposes (see ). + Vendor classes are declared in a vendor-controlled namespace. A vendor module declares + its own prefix and its own default_prefix, so the class URI of every class it + defines is formed from a namespace the vendor controls, and two vendors that independently + choose the same local name for a class still define two distinct classes. The + @type of an instance of a vendor class is written as a CURIE using that + prefix, as specified in ; only the classes + of the ONVIF Agentic Schema Bundle are written as bare local names. + The prefixes served by one ONVIF Device shall be mutually distinct. Where two vendor + modules a device serves declare the same prefix for different namespaces, the device + arbitrates: it renames one of them in the context it derives and in the @type + values it emits. A prefix is therefore local to one device, and an ONVIF Client shall + resolve a CURIE through the context of the session in which it was received rather than + treat the prefix as a global name. + Two consequences follow from the structure of a LinkML module and shall be taken into + account by anyone defining a vendor class. + + + Class names are flat across the imports closure. A vendor module that imports the + bundle shares one name space with it, so a vendor class shall not reuse the local name + of a class defined by the bundle or by another module in the same closure. The + namespacing described above distinguishes the class URIs; it does + not make the local names independent within a single closure. + + + An enumeration reached through imports cannot be extended with further + permissible values. A vendor that needs a value an enumeration of this specification + does not offer cannot add it to that enumeration; it shall either use the fallback value + the enumeration provides, where one exists, or define a class of its own carrying an + enumeration of its own. This is why the enumerations of this specification that describe + a classification carry Other and Unknown values (see ). + + + An ONVIF Client that receives an item of a class it cannot resolve shall handle it as + specified in , and shall not discard the + enclosing envelope on that account. +
+
+
+ + + Example Call Sequence (informative) + This annex is informative and provides an example end-to-end sequence with sample + values. + +
+ Network discovery (ONVIF Core) + Request (Client to Device): The ONVIF Client sends ONVIF Core + discovery requests (for example WS-Discovery Probe) to locate devices on the network. + Response (Device to Client): The ONVIF Device returns discovery + responses (for example ProbeMatches) with the Device Service endpoint. +
+
+ Service discovery (ONVIF Core GetServices) + Request (Client to Device): The ONVIF Client calls ONVIF Core + GetServices on the Device Service endpoint. + Response (Device to Client): The ONVIF Device returns + GetServiceResponse including the Agentic Service entry with MCP endpoint URL + (example: https://192.0.2.10/mcp). +
+
+ Session initialization + Request (Client to Device): The ONVIF Client calls + server/discover to obtain the device identity, supported protocol versions, + and capability flags. + { + "jsonrpc": "2.0", + "id": 1, + "method": "server/discover", + "params": { + "_meta": { + "io.modelcontextprotocol/protocolVersion": "2026-07-28", + "io.modelcontextprotocol/clientInfo": { + "name": "MyAgenticClient", + "version": "1.0.0" + }, + "io.modelcontextprotocol/clientCapabilities": { + "extensions": { + "io.modelcontextprotocol/tasks": {} + } + } + } + } +} + Response (Device to Client): The ONVIF Device returns its + identity, the list of supported protocol versions, and its capability flags. + { + "jsonrpc": "2.0", + "id": 1, + "result": { + "resultType": "complete", + "identity": { + "name": "ONVIF Agentic Service", + "version": "1.0.0" + }, + "protocolVersions": ["2026-07-28"], + "capabilities": { + "resources": {}, + "tools": {}, + "events": { + "listChanged": true + }, + "extensions": { + "io.modelcontextprotocol/tasks": {} + } + } + } +} + Legacy client rejection (informative): A legacy client + connecting with a pre-2026-07-28 protocol version (for example via an + initialize request) will receive an + UnsupportedProtocolVersionError. The ONVIF Device shall not support + protocol versions prior to 2026-07-28 and shall always include the + supported list so that the client can retry. + { + "jsonrpc": "2.0", + "id": 1, + "method": "initialize", + "params": { + "protocolVersion": "2024-11-05", + "capabilities": {}, + "clientInfo": { "name": "LegacyClient", "version": "0.9.0" } + } +} + { + "jsonrpc": "2.0", + "id": 1, + "error": { + "code": -32022, + "message": "UnsupportedProtocolVersionError", + "data": { + "supported": ["2026-07-28"] + } + } +} + Request (Client to Device): The ONVIF Client sends the + server/discover request to https://192.0.2.10/mcp as its + first request on the connection, as defined by MCP 2026-07-28. The session initialization + exchange is a single JSON-RPC request/response; the ONVIF Client subsequently opens an + events/stream request, or calls events/subscribe, to receive + metadata events, as shown in . +
+
+ Schema resource inventory + Request (Client to Device): The ONVIF Client sends + resources/list to enumerate all resources, including LinkML schema + resources. + { + "jsonrpc": "2.0", + "id": 6, + "method": "resources/list", + "params": { + "_meta": { + "io.modelcontextprotocol/protocolVersion": "2026-07-28" + } + } +} + Response (Device to Client): The ONVIF Device returns available + resources. Resources with mimeType: application/linkml+yaml are the schema + files to be retrieved in . The device serves the + six modules of the ONVIF Agentic Schema Bundle described in + . + { + "jsonrpc": "2.0", + "id": 6, + "result": { + "resultType": "complete", + "resources": [ + { + "uri": "linkml://192.0.2.10/agentic/common", + "name": "ONVIF Agentic Common Types", + "mimeType": "application/linkml+yaml" + }, + { + "uri": "linkml://192.0.2.10/agentic/enums", + "name": "ONVIF Agentic Enumerations", + "mimeType": "application/linkml+yaml" + }, + { + "uri": "linkml://192.0.2.10/agentic/time", + "name": "ONVIF Agentic Time", + "mimeType": "application/linkml+yaml" + }, + { + "uri": "linkml://192.0.2.10/agentic/signature", + "name": "ONVIF Agentic Signature", + "mimeType": "application/linkml+yaml" + }, + { + "uri": "linkml://192.0.2.10/agentic/base", + "name": "ONVIF Agentic Metadata Model", + "mimeType": "application/linkml+yaml" + }, + { + "uri": "linkml://192.0.2.10/agentic", + "name": "ONVIF Agentic Skill Interface", + "mimeType": "application/linkml+yaml" + } + ] + } +} + These resource URIs are chosen by the ONVIF Device and are not the same thing as the + id of the module they carry: the module served at + linkml://192.0.2.10/agentic/base declares + id: https://www.onvif.org/ver10/agentic/base/linkml/, and another device serving + the same module would very likely address it differently. The distinction is the one drawn in + . +
+
+ Schema retrieval + Request (Client to Device): The ONVIF Client sends + resources/read for each application/linkml+yaml resource URI + obtained from . The example reads + agentic/base. + { + "jsonrpc": "2.0", + "id": 7, + "method": "resources/read", + "params": { + "uri": "linkml://192.0.2.10/agentic/base", + "_meta": { + "io.modelcontextprotocol/protocolVersion": "2026-07-28" + } + } +} + Response (Device to Client): The ONVIF Device returns the + LinkML schema as a YAML string in the text field. The ONVIF Client + registers this schema in its validator. The request is repeated for each of the six modules + listed in , since a module is only interpretable + together with the modules it imports. + { + "jsonrpc": "2.0", + "id": 7, + "result": { + "resultType": "complete", + "contents": [{ + "uri": "linkml://192.0.2.10/agentic/base", + "mimeType": "application/linkml+yaml", + "text": "id: https://www.onvif.org/ver10/agentic/base/linkml/\nname: onvif-agentic-base\n..." + }] + } +} + Having loaded the six modules, the ONVIF Client holds the whole vocabulary the device + will use in its payloads, and can derive from them both the JSON Schema it validates against + and, if it performs JSON-LD processing, the context described in + . No further schema retrieval is needed + unless the device later announces a class the client cannot resolve, which is the case shown + in . +
+
+ Tool discovery + Request (Client to Device): The ONVIF Client sends + tools/list to obtain the catalogue of available Skills. + { + "jsonrpc": "2.0", + "id": 8, + "method": "tools/list", + "params": { + "_meta": { + "io.modelcontextprotocol/protocolVersion": "2026-07-28" + } + } +} + Response (Device to Client): The ONVIF Device returns one Tool + entry per supported Skill, each with a compiled inputSchema derived from the + LinkML model. The example shows get_status only. + { + "jsonrpc": "2.0", + "id": 8, + "result": { + "resultType": "complete", + "tools": [ + { + "name": "get_status", + "description": "Returns the operational status of the agentic engine.", + "inputSchema": { + "type": "object", + "properties": {}, + "required": [] + } + } + ] + } +} +
+
+ Skill invocation — get_status + Request (Client to Device): The ONVIF Client calls + get_status with no arguments. + { + "jsonrpc": "2.0", + "id": 9, + "method": "tools/call", + "params": { + "name": "get_status", + "arguments": {}, + "_meta": { + "io.modelcontextprotocol/protocolVersion": "2026-07-28" + } + } +} + Response (Device to Client): The ONVIF Device returns the current + state of the agentic engine, the list of active functions, and the engine firmware + version. + { + "jsonrpc": "2.0", + "id": 9, + "result": { + "resultType": "complete", + "content": [{ "type": "text", "text": "agentic engine running." }], + "structuredContent": { + "state": "running", + "activeFunctions": [ + { + "function": "vehicle_detection", + "executionId": "exec_vehicle_001" + }, + { + "function": "vehicle_reidentification", + "executionId": "exec_reid_001" + } + ], + "engineVersion": "2.1.4" + } + } +} +
+
+ Skill invocation — list_functions + Request (Client to Device): The ONVIF Client calls + list_functions with no arguments. + { + "jsonrpc": "2.0", + "id": 10, + "method": "tools/call", + "params": { + "name": "list_functions", + "arguments": {}, + "_meta": { + "io.modelcontextprotocol/protocolVersion": "2026-07-28" + } + } +} + Response (Device to Client): The ONVIF Device returns all + functions it supports, their configured/available state, and the LinkML classes that govern + the calls applicable to each function. Every entry carries both a local + name and a canonicalUri. + { + "jsonrpc": "2.0", + "id": 10, + "result": { + "resultType": "complete", + "content": [{ "type": "text", "text": "4 function(s) available." }], + "structuredContent": { + "functions": [ + { + "name": "vehicle_detection", + "canonicalUri": "https://vendor.example/agentic/function/vehicle_detection", + "description": "Detect and classify vehicles in the scene.", + "enabled": true, + "configSchema": "https://vendor.example/agentic/linkml/#/$defs/VehicleDetectionConfig" + }, + { + "name": "vehicle_reidentification", + "canonicalUri": "https://vendor.example/agentic/function/vehicle_reidentification", + "description": "Assert that vehicle observations refer to the same physical vehicle.", + "enabled": true, + "configSchema": "https://vendor.example/agentic/linkml/#/$defs/VehicleReidentificationConfig" + }, + { + "name": "license_plate_recognition", + "canonicalUri": "https://vendor.example/agentic/function/license_plate_recognition", + "description": "Read license plates of detected vehicles.", + "enabled": false, + "configSchema": "https://vendor.example/agentic/linkml/#/$defs/LicensePlateRecognitionConfig" + }, + { + "name": "set_event_stream_parameters", + "canonicalUri": "https://www.onvif.org/ver10/agentic/function/set_event_stream_parameters", + "description": "Set the keep-alive interval of the event stream.", + "enabled": true, + "executionSchema": "https://www.onvif.org/ver10/agentic/linkml/#/$defs/SetEventStreamParametersRequest", + "resultSchema": "https://www.onvif.org/ver10/agentic/linkml/#/$defs/SetEventStreamParametersResponse", + "capabilitiesSchema": "https://www.onvif.org/ver10/agentic/linkml/#/$defs/EventStreamCapabilities" + } + ] + } + } +} + The two identifiers play different roles, as specified in + . The name is what the ONVIF Client + passes back in the function argument of configure_function, + execute_function, stop_function and + get_function_capabilities; it is unique within this response only, and this + device may have renamed a function to make it so. The canonicalUri is what the + client uses to recognise the function: it is the same on every device + that implements the function, so a client that knows how to drive + https://vendor.example/agentic/function/vehicle_reidentification can drive it on + any of them, whatever local name each has chosen. + The reserved function has a canonicalUri in the ONVIF function namespace, + https://www.onvif.org/ver10/agentic/function/ followed by the reserved name. The + three others lie in a namespace controlled by the party that defined them. + license_plate_recognition is listed with enabled: false. The + function exists on this device but is not configured, so the ONVIF Client can see that + license plate observations are obtainable here and knows to call + configure_function first. This is why the catalogue lists unconfigured functions + rather than hiding them. +
+
+ Skill invocation — get_function_capabilities + Request (Client to Device): The ONVIF Client reads the static + capabilities of the reserved set_event_stream_parameters function before choosing an + interval, so that its request is not clamped. The arguments object is an + instance of the LinkML class GetFunctionCapabilities. + { + "jsonrpc": "2.0", + "id": 13, + "method": "tools/call", + "params": { + "name": "get_function_capabilities", + "arguments": { + "function": "set_event_stream_parameters" + }, + "_meta": { + "io.modelcontextprotocol/protocolVersion": "2026-07-28" + } + } +} + Response (Device to Client): The capabilities object + is an instance of EventStreamCapabilities, the class named by + capabilitiesSchema in the function's catalogue entry. These values are + invariant for this device instance. + { + "jsonrpc": "2.0", + "id": 13, + "result": { + "resultType": "complete", + "content": [{ "type": "text", + "text": "Keep-alive 5000-300000 ms; up to 4 concurrent streams." }], + "structuredContent": { + "function": "set_event_stream_parameters", + "capabilities": { + "defaultKeepaliveIntervalMs": 30000, + "minKeepaliveIntervalMs": 5000, + "maxKeepaliveIntervalMs": 300000, + "maxConcurrentStreams": 4 + } + } + } +} + Response (Device to Client — unknown function): A function the + ONVIF Device does not support is rejected. + { + "jsonrpc": "2.0", + "id": 13, + "error": { + "code": -32011, + "message": "NotFound", + "data": { "function": "thermal_drift_detection" } + } +} +
+
+ Skill invocation — configure_function + Request (Client to Device): The ONVIF Client calls + configure_function specifying the function and a + config object whose structure matches the LinkML class identified by + configSchema (obtained from list_functions). + { + "jsonrpc": "2.0", + "id": 11, + "method": "tools/call", + "params": { + "name": "configure_function", + "arguments": { + "function": "vehicle_detection", + "config": { + "sensitivity": 0.80, + "channel": "ch1", + "classifyUse": true + } + }, + "_meta": { + "io.modelcontextprotocol/protocolVersion": "2026-07-28", + "io.modelcontextprotocol/clientCapabilities": { + "extensions": { + "io.modelcontextprotocol/tasks": {} + } + } + } + } +} + Response (Device to Client — success): + { + "jsonrpc": "2.0", + "id": 11, + "result": { + "resultType": "complete", + "content": [{ "type": "text", "text": "vehicle_detection configured successfully." }], + "structuredContent": { + "function": "vehicle_detection", + "applied": { + "sensitivity": 0.80, + "channel": "ch1", + "classifyUse": true + } + } + } +} + classifyUse is a configuration option of this vendor's function, not a + field of the metadata model. Enabling it is what makes the difference, in the observations of + , between a use field carrying + Unknown and a use field being absent altogether: a device that does + not classify vehicle use omits the field, whereas a device that classifies it and fails + reports Unknown. + Response (Device to Client — asynchronous): If configuration + requires asynchronous processing, the same tools/call request may return a + task handle instead of the final result. + { + "jsonrpc": "2.0", + "id": 11, + "result": { + "resultType": "task", + "task": { + "taskId": "task_123", + "status": "working", + "ttlMs": 3600000, + "pollIntervalMs": 2000 + } + } +} + Response (Device to Client — validation error): If the + config object violates a schema constraint, the ONVIF Device returns a + structured error identifying the failing field. + { + "jsonrpc": "2.0", + "id": 11, + "error": { + "code": -32602, + "message": "InvalidParams", + "data": { + "field": "config.sensitivity", + "violation": "value 1.5 exceeds maximum 1.0" + } + } +} +
+
+ Skill invocation — execute_function + Request (Client to Device): The ONVIF Client starts a configured + function. + { + "jsonrpc": "2.0", + "id": 12, + "method": "tools/call", + "params": { + "name": "execute_function", + "arguments": { + "function": "vehicle_detection" + }, + "_meta": { + "io.modelcontextprotocol/protocolVersion": "2026-07-28", + "io.modelcontextprotocol/clientCapabilities": { + "extensions": { + "io.modelcontextprotocol/tasks": {} + } + } + } + } +} + Response (Device to Client — asynchronous start): The task + represents only the start operation. It completes when the function is running; it does not + remain active for the lifetime of the detection. + { + "jsonrpc": "2.0", + "id": 12, + "result": { + "resultType": "task", + "task": { + "taskId": "task_start_vehicle_001", + "status": "working", + "ttlMs": 3600000, + "pollIntervalMs": 2000 + } + } +} + The terminal task result shall include the execution identifier, for example + exec_vehicle_001. Events produced by the running function are delivered on the + ONVIF Client's open events/stream request, or via webhook. +
+
+ Skill invocation — set_event_stream_parameters + Request (Client to Device): The ONVIF Client shortens the + keep-alive interval of its push streams from the 30 second default to 10 seconds. The + parameters object is an instance of the LinkML class + SetEventStreamParametersRequest. + { + "jsonrpc": "2.0", + "id": 14, + "method": "tools/call", + "params": { + "name": "execute_function", + "arguments": { + "function": "set_event_stream_parameters", + "parameters": { + "keepaliveIntervalMs": 10000 + } + }, + "_meta": { + "io.modelcontextprotocol/protocolVersion": "2026-07-28" + } + } +} + Response (Device to Client): The ONVIF Device confirms the + interval it applied. The value reported in appliedKeepaliveIntervalMs is + authoritative. The range the device supports is not part of this result; it is read with + get_function_capabilities (see ). + { + "jsonrpc": "2.0", + "id": 14, + "result": { + "resultType": "complete", + "content": [{ "type": "text", "text": "Keep-alive interval set to 10000 ms." }], + "structuredContent": { + "executionId": "exec_keepalive_001", + "appliedKeepaliveIntervalMs": 10000, + "clamped": false, + "affectedStreams": [30] + } + } +} + Response (Device to Client — clamped): A request below the + device's minimum is clamped rather than rejected; the client adopts the returned + value. + { + "jsonrpc": "2.0", + "id": 14, + "result": { + "resultType": "complete", + "content": [{ "type": "text", "text": "Requested 1000 ms clamped to the device minimum." }], + "structuredContent": { + "executionId": "exec_keepalive_002", + "appliedKeepaliveIntervalMs": 5000, + "clamped": true, + "affectedStreams": [30] + } + } +} +
+
+ Skill invocation — stop_function + Request (Client to Device): The ONVIF Client stops an active + execution. + { + "jsonrpc": "2.0", + "id": 13, + "method": "tools/call", + "params": { + "name": "stop_function", + "arguments": { + "function": "vehicle_detection", + "executionId": "exec_vehicle_001" + }, + "_meta": { + "io.modelcontextprotocol/protocolVersion": "2026-07-28", + "io.modelcontextprotocol/clientCapabilities": { + "extensions": { + "io.modelcontextprotocol/tasks": {} + } + } + } + } +} + The device may return a task when stopping the execution requires asynchronous + processing. The task completes when the execution is stopped. +
+
+ Event delivery — catalogue, stream, and webhook examples + The examples in this section follow one vehicle through two events. In the first, the + device reports that a vehicle passed the main gate but cannot say what kind of vehicle it + was. In the second, four seconds later, the same vehicle is observed at the ambulance + drop-off, where it is classified as a van in emergency medical service, and an analytics + module asserts that the two observations are of the same physical vehicle. This is the + ordinary case of a first observation being refined by a later one, and it is worked through + in after the wire format has been + shown. + Event type catalogue (Client to Device): The ONVIF Client calls + events/list to discover the event types exposed by the device. + { + "jsonrpc": "2.0", + "id": 20, + "method": "events/list", + "params": {} +} + { + "jsonrpc": "2.0", + "id": 20, + "result": { + "events": [ + { + "name": "VehicleObservation", + "canonicalUri": "https://www.onvif.org/ver10/agentic/linkml/VehicleObservation", + "description": "Emitted when the vehicle detection function observes a vehicle", + "delivery": ["push", "webhook"], + "inputSchema": { + "type": "object", + "properties": { + "locationToken": { + "type": "string", + "description": "Token of a configured location to filter on" + } + } + }, + "payloadSchema": { + "$ref": "https://www.onvif.org/ver10/agentic/base/linkml/#/$defs/InformationEnvelope" + } + }, + { + "name": "VehicleReidentification", + "canonicalUri": "https://www.onvif.org/ver10/agentic/linkml/VehicleReidentification", + "description": "Emitted when two vehicle observations are found to be of the same vehicle", + "delivery": ["push", "webhook"], + "inputSchema": { + "type": "object", + "properties": { + "locationToken": { + "type": "string", + "description": "Token of a configured location to filter on" + } + } + }, + "payloadSchema": { + "$ref": "https://www.onvif.org/ver10/agentic/base/linkml/#/$defs/InformationEnvelope" + } + } + ] + } +} + An event type is a metadata class, as specified in + . Both entries therefore carry the same + payloadSchema: the payload of any event is an + InformationEnvelope, and what distinguishes one event type from another is the + class named by canonicalUri, which is the class an ONVIF Client is asking to be + told about among the items the envelope carries. Neither entry names a class invented for + the purpose of eventing; both name classes of the metadata model that the device is able to + emit. + Stream requests (Client to Device): The ONVIF Client opens two + long-lived events/stream requests, one per class it is interested in, each with + a null cursor to start from now. On Streamable HTTP each is an HTTP POST to + /mcp whose response is an SSE stream. + POST /mcp HTTP/1.1 +Host: 192.0.2.10 +Accept: text/event-stream +Content-Type: application/json +MCP-Protocol-Version: 2026-07-28 +Authorization: Bearer <ES256 JWT> + +{ + "jsonrpc": "2.0", + "id": 30, + "method": "events/stream", + "params": { + "name": "VehicleObservation", + "arguments": {}, + "cursor": null, + "maxAgeMs": 300000 + } +} + { + "jsonrpc": "2.0", + "id": 31, + "method": "events/stream", + "params": { + "name": "VehicleReidentification", + "arguments": {}, + "cursor": null, + "maxAgeMs": 300000 + } +} + Both subscriptions pass an empty arguments object although the event type + offers a locationToken filter. Filtering on + Area_MainGate would have delivered the first observation and withheld the + second, and the ONVIF Client would then have received a re-identification citing an + observation it never saw. A filter narrower than the phenomenon being tracked breaks the + chain it is meant to follow, and an ONVIF Client that intends to correlate items across + locations shall not apply one. + Stream response, first event (Device to Client): The ONVIF Device + confirms the subscription and then delivers the first occurrence. The vehicle has been + detected, but neither its type nor its use could be determined. + HTTP/1.1 200 OK +Content-Type: text/event-stream + +data: {"jsonrpc":"2.0","method":"notifications/events/active","params":{ +data: "cursor": "historyId_10040", +data: "truncated": false, +data: "_meta": {"io.modelcontextprotocol/subscriptionId": 30} +data: }} + +data: {"jsonrpc":"2.0","method":"notifications/events/event","params":{ +data: "eventId": "evt_veh_0001", +data: "name": "VehicleObservation", +data: "timestamp": "2026-08-04T13:05:00.120Z", +data: "data": { +data: "@context": "https://www.onvif.org/ver10/agentic/linkml/", +data: "@type": "InformationEnvelope", +data: "id": "0a7e1c34-9f2b-4d61-8c05-3ab7e6d91f42", +data: "items": [ +data: { +data: "@type": "VehicleObservation", +data: "id": "2c9f4b18-7d3e-4a52-9e61-0b8c5f2a1d76", +data: "confidence": 0.62, +data: "productionTime": { +data: "@type": "ISO8601Timestamp", +data: "timestamp": "2026-08-04T13:05:00.120Z" +data: }, +data: "observedTime": { +data: "@type": "ISO8601Timestamp", +data: "timestamp": "2026-08-04T13:05:00.000Z" +data: }, +data: "observedSpace": { +data: "@type": "FunctionalLocation", +data: "name": "Main Gate", +data: "token": "Area_MainGate" +data: }, +data: "provenance": { +data: "@type": "ONVIFDevice", +data: "entity": { "token": "VideoSource_1" }, +data: "publicKeys": [ { "keyId": "metadata-signing-1" } ] +data: }, +data: "type": "Unknown", +data: "use": "Unknown" +data: } +data: ] +data: }, +data: "cursor": "historyId_10042", +data: "_meta": {"io.modelcontextprotocol/subscriptionId": 30} +data: }} + Stream response, second event (Device to Client): Four seconds + later the vehicle is observed at the ambulance drop-off and classified. The envelope carries + two items: the new observation, and the assertion that ties it to the earlier one. A + keep-alive follows during the quiet period afterwards. + data: {"jsonrpc":"2.0","method":"notifications/events/event","params":{ +data: "eventId": "evt_veh_0002", +data: "name": "VehicleObservation", +data: "timestamp": "2026-08-04T13:05:04.310Z", +data: "data": { +data: "@context": "https://www.onvif.org/ver10/agentic/linkml/", +data: "@type": "InformationEnvelope", +data: "id": "5d3b8e07-1a4c-4f92-b6d8-7e2019c4a3f5", +data: "items": [ +data: { +data: "@type": "VehicleObservation", +data: "id": "6b1e0d92-4c73-4a18-8f5d-2e9a7c04b3e1", +data: "confidence": 0.94, +data: "productionTime": { +data: "@type": "ISO8601Timestamp", +data: "timestamp": "2026-08-04T13:05:04.090Z" +data: }, +data: "observedTime": { +data: "@type": "ISO8601Timestamp", +data: "timestamp": "2026-08-04T13:05:04.000Z" +data: }, +data: "observedSpace": { +data: "@type": "FunctionalLocation", +data: "name": "Ambulance Drop-off", +data: "token": "Area_AmbulanceDropoff" +data: }, +data: "provenance": { +data: "@type": "ONVIFDevice", +data: "entity": { "token": "VideoSource_1" }, +data: "publicKeys": [ { "keyId": "metadata-signing-1" } ] +data: }, +data: "type": "Van", +data: "use": "Ambulance" +data: }, +data: { +data: "@type": "VehicleReidentification", +data: "id": "9f4c2a61-08d5-4e37-b19c-6a3f7d21e480", +data: "confidence": 0.88, +data: "productionTime": { +data: "@type": "ISO8601Timestamp", +data: "timestamp": "2026-08-04T13:05:04.310Z" +data: }, +data: "provenance": { +data: "@type": "AnalyticsModule", +data: "token": "ReID_1", +data: "algorithm": "vehicle-reidentification", +data: "version": "4.2.0", +data: "entity": { "token": "VideoSource_1" }, +data: "publicKeys": [ { "keyId": "metadata-signing-1" } ] +data: }, +data: "supportedBy": [ +data: "2c9f4b18-7d3e-4a52-9e61-0b8c5f2a1d76", +data: "6b1e0d92-4c73-4a18-8f5d-2e9a7c04b3e1" +data: ], +data: "vehicleId": "c4d81f36-2b90-4e57-a8c1-5f7042e9b613", +data: "authoritativeObservation": "6b1e0d92-4c73-4a18-8f5d-2e9a7c04b3e1" +data: } +data: ] +data: }, +data: "cursor": "historyId_10061", +data: "_meta": {"io.modelcontextprotocol/subscriptionId": 30} +data: }} + +data: {"jsonrpc":"2.0","method":"notifications/events/heartbeat","params":{ +data: "cursor": "historyId_10070", +data: "_meta": {"io.modelcontextprotocol/subscriptionId": 30} +data: }} + This envelope satisfies both subscriptions, because it contains an item of each + subscribed class. The ONVIF Device therefore delivers it on subscription 31 as well, as a + separate occurrence with its own eventId. The data field is + abridged below: it carries the envelope shown above, byte for byte, and only its identifier + is repeated here so that the two deliveries can be seen to refer to one envelope. + data: {"jsonrpc":"2.0","method":"notifications/events/event","params":{ +data: "eventId": "evt_reid_0001", +data: "name": "VehicleReidentification", +data: "timestamp": "2026-08-04T13:05:04.310Z", +data: "data": { +data: "@type": "InformationEnvelope", +data: "id": "5d3b8e07-1a4c-4f92-b6d8-7e2019c4a3f5", +data: "items": [] +data: }, +data: "cursor": "historyId_10061", +data: "_meta": {"io.modelcontextprotocol/subscriptionId": 31} +data: }} + The empty items list above is an artefact of the abridgement and never + appears on the wire: items is mandatory and carries at least one item, and here + it carries the two items delivered on subscription 30. + The ONVIF Client now holds the same two items twice, under two different + eventId values. It deduplicates on the item identifiers + 6b1e0d92-… and 9f4c2a61-…, not on eventId, which is + per-delivery and differs precisely because the delivery differed. Item identifiers are + unique and never reused, which makes this deduplication exact. + The correspondences between the MCP occurrence and the ONVIF envelope are worth reading + off this example, since the two levels are easy to confuse (see + ). The name + VehicleObservation and the @type of the item happen to be the same + string, but they are different fields serving different purposes: the first says which + subscription this delivery belongs to, the second says what the item is. The + eventId evt_veh_0002 is not the identifier of the envelope + 5d3b8e07-…, nor of any item in it. The timestamp + 13:05:04.310Z is when the device dispatched the occurrence, and is not the + productionTime of either item, still less the observedTime of + 13:05:04.000Z. And cursor is a position in the subscription, not a + fact about the world: it is the one field an ONVIF Client persists and sends back, and it + carries no evidential weight. + Every line of an SSE event carries its own data: prefix. This is not a + typographical device of this document but the framing rule of text/event-stream: + the prefix is a field name, not part of the payload, and a receiver strips it from each + line and joins the remainders with a line feed to recover the payload. A JSON document may + therefore be laid out over as many lines as readability calls for — the line feeds + reintroduced by the receiver are insignificant whitespace between JSON tokens, and a + payload can never contain a raw line feed of its own because JSON escapes them inside + strings. An implementation MAY equally emit each notification on a single + data: line; the two forms are indistinguishable to the receiver. A blank line + terminates the event. + The keep-alive frame is sent once per keep-alive interval — 30 seconds by default — on + a stream that delivered no event during that interval. See for how the ONVIF Client changes that + interval. + Neither envelope above carries a signature. Signing is optional, and on a + continuous metadata stream a device may reasonably omit it; the price is that the items + carry no integrity or non-repudiation claim. + shows the signed form. + +
+ How the second event refines the first + The two events above are the normal way in which analytics improves its own output, + and the model is built so that it can do so without ever contradicting itself. It is worth + following what each of the three items claims. + At 13:05:00 the device saw something at the main gate. It was confident enough that a + vehicle was there to report it — a confidence of 0.62 — but it could determine neither the + type of the vehicle nor the use it was being put to. Both fields carry + Unknown. This is not a defect of the report: type is a mandatory + slot, and Unknown is what allows the device to state a detection it is sure of + without inventing a classification it is not. Had the device not classified vehicle use at + all, the use field would have been absent rather than + Unknown; here it is present and Unknown, which says something + more specific — the device does classify use, and it tried, and it failed. An ONVIF Client + can tell those two situations apart, and they call for different responses. + At 13:05:04 the same device, on the same channel, saw a vehicle at the ambulance + drop-off and this time classified it: a Van in Ambulance use, at + a confidence of 0.94. Nothing in this second observation refers to the first. It is an + independent report of what the sensor saw at a different place and a different time, and it + would be exactly the same report if the first observation had never been made. + The link between the two is the third item, and it is a different kind of claim + altogether. VehicleReidentification is an Assertion: it states + that observations 2c9f4b18-… and 6b1e0d92-… are of the same + physical vehicle. It lists both in supportedBy, which is why that field + requires at least two entries — a single observation cannot be re-identified. It assigns + the vehicle a stable identifier, vehicleId + c4d81f36-…, which designates the physical vehicle and not any information + item, and which a later re-identification of the same vehicle will reuse, so that an ONVIF + Client can accumulate what is known about one vehicle over time. And it nominates + 6b1e0d92-… as the authoritativeObservation, telling the client + which of the two classifications to prefer. + What the assertion does not do is modify either observation. + The item 2c9f4b18-… still says Unknown, still at a confidence of + 0.62, and it will say so for as long as it is retained. Nothing is retracted, nothing is + overwritten, and an ONVIF Client that received the first event and then lost its + connection is not holding a report that has since become false — it is holding a true + report of what the sensor could determine at 13:05:00. An Observation is never + revised, and this is the property that makes a metadata stream auditable: an observation + recorded at the time of an incident reads afterwards exactly as it read then. What changes + is not the record but what can be concluded from it, and conclusions are separate items + with their own identity. + The provenances make the distinction visible. Both observations are provenanced to an + ONVIFDevice naming the video source that produced them. The assertion is + provenanced to an AnalyticsModule — token ReID_1, algorithm + vehicle-reidentification, version 4.2.0 — because an algorithm, + not a sensor, produced it. The two items travel in the same envelope and leave the device + through the same interface, but they do not have the same author, and an ONVIF Client may + have good reason to accept what the sensor reports while treating the re-identification + with more caution, or to accept re-identifications from version 4.2.0 of this algorithm + and not from an earlier one. That decision is only available to a client if the items say + who made them, which is why provenance is mandatory and why the two + concrete provenance classes are distinct. + Confidence follows the same rule. The assertion is at 0.88 while the observation it + nominates as authoritative is at 0.94, and this ordering is the expected one: the + algorithm is at least as uncertain as its evidence, since it may have matched the wrong + vehicle even where each individual observation was sound. An ONVIF Client shall not + propagate the confidence of an observation to an assertion that cites it, in either + direction. + Finally, the two observations reached the client in two separate envelopes, four + seconds apart, while the assertion travelled together with the observation it was derived + from. That is the general pattern: items whose production is separated in time are not + gathered into one envelope but linked by identifier, whereas an assertion and the + observation produced at the same moment are delivered together, so that a client receives + the claim and its immediate support in one delivery. The reference to + 2c9f4b18-… resolves against what the client already holds; if it does not — + because the client subscribed too late, or applied a filter that excluded the first + observation — then the client holds an assertion it cannot fully resolve, and shall treat + it as such rather than discarding the envelope. +
+ +
+ Webhook delivery of the same events + Webhook subscription request (Client to Device): Instead of + keeping a stream open, the ONVIF Client MAY register a callback URL for the same event + type, when the device advertises "webhook" in delivery. + { + "jsonrpc": "2.0", + "id": 22, + "method": "events/subscribe", + "params": { + "name": "VehicleObservation", + "arguments": {}, + "delivery": { + "mode": "webhook", + "url": "https://client.example.com/hooks/onvif-vehicle", + "secret": "whsec_5WbX5uJd9zX2mVvR8zQwHnA7pKtC3sYb" + }, + "cursor": null, + "ttlMs": 3600000 + } +} + { + "jsonrpc": "2.0", + "id": 22, + "result": { + "id": "sub_9f2a1c7e0b4d3f6a", + "refreshBefore": "2026-08-04T14:05:00Z", + "cursor": "historyId_10040", + "truncated": false + } +} + Webhook delivery (Device to callback endpoint): As matching + events occur, the ONVIF Device POSTs each EventOccurrence to the registered + callback URL, signed per Standard Webhooks and identifying the subscription. The + occurrence is the same object that the stream carried, and the payload is the same + InformationEnvelope; only the framing differs. + POST /hooks/onvif-vehicle HTTP/1.1 +Host: client.example.com +Content-Type: application/json +webhook-id: msg_2f6b1a9d +webhook-timestamp: 1754312700 +webhook-signature: v1,K5r2m9QvC1nF8pXeVYtR3zJdL6oW0uAqBs4h7g== +X-MCP-Subscription-Id: sub_9f2a1c7e0b4d3f6a + +{ + "eventId": "evt_veh_0001", + "name": "VehicleObservation", + "timestamp": "2026-08-04T13:05:00.120Z", + "data": { + "@context": "https://www.onvif.org/ver10/agentic/linkml/", + "@type": "InformationEnvelope", + "id": "0a7e1c34-9f2b-4d61-8c05-3ab7e6d91f42", + "items": [ + { + "@type": "VehicleObservation", + "id": "2c9f4b18-7d3e-4a52-9e61-0b8c5f2a1d76", + "confidence": 0.62, + "productionTime": { + "@type": "ISO8601Timestamp", + "timestamp": "2026-08-04T13:05:00.120Z" + }, + "observedTime": { + "@type": "ISO8601Timestamp", + "timestamp": "2026-08-04T13:05:00.000Z" + }, + "observedSpace": { + "@type": "FunctionalLocation", + "name": "Main Gate", + "token": "Area_MainGate" + }, + "provenance": { + "@type": "ONVIFDevice", + "entity": { "token": "VideoSource_1" }, + "publicKeys": [ { "keyId": "metadata-signing-1" } ] + }, + "type": "Unknown", + "use": "Unknown" + } + ] + }, + "cursor": "historyId_10042" +} + The webhook signature attests the transport: it tells the callback endpoint that this + HTTP request came from the party holding the subscription secret. It says nothing about the + items inside, and it does not survive the request — once the body has been read, the + signature is gone. An envelope that has to remain verifiable after delivery carries its own + signature, as shown in ; the two + mechanisms protect different things and neither substitutes for the other. +
+
+
+ Signed information envelope example + The example below shows a complete InformationEnvelope signed with the + OnvifSignature profile defined in . It + encloses two observations produced by the same channel: a vehicle observation and the + observation of its licence plate. + Two details are worth noting. First, the entries of hashes are + not in the order in which the items were produced: the licence plate + observation was produced second but appears first, because its identifier sorts before the + one of the vehicle observation. This is the ordering rule of at work. Second, the key field uses a + PublicKeyIdentifier, so the certificate chain is not repeated in the + envelope. + The provenance of both items is an ONVIFDevice (see ) with its descriptive fields populated and the channel named + through entity, so that the example reads clearly. All of those fields are + optional, and the minimal form of the class — a single key identifier — is equally valid + and considerably shorter, which matters because provenance is repeated on every item. The + stream examples of use that minimal form. + Here the declared key carries a fingerprint as well as an identifier (see ), and the same fingerprint appears in the + key field of the signature. Three things can therefore be checked, and they are + not the same check. The keyId declared in publicKeys equals the one + the signature names, so the envelope was signed with a key the producing device claims as its + own. The fingerprints equal each other, so the two references are to the same key + material and not merely to the same keystore entry name. And an ONVIF + Client that obtained this device's key fingerprint through the Advanced Security Service, or + at provisioning, can compare it with the value here and establish that the key is the one it + trusts — which no comparison internal to the envelope could establish, since an attacker who + fabricates an envelope can make it internally consistent. + The fingerprint in the key field is covered by the signature, because + key is part of the signature configuration and the configuration is hashed into + envelopeDigest. The fingerprints in publicKeys are covered by the + per-item digests, since provenance is part of the content of an item. Neither can be + substituted without invalidating something. + { + "@context": "https://www.onvif.org/ver10/agentic/linkml/", + "@type": "InformationEnvelope", + "id": "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed", + "items": [ + { + "@type": "VehicleObservation", + "id": "9c1f0a7e-3d52-4c8a-8f0b-2e6d1a4c7b93", + "confidence": 0.91, + "productionTime": { + "@type": "ISO8601Timestamp", + "timestamp": "2026-08-04T13:05:00.120Z" + }, + "provenance": { + "@type": "ONVIFDevice", + "manufacturer": "ACME Corporation", + "model": "AC-4200", + "firmwareVersion": "3.1.4", + "serialNumber": "AC42-00193847", + "hardwareId": "AC4200-RevB", + "entity": { "token": "VideoSource_1" }, + "publicKeys": [ + { + "keyId": "metadata-signing-1", + "fingerprints": [ + { + "algorithm": "SHA256", + "value": "Ry9mXk1tQ0pQb0hZd2s3TnZFcjJhUDVjNmJHOHVMdz0=" + } + ] + } + ] + }, + "type": "Car", + "color": { + "color_cluster": [ + { "color": { "x": 0.12, "y": 0.44, "z": 0.58, "likelihood": 0.77 } } + ] + } + }, + { + "@type": "LicensePlateObservation", + "id": "3f2b8c1e-6a4d-4f7b-9e21-5c8d0a1b2e3f", + "confidence": 0.88, + "productionTime": { + "@type": "ISO8601Timestamp", + "timestamp": "2026-08-04T13:05:00.180Z" + }, + "provenance": { + "@type": "ONVIFDevice", + "manufacturer": "ACME Corporation", + "model": "AC-4200", + "firmwareVersion": "3.1.4", + "serialNumber": "AC42-00193847", + "hardwareId": "AC4200-RevB", + "entity": { "token": "VideoSource_1" }, + "publicKeys": [ + { + "keyId": "metadata-signing-1", + "fingerprints": [ + { + "algorithm": "SHA256", + "value": "Ry9mXk1tQ0pQb0hZd2s3TnZFcjJhUDVjNmJHOHVMdz0=" + } + ] + } + ] + }, + "plateNumber": { "value": "AB123CD", "likelihood": 0.88 }, + "countryCode": { "value": "IT", "likelihood": 0.99 } + } + ], + "hashes": [ + { + "item": "3f2b8c1e-6a4d-4f7b-9e21-5c8d0a1b2e3f", + "digest": "E3JseugV6ZqEG0/LOG/J+oiM/ri/s9r4VRig/UdP+eA=" + }, + { + "item": "9c1f0a7e-3d52-4c8a-8f0b-2e6d1a4c7b93", + "digest": "2R6DjCH+OaXRbmJdaeei70aaBgm/1jSpurL6D9PVfsY=" + } + ], + "signature": { + "@type": "OnvifSignature", + "digestAlgorithm": "SHA256", + "signatureAlgorithm": "ECDSA_P256_SHA256", + "created": "2026-08-04T13:05:00.200Z", + "key": { + "@type": "PublicKeyIdentifier", + "keyId": "metadata-signing-1", + "fingerprints": [ + { + "algorithm": "SHA256", + "value": "Ry9mXk1tQ0pQb0hZd2s3TnZFcjJhUDVjNmJHOHVMdz0=" + } + ] + }, + "envelopeDigest": "9CkF0ap3z4NJVJaS5gF22AOgEeegqRdTpqu/g5tQ/3g=", + "signatureValue": "MEUCICp2gQfPcz4q5mZ2rDhUaotdS0y4leaiXL2DJ1Jfhw6l..." + } +} + The signatureValue above is abridged, as are the certificates later in this + section: a DER encoded ECDSA P-256 signature is 96 base64 characters and does not fit the + width of this page. The trailing ellipsis marks the elision and is not part of the value, + which on the wire is base64 characters and padding alone, with nothing else inside the + string. Every digest in the example is shown in full, since a SHA-256 digest fits. + In this example envelopeDigest is obtained by hashing the canonical form of + the signature configuration — that is, the signature object above without + envelopeDigest and signatureValue — followed by the raw octets of + the two digests, taken in the order in which they appear in hashes. The + base64 text of the digests is not what is concatenated; the bytes it encodes are. + When the certificate chain has to travel with the envelope, the key field + carries an X509CertificateChain instead. The chain is ordered from the leaf + certificate outwards and stops short of the certification authority certificate: + "key": { + "@type": "X509CertificateChain", + "userProvisioned": false, + "certificateChain": [ + "-----BEGIN CERTIFICATE-----\nMIIBkTCCATegAwIBAgIUJ...\n-----END CERTIFICATE-----", + "-----BEGIN CERTIFICATE-----\nMIIBvjCCAWSgAwIBAgIUP...\n-----END CERTIFICATE-----" + ] +} + Because key is part of the signature configuration, changing the key + descriptor — including switching between these two forms — changes + envelopeDigest and therefore requires a new signature. +
+ +
+ Dynamic schema re-registration + This example shows the recovery procedure of + . The device has been updated and now + emits a vendor class, acme:ThermalObservation, which the ONVIF Client does not + hold: the prefix acme is bound by no module the client loaded when it + established the session. The trigger is that unresolvable @type, not the value + of @context, which is a constant and is the same here as in every other + payload. + Event notification with an unresolvable type (Device to Client): the + notification is delivered on the open events/stream response. The envelope + carries two items, only one of which the client can interpret. + data: {"jsonrpc":"2.0","method":"notifications/events/event","params":{ +data: "eventId": "evt_veh_0007", +data: "name": "VehicleObservation", +data: "timestamp": "2026-08-04T13:10:00.085Z", +data: "data": { +data: "@context": "https://www.onvif.org/ver10/agentic/linkml/", +data: "@type": "InformationEnvelope", +data: "id": "b8e37f05-6c21-4a9d-90f3-1d5e8ac47206", +data: "items": [ +data: { +data: "@type": "VehicleObservation", +data: "id": "4e70a3c8-52b9-4d16-8ac7-91f0b26d5e34", +data: "confidence": 0.90, +data: "productionTime": { +data: "@type": "ISO8601Timestamp", +data: "timestamp": "2026-08-04T13:10:00.085Z" +data: }, +data: "provenance": { +data: "@type": "ONVIFDevice", +data: "entity": { "token": "VideoSource_1" }, +data: "publicKeys": [ { "keyId": "metadata-signing-1" } ] +data: }, +data: "type": "Van", +data: "use": "Ambulance" +data: }, +data: { +data: "@type": "acme:ThermalObservation", +data: "id": "d1c94b26-8f57-4e03-a2b8-6035ce7d91af", +data: "confidence": 0.87, +data: "productionTime": { +data: "@type": "ISO8601Timestamp", +data: "timestamp": "2026-08-04T13:10:00.085Z" +data: }, +data: "provenance": { +data: "@type": "ONVIFDevice", +data: "entity": { "token": "VideoSource_2" }, +data: "publicKeys": [ { "keyId": "metadata-signing-1" } ] +data: }, +data: "peakCelsius": 41.8 +data: } +data: ] +data: }, +data: "cursor": "historyId_10055", +data: "_meta": {"io.modelcontextprotocol/subscriptionId": 30} +data: }} + The ONVIF Client suspends validation of the second item and discards neither it nor the + envelope. The first item is of a class the client holds, and it processes it normally. This + matters: an envelope is a group of items, not an all-or-nothing unit, and a client that threw + the envelope away because one item was unrecognised would lose a vehicle observation it was + perfectly able to understand. + Schema retrieval is a separate request/response exchange on the same /mcp + endpoint; the events/stream request remains open throughout, and further events + continue to arrive on it while the exchange is in progress. + Resource enumeration (Client to Device): The client re-calls + resources/list. It does not guess a URI from the prefix: a prefix is not a + resource address, and the address at which this device serves the vendor module is something + only the device can state. + { + "jsonrpc": "2.0", + "id": 24, + "method": "resources/list", + "params": { + "_meta": { + "io.modelcontextprotocol/protocolVersion": "2026-07-28" + } + } +} + { + "jsonrpc": "2.0", + "id": 24, + "result": { + "resultType": "complete", + "resources": [ + { + "uri": "linkml://192.0.2.10/agentic/base", + "name": "ONVIF Agentic Metadata Model", + "mimeType": "application/linkml+yaml" + }, + { + "uri": "linkml://192.0.2.10/vendor/acme/thermal", + "name": "ACME Thermal Extension", + "mimeType": "application/linkml+yaml" + } + ] + } +} + The listing is abridged; the six bundle modules of + are still present. What is new is the last + entry, which the client does not yet hold. + Schema fetch request (Client to Device): The ONVIF Client reads the + module it is missing. + { + "jsonrpc": "2.0", + "id": 25, + "method": "resources/read", + "params": { + "uri": "linkml://192.0.2.10/vendor/acme/thermal", + "_meta": { + "io.modelcontextprotocol/protocolVersion": "2026-07-28" + } + } +} + Response (Device to Client): The ONVIF Device returns the vendor + module as a YAML string in the text field, abridged here as in + . + { + "jsonrpc": "2.0", + "id": 25, + "result": { + "resultType": "complete", + "contents": [{ + "uri": "linkml://192.0.2.10/vendor/acme/thermal", + "mimeType": "application/linkml+yaml", + "text": "id: https://acme.example/agentic/thermal/linkml/\nname: acme-agentic-thermal\n..." + }] + } +} + With its escaped newlines resolved, the module reads as follows. It declares its own + prefix and its own default_prefix, so the classes it defines lie in a namespace + ACME controls, and it imports agentic/base because + ThermalObservation derives from Observation. + id: https://acme.example/agentic/thermal/linkml/ +name: acme-agentic-thermal +prefixes: + linkml: https://w3id.org/linkml/ + onvif: https://www.onvif.org/ver10/agentic/linkml/ + acme: https://acme.example/agentic/linkml/ +imports: + - linkml:types + - agentic/base +default_prefix: acme + +classes: + + ThermalObservation: + is_a: Observation + description: Peak apparent temperature measured over the observed region. + attributes: + peakCelsius: + range: float + required: true + The ONVIF Client registers the module under its schema identifier + https://acme.example/agentic/thermal/linkml/ and rebuilds its mapping from names + and prefixes to class identifiers over the whole set of modules it now holds. The prefix + acme now binds to https://acme.example/agentic/linkml/, so + acme:ThermalObservation resolves to the class identifier + https://acme.example/agentic/linkml/ThermalObservation. That identifier, and not + the CURIE, is what the client stores: the prefix is local to this device and this session, + while the class identifier is the same wherever the class appears. The suspended item is then + validated, and every subsequent item of the class is validated as it arrives. + This path is a recovery path, not the normal one. The ONVIF Device should have announced + the change with notifications/events/list_changed, on receipt of which the client + would have re-called events/list and resources/list and loaded the + module before the first item of the new class was ever delivered. The procedure above is what + keeps the client working when that announcement did not arrive, or arrived too + late. +
+
+ +
diff --git a/doc/Security.xml b/doc/Security.xml index aba124e68..37b91061b 100644 --- a/doc/Security.xml +++ b/doc/Security.xml @@ -4,12 +4,12 @@ Security Service Specification Security Configuration - 26.06 + 26.12 ONVIF™ www.onvif.org - June, 2026 + December, 2026 @@ -212,6 +212,14 @@ Deprecate PasswordBasedMACAlgorithms. Several clarifications. + + 26.12 + Dec-2026 + + Ottavio Campana + + Extend authorization server sections to include OAuth 2.1 profile guidance while preserving OAuth 2.0 and OpenID Connect compatibility. + @@ -321,6 +329,10 @@ <http://www.ietf.org/rfc/rfc7519.txt> + IETF RFC 7636 Proof Key for Code Exchange by OAuth Public Clients + <http://www.ietf.org/rfc/rfc7636.txt> IETF RFC 7643 System for Cross-domain Identity Management: Core Schema <<http://www.ietf.org/rfc/rfc8414.txt> + IETF OAuth 2.1 Authorization Framework (draft-ietf-oauth-v2-1-13) + <https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13> IETF RFC 8705 OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens <Protected EAP + + PKCE + + Proof Key for Code Exchange + + SCTP @@ -1098,6 +1120,10 @@ machine authorization. Both approaches are based on OAuth 2.0 as defined in RFC6749. OpenID Connect has been developed as an extension of OAuth 2.0 especially for granting access to human users. + This specification also defines an OAuth 2.1 profile for Authorization Server + integrations. In this profile, devices and clients shall use the same configuration objects + and authentication methods defined in this section while applying OAuth 2.1 security + requirements for the selected flow. OAuth 2.0 defines a web API called "authorization endpoint" to retrieve tokens. Clients control the purpose via scope parameters.
@@ -1108,6 +1134,8 @@ xmlns:xlink="http://www.w3.org/1999/xlink" linkend="table_smg_rzq_swb"/>. In case of success the authorization server responds to the request with an access token that authorizes access to the actual resource. + For OAuth 2.1 deployments, the same client credentials flow and configuration type + OAuthClientCredentials shall be used. The Client Credentials Flow is summarized in .
OpenID Connect client credentials flow for devices @@ -1128,6 +1156,12 @@ authentication and authorization. Users can retrieve JWTs from an OpenID Connect server by authenticating and authorizing access to resources by following the OAuth2 Authorization Code Flow. + For OAuth 2.1 deployments, Authorization Code flow shall use Proof Key for Code + Exchange (PKCE), and clients should request only the scopes required for the targeted + operation. + In particular, the client shall include code_challenge in the + authorization request and code_verifier in the token request as specified by + RFC 7636. The Authorization Code Flow is summarized in .
OpenID Connect authorization code flow for users @@ -1271,6 +1305,7 @@ OAuth2 authorization code flow per RFC 6749. + For OAuth 2.1 profile deployments, this flow shall be used with PKCE. @@ -1279,6 +1314,7 @@ OAuth2 client credentials grant flow per RFC 6749. + This type is compatible with OAuth 2.1 profile deployments. @@ -1287,6 +1323,7 @@ OpenID Connect authorization code flow per Open ID Connect Core. + For OAuth 2.1 profile deployments, this flow shall be used with PKCE. The ServerUri is used as metadata URI, where you can retrieve the endpoint URIs for authorization, token and JWKS. @@ -1313,7 +1350,8 @@ client_secret_basic - Use HTTP Authorization header to specify client_secret, see RFC 6749 + Use HTTP Authorization header to specify client_secret, see RFC 6749. This + method is recommended for OAuth 2.1 profile deployments. @@ -1321,7 +1359,9 @@ client_secret_post - Use HTTP POST body to specify client_secret, see RFC 6749 + Use HTTP POST body to specify client_secret, see RFC 6749. This method is + kept for backwards compatibility and is not recommended for OAuth 2.1 profile + deployments. @@ -4540,6 +4580,170 @@ assigned media signing certificates by invoking GetCertificationPath with the CertificationPathID, followed by GetCertificates.
+ + +
+ AI Metadata Signing +
+ Overview + AI metadata authenticity data in the form of digital signatures is generated by the + device and embedded in the AI metadata payload as described in the [ONVIF AI Service + Specification]. Metadata is signed using a certificate based on a private key provisioned + in one of the approaches listed below. + + + Factory Provisioned Key + + Private key provisioned into the device by the manufacturer. The associated + certificate holds the corresponding public key. A device that supports AI metadata + signing shall always have a factory-provisioned key and shall use it for signing + unless a user-provisioned key has been assigned. + + + + User Provisioned Key + + An additional private key that the user can provision, independently of the + factory-provisioned key. When assigned, it shall be used in place of the + factory-provisioned key for AI metadata signing. + + + +
+ +
+ AddAISigningCertificateAssignment + This operation assigns a certification path (certificate chain) to use for AI + metadata signing, replacing the factory-provisioned one. The leaf certificate in the + chain and its associated private key shall be used for signing AI metadata as described + in the [ONVIF AI Service Specification]. This key and certificate are referred to as + the user-provisioned key and certificate in that specification. + If a user-provisioned certification path is configured, ongoing AI metadata streams + shall be stopped by the device. + A device shall support this command if the UserAISigningKeySupported + capability is true. + + + request + + CertificationPathID [tas:CertificationPathID] + The ID of the certification path to assign for AI metadata + signing. + + + + response + + This message is empty. + + + + faults + + env:Sender - ter:InvalidArgVal - ter:CertificationPathID + No certification path is stored in the keystore under the given + certification path ID. + env:Sender - ter:InvalidArgVal - ter:NoPrivateKey + The key pair associated with the leaf certificate in the + certificate chain does not have an associated private key. + + + + access class + + WRITE_SYSTEM + + + +
+ +
+ RemoveAISigningCertificateAssignment + This operation removes the user-provisioned certificate assignment for AI metadata + signing. After removal, the device shall revert to using the factory-provisioned key. + The factory-provisioned certification path cannot be removed. + If a user-provisioned certification path is removed, ongoing AI metadata streams + shall be stopped by the device. + A device shall support this command if the UserAISigningKeySupported + capability is true. + + + request + + CertificationPathID [tas:CertificationPathID] + The ID of the user-provisioned certification path to remove. + + + + response + + This message is empty. + + + + faults + + env:Sender - ter:InvalidArgVal - ter:OldCertificationPathID + No certification path under the given ID is assigned for AI + metadata signing. + env:Sender - ter:InvalidArgVal - ter:ReferenceExists + A reference exists for the object that is to be deleted. + + + + access class + + WRITE_SYSTEM + + + +
+ +
+ GetAssignedAISigningCertificates + This operation returns the IDs of the certification paths assigned for AI metadata + signing on the device. The response shall always include the factory-provisioned + certification path and may additionally include a user-provisioned certification path + assigned via AddAISigningCertificateAssignment. + A device shall support this command if the AISigningSupported + capability is true. + The response list shall be ordered with the factory-provisioned ID first, followed + by the user-provisioned ID if present. + + + request + + This message is empty. + + + + response + + CertificationPathID - optional, max 2 [tas:CertificationPathID] + List of certification path IDs assigned for AI metadata signing. + At least one certification path referring to the factory-provisioned certificates + shall be returned. At most two certification paths shall be returned. + + + + faults + + None + + + + access class + + READ_SYSTEM_SECRET + + + + As the response structure includes just CertificationPathID, the client may retrieve + the assigned AI signing certificates by invoking GetCertificationPath with the + CertificationPathID, followed by GetCertificates. +
+
+
Authorization Server Configuration This chapter describes configuration of external authorization servers. For an overview @@ -5182,6 +5386,43 @@
+
+ AI Signing Capabilities + The AI Signing capabilities reflect optional functionality related to signing of AI + metadata as described in the [ONVIF AI Service Specification]. + + AI Signing Capabilities + + + + + + Capability Name + Capability Semantics + + + + + AISigningSupported + + Indicates whether the device supports signing of AI metadata according + to the [ONVIF AI Service Specification]. A device that sets this capability + to true shall have a factory-provisioned signing key and shall support + GetAssignedAISigningCertificates. + + + + UserAISigningKeySupported + + Indicates whether the device supports provisioning of a user-supplied + signing key for AI metadata, via AddAISigningCertificateAssignment and + RemoveAISigningCertificateAssignment. + + + + +
+
Authorization Server Capabilities The authorization server capabilities reflect optional functionality regarding @@ -5605,7 +5846,6 @@ Service specific data types The service specific data types are defined in security.wsdl.
-
Security Considerations @@ -5625,6 +5865,12 @@ Operations with arguments that need protection against eavesdropping or manipulation shall only be executed over sufficiently protected communication channels. + + For OAuth 2.1 Authorization Code deployments, clients shall use Proof Key for Code + Exchange (PKCE) according to RFC 7636. PKCE mitigates authorization code interception + attacks by binding token exchange to a client-generated secret + (code_verifier) that is never transmitted in the authorization request. + It is good practice not to use the same key for different purposes. In order to prevent the device from using the same key for different purposes unnoticedly, this diff --git a/doc/index.html b/doc/index.html index 107863fb0..0dd568e62 100644 --- a/doc/index.html +++ b/doc/index.html @@ -81,6 +81,20 @@

Document preview

+Agentic +agentic.yaml + + + + + + Analytics analytics.wsdl rules.xsd, humanbody.xsd, humanface.xsd diff --git a/doc/linkml.php b/doc/linkml.php new file mode 100644 index 000000000..32c6fa29d --- /dev/null +++ b/doc/linkml.php @@ -0,0 +1,115 @@ + + + + + + + LinkML Schema Viewer + + + + + + + +

LinkML Schema:

+ +
+

Diagramma delle Classi

+
Caricamento diagramma...
+
+ +
+

Dettaglio Classi e Attributi

+
+
+ + + + diff --git a/doc/media/AI/classes.png b/doc/media/AI/classes.png new file mode 100644 index 000000000..a41871f46 Binary files /dev/null and b/doc/media/AI/classes.png differ diff --git a/doc/media/AI/stack_overview.svg b/doc/media/AI/stack_overview.svg new file mode 100644 index 000000000..d97841e10 --- /dev/null +++ b/doc/media/AI/stack_overview.svg @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + OIDC Authorization Server + Issues ES256 JWTs · Exposes JWKS + + + + + + VMS / MCP Host + Layer 1 — ONVIF Client + Layer 2 — LinkML Validator + OAuth2 token consumer + [ 0 ] OIDC · [ 1 ] VMS · [ 2 ] Validator + + + + + + AI Service / MCP Server + Layer 3 — MCP Server endpoint + Layer 4 — Skills (MCP Tools) + Layer 5 — Metadata Publisher + [ 3..7 ] MCP Server · Schema · Bridge + + + + + + + + Bearer JWT + + + + + + + + GET /.../jwks + + + + + + Control Bus (A) + MCP tools/call · Authorization: Bearer JWT + + + + + + + + Data Bus (B) + JSON-LD metadata events · SSE / notifications/message + diff --git a/yaml/agentic.yaml b/yaml/agentic.yaml new file mode 100644 index 000000000..81162522d --- /dev/null +++ b/yaml/agentic.yaml @@ -0,0 +1,394 @@ +id: https://www.onvif.org/ver10/agentic/linkml/ +name: onvif-agentic-service +description: ONVIF Agentic Service base schema +prefixes: + linkml: https://w3id.org/linkml/ + onvif: https://www.onvif.org/ver10/agentic/linkml/ +imports: + - linkml:types + - agentic/base +default_prefix: onvif +default_range: string + +# Classes are declared in dependency order: no class refers to a class declared +# below it. The three groups are, in order: the abstract bases that every +# function specialises, the generic classes that describe functions as data, and +# the classes of the reserved set_event_stream_parameters function. + +classes: + + # --- Abstract bases ------------------------------------------------------- + + FunctionExecutionParameters: + abstract: true + description: >- + Abstract base class for the execution-specific parameters object carried + in the parameters argument of the execute_function Skill. + attributes: + extensible: + range: Extensible + required: false + description: Optional vendor extension container. + + FunctionExecutionResult: + abstract: true + description: >- + Abstract base class for the structuredContent object returned by the + execute_function Skill. + attributes: + executionId: + range: string + required: true + description: >- + Identifier of the function execution started, or affected, by the + execute_function call. + extensible: + range: Extensible + required: false + description: Optional vendor extension container. + + FunctionCapabilities: + abstract: true + description: >- + Abstract base class for the static capabilities of a function: the + invariant properties that describe what a device instance supports for + that function, such as the ranges it accepts. Capabilities do not depend + on any particular invocation and are therefore never returned in the + result of execute_function. They are read with the + get_function_capabilities Skill, and the class that applies to a given + function is named by FunctionDescriptor.capabilitiesSchema. + attributes: + extensible: + range: Extensible + required: false + description: Optional vendor extension container. + + FunctionInvocation: + abstract: true + description: >- + Abstract binding between a function exposed by an ONVIF Device and the + classes that define its input and its output. A concrete subclass fixes + the function identifier and narrows the parameters and result ranges to + the classes that apply to that function. LinkML has no construct for + declaring an operation, so this class is the normative way in which this + schema states which parameters a function accepts and which result it + returns. + attributes: + function: + range: string + required: true + description: >- + Function identifier, as returned by the list_functions Skill and as + passed in the function argument of execute_function. + parameters: + range: FunctionExecutionParameters + required: false + description: >- + Parameters accepted by this function in the parameters argument of + execute_function. + result: + range: FunctionExecutionResult + required: false + description: >- + Result returned by this function in the structuredContent of the + execute_function response. + + # --- Function catalogue and capabilities Skills --------------------------- + + FunctionDescriptor: + description: >- + A single entry of the function catalogue returned by the list_functions + Skill. Each entry names a function and points at the LinkML classes that + define its configuration, its execution parameters, and its result. + attributes: + name: + range: string + required: true + description: >- + Local name of the function on this ONVIF Device, for example + vehicle_detection or set_event_stream_parameters. It is the value passed in + the function argument of configure_function, execute_function, + stop_function and get_function_capabilities. + + The name is unique within a single list_functions response and is + arbitrated by the ONVIF Device: where two independently defined + functions would claim the same local name, the device renames one of + them. It is therefore not a global identifier, and an ONVIF Client + shall not use it as a key across devices; canonicalUri serves that + purpose. + canonicalUri: + range: uri + required: true + description: >- + Canonical identifier of the function, which is the same on every + ONVIF Device that implements it. It is the value an ONVIF Client uses + to recognise a function and to correlate it across devices, and it is + stable under any renaming of the local name. + + For a function reserved by this specification the value is + https://www.onvif.org/ver10/agentic/function/ followed by the reserved + name, for example + https://www.onvif.org/ver10/agentic/function/set_event_stream_parameters. For + any other function the value shall lie in a namespace controlled by + the party that defined the function. + description: + range: string + required: false + description: Human-readable description of what the function does. + enabled: + range: boolean + required: true + description: >- + Whether this function is configured and available for execution. + configSchema: + range: uri + required: false + description: >- + URI of the LinkML class that defines the config argument accepted by + configure_function for this function. + executionSchema: + range: uri + required: false + description: >- + URI of the LinkML class that defines the parameters argument accepted + by execute_function for this function. Present when the function + accepts execution parameters. + resultSchema: + range: uri + required: false + description: >- + URI of the LinkML class that defines the structuredContent returned + by execute_function for this function. + capabilitiesSchema: + range: uri + required: false + description: >- + URI of the LinkML class, derived from FunctionCapabilities, that + defines the structure of the capabilities returned by + get_function_capabilities for this function. It is present when the + function has capabilities that an ONVIF Client can read. + extensible: + range: Extensible + required: false + description: Optional vendor extension container. + + ListFunctionsResult: + description: >- + Structured result returned by the list_functions Skill: the authoritative + machine-readable catalogue of the functions supported by a device + instance. This class is a root of the schema: it is the shape of a Skill + response and is therefore not referenced by any other class. + attributes: + functions: + range: FunctionDescriptor + multivalued: true + inlined_as_list: true + required: true + description: >- + Zero or more function descriptors. The catalogue always contains the + reserved set_event_stream_parameters function. + extensible: + range: Extensible + required: false + description: Optional vendor extension container. + + GetFunctionCapabilities: + description: >- + Arguments accepted by the get_function_capabilities Skill. + attributes: + function: + range: string + required: true + description: >- + Function identifier whose capabilities are requested, as returned by + the list_functions Skill. + extensible: + range: Extensible + required: false + description: Optional vendor extension container. + + GetFunctionCapabilitiesResponse: + description: >- + Structured result returned by the get_function_capabilities Skill. It + carries the invariant properties of a single function, kept separate from + the result of any execution of that function. + attributes: + function: + range: string + required: true + description: Function identifier to which the capabilities apply. + capabilities: + range: FunctionCapabilities + required: true + description: >- + Capabilities of the named function, an instance of the class derived + from FunctionCapabilities that the function catalogue names in + capabilitiesSchema. + extensible: + range: Extensible + required: false + description: Optional vendor extension container. + + # --- Reserved function: set_event_stream_parameters ------------------------ + + SetEventStreamParametersRequest: + abstract: false + is_a: FunctionExecutionParameters + description: >- + Execution parameters of the reserved set_event_stream_parameters + function. The function sets the settable parameters of the event stream; + at present the only one is the interval at which the ONVIF Device emits + notifications/events/heartbeat keep-alive messages on open events/stream + responses. + + The invariant properties of the event stream, such as the number of + concurrent streams the ONVIF Device supports, are not set here. They are + read with the get_function_capabilities Skill, which for this function + returns EventStreamCapabilities. + attributes: + keepaliveIntervalMs: + range: integer + required: false + ifabsent: int(30000) + minimum_value: 1000 + maximum_value: 3600000 + unit: + ucum_code: ms + description: >- + Requested interval, in milliseconds, between two consecutive + keep-alive notifications on an events/stream response. Defaults to + 30000 (30 seconds). The ONVIF Device clamps the requested value to + the range it supports and reports the value actually applied in + SetEventStreamParametersResponse.appliedKeepaliveIntervalMs. + subscriptionId: + range: integer + required: false + description: >- + JSON-RPC id of the events/stream request to which the new interval + applies. When omitted, the new interval applies to every stream + opened by the authenticated principal, including streams opened + after this call. + + SetEventStreamParametersResponse: + abstract: false + is_a: FunctionExecutionResult + description: >- + Structured result returned by the execute_function Skill when it is + invoked for the reserved set_event_stream_parameters function. + slot_usage: + executionId: + description: Identifier of the execution that applied the new interval. + attributes: + appliedKeepaliveIntervalMs: + range: integer + required: true + unit: + ucum_code: ms + description: >- + Keep-alive interval actually applied by the ONVIF Device, in + milliseconds. This value is authoritative and may differ from the + requested one when the request was clamped. + clamped: + range: boolean + required: false + ifabsent: "false" + description: >- + Whether the requested interval was clamped to the range supported by + the ONVIF Device. When true, appliedKeepaliveIntervalMs differs from + the requested value. The supported range itself is read with the + get_function_capabilities Skill. + affectedStreams: + range: integer + multivalued: true + inlined_as_list: true + required: false + description: >- + JSON-RPC ids of the events/stream requests to which the applied + interval was propagated. + + EventStreamCapabilities: + abstract: false + is_a: FunctionCapabilities + description: >- + Static capabilities of the reserved set_event_stream_parameters function, + which are the invariant properties of the event stream of an ONVIF Device: + the keep-alive interval range it supports, the interval it uses when none + was requested, and the number of concurrent streams it can serve. These + values do not depend on any invocation and are read with the + get_function_capabilities Skill. + + The class covers the event stream as a whole and not the keep-alive + mechanism alone, because an ONVIF Client has to know the stream limits + before it opens a stream, and the reserved function that configures the + stream is the one place in this model where those limits have an owner. + attributes: + defaultKeepaliveIntervalMs: + range: integer + required: true + ifabsent: int(30000) + unit: + ucum_code: ms + description: >- + Keep-alive interval used by the ONVIF Device when none was + requested, in milliseconds. It is 30000 (30 seconds). + minKeepaliveIntervalMs: + range: integer + required: true + unit: + ucum_code: ms + description: >- + Shortest keep-alive interval supported by the ONVIF Device, in + milliseconds. A shorter requested interval is clamped to this value. + maxKeepaliveIntervalMs: + range: integer + required: true + unit: + ucum_code: ms + description: >- + Longest keep-alive interval supported by the ONVIF Device, in + milliseconds. A longer requested interval is clamped to this value. + maxConcurrentStreams: + range: integer + required: true + minimum_value: 1 + description: >- + Greatest number of events/stream requests the ONVIF Device serves + concurrently for the authenticated principal. An ONVIF Client holds + one stream per subscription, so this value bounds the number of + subscriptions it can receive by push at any one time. + + The value is at least 1. A request that would exceed it is rejected + with -32013 ResourceExhausted, which an ONVIF Client can avoid + entirely by reading this value before it opens a stream. + + SetEventStreamParametersInvocation: + abstract: false + is_a: FunctionInvocation + description: >- + Declaration of the reserved set_event_stream_parameters function: it is + invoked through the execute_function Skill, it accepts + SetEventStreamParametersRequest, it returns + SetEventStreamParametersResponse, and its capabilities are + EventStreamCapabilities. The function sets the interval at which the ONVIF + Device emits notifications/events/heartbeat keep-alive messages on open + events/stream responses, whose default is 30000 milliseconds. + annotations: + mcp_skill: execute_function + access_class: ACTUATE + slot_usage: + function: + equals_string: "set_event_stream_parameters" + required: true + description: >- + Reserved function identifier. It is always + set_event_stream_parameters for this invocation. + parameters: + range: SetEventStreamParametersRequest + required: true + description: Keep-alive parameters accepted by the function. + result: + range: SetEventStreamParametersResponse + required: false + description: >- + Keep-alive result returned by the function, reporting the interval + actually applied. diff --git a/yaml/agentic/base.yaml b/yaml/agentic/base.yaml new file mode 100644 index 000000000..068b9252e --- /dev/null +++ b/yaml/agentic/base.yaml @@ -0,0 +1,440 @@ +id: https://www.onvif.org/ver10/agentic/base/linkml/ +name: onvif-agentic-base +description: ONVIF Agentic Service base schema +prefixes: + linkml: https://w3id.org/linkml/ + onvif: https://www.onvif.org/ver10/agentic/linkml/ +imports: + - linkml:types + - enums + - common + - time + - signature +default_prefix: onvif +default_range: string + +classes: + + InformationItem: + abstract: true + description: >- + Abstract base container for a single unit of information. + attributes: + id: + range: UUID + identifier: true + required: true + description: >- + Identifier of the information item. It shall be unique across every + item the ONVIF Device emits, and shall never be reused. + + It is carried on the wire as a plain UUID string and not as a JSON-LD + node identifier: a bare UUID is not an IRI, and binding it to @id + would require every identifier to be rewritten in urn:uuid form. The + cross-references between items are therefore resolved by an ONVIF + Client according to this specification, and are not RDF edges. + confidence: + range: Likelihood + required: true + description: >- + Confidence level associated with the information, in the range 0.0 to + 1.0 inclusive. The range is Likelihood, the same type used by every + other confidence-bearing slot of this model, such as the likelihood of + a StringLikelihood or of a Color, so that a single interpretation + applies wherever a confidence appears. + + The confidence of an item is the confidence of that item alone. It is + not derived from, and shall not be propagated to, any item that cites + it in supportedBy. + productionTime: + range: Time + required: true + description: Production timestamp of the information item. + provenance: + range: Provenance + required: true + description: Provenance of the information item. + extensible: + range: Extensible + required: false + description: Optional vendor extension container. + + InformationEnvelope: + description: >- + Optional container that groups one or more information items and may + carry a single envelope-level signature. + attributes: + id: + range: UUID + identifier: true + required: true + description: >- + Identifier of the envelope. It is carried on the wire as a plain UUID + string and not as a JSON-LD node identifier, for the reason given for + the identifier of InformationItem. + items: + range: InformationItem + multivalued: true + inlined_as_list: true + required: true + description: One or more enclosed information items. + hashes: + range: ItemDigest + multivalued: true + inlined_as_list: true + required: false + description: >- + One digest per enclosed information item, sorted by the item field + in ascending order. The list is optional: the envelope digest + carried by the signature is sufficient to verify the integrity of + the group as a whole, and omitting the list only gives up the + ability to identify which individual item was altered. + signature: + range: Signature + required: false + description: Optional envelope-level signature. + + Provenance: + abstract: true + description: >- + Abstract provenance descriptor for an InformationItem. It answers the + question of who is asserting the information, and is specialised by + concrete classes describing a particular kind of producer. + attributes: + extensible: + range: Extensible + required: false + description: Optional vendor extension container. + + DeviceEntity: + description: >- + A physical or logical entity of an ONVIF Device, such as an input, an + output, or a channel. It mirrors tt:DeviceEntity of the ONVIF Schema, + which likewise carries a single token attribute. + attributes: + token: + range: ReferenceToken + required: true + description: Unique identifier referencing the entity. + + ONVIFDevice: + is_a: Provenance + description: >- + Concrete Provenance identifying an ONVIF Device as the producer of an + information item. + + The descriptive fields are all optional and self-asserted, and are + meant for diagnostics, inventory and presentation. The only mandatory + field is publicKeys, because a key identifier is the one piece of + information in this class that refers to material an ONVIF Client can + verify by an independent path; the descriptive fields refer to nothing + that can be checked. + attributes: + manufacturer: + range: string + required: false + description: >- + The manufacturer of the device, as returned by the Manufacturer + field of GetDeviceInformationResponse. + model: + range: string + required: false + description: >- + The device model, as returned by the Model field of + GetDeviceInformationResponse. + firmwareVersion: + range: string + required: false + description: >- + The firmware version in the device, as returned by the + FirmwareVersion field of GetDeviceInformationResponse. + serialNumber: + range: string + required: false + description: >- + The serial number of the device, as returned by the SerialNumber + field of GetDeviceInformationResponse. + hardwareId: + range: string + required: false + description: >- + The hardware ID of the device, as returned by the HardwareId field + of GetDeviceInformationResponse. + entity: + range: DeviceEntity + required: false + description: >- + Optional entity of the device that produced the information, used + when a device has several sources that would otherwise be + indistinguishable. + publicKeys: + range: DevicePublicKey + multivalued: true + inlined_as_list: true + required: true + minimum_cardinality: 1 + description: >- + One or more public keys the device declares as its own. At least + one key shall be present. + + AnalyticsModule: + is_a: Provenance + description: >- + Concrete Provenance identifying an analytics module running on an ONVIF + Device as the producer of an information item. It is the provenance to use + when the producer is an algorithm rather than a sensor, which is typically + the case for an Assertion. + + Distinguishing the module from the device that hosts it is what allows the + two kinds of claim to be told apart: an Observation produced by a video + source and an Assertion derived from it by an algorithm running on the same + device have different producers, and an ONVIF Client may have reason to + trust one and not the other. + + As in ONVIFDevice, publicKeys is the only mandatory descriptor, because the + key identifier is the one piece of information in this class that refers to + material an ONVIF Client can verify by an independent path. + attributes: + token: + range: ReferenceToken + required: true + description: >- + Unique identifier of the analytics module within the ONVIF Device. It + mirrors the token of tt:AnalyticsModule of the ONVIF Schema, so that a + module named here can be looked up in the analytics configuration of + the device. + algorithm: + range: string + required: false + description: >- + Identifier of the algorithm the module implements, for example + vehicle-reidentification. + version: + range: string + required: false + description: >- + Version of the algorithm, or of the model it runs. It is the field that + makes a derived item reproducible: two items produced by the same + algorithm in different versions are not comparable, and an ONVIF Client + that has qualified one version has not thereby qualified another. + entity: + range: DeviceEntity + required: false + description: >- + Optional entity of the device whose data the module consumed, used when + a device has several sources that would otherwise be + indistinguishable. + publicKeys: + range: DevicePublicKey + multivalued: true + inlined_as_list: true + required: true + minimum_cardinality: 1 + description: >- + One or more public keys the device declares as its own for items + produced by this module. At least one key shall be present. + + Location: + abstract: true + description: >- + Abstract spatial descriptor for an InformationItem. + + The class is abstract because a place can be given in two irreducibly + different ways: by the function it serves, which is what FunctionalLocation + expresses, or by its geometry. This specification defines the functional + form only; a geometric form may be added as a further concrete subclass + without changing Observation. + attributes: + extensible: + range: Extensible + required: false + description: Optional vendor extension container. + + FunctionalLocation: + is_a: Location + description: >- + Concrete Location naming a place by the function it serves rather than by + its geometry. It is the location descriptor to use when what matters about + a place is what happens there, for example an ambulance drop-off, a loading + bay or a pedestrian crossing. + + A functional location is meaningful only within the installation it belongs + to: the name is assigned when the site is commissioned and carries no + meaning outside it. An ONVIF Client shall therefore treat name as a label + for presentation, and token, where present, as the key for correlation. + attributes: + name: + range: string + required: true + description: >- + Human readable name of the place, as configured on the ONVIF Device, + for example Ambulance Drop-off. + token: + range: ReferenceToken + required: false + description: >- + Optional identifier of the configured area the name refers to. It + allows the place to be correlated across information items even if its + name is later changed, and to be looked up in the analytics + configuration of the ONVIF Device. + description: + range: string + required: false + description: >- + Optional longer description of the function the place serves. It is + omitted from items carried in a metadata stream, where the location is + repeated on every item, and belongs to the configuration and + presentation paths instead. + + Observation: + abstract: true + is_a: InformationItem + description: >- + Abstract InformationItem representing a measurement generated by an + ONVIF Device. + attributes: + observedTime: + range: Time + required: false + description: Temporal context observed by this observation. + observedSpace: + range: Location + required: false + description: Spatial context observed by this observation. + + VehicleObservation: + abstract: false + is_a: Observation + description: Information about a vehicle. + attributes: + type: + range: VehicleType + required: true + description: >- + The type of the vehicle. Acceptable values are typically defined + in VehicleType. Where a vehicle has been detected but not classified, + the value is Unknown: the slot is required, so an ONVIF Device is never + obliged to guess a type in order to report a detection. + use: + range: VehicleUse + required: false + description: >- + The use the vehicle is put to, which is orthogonal to its type. The + slot is omitted by an ONVIF Device that does not classify vehicle use; + the value Unknown states that the device does classify it but could not + determine it for this observation. + brand: + range: StringLikelihood + required: false + description: The brand of the vehicle + model: + range: StringLikelihood + required: false + description: The model of the vehicle + color: + description: Descriptor for the vehicle's color. + range: ColorDescriptor + required: false + + LicensePlateObservation: + abstract: false + is_a: Observation + description: Information about a vehicle's license plate. + attributes: + plateNumber: + description: A string representing the vehicle license plate number. + range: StringLikelihood + required: true + plateType: + description: >- + A description of the vehicle license plate type (e.g., "Normal", + "Police", "Diplomat"). + range: PlateType + required: false + countryCode: + description: >- + Describes the country of the license plate. The country code shall + be encoded as two letter code according to ISO 3166-1:2013 Alpha-2. + range: StringLikelihood + required: false + issuingEntity: + description: >- + State, province, or authority that issues the license plate. + range: StringLikelihood + required: false + + BarcodeObservation: + abstract: false + is_a: Observation + description: Information extracted from a barcode. + attributes: + data: + description: Information encoded in barcode. + range: StringLikelihood + required: true + type: + description: Type of the barcode. Acceptable values are defined in BarcodeType. + range: BarcodeTypeLikelihood + required: false + ppm: + description: Refers to the pixels per module. + range: float + required: false + + Assertion: + abstract: true + is_a: InformationItem + description: >- + Abstract InformationItem representing a statement supported by one or + more information items. + attributes: + supportedBy: + range: UUID + multivalued: true + required: true + description: >- + Identifiers of one or more supporting information items. The items + are referenced, not nested: each identifier shall resolve to an + information item the ONVIF Client has already received. + + VehicleReidentification: + abstract: false + is_a: Assertion + description: >- + Concrete Assertion stating that two or more vehicle observations, produced + at different times, refer to the same physical vehicle. It is the mechanism + by which a later and better informed observation supersedes the + classification carried by an earlier one, without either observation being + retracted. + + Neither observation is modified by this assertion. What the sensor saw + remains on the record at the confidence it deserved, and what the algorithm + concluded is a separate claim with its own confidence and its own + provenance, which an ONVIF Client may accept or discard on its own merits. + slot_usage: + supportedBy: + minimum_cardinality: 2 + description: >- + Identifiers of the vehicle observations that refer to the same physical + vehicle. At least two shall be present, since a single observation + cannot be re-identified. + attributes: + vehicleId: + range: UUID + required: true + description: >- + Stable identifier of the physical vehicle to which every observation + listed in supportedBy refers. It designates a physical entity and not an + InformationItem, and is therefore not subject to the resolution rule + that applies to supportedBy. + + Successive re-identifications of the same vehicle shall reuse this + value, so that an ONVIF Client can accumulate what is known about one + vehicle across several assertions. + authoritativeObservation: + range: UUID + required: false + description: >- + The observation listed in supportedBy whose classification an ONVIF + Client should prefer. Where absent, the observation with the most recent + productionTime applies. diff --git a/yaml/agentic/common.yaml b/yaml/agentic/common.yaml new file mode 100644 index 000000000..5058a4da0 --- /dev/null +++ b/yaml/agentic/common.yaml @@ -0,0 +1,225 @@ +id: https://www.onvif.org/ver10/agentic/common/linkml/ +name: onvif-agentic-common +description: ONVIF Agentic Service common schema +prefixes: + linkml: https://w3id.org/linkml/ + onvif: https://www.onvif.org/ver10/agentic/linkml/ +imports: + - linkml:types + - enums +default_prefix: onvif +default_range: string + +types: + Likelihood: + typeof: float + description: >- + A float value representing a probability or likelihood, constrained + between 0.0 and 1.0. + minimum_value: 0.0 + maximum_value: 1.0 + + UUID: + typeof: string + description: >- + Universally Unique Identifier in the canonical lowercase hyphenated + form specified in RFC 9562. Used as the range of every object + identifier slot in this model. + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' + + Base64Binary: + typeof: string + description: >- + Binary value encoded with the standard base64 alphabet defined in + RFC 4648, including padding. + pattern: '^[A-Za-z0-9+/]+={0,2}$' + + ReferenceToken: + typeof: string + description: >- + Unique identifier referencing a physical or logical resource of an + ONVIF Device. It mirrors tt:ReferenceToken of the ONVIF Schema, and is + therefore limited to 64 characters. + pattern: '^.{1,64}$' + + KeyID: + typeof: string + description: >- + Unique identifier of a key in the keystore of an ONVIF Device. It + mirrors tas:KeyID of the ONVIF Advanced Security Service, which is an + XML NCName limited to 64 characters. Using the same identifier space + allows a key named here to be looked up in the keystore of the device. + pattern: '^[A-Za-z_][A-Za-z0-9._-]{0,63}$' + +classes: + + Extensible: + abstract: true + description: >- + Abstract class carrying extensions. It is used as the range of an + optional slot named extensible, which classes that support vendor + extensions declare individually; it is not intended to be inherited + via is_a, as it carries no attributes of its own. The only exceptions + are VendorExtension and VendorExtensible, which are themselves + extension containers. + comments: + - 'Declare an optional slot "extensible" with range Extensible on a class + that supports vendor extensions. Do not inherit it with is_a.' + + VendorExtension: + abstract: false + is_a: Extensible + description: >- + Container for a single vendor-specific extension entry. + attributes: + vendor_namespace: + range: uri + required: true + description: URI namespace that uniquely identifies the vendor. + name: + range: string + required: true + description: Local name of the extension element within the vendor namespace. + value: + range: Any + required: false + description: Vendor-specific payload. + + VendorExtensible: + abstract: false + is_a: Extensible + description: >- + Concrete container for grouping multiple vendor-specific extensions. + attributes: + vendorExtensions: + range: VendorExtension + multivalued: true + inlined_as_list: true + required: false + description: Zero or more vendor-specific extension entries. + + Any: + description: >- + A dynamic type that allows arbitrary nested data. + class_uri: linkml:Any + + StringLikelihood: + description: >- + A compound data structure combining a string value with a likelihood + score. + attributes: + value: + description: The primary string value. + range: string + required: true + likelihood: + description: The float value representing the likelihood. + range: Likelihood + required: true + + BarcodeTypeLikelihood: + description: >- + A compound data structure combining a barcode type with a likelihood + score. + attributes: + value: + description: The primary barcode type. + range: BarcodeType + required: true + likelihood: + description: The float value representing the likelihood. + range: Likelihood + required: true + + Color: + description: >- + Represents a color defined by three coordinates (X, Y, Z) in a + specific colorspace. If the colorspace is absent and not defined on + a higher level, YCbCr is implied. + attributes: + x: + description: >- + The X coordinate of the color (e.g., Y value in YCbCr, R value in + RGB). + range: float + required: true + y: + description: >- + The Y coordinate of the color (e.g., Cb value in YCbCr, G value in + RGB). + range: float + required: true + z: + description: >- + The Z coordinate of the color (e.g., Cr value in YCbCr, B value in + RGB). + range: float + required: true + colorspace: + description: URI defining the colorspace. + range: Colorspace + required: false + likelihood: + description: Likelihood that the color is correct. + range: Likelihood + required: false + + ColorCovariance: + description: Represents the covariance matrix associated with a color distribution. + attributes: + xx: + description: Variance in the X dimension. + range: float + required: true + yy: + description: Variance in the Y dimension. + range: float + required: true + zz: + description: Variance in the Z dimension. + range: float + required: true + xy: + description: Covariance between X and Y dimensions. + range: float + required: false + xz: + description: Covariance between X and Z dimensions. + range: float + required: false + yz: + description: Covariance between Y and Z dimensions. + range: float + required: false + colorspace: + description: URI defining the colorspace. + range: Colorspace + required: false + + ColorCluster: + description: >- + A grouping of a specific color with its associated weight and + covariance. + attributes: + color: + description: The primary color value. + range: Color + required: true + weight: + description: >- + The weight of the color in the cluster (e.g., percentage or ratio). + range: float + required: false + covariance: + description: The color covariance matrix or values. + range: ColorCovariance + required: false + + ColorDescriptor: + description: A descriptor containing one or more color clusters associated with an object. + attributes: + color_cluster: + description: A list of color clusters. + range: ColorCluster + multivalued: true + required: false diff --git a/yaml/agentic/enums.yaml b/yaml/agentic/enums.yaml new file mode 100644 index 000000000..af66ea51c --- /dev/null +++ b/yaml/agentic/enums.yaml @@ -0,0 +1,190 @@ +id: https://www.onvif.org/ver10/agentic/enum/linkml/ +name: onvif-agentic-enum +description: ONVIF Agentic Service enums +prefixes: + linkml: https://w3id.org/linkml/ + onvif: https://www.onvif.org/ver10/agentic/linkml/ +imports: + - linkml:types +default_prefix: onvif +default_range: string + +enums: + + BarcodeType: + description: Standard formats for barcodes and 2D codes. + permissible_values: + Code39: + title: "Code-39" + Code49: + title: "Code-49" + Code93: + title: "Code-93" + Code128: + title: "Code-128" + Code11: + title: "Code-11" + Code25Interleaved: + title: "Code-25-Interleaved" + Code25NonInterleaved: + title: "Code-25-NonInterleaved" + DataMatrix: + Maxicode: + Postnet: + RM4SCC: + description: RoyalMail + ISBN13: + title: "ISBN-13" + ISBN13Dual: + title: "ISBN-13-Dual" + ISBN10: + title: "ISBN-10" + ITF14: + title: "ITF-14" + EAN2: + title: "EAN-2" + EAN8: + title: "EAN-8" + EAN13: + title: "EAN-13" + EAN14: + title: "EAN-14" + EAN18: + title: "EAN-18" + EAN99: + title: "EAN-99" + EAN128: + title: "EAN-128" + SCC14: + title: "SCC-14" + SSCC18: + title: "SSCC-18" + UPCA: + title: "UPC-A" + UPCE: + title: "UPC-E" + PDF417: + QRCode: + + Colorspace: + description: Acceptable colorspace URIs for color representation. + permissible_values: + YCbCr: + meaning: "http://www.onvif.org/ver10/colorspace/YCbCr" + description: YCbCr colorspace (default if absent). + RGB: + meaning: "http://www.onvif.org/ver10/colorspace/RGB" + description: RGB colorspace. + CIELUV: + meaning: "http://www.onvif.org/ver10/colorspace/CIELUV" + description: CIE LUV colorspace (Deprecated). + CIELAB: + meaning: "http://www.onvif.org/ver10/colorspace/CIELAB" + description: CIE 1976 (L*a*b*) colorspace (Deprecated). + HSV: + meaning: "http://www.onvif.org/ver10/colorspace/HSV" + description: HSV colorspace (Deprecated). + + PlateType: + description: Acceptable values for license plate types. + permissible_values: + Normal: + Police: + Diplomat: + Temporary: + + VehicleType: + description: >- + Allowed vehicle types. Bus, Car, Truck, Bicycle and Motorcycle mirror + tt:VehicleType of the ONVIF Schema; Van, Other and Unknown extend it, so + this enumeration is a superset of tt:VehicleType and not a strict mapping + of it. + permissible_values: + Bus: + Car: + Truck: + Van: + Bicycle: + Motorcycle: + Other: + description: The type was determined, but it is not one of the values above. + Unknown: + description: >- + A vehicle was detected but its type could not be determined. This is + the value to use when classification failed or was not attempted, + since type is a required slot. + + VehicleUse: + description: >- + Allowed uses of a vehicle. The use of a vehicle is orthogonal to its + type: an ambulance is a Van, a Truck or a Car that is put to emergency + medical service. This enumeration has no counterpart in the ONVIF Schema. + permissible_values: + Private: + Taxi: + PublicTransport: + Delivery: + Ambulance: + Police: + Fire: + Other: + description: The use was determined, but it is not one of the values above. + Unknown: + description: >- + The use could not be determined, although the ONVIF Device does + classify vehicle use. It is distinct from the absence of the use + slot, which states that the device does not classify use at all. + + DigestAlgorithm: + description: >- + Hash algorithms that may be used to digest a canonicalised + InformationItem, to compute the envelope digest, and to compute the + fingerprint of a public key. Each permissible value carries, in its + meaning, the object identifier of the algorithm, so that the formal + identifier is the same one used by the ONVIF Media Signing + Specification. + + This enumeration only fixes the wire representation of an algorithm + name. It is not a statement of which algorithms are acceptable: the + algorithm an ONVIF Device shall use, and the algorithms an ONVIF Client + shall accept, are those mandated by the current version of the ONVIF + Security Baseline. Where the two disagree, the ONVIF Security Baseline + prevails, and a value listed here may well be forbidden by it. + permissible_values: + SHA256: + meaning: "urn:oid:2.16.840.1.101.3.4.2.1" + description: SHA-256 as specified in FIPS 180-4. + SHA384: + meaning: "urn:oid:2.16.840.1.101.3.4.2.2" + description: SHA-384 as specified in FIPS 180-4. + SHA512: + meaning: "urn:oid:2.16.840.1.101.3.4.2.3" + description: SHA-512 as specified in FIPS 180-4. + + SignatureAlgorithm: + description: >- + Signature algorithms that may be used to sign an envelope digest. Each + permissible value carries, in its meaning, the object identifier of the + algorithm. + + This enumeration only fixes the wire representation of an algorithm + name. It is not a statement of which algorithms are acceptable: the + algorithm an ONVIF Device shall use, and the algorithms an ONVIF Client + shall accept, are those mandated by the current version of the ONVIF + Security Baseline. Where the two disagree, the ONVIF Security Baseline + prevails, and a value listed here may well be forbidden by it. + permissible_values: + ECDSA_P256_SHA256: + meaning: "urn:oid:1.2.840.10045.4.3.2" + description: ECDSA over NIST P-256 with SHA-256. + ECDSA_P384_SHA384: + meaning: "urn:oid:1.2.840.10045.4.3.3" + description: ECDSA over NIST P-384 with SHA-384. + ECDSA_P521_SHA512: + meaning: "urn:oid:1.2.840.10045.4.3.4" + description: ECDSA over NIST P-521 with SHA-512. + RSASSA_PSS: + meaning: "urn:oid:1.2.840.113549.1.1.10" + description: >- + RSASSA-PSS. The digest used within the padding scheme is the one + declared by the digestAlgorithm field. diff --git a/yaml/agentic/signature.yaml b/yaml/agentic/signature.yaml new file mode 100644 index 000000000..1bb34561d --- /dev/null +++ b/yaml/agentic/signature.yaml @@ -0,0 +1,230 @@ +id: https://www.onvif.org/ver10/agentic/signature/linkml/ +name: onvif-agentic-signature +description: ONVIF Agentic Service signature schema +prefixes: + linkml: https://w3id.org/linkml/ + onvif: https://www.onvif.org/ver10/agentic/linkml/ +imports: + - linkml:types + - enums + - common +default_prefix: onvif +default_range: string + +classes: + + ItemDigest: + description: >- + Digest of a single canonicalised InformationItem, bound to the + identifier of the item it covers. A signed InformationEnvelope carries + one ItemDigest per enclosed item, which allows a verifier that detects + a mismatch to determine exactly which item was altered. + attributes: + item: + range: UUID + required: true + description: >- + Identifier of the InformationItem covered by this digest. It is + equal to the id field of that item. + digest: + range: Base64Binary + required: true + description: >- + Digest of the canonical form of the item, computed with the + digest algorithm declared by the enclosing signature. + + KeyFingerprint: + description: >- + Digest of a public key, computed over the key material itself rather than + over a certificate that carries it. Two certificates issued at different + times for the same key have the same fingerprint, so a fingerprint + follows the key across certificate renewals, across firmware versions and + across devices, which the fingerprint of a certificate does not. + + A fingerprint is what makes the key declaration of a provenance checkable: + a KeyID names an entry in the keystore of one device and says nothing + about the material it holds, whereas a fingerprint can be compared with a + value an ONVIF Client obtained by an independent path. + attributes: + algorithm: + range: DigestAlgorithm + required: true + description: >- + Digest algorithm used to compute the fingerprint. The algorithm + actually used shall be one of those mandated by the current version of + the ONVIF Security Baseline. + value: + range: Base64Binary + required: true + description: >- + Digest of the DER encoding of the SubjectPublicKeyInfo structure of + the key, as specified in RFC 5280. The input is the same octet + sequence that the PEM form carried by subjectPublicKeyInfo encodes, so + a fingerprint can always be recomputed from that field alone. + + SigningKey: + abstract: true + description: >- + Abstract descriptor of the key used to produce a signature. It is + abstract because the key material may either travel with the signed + content or be published once and subsequently referenced. + attributes: + extensible: + range: Extensible + required: false + description: Optional vendor extension container. + + X509CertificateChain: + is_a: SigningKey + description: >- + Concrete SigningKey that carries the certificate chain needed to + verify the signature. The leaf certificate contains the public key. + attributes: + certificateChain: + range: string + multivalued: true + required: true + description: >- + Certificate chain in PEM format, ordered from the leaf certificate + towards the certification authority. The certification authority + certificate itself shall not be included. + userProvisioned: + range: boolean + required: false + ifabsent: 'boolean(false)' + description: >- + True when the chain is a user provisioned certificate chain rather + than a manufacturer provisioned one. + + PublicKeyIdentifier: + is_a: SigningKey + description: >- + Concrete SigningKey that references key material distributed out of + band, so that the certificate chain does not have to be repeated in + every signed envelope. + attributes: + keyId: + range: KeyID + required: true + description: >- + Identifier of the key in the keystore of the ONVIF Device. It may + be matched against the keys the device declares in the publicKeys + field of its provenance. + verificationMethod: + range: uri + required: false + description: >- + Optional URI from which the corresponding public key or + certificate chain can be retrieved. + fingerprints: + range: KeyFingerprint + multivalued: true + inlined_as_list: true + required: false + description: >- + Zero or more fingerprints of the referenced key, at most one per + digest algorithm. Because the key descriptor is part of the signature + configuration, and the signature configuration is covered by the + envelope digest, a fingerprint carried here is covered by the + signature: it binds the signature to key material rather than to the + name of a keystore entry. + + DevicePublicKey: + description: >- + A public key an ONVIF Device declares as its own. The declaration is + informative: it allows a key to be discovered and a key rotation to be + followed, but it does not by itself establish that the key is + trustworthy. + attributes: + keyId: + range: KeyID + required: true + description: >- + Identifier of the key in the keystore of the ONVIF Device. It names an + entry of that keystore and not the key material it holds: the same + identifier may designate different material after a key rotation, and + the same identifier on two devices designates unrelated material. + fingerprints: + range: KeyFingerprint + multivalued: true + inlined_as_list: true + required: false + description: >- + Zero or more fingerprints of the key, at most one per digest + algorithm. An ONVIF Client that holds a fingerprint obtained by an + independent path considers the key matched when that fingerprint is + equal to one of those listed, and shall not consider a key matched on + the basis of keyId alone. + + The slot is normally omitted from items carried in a metadata stream, + where provenance is repeated on every item, and is populated where an + ONVIF Client is expected to pin a key, such as in a signed + InformationEnvelope. + subjectPublicKeyInfo: + range: string + required: false + description: >- + Optional public key in PEM format, carrying a SubjectPublicKeyInfo + structure. It is omitted unless the key material has to travel with + the information item, since provenance is repeated on every item. + extensible: + range: Extensible + required: false + description: Optional vendor extension container. + + Signature: + abstract: true + description: >- + Abstract cryptographic attestation descriptor. + attributes: + extensible: + range: Extensible + required: false + description: Optional vendor extension container. + + OnvifSignature: + is_a: Signature + description: >- + Concrete Signature profile defined by this specification, aligned with + the ONVIF Media Signing Specification. The envelope digest is computed + over the signature configuration followed by the per-item digests in + ascending item identifier order, and the signature is produced over + that digest. + attributes: + digestAlgorithm: + range: DigestAlgorithm + required: true + description: >- + Hash algorithm used both for the per-item digests and for the + envelope digest. The algorithm actually used shall be one of those + mandated by the current version of the ONVIF Security Baseline; + that document, and not the enumeration below, is authoritative on + which algorithms are allowed at any given time. + signatureAlgorithm: + range: SignatureAlgorithm + required: true + description: >- + Algorithm used to sign the envelope digest. The algorithm actually + used shall be one of those mandated by the current version of the + ONVIF Security Baseline; that document, and not the enumeration + below, is authoritative on which algorithms are allowed at any + given time. + created: + range: datetime + required: true + description: Time at which the signature was created, in ISO 8601 UTC. + key: + range: SigningKey + required: true + description: Descriptor of the key used to produce the signature. + envelopeDigest: + range: Base64Binary + required: true + description: >- + Digest computed over the canonical form of the signature + configuration followed by the raw digest octets of every + ItemDigest, in ascending item identifier order. + signatureValue: + range: Base64Binary + required: true + description: Digital signature computed over the envelope digest. diff --git a/yaml/agentic/time.yaml b/yaml/agentic/time.yaml new file mode 100644 index 000000000..ba0a5598d --- /dev/null +++ b/yaml/agentic/time.yaml @@ -0,0 +1,50 @@ +id: https://www.onvif.org/ver10/agentic/time/linkml/ +name: onvif-agentic-time +description: ONVIF Agentic Service time schema +prefixes: + linkml: https://w3id.org/linkml/ + onvif: https://www.onvif.org/ver10/agentic/linkml/ +imports: + - linkml:types + - common +default_prefix: onvif +default_range: string + +classes: + + Time: + abstract: true + description: >- + Abstract production-time descriptor for an InformationItem. + attributes: + extensible: + range: Extensible + required: false + description: Optional vendor extension container. + + ISO8601Timestamp: + abstract: false + is_a: Time + description: >- + An ISO 8601 timestamp is an internationally agreed-upon format for + representing dates and times as YYYY-MM-DDTHH:MM:SS + (e.g., 2026-09-09T15:54:00), designed to be clear for both humans + and machines + attributes: + timestamp: + range: datetime + required: true + description: The ISO 8601 timestamp + + ISO8601Interval: + abstract: false + is_a: Time + description: >- + An ISO 8601 time interval represented as a single string + (e.g., '2026-09-09T15:00:00Z/2026-09-09T16:00:00Z' or + '2026-09-09T15:00:00Z/P1M' or 'R5/2026-09-09T15:00:00Z/P1M'). + attributes: + intervalString: + range: string + required: true + description: The time interval formatted according to the ISO 8601 standard.