Internet-Draft | CoSERV | June 2025 |
Howard & Fossati | Expires 14 December 2025 | [Page] |
In the Remote Attestation Procedures (RATS) architecture, Verifiers require Endorsements and Reference Values to assess the trustworthiness of Attesters. This document specifies the Concise Selector for Endorsements and Reference Values (CoSERV), a structured query/result format designed to facilitate the discovery and retrieval of these artifacts from various providers. CoSERV defines a query language and corresponding result structure using CDDL, which can be serialized in CBOR format, enabling efficient interoperability across diverse systems.¶
This note is to be removed before publishing as an RFC.¶
The latest revision of this draft can be found at https://rats-endorsements-distribution.github.io/draft-howard-rats-coserv/draft-howard-rats-coserv.html. Status information for this document may be found at https://datatracker.ietf.org/doc/draft-howard-rats-coserv/.¶
Discussion of this document takes place on the Remote ATtestation ProcedureS Working Group mailing list (mailto:rats@ietf.org), which is archived at https://mailarchive.ietf.org/arch/browse/rats/. Subscribe at https://www.ietf.org/mailman/listinfo/rats/.¶
Source for this draft and an issue tracker can be found at https://github.com/rats-endorsements-distribution/draft-howard-rats-coserv.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 14 December 2025.¶
Copyright (c) 2025 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
Remote Attestation Procedures (RATS) enable Relying Parties to evaluate the trustworthiness of remote Attesters by appraising Evidence. This appraisal necessitates access to Endorsements and Reference Values, which are often distributed across multiple providers, including hardware manufacturers, firmware developers, and software vendors. The lack of standardized methods for querying and retrieving these artifacts poses challenges in achieving seamless interoperability.¶
The Concise Selector for Endorsements and Reference Values (CoSERV) addresses this challenge by defining a query language and a corresponding result structure for the transaction of artifacts between a provider and a consumer. The query language format provides Verifiers with a standard way to specify the environment characteristics of Attesters, such that the relevant artifacts can be obtained from Endorsers and Reference Value Providers. In turn, the result format allows those Endorsers and Reference Value Providers to package the artifacts within a standard structure. This facilitates the efficient discovery and retrieval of relevant Endorsements and Reference Values from providers, maximising the re-use of common software tools and libraries within the transactions.¶
The CoSERV query language is intended to form the input data type for tools and services that provide access to Endorsements and Reference Values. The CoSERV result set is intended to form the corresponding output data type from those tools and services. This document does not define the complete APIs or interaction models for such tools and services. The scope of this document is limited to the definitions of the query language and the result set only.¶
Both the query language and the result set are designed for extensibility. This addresses the need for a common baseline format to optimise for interoperability and software reuse, while maintaining the flexibility demanded by a dynamic and diverse ecosystem.¶
The environment characteristics of Endorsements and Reference Values are derived from the equivalent concepts in CoRIM [I-D.ietf-rats-corim]. CoSERV therefore borrows heavily from CoRIM, and shares some data types for its fields. And, like CoRIM, the CoSERV schema is defined using CDDL [RFC8610]. A CoSERV query can be serialized in CBOR [STD94] format.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
This document uses terms and concepts defined by the RATS architecture. For a complete glossary, see Section 4 of [RFC9334].¶
This document uses terms and concepts defined by the CoRIM specification. For a complete glossary, see Section 1.1.1 of [I-D.ietf-rats-corim].¶
This document uses the terms "actual state" and "reference state" as defined in Section 2 of [I-D.ietf-rats-endorsements].¶
The terminology from CBOR [STD94], CDDL [RFC8610] and COSE [STD96] applies; in particular, CBOR diagnostic notation is defined in Section 8 of [STD94] and Appendix G of [RFC8610]. Terms and concepts are always referenced as proper nouns, i.e., with Capital Letters.¶
The roles of Endorser or Reference Value Provider might sometimes be fulfilled by aggregators, which collect from multiple supply chain sources, or even from other aggregators, in order to project a holistic view of the endorsed system. The notion of such an aggregator is not explicit in the RATS architecture. In practice, however, supply chains are complex and multi-layered. Supply chain sources can include silicon manufacturers, device manufacturers, firmware houses, system integrators, service providers and more. In practical terms, an Attester is likely to be a complex entity, formed of components from across such supply chains. Evidence would be likewise structured, with contributions from different segments of the Attester's overall anatomy. A Verifier for such Evidence may find it convenient to contact an aggregator as a single source of truth for Endorsements and Reference Values. An aggregator would have intelligence about the Attester's complete anatomy and supply chain. It would have the ability to contact all contributing supply chain actors for their individual Endorsements and Reference Values, before collecting them into a cohesive set, and delivering them to the Verifier as a single, ergonomic package. In pure RATS terms, an aggregator is still an Endorser or a Reference Value Provider - or, more likely, both. It is not a distinct role, and so there is no distinctly-modeled conveyance between an aggregator and a Verifier. However, when consuming from an aggregator, the Verifier may need visibility of the aggregation process, possibly to the extent of needing to audit the results by inspecting the individual inputs that came from the original supply chain actors. CoSERV addresses this need, catering equally for both aggregating and non-aggregating supply chain sources.¶
To support deployments with aggregators, CoSERV allows for flexible trust models as follows.¶
Shallow Trust: in this model, the consumer trusts the aggregator, solely and completely, to provide authentic descriptions of the endorsed system. The consumer does not need to audit the results of the aggregation process.¶
Deep Trust: in this model, the consumer has a trust relationship with the aggregator, but does not deem this to be sufficient. The consumer can still use the collected results from the aggregation process, where it is convenient to do so, but also needs to audit those results.¶
Any given CoSERV transaction can operate according to either model. The consumer decides which model to use when it forms a query. The CoSERV result payload can convey both the aggregated result and the audit trail as needed. The payload size may be smaller when the shallow model is used, but the choice between the two models is a question for implementations and deployments.¶
Although CoSERV is designed to support aggregation, it is not a requirement. When aggregation is not used, CoSERV still fulfills the need for a standard conveyance mechanism between Verifiers and Endorsers or Reference Value Providers.¶
CoSERV is designed to facilitate query-response transactions between a producer and a consumer. In the RATS model, the producer is either an Endorser or a Reference Value Provider, and the consumer is a Verifier. CoSERV defines a single top-level data type that can be used for both queries and result sets. Queries are authored by the consumer (Verifier), while result sets are authored by the producer (Endorser or Reference Value Provider) in response to the query. A CoSERV data object always contains a query. When CoSERV is used to express a result set, the query is retained alongside the result set that was yielded by that query. This allows consumers to verify a match between the query that was sent to the producer, and the query that was subsequently returned with the result set. Such verification is useful because it mitigates security threats arising from any untrusted infrastructure or intermediaries that might reside between the producer and the consumer. An example of this is caching in HTTP [STD98] and CoAP [RFC7252]. It might be expensive to compute the result set for a query, which would make caching desirable. However, if caching is managed by an untrusted intermediary, then there is a risk that such an untrusted intermediary might return incorrect results, either accidentally or maliciously. Pairing the original query with each result set provides an end-to-end contract between the consumer and producer, mitigating such risks. The transactional pattern between the producer and the consumer would be that the consumer begins the transaction by authoring a query and sending it to the producer as a CoSERV object. The producer receives the query, computes results, and returns a new CoSERV object formed from the results along with the original query. Notionally, the producer is "adding" the results to the query before sending it back to the consumer.¶
Artifacts are what the consumer (Verifier) needs in order to verify and appraise Evidence from the Attester, and therefore they form the bulk of the response payload in a CoSERV transaction. The common CoSERV query language recognises three artifact types. These correspond to the three categories of endorsement artifact that can be identified natively in the RATS architecture:¶
Trust Anchor: A trust anchor is as defined in [RFC6024]. An example of a trust anchor would be the public part of the asymmetric signing key that is used by the Attester to sign Evidence, such that the Verifier can verify the cryptographic signature.¶
Endorsed Value: An endorsed value is as defined in Section 1.1.1 of [I-D.ietf-rats-corim]. This represents a characteristic of the Attester that is not directly presented in the Evidence, such as certification data related to a hardware or firmware module.¶
Reference Value: A reference value is as defined in Section 1.1.1 of [I-D.ietf-rats-corim]. A reference value specifies an individual aspect of the Attester's desired state. Reference values are sometimes informally called "golden values". An example of a reference value would be the expected hash or checksum of a binary firmware or software image running in the Attester's environment. Evidence from the Attester would then include claims about the Attester's actual state, which the Verifier can then compare with the reference values at Evidence appraisal time.¶
When artifacts are produced by an aggregator (see Section 2), the following additional classifications apply:¶
Collected Artifacts: these refer to artifacts that were derived by the aggregator by collecting and presenting data from original supply chain sources, or from other aggregators. Collected artifacts form a single holistic package, and provide the most ergonomic consumption experience for the Verifier.¶
Source Arfifacts: these refer to artifacts that were obtained directly from the original supply chain sources, and used as inputs into the aggregation process, allowing the aggregator to derive the collected artifacts.¶
In the shallow trust model of aggregation, only the collected artifacts are used by the consumer. In the deep trust model, both the collected artifacts and the source artifacts are used. The source artifacts allow the consumer to audit the collected artifacts and operate the trust-but-verify principle.¶
The environment defines the scope (or scopes) in which the endorsement artifacts are applicable. Given that the consumer of these artifacts is likely to be a Verifier in the RATS model, the typical interpretation of the environment would be that of an Attester that either has produced evidence, or is expected to produce evidence, that the Verifier needs to appraise. The Verifier consequently needs to query the Endorser or Reference Value Provider for artifacts that are applicable in that environment. There are three mutually-exclusive methods for defining the environment within a CoSERV query. Exactly one of these three methods MUST be used for the query to be valid. All three methods correspond to environments that are also defined within CoRIM [I-D.ietf-rats-corim].¶
Class: A class is an environment that is expected to be common to a group of similarly-constructed Attesters, who might therefore share the same set of endorsed characteristics. An example of this might be a fleet of computing devices of the same model and manufacturer.¶
Instance: An instance is an environment that is unique to an individual and identifiable Attester, such as a single computing device or component.¶
Group: A group is a collection of common Attester instances that are collected together based on some defined semantics. For example, Attesters may be put into groups for the purpose of anonymity.¶
The purpose of a query is to allow the consumer (Verifier) to specify the artifacts that it needs. The information that is conveyed in a CoSERV query includes the following:¶
A specification of the required artifact type: Reference Value, Endorsed Value or Trust Anchor. See Section 3.2 for definitions of artifact types. A single CoSERV query can only specify a single artifact type.¶
A specification of the Attester's environment. Environments can be selected according to Attester instance, group or class. See Section 3.3 for full definitions. To facilitate efficient transactions, a single query can specify either multiple instances, multiple groups or multiple classes. However, it is not possible to mix instance-based selectors, group-based selectors and class-based selectors in a single query.¶
A timestamp, denoting the time at which the CoSERV query was sent.¶
A switch to select the desired supply chain depth. A CoSERV query can request collected artifacts, source artifacts, or both. This switch is especially relevant when the CoSERV query is fulfilled by an aggregator. The collected artifacts are intended for convenient consumption (according to the shallow trust model), while the source artifacts are principally useful for auditing (according to the deep trust model). It is possible for a query to select for source artifacts only, without the collected artifacts. This might happen when the consumer needs to inspect or audit artifacts from across the deep supply chain, while not requiring the convenience of the aggregated view. It could also happen when the consumer is acting as an intermediate broker, gathering artifacts for delivery to another aggregator. See Section 2 for details on aggregation, auditing and trust models.¶
The result set contains the artifacts that the producer collected in response to the query. The top-level structure of the result set consists of the following three items:¶
A collection of one or more result entries. This will be a collection of either reference values, endorsed values or trust anchors. See Section 3.2 for definitions of artifact types. In the future, it may be possible to support additional artifact types via an extension mechanism. Artifact types are never mixed in any single CoSERV result set. The artifacts in the result collection therefore MUST match the single artifact type specified in the original CoSERV query.¶
A timestamp indicating the expiry time of the entire result set. Consumers MUST NOT consider any part of the result set to be valid after this expiry time.¶
A collection of the original source materials from which the producer derived the correct artifacts to include in the result set. These source materials are optional, and their intended purpose is auditing. They are included only when requested by the original CoSERV query. Source materials would typically be requested in cases where the consumer is not willing to place sole trust in the producer, and therefore needs an audit trail to enable additional verifications.¶
Each individual result entry combines a CoMID triple with an authority delegation chain. CoMID triples are exactly as defined in Section 5.1.4 of [I-D.ietf-rats-corim]. Each CoMID triple will demonstrate the association between an environment matching that of the CoSERV query, and a single artifact such as a reference value, trust anchor or endorsed value. The authority delegation chain is composed of one or more authority delegates. Each authority delegate is represented by a public key or key identifier, which the consumer can check against its own set of trusted authorities. The authority delegation chain serves to establish the provenance of the result entry, and enables the Verifier to evaluate the trustworthiness of the associated artifact. The purpose of the authority delegation chain is to allow CoSERV responses to support decentralized trust models, where Verifiers may apply their own policy to determine which authorities are acceptable for different classes of artifact.¶
Because each result entry combines a CoMID triple with an authority delegation chain, the entries are consequently known as quadruples (or "quads" for short).¶
This section specifies the CBOR data model for CoSERV queries and result sets.¶
CDDL is used to express rules and constraints of the data model for CBOR. These rules must be strictly followed when creating or validating CoSERV data objects.¶
The top-level CoSERV data structure is given by the following CDDL:¶
coserv = { &(profile: 0) => profile &(query: 1) => query ? &(results: 2) => results } profile = oid-type / ~uri¶
CoSERV inherits the following types from the CoRIM data model class-map
, $class-id-type-choice
, $instance-id-type-choice
and $group-id-type-choice
.¶
The collated CDDL is in Appendix A.¶
In common with EAT and CoRIM, CoSERV supports the notion of profiles. As with EAT and CoRIM, profiles are a way to extend or specialize the structure of a generic CoSERV query in order to cater for a specific use case or environment.¶
In a CoSERV query, the profile can be identified by either a Uniform Resource Identifier (URI) or an Object Identifier (OID).
This convention is identical to how EAT profiles are identified using the eat_profile
claim as described in Section 4.3.2 of [I-D.ietf-rats-eat].¶
The CoSERV query language enables Verifiers to specify the desired characteristics of Endorsements and Reference Values based on the environment in which they are applicable.¶
The top-level structure of a CoSERV query is given by the following CDDL:¶
query = { &(artifact-type: 0) => artifact-type &(environment-selector: 1) => environment-selector-map &(timestamp: 2) => tdate ; RFC3339 date &(result-type: 3) => result-type } artifact-type = &(endorsed-values: 0) / &(trust-anchors: 1) / &(reference-values: 2) result-type = &(collected-artifacts: 0) / &(source-artifacts: 1) / &(both: 2)¶
The meanings of these fields are detailed in the following subsections.¶
The artifact-type
field is the foremost discriminator of the query.
It is a top-level category selector. Its three permissible values are trust-anchors
(codepoint 1), endorsed-values
(codepoint 0) and reference-values
(codepoint 2).¶
See Section 3.2 for full definitions of artifact types.¶
It is expected that implementations might choose to store these different categories of artifacts in different top-level stores or database tables.
Where this is the case, the artifact-type
field serves to narrow the query down to the correct store or table.
Even where this is not the case, the discriminator is useful as a filter for the consumer, resulting in an efficiency gain by avoiding the transfer of unwanted data items.¶
The environment selector forms the main body of the query, and its CDDL is given below:¶
environment-selector-map = { selector } selector //= ( &(class: 0) => [ + class-map ] ) selector //= ( &(instance: 1) => [ + $instance-id-type-choice ] ) selector //= ( &(group: 2) => [ + $group-id-type-choice ] )¶
Environments can be specified according to instance, group or class. See Section 3.3 for details.¶
Although these three environment definitions are mutually-exclusive in a CoSERV query, all three support multiple entries. This is to gain efficiency by allowing the consumer (Verifier) to query for multiple artifacts in a single transaction. For example, where artifacts are being indexed by instance, it would be possible to specify an arbitrary number of instances in a single query, and therefore obtain the artifacts for all of them in a single transaction. Likewise for classes and groups. However, it would not be possible for a single query to specify more than one kind of environment. For example, it would not be possible to query for both class-level and instance-level artifacts in a single CoSERV transaction.¶
When multiple environment selectors are present in a single query, such as multiple instances or multiple groups, the implementation of the artifact producer MUST consider these to be alternatives, and hence use a logical OR
operation when applying the query to its internal data stores.¶
Below is an illustrative example of how a CoSERV query for endorsed values, selecting for multiple Attester instances, might be transformed into a semantically-equivalent SQL database query:¶
SELECT * FROM endorsed_values WHERE ( instance-id = "At6tvu/erQ==" ) OR ( instance-id = "iZl4ZVY=" )`¶
The same applies for class-based selectors; however, since class selectors are themselves composed of multiple inner fields, the implementation of the artifact producer MUST use a logical AND
operation in consideration of the inner fields for each class.¶
Also, for class-based selectors, any unset fields in the class are assumed to be wildcard (*
), and therefore match any value.¶
Below is an illustrative example of how a CoSERV query for reference values, selecting for multiple Attester classes, might be transformed into a semantically-equivalent SQL database query:¶
SELECT * FROM reference_values WHERE ( class-id = "iZl4ZVY=" AND class-vendor = "ACME Inc." ) OR ( class-id = "31fb5abf-023e-4992-aa4e-95f9c1503bfa" )¶
The timestamp
field records the date and time at which the query was made, formatted according to Section 3.4.1 of [STD94].
Implementations SHOULD populate this field with the current date and time when forming a CoSERV query.¶
The result-type
field selects for either collected-artifacts
(codepoint 0), source-artifacts
(codepoint 1) or both
(codepoint 2).
See Section 2 for definitions of source and collected artifacts.¶
The result set structure is given by the following CDDL:¶
results = { result-set &(expiry: 10) => tdate ; RFC3339 date ? &(source-artifacts: 11) => [ + cmw-record ] } result-set //= reference-values result-set //= endorsed-values result-set //= trust-anchors result-set //= $$result-set-extensions refval-quad = { &(authorities: 1) => [ + $crypto-key-type-choice ] &(rv-triple: 2) => reference-triple-record } reference-values = ( &(rvq: 0) => [ * refval-quad ] ) endval-quad = { &(authorities: 1) => [ + $crypto-key-type-choice ] &(ev-triple: 2) => endorsed-triple-record } cond-endval-quad = { &(authorities: 1) => [ + $crypto-key-type-choice ] &(ce-triple: 2) => conditional-endorsement-triple-record } endorsed-values = ( &(evq: 1) => [ * endval-quad ] &(ceq: 2) => [ * cond-endval-quad ] ) ak-quad = { &(authorities: 1) => [ + $crypto-key-type-choice ] &(ak-triple: 2) => attest-key-triple-record } cots-stmt = { &(authorities: 1) => [ + $crypto-key-type-choice ] &(cots: 2) => cots } trust-anchors = ( &(akq: 3) => [ * ak-quad ] &(tas: 4) => [ * cots-stmt ] ) ; ; import CoTS ; cots = "TODO COTS" ; ; import CMW ; cmw-record = "TODO CMW"¶
Implementations may wish to use serialized CoSERV queries as canonical identifiers for artifact collections. For example, a Reference Value Provider service may wish the cache the results of a CoSERV query to gain efficiency when responding to a future identical query. For these use cases to be effective, it is essential that any given CoSERV query is always serialized to the same fixed sequence of CBOR bytes. Therefore, CoSERV queries MUST always use CBOR deterministic encoding as specified in Section 4.2 of [STD94]. Further, CoSERV queries MUST use CBOR definite-length encoding.¶
CoSERV is designed to ensure that any result set passed from a producer to a consumer is precisely the result set that corresponds to the consumer's original query.
This is the reason why the original query is always included along with the result set in the data model.
However, this measure is only sufficient in cases where the conveyance protocol guarantees that CoSERV result sets are always transacted over an end-to-end secure channel without any intermediaries.
Wherever this is not the case, producers MUST create an additional cryptographic binding between the query and the result.
This is achieved by transacting the result set within a cryptographic envelope, with a signature added by the producer, which is verified by the consumer.
A CoSERV data object can be signed using COSE [STD96].
A signed-coserv
is a COSE_Sign1
with the following layout:¶
signed-coserv = [ protected: bytes .cbor signed-coserv-protected-hdr unprotected: signed-coserv-unprotected-hdr payload: bytes .cbor coserv signature: bytes ]¶
The payload MUST be the CBOR-encoded CoSERV.¶
signed-coserv-protected-hdr = { 1 => int ; alg 2 => "application/coserv+cbor" / 10000 ; cty * cose.label => cose.values } signed-coserv-unprotected-hdr = { * cose.label => cose.values } cose.label = int / text cose.values = any¶
The protected header MUST include the signature algorithm identifier.
The protected header MUST include either the content type application/coserv+cbor
or the CoAP Content-Format TBD1.
Other header parameters MAY be added to the header buckets, for example a kid
that identifies the signing key.¶
This section provides some illustrative examples of valid CoSERV query objects.¶
The following example shows a query for Reference Values scoped by a single class.
The artifact-type
is set to 2 (reference-values
), indicating a query for Reference Values.
The profile
is given the example value of tag:example.com,2025:cc-platform#1.0.0
.
Finally, the environment-selector
uses the key 0 to select for class, and the value contains a single entry with illustrative settings for the identifier, vendor and model.¶
{ / profile / 0: "tag:example.com,2025:cc-platform#1.0.0", / query / 1: { / artifact-type / 0: 2, / reference-values / / environment-selector / 1: { / class / 0: [ { / class-id / 0: 560(h'00112233'), / tagged-bytes / / vendor / 1: "Example Vendor", / model / 2: "Example Model" } ] }, / timestamp / 2: 0("2030-12-01T18:30:01Z"), / result-type / 3: 1 / source-material / } }¶
The next example is similar, but adds a second entry to the set of classes in the environment-map
, showing how multiple classes can be queried at the same time.¶
{ / profile / 0: "tag:example.com,2025:cc-platform#1.0.0", / query / 1: { / artifact-type / 0: 2, / reference-values / / environment-selector / 1: { / class / 0: [ { / class-id / 0: 560(h'8999786556'), / tagged-bytes / / vendor / 1: "Example Vendor", / model / 2: "Example Model" }, { / class-id / 0: 37(h'31FB5ABF023E4992AA4E95F9C1503BFA') / UUID / } ] }, / timestamp / 2: 0("2030-12-01T18:30:01Z"), / result-type / 3: 2 / both collected and source material / } }¶
The following example shows a query for Reference Values scoped by instance.
Again, the artifact-type
is set to 2, and profile
is given a demonstration value. The environment-selector
now uses the key 1 to select for instances, and the value contains two entries with example instance identifiers.¶
{ / profile / 0: "tag:example.com,2025:cc-platform#1.0.0", / query / 1: { / artifact-type / 0: 2, / reference-values / / environment-selector / 1: { / instance / 1: [ 550(h'02DEADBEEFDEAD'), / UEID / 560(h'8999786556') / tagged-bytes / ] }, / timestamp / 2: 0("2030-12-01T18:30:01Z"), / result-type / 3: 0 / collected material / } }¶
This section provides some illustrative examples of valid CoSERV queries with their corresponding result sets.¶
In this next example, the query is a reference value query based on class.¶
The top-level structure is a map with three entries: profile
(codepoint 0), query
(codepoint 1) and results
(codepoint 2).¶
The profile and query structures are the same as in the previous examples.
The result structure is a map with two entries: expiry
(codepoint 10) and reference-value triples
(codepoint 0).
A single reference-value triple is shown in this example. Its environment-map
, as expected, is the same as the environment-map
that was supplied in the query.
The rest of the structure is the measurement-map
as defined in CoRIM [I-D.ietf-rats-corim].¶
{ / profile / 0: "tag:example.com,2025:cc-platform#1.0.0", / query / 1: { 0: 2, 1: { 0: [ { 0: 560(h'8999786556') } ] }, 2: 0("2030-12-01T18:30:01Z"), 3: 0 }, / results / 2: { 10: 0("2030-12-13T18:30:02Z"), 0: [ { 1: [ 560(h'abcdef') ], 2: [ { 0: { 0: 560(h'8999786556') } }, [ { 0: 37(h'31FB5ABF023E4992AA4E95F9C1503BFA'), 1: { / version / 0: { 0: "1.2.3", 1: 16384 }, / svn / 1: 553(2) } } ] ] } ] } }¶
RFC Editor: please remove this section prior to publication.¶
This section records the status of known implementations of the protocol defined by this specification at the time of posting of this Internet-Draft, and is based on a proposal described in [RFC7942]. The description of implementations in this section is intended to assist the IETF in its decision processes in progressing drafts to RFCs. Please note that the listing of any individual implementation here does not imply endorsement by the IETF. Furthermore, no effort has been spent to verify the information presented here that was supplied by IETF contributors. This is not intended as, and must not be construed to be, a catalog of available implementations or their features. Readers are advised to note that other implementations may exist.¶
According to [RFC7942], "this will allow reviewers and working groups to assign due consideration to documents that have the benefit of running code, which may serve as evidence of valuable experimentation and feedback that have made the implemented protocols more mature. It is up to the individual working groups to use this information as they see fit".¶
Responsible Organisation: Veraison (open source project within the Confidential Computing Consortium).¶
Location: https://github.com/veraison¶
Description: Veraison provides components that can be used to build a Verifier, and also exemplifies adjacent RATS roles such as the Relying Party. There is an active effort to extend Veraison so that it can act in the capacity of an Endorser or Reference Value Provider, showing how CoSERV can be used as a query language for such services. This includes library code to assist with the creation, parsing and manipulation of CoSERV queries.¶
Level of Maturity: This is a proof-of-concept prototype implementation.¶
License: Apache-2.0.¶
Coverage: This implementation covers all aspects of the CoSERV query language.¶
Contact: Thomas Fossati, Thomas.Fossati@linaro.org¶
The CoSERV data type serves an auxiliary function in the RATS architecture. It does not directly convey Evidence, Endorsements, Reference Values, Policies or Attestation Results. CoSERV exists only to facilitate the interactions between the Verifier and the Endorser or Reference Value Provider roles. Consequently, there are fewer security considerations for CoSERV, particularly when compared with data objects such as EAT or CoRIM.¶
Certain security characteristics are desirable for interactions between the Verifier and the Endorser or Reference Value Provider. However, these characteristics would be the province of the specific implementations of these roles, and of the transport protocols in between them. They would not be the province of the CoSERV data object itself. Examples of such desirable characteristics might be:¶
The Endorser or Reference Value Provider is available to the Verifier when needed.¶
The Verifier is authorised to query data from the Endorser or Reference Value Provider.¶
Queries cannot be intercepted or undetectably modified by an entity that is interposed between the Verifier and the Endorser or Reference Value Provider.¶
Implementations should take care when transforming CoSERV queries into native query types that are compatible with their underlying storage technology (such as SQL queries). There is a risk of injection attacks arising from poorly-formed or maliciously-formed CoSERV queries. Implementations must ensure that suitable sanitization procedures are in place when performing such translations.¶
A CoSERV query can potentially contain privacy-sensitive information.
Specifically, the environment-selector
field of the query may reference identifiable Attester instances in some cases.
This concern naturally also extends to the data objects that might be returned to the consumer in response to the query, although the specifications of such data objects are beyond the scope of this document.
Implementations should ensure that appropriate attention is paid to this.
Suitable mitigations include the following:¶
RFC Editor: replace "RFCthis" with the RFC number assigned to this document.¶
IANA is requested to add the following media types to the "Media Types" registry [IANA.media-types].¶
Name | Template | Reference |
---|---|---|
coserv+cbor
|
application/coserv+cbor
|
Section 4 of RFCthis |
coserv+cose
|
application/coserv+cose
|
Section 4.6 of RFCthis |
application/coserv+cbor
application¶
coserv+cbor¶
n/a¶
"profile" (CoSERV profile in string format. OIDs must use the dotted-decimal notation.)¶
binary (CBOR)¶
n/a¶
RFCthis¶
Verifiers, Endorsers, Reference Value Providers¶
The syntax and semantics of fragment identifiers are as specified for "application/cbor". (No fragment identification syntax is currently defined for "application/cbor".)¶
RATS WG mailing list (rats@ietf.org)¶
COMMON¶
none¶
IETF¶
no¶
application/coserv+cose
application
¶
coserv+cose
¶
n/a (cose-type is explicitly not supported, as it is understood to be "cose-sign1")¶
"profile" CoSERV profile in string format.
OIDs must use the dotted-decimal notation.
Note that the cose-type
parameter is explicitly not supported, as it is understood to be "cose-sign1"
.¶
binary¶
n/a¶
RFCthis¶
Verifiers, Endorsers, Reference Value Providers¶
n/a¶
RATS WG mailing list (rats@ietf.org)¶
COMMON¶
none¶
IETF¶
no¶
IANA is requested to register the following Content-Format IDs in the "CoAP Content-Formats" registry, within the "Constrained RESTful Environments (CoRE) Parameters" registry group [IANA.core-parameters]:¶
Content-Type | Content Coding | ID | Reference |
---|---|---|---|
application/coserv+cbor | - | TBD1 | Section 4 of RFCthis |
application/coserv+cose | - | TBD2 | Section 4.6 of RFCthis |
If possible, TBD1 and TBD2 should be assigned in the 256..9999 range.¶
coserv = { &(profile: 0) => profile &(query: 1) => query ? &(results: 2) => results } profile = oid-type / ~uri environment-selector-map = { selector } selector //= ( &(class: 0) => [ + class-map ] ) selector //= ( &(instance: 1) => [ + $instance-id-type-choice ] ) selector //= ( &(group: 2) => [ + $group-id-type-choice ] ) concise-mid-tag = { ? &(language: 0) => text &(tag-identity: 1) => tag-identity-map ? &(entities: 2) => [ + comid-entity-map ] ? &(linked-tags: 3) => [ + linked-tag-map ] &(triples: 4) => triples-map * $$concise-mid-tag-extension } attest-key-triple-record = [ environment: environment-map key-list: [ + $crypto-key-type-choice ] ? conditions: non-empty< { ? &(mkey: 0) => $measured-element-type-choice, ? &(authorized-by: 1) => [ + $crypto-key-type-choice ] }> ] $class-id-type-choice /= tagged-oid-type $class-id-type-choice /= tagged-uuid-type $class-id-type-choice /= tagged-bytes class-map = non-empty<{ ? &(class-id: 0) => $class-id-type-choice ? &(vendor: 1) => tstr ? &(model: 2) => tstr ? &(layer: 3) => uint ? &(index: 4) => uint }> comid-entity-map = entity-map<$comid-role-type-choice, $$comid-entity-map-extension> $comid-role-type-choice /= &(tag-creator: 0) $comid-role-type-choice /= &(creator: 1) $comid-role-type-choice /= &(maintainer: 2) conditional-endorsement-series-triple-record = [ condition: stateful-environment-record series: [ + conditional-series-record ] ] conditional-series-record = [ selection: [ + measurement-map] addition: [ + measurement-map ] ] COSE_KeySet = [ + COSE_Key ] COSE_Key = { 1 => tstr / int ? 2 => bstr ? 3 => tstr / int ? 4 => [+ (tstr / int) ] ? 5 => bstr * cose-label => cose-value } cose-label = int / tstr cose-value = any coswid-triple-record = [ environment-map [ + concise-swid-tag-id ] ] concise-swid-tag-id = text / bstr .size 16 $crypto-key-type-choice /= tagged-pkix-base64-key-type $crypto-key-type-choice /= tagged-pkix-base64-cert-type $crypto-key-type-choice /= tagged-pkix-base64-cert-path-type $crypto-key-type-choice /= tagged-cose-key-type $crypto-key-type-choice /= tagged-thumbprint-type $crypto-key-type-choice /= tagged-cert-thumbprint-type $crypto-key-type-choice /= tagged-cert-path-thumbprint-type $crypto-key-type-choice /= tagged-pkix-asn1der-cert-type $crypto-key-type-choice /= tagged-bytes tagged-pkix-base64-key-type = #6.554(tstr) tagged-pkix-base64-cert-type = #6.555(tstr) tagged-pkix-base64-cert-path-type = #6.556(tstr) tagged-thumbprint-type = #6.557(digest) tagged-cose-key-type = #6.558(COSE_KeySet / COSE_Key) tagged-cert-thumbprint-type = #6.559(digest) tagged-cert-path-thumbprint-type = #6.561(digest) tagged-pkix-asn1der-cert-type = #6.562(bstr) domain-dependency-triple-record = [ $domain-type-choice [ + $domain-type-choice ] ] domain-membership-triple-record = [ $domain-type-choice [ + environment-map ] ] conditional-endorsement-triple-record = [ conditions: [ + stateful-environment-record ] endorsements: [ + endorsed-triple-record ] ] $domain-type-choice /= uint $domain-type-choice /= text $domain-type-choice /= tagged-uuid-type $domain-type-choice /= tagged-oid-type endorsed-triple-record = [ condition: environment-map endorsement: [ + measurement-map ] ] entity-map<role-type-choice, extension-socket> = { &(entity-name: 0) => $entity-name-type-choice ? &(reg-id: 1) => uri &(role: 2) => [ + role-type-choice ] * extension-socket } $entity-name-type-choice /= text environment-map = non-empty<{ ? &(class: 0) => class-map ? &(instance: 1) => $instance-id-type-choice ? &(group: 2) => $group-id-type-choice }> flags-map = { ? &(is-configured: 0) => bool ? &(is-secure: 1) => bool ? &(is-recovery: 2) => bool ? &(is-debug: 3) => bool ? &(is-replay-protected: 4) => bool ? &(is-integrity-protected: 5) => bool ? &(is-runtime-meas: 6) => bool ? &(is-immutable: 7) => bool ? &(is-tcb: 8) => bool ? &(is-confidentiality-protected: 9) => bool * $$flags-map-extension } $group-id-type-choice /= tagged-uuid-type $group-id-type-choice /= tagged-bytes identity-triple-record = [ environment: environment-map key-list: [ + $crypto-key-type-choice ] ? conditions: non-empty<{ ? &(mkey: 0) => $measured-element-type-choice, ? &(authorized-by: 1) => [ + $crypto-key-type-choice ] }> ] $instance-id-type-choice /= tagged-ueid-type $instance-id-type-choice /= tagged-uuid-type $instance-id-type-choice /= $crypto-key-type-choice $instance-id-type-choice /= tagged-bytes ip-addr-type-choice = ip4-addr-type / ip6-addr-type ip4-addr-type = bytes .size 4 ip6-addr-type = bytes .size 16 raw-int-type-choice = int / tagged-int-range int-range = [min: int / negative-inf, max: int / positive-inf] tagged-int-range = #6.564(int-range) positive-inf = null negative-inf = null linked-tag-map = { &(linked-tag-id: 0) => $tag-id-type-choice &(tag-rel: 1) => $tag-rel-type-choice } mac-addr-type-choice = eui48-addr-type / eui64-addr-type eui48-addr-type = bytes .size 6 eui64-addr-type = bytes .size 8 $measured-element-type-choice /= tagged-oid-type $measured-element-type-choice /= tagged-uuid-type $measured-element-type-choice /= uint $measured-element-type-choice /= tstr measurement-map = { ? &(mkey: 0) => $measured-element-type-choice &(mval: 1) => measurement-values-map ? &(authorized-by: 2) => [ + $crypto-key-type-choice ] } measurement-values-map = non-empty<{ ? &(version: 0) => version-map ? &(svn: 1) => svn-type-choice ? &(digests: 2) => digests-type ? &(flags: 3) => flags-map ? ( &(raw-value: 4) => $raw-value-type-choice, ? &(raw-value-mask: 5) => raw-value-mask-type ) ? &(mac-addr: 6) => mac-addr-type-choice ? &(ip-addr: 7) => ip-addr-type-choice ? &(serial-number: 8) => text ? &(ueid: 9) => ueid-type ? &(uuid: 10) => uuid-type ? &(name: 11) => text ? &(cryptokeys: 13) => [ + $crypto-key-type-choice ] ? &(integrity-registers: 14) => integrity-registers ? &(raw-int: 15) => raw-int-type-choice * $$measurement-values-map-extension }> non-empty<M> = (M) .and ({ + any => any }) oid-type = bytes tagged-oid-type = #6.111(oid-type) $raw-value-type-choice /= tagged-bytes $raw-value-type-choice /= tagged-masked-raw-value raw-value-mask-type = bytes tagged-masked-raw-value = #6.563([ value: bytes mask : bytes ]) reference-triple-record = [ ref-env: environment-map ref-claims: [ + measurement-map ] ] stateful-environment-record = [ environment: environment-map, claims-list: [ + measurement-map ] ] svn-type = uint svn = svn-type min-svn = svn-type tagged-svn = #6.552(svn) tagged-min-svn = #6.553(min-svn) svn-type-choice = svn / tagged-svn / tagged-min-svn $tag-id-type-choice /= tstr $tag-id-type-choice /= uuid-type tag-identity-map = { &(tag-id: 0) => $tag-id-type-choice ? &(tag-version: 1) => tag-version-type } $tag-rel-type-choice /= &(supplements: 0) $tag-rel-type-choice /= &(replaces: 1) tag-version-type = uint .default 0 tagged-bytes = #6.560(bytes) triples-map = non-empty<{ ? &(reference-triples: 0) => [ + reference-triple-record ] ? &(endorsed-triples: 1) => [ + endorsed-triple-record ] ? &(identity-triples: 2) => [ + identity-triple-record ] ? &(attest-key-triples: 3) => [ + attest-key-triple-record ] ? &(dependency-triples: 4) => [ + domain-dependency-triple-record ] ? &(membership-triples: 5) => [ + domain-membership-triple-record ] ? &(coswid-triples: 6) => [ + coswid-triple-record ] ? &(conditional-endorsement-series-triples: 8) => [ + conditional-endorsement-series-triple-record ] ? &(conditional-endorsement-triples: 10) => [ + conditional-endorsement-triple-record ] * $$triples-map-extension }> ueid-type = bytes .size (7..33) tagged-ueid-type = #6.550(ueid-type) uuid-type = bytes .size 16 tagged-uuid-type = #6.37(uuid-type) version-map = { &(version: 0) => text ? &(version-scheme: 1) => $version-scheme } digest = [ alg: (int / text), val: bytes ] digests-type = [ + digest ] integrity-register-id-type-choice = uint / text integrity-registers = { + integrity-register-id-type-choice => digests-type } concise-swid-tag = { tag-id => text / bstr .size 16, tag-version => integer, ? corpus => bool, ? patch => bool, ? supplemental => bool, software-name => text, ? software-version => text, ? version-scheme => $version-scheme, ? media => text, ? software-meta => one-or-more<software-meta-entry>, entity => one-or-more<entity-entry>, ? link => one-or-more<link-entry>, ? payload-or-evidence, * $$coswid-extension, global-attributes, } payload-or-evidence //= ( payload => payload-entry ) payload-or-evidence //= ( evidence => evidence-entry ) any-uri = uri label = text / int $version-scheme /= multipartnumeric $version-scheme /= multipartnumeric-suffix $version-scheme /= alphanumeric $version-scheme /= decimal $version-scheme /= semver $version-scheme /= int / text any-attribute = ( label => one-or-more<text> / one-or-more<int> ) one-or-more<T> = T / [ 2* T ] global-attributes = ( ? lang => text, * any-attribute, ) hash-entry = [ hash-alg-id: int, hash-value: bytes, ] entity-entry = { entity-name => text, ? reg-id => any-uri, role => one-or-more<$role>, ? thumbprint => hash-entry, * $$entity-extension, global-attributes, } $role /= tag-creator $role /= software-creator $role /= aggregator $role /= distributor $role /= licensor $role /= maintainer $role /= int / text link-entry = { ? artifact => text, href => any-uri, ? media => text, ? ownership => $ownership, rel => $rel, ? media-type => text, ? use => $use, * $$link-extension, global-attributes, } $ownership /= shared $ownership /= private $ownership /= abandon $ownership /= int / text $rel /= ancestor $rel /= component $rel /= feature $rel /= installationmedia $rel /= packageinstaller $rel /= parent $rel /= patches $rel /= requires $rel /= see-also $rel /= supersedes $rel /= supplemental $rel /= -256..64436 / text $use /= optional $use /= required $use /= recommended $use /= int / text software-meta-entry = { ? activation-status => text, ? channel-type => text, ? colloquial-version => text, ? description => text, ? edition => text, ? entitlement-data-required => bool, ? entitlement-key => text, ? generator => text / bstr .size 16, ? persistent-id => text, ? product => text, ? product-family => text, ? revision => text, ? summary => text, ? unspsc-code => text, ? unspsc-version => text, * $$software-meta-extension, global-attributes, } path-elements-group = ( ? directory => one-or-more<directory-entry>, ? file => one-or-more<file-entry>, ) resource-collection = ( path-elements-group, ? process => one-or-more<process-entry>, ? resource => one-or-more<resource-entry>, * $$resource-collection-extension, ) file-entry = { filesystem-item, ? size => uint, ? file-version => text, ? hash => hash-entry, * $$file-extension, global-attributes, } directory-entry = { filesystem-item, ? path-elements => { path-elements-group }, * $$directory-extension, global-attributes, } process-entry = { process-name => text, ? pid => integer, * $$process-extension, global-attributes, } resource-entry = { type => text, * $$resource-extension, global-attributes, } filesystem-item = ( ? key => bool, ? location => text, fs-name => text, ? root => text, ) payload-entry = { resource-collection, * $$payload-extension, global-attributes, } evidence-entry = { resource-collection, ? date => integer-time, ? device-id => text, ? location => text, * $$evidence-extension, global-attributes, } integer-time = #6.1(int) tag-id = 0 software-name = 1 entity = 2 evidence = 3 link = 4 software-meta = 5 payload = 6 hash = 7 corpus = 8 patch = 9 media = 10 supplemental = 11 tag-version = 12 software-version = 13 version-scheme = 14 lang = 15 directory = 16 file = 17 process = 18 resource = 19 size = 20 file-version = 21 key = 22 location = 23 fs-name = 24 root = 25 path-elements = 26 process-name = 27 pid = 28 type = 29 entity-name = 31 reg-id = 32 role = 33 thumbprint = 34 date = 35 device-id = 36 artifact = 37 href = 38 ownership = 39 rel = 40 media-type = 41 use = 42 activation-status = 43 channel-type = 44 colloquial-version = 45 description = 46 edition = 47 entitlement-data-required = 48 entitlement-key = 49 generator = 50 persistent-id = 51 product = 52 product-family = 53 revision = 54 summary = 55 unspsc-code = 56 unspsc-version = 57 multipartnumeric = 1 multipartnumeric-suffix = 2 alphanumeric = 3 decimal = 4 semver = 16384 tag-creator=1 software-creator=2 aggregator=3 distributor=4 licensor=5 maintainer=6 abandon=1 private=2 shared=3 ancestor=1 component=2 feature=3 installationmedia=4 packageinstaller=5 parent=6 patches=7 requires=8 see-also=9 supersedes=10 optional=1 required=2 recommended=3¶
TODO acknowledge.¶