---
# System prepended metadata

title: Supply Chain Integrity Model

---

---
title: Supply Chain Integrity Model
abbrev: SCIM
docname: draft-birkholz-scim-latest
stand_alone: true
ipr: trust200902
area: Security
wg: RATS Working Group
kw: Internet-Draft
cat: std
pi:
  toc: yes
  sortrefs: yes
  symrefs: yes

author:
- ins: J. Doe
  name: John Doe
  org: ACME Inc.
  abbrev: ACME Inc.
  email: john.doe@loopback
  street: Loop Back 127
  code: '12712'
  city: Loopback
  country: Germany

normative:
  RFC2119:
  RFC8174:
  I-D.ietf-sacm-coswid: coswid

informative:

--- abstract

Abstract

--- middle

[TOC]

# Introduction

This document describes a generic model, the Supply Chain Integrity Model (SCIM) for managing data about the security, quality, and integrity of assets (physical, digital, and human) across end-to-end supply chains. 

# References

Distributed Identity (DID) - https://www.w3.org/TR/did-core/

Confidential Consortium Framework (CCF) - https://microsoft.github.io/CCF/

Note: Later generalize to not reference DID or CCF specifically.

# Terminology

Actors:
: Agent - (W3C:PROV-O) An agent is something that bears some form of responsibility for an activity taking place, for the existence of an entity, or for another agent's activity. 
: Person - Person agents are people.
: Organization - An organization is a social or legal institution such as a company, society, etc.
: Software Agent - A software agent is running software.

Roles:
: Issuing Authority - Agent that issues Signed Claims, e.g. Microsoft. 
: Auditor - An Issuing Authority that issues signed audit claims about artifacts that are, for example, other claims, or software packages, or activities conducted by a role, or other resources.
: Claim Generator - Software Agent that generates Claims, e.g. Office build system.
: Claim Signer - Software Agent that accepts unsigned Claims and signs them using protected capabilities endorsed by an Issuing Authority, e.g. Microsoft signing service including an endorsed RoT.
: Ledger Service - Software Agent that accepts and logs Signed Claims based on Trust Anchors, making them Registered Claims.
: Ledger Authority - Agent that governs a Ledger Service, e.g. 'Microsoft', 'Global Supply Chain Consortium'. Governance includes managing Trust Anchors.
: Claims Registration Requestor - Software Agent that submits Signed Claims to a Ledger Service for registration.
: Claims Index Service - Software Agent that supports querying of Registered Claims.

Duties:
: Timestamping an activity (e.g. an essential duty of the Ledger Services)

Documents (data at rest):
: Claims
    * Anonymous statements produced by a human or tool, e.g. evidence, endorsements, and policy
    * Arbitrary format, but with defined media type
    * Comes without guarantees
    * Process: Statements produced by human or tool
    * Guarantees: None
    * Analogy: Real world document/letter
: Signed Claims - claims wrapped with a header and signed.
    * Header contains media type of claims and signing key details
    * No restriction on media type of claims
    * Process: Signed
    * Guarantees: Proof of possession of private key
    * Analogy: Signed document or letter
: Registered Claims - signed claims wrapped in a ledger receipt.
    * Process:
        * Signed claims are submitted (via REST)
        * The ledger either:
          * Has a cached DID document for the issuer, or
          * Resolves the DID document for the issuer
        * The ledger makes collateral used to resolve the DID document transparent
          * e.g., TLS certificate (with OCSP) for did:web
        * The ledger validates the claims signature based on the public key contained (at the specified keyid) in the DID document
        * The signed claims are made transparent by reaching consensus
        * Note that the media type of the claims and the claims themselves are considered opaque
    * Guarantees: 
        * The Signed Claims are transparant
        * The process by which the Signed Claims are registered is transparant
        * The signature is valid.
        * The DID verification material was valid when the Signed Claims were validated by the ledger.
          * Deciding if DID verification material is valid is DID method specific.
        * The DID document corresponding to the DID referenced in the signed claims header contained the public key corresponding to the private key at a specific keyid (the DID document can have multiple keyids)
        * The Ledger contains the DID document that was used to validate the public key
        * The "rules of the system" at the time the Signed Claims were made transparent are themselves transparent
        * Hardware attestation reports indicating that the system was valid at the time it executed are transparent
        * The history of all Ledger governance that could affect the registering of Signed Claims is itself transparent

## Media types

Claims are represented as a document with a media type. Examples are SBOMs, policies, audits, freshness information, and others.

Signed Claims are claims embedded in a signing envelope where the media type of the claims is included in the envelope. The signing envelope itself has a media type as well, currently fixed to application/cose.

Registered claims are Signed Claims embedded in a Claims Registration Receipt where the media type of the signing envelope is included in the receipt.

In this document, the media type of the claims is also called content type.

### SCIM-defined content types

Generally, SCIM is agnostic to claims content types. However, to aid interoperability this specification recommends and/or defines certain  content types.


  * freshness claims?
    * default fall-back? maybe even MTI? Part of SCIM [FIXME]

## Claims Index Service Capabilites

MAIK: I'm not sure we can realistically define an interface for such a service as it will depend on the use case. We could define a very generic interface but this may be less valuable.

* content-types?
* Encoding by Hash, URL, and description of _access method_ [FIXME]
* requirement: The *query engine* (Claims Index Service) is the thing which has to know about the media-type decoding.

common (media?) types to filter by:
- vulnerabilities
- 

## Mirroring / Bulk retrieval

REST API interface to allow bulk-fetching of registered claims according to some filter criteria:
- required: start txid
- optional: end txid, may be higher than actual (if missing, until latest)
- optional: content type(s)
- optional: issuer(s)

Result:
- cbor list of receipts
- actual end txid of given range
- pagination

Notes:
- tx ids in ledger must be increasing, not guids, otherwise range query does not make sense

basis for developing a query engine, where (a subset of) data is continually mirrored

whether part of the ledger or not, it should be part of SCIM


### Vital SCIM Metadata

* "EO metadata" -> ??




## Messages (data in flight) for End-User Interface

Claims Registration Request:

: Operation: HTTP message to enter Signed Claims in a Ledger Service.
: From: Claims Registration Requestor
: To: Ledger Service

Claims Registration Response:
: Operation: HTTP message returned by a Ledger Service in response to a Claims Registration Request, confirming whether the Signed Claims have been accepted for registration, pending consensus.
: From: Ledger Service
: To: Claims Registration Requestor

Claims Registration Receipt Request:
: Operation: HTTP message to request a receipt for a successful claims registration.
: From: Claims Registration Requestor
: To: Ledger Service

Claims Registration Receipt Response: 
: Operation: HTTP message returned by a Ledger Service in response to a Claims Registration Receipt Request, containing either the receipt or error details.
: From: Ledger Service
: To: Claims Registration Requestor

Questions:
* **Maik:** How are Duties different from Roles?
* How do we handle policy and verification in the model?
 
Ledger:
: tbd

## Messages "internal to the Ledger"

**MAIK:** That seems like a lot. I don't want to paste the CCF REST API in here. It's implementation-specific.

## Policy Evaluation Phases

1. Verify Claims_Registration_Receipt -> walking thourgh hash tree, "check the proof"
   * one or more trsuted services key roots (as the included signature is over the root cert only)
   * then you walk the proof (check existence of tree nodes in ledger according to path in receipt)
   * public key in the receipt is the basis for trust decisions based on your policies -> actually trusted trust anchors in trust anchor store
   * this is probably very well-defined and simple to follow (integrity & trust decision based on HRoT)
     * not part of your policy engine, just code that does signature validation
     * Trust Anchor management might be "out-of-band"
2. Look at content that might be part of the payload or around it (freshnes/expire/version)
   * where does Claims that enable this go?
   * could be content, could be in the wrapper
   * is the DID issuer in my list of trusted DID issuers?
   * root policy? how to identify, how to trust?
     * e.g., one trusted issuer for DID
     * if that content from that issuer, I can trust that policy
   * "list of all the other claims that are attributes of the first claims" 2nd claims -> metadata
3. Process signed_claims to arraive at a certain conclusion
   * here 


## Requirements Notation

{::boilerplate bcp14-tagged}

{: #mybody}
# SCIM

## The SCIM Diagram

~~~~
 .---------------------.                    .---------------------.
| SoftwareAgent:        |                  | Message:              |
| SCIM Assertion-Set    |    generates     | SCIM Assertion Set    |
|      Generator        +----------------->|                       |
| RATS Claims Generator |                  | RATS Claim            |
 '---------------------'                    '---------------------'
            ^                                          ^
            | owns                                     | consumes
            |                                          |
 .----------+----------.                    .----------+----------.
| Agent:                |                  | SoftwareAgent:        |
| SCIM Issuer           |   generates +    | SCIM Header Adder &   |
|                       +----------------->|      Signer           |
| RATS RP Owner         |  header-claims   | RATS Claim Collector  |
 '----------+----------'                    '----------+----------'
            |                                          |
            | owns                                     | generates
            v                                          v
 .---------------------.                    .---------------------.
| SoftwareAgent:        |                  | Message:              |
| SCIM ReceiptRequester |     consumes     | (COSE) Signed SCIM    |
| RATS Attester         +----------------->|        Claims Set     |
| RATS Relying Party    |                  | RATS Claim            |
 '----------+-----+----'                    '---------------------'
            |     |                    
            |      '----------------.                  
            v generates              | consumes          
 .---------------------.             |      .---------------------.
| Message:              |            |     | Message:              |
| SCIM ReceiptRequest   |             '--->| SCIM Receipt          |
|                       |             .--->| RATS AR-augmented     |
| RATS Evidence         |            |     | Evidence              |
 '----------+----------'             |      '---------------------'
            ^ consumes               | generates        
            |      .----------------'                  
            |     |
 .----------+-----+----.                    .---------------------.
| SoftwareAgent:        |                  | Agent:                |
| SCIM Ledger Service   |     consumes     | SCIM Ledger Authority |
|                       +----------------->|                       |
| RATS Endorsed Verifier|                  | RATS Verifier Owner   |
 '----------+----------'                    '----------+----------'
            |                                          |
            | generates                                | owns      
            v                                          v
 .---------------------.                    .---------------------.
| Messages:             |                  | SoftwareAgent:        |
| Receipt Ledger        |     consumes     | "Store"               |
|                       |<-----------------|                       |
| RATS Evidence         |                  | RATS Verifier         |
 '---------------------'                    '---------------------'
~~~~
# Trust Anchor Model

* DID specifica
  * TLS cert verfiication can happen inside a TEE
* Ledger HRoT

# SCIM Roles and Messages

## Roles

### Claim-Set Generator

### Issuer

## Messages

This section describes the HTTP messages sent to and received from the Ledger Service.

TODO: probably should define URL paths as well, not just verb, headers, body

### Claims Registration Request

A Claims Registration Request is an HTTP `POST` message  sent to the Ledger Service with the `Content-Type: application/cose` header and the body being the Signed Claims to register.

Signed Claims are represented as a tagged `COSE_Sign1` message.

The COSE protected header must contain the following parameters:

- alg (label: `1`): Asymmetric signature algorithm as integer, for example `-35` for ECDSA with SHA-384, see [COSE Algorithms registry](https://www.iana.org/assignments/cose/cose.xhtml)
- payload type (label: `3`): Media type of claims as string, for example `application/spdx+cbor`
- issuer (label: `258`, to be registered): DID of the signer as string, for example `did:web:example.com`

Depending on the DID method the protected header must contain one or more of the following parameters:

- kid (label: `4`): Key identifier as a UTF-8 string encoded as a byte string, required for `did:web`

In CDDL notation, the Signed Claims message is defined as follows:

```
Signed_Claims = COSE_Sign1_Tagged

COSE_Sign1_Tagged = #6.18(COSE_Sign1)

COSE_Sign1 = [
  protected : bstr .cbor Protected_Header,
  unprotected : {},  ; not used, hence an empty map
  payload : bstr,
  signature : bstr
]

Protected_Header = {
  ; mandatory
  1 => int               ; algorithm identifier
  3 => tstr              ; payload type
  258 => tstr            ; DID of issuer

  ; mandatory depending on DID method
  ? 4 => bstr            ; key identifier
  ? 33 => COSE_X509      ; X.509 certificate chain, excluding Root CA certificate
}

COSE_X509 = bstr / [ 2*certs: bstr ]
```

### Claims Registration Response

A Claims Registration Response is an HTTP message returned by the Ledger Service in response to a Claims Registration Request.

There are multiple cases:

- HTTP Status `201` - Registration was tentatively successful pending service consensus.
- HTTP Status `400` - Registration was unsuccessful.
  - Error code `AwaitingDIDResolutionTryLater`
  - Error code `InvalidInput`

The `201` response contains the `Location` HTTP header to request the Claims Registration Receipt at the given URL.

The `400` response has a `Content-Type: application/json` header and a body containing details about the error:

```json
{
  "error": {
    "code": "<error code>",
    "message": "<message>"
  }
}
```

`AwaitingDIDResolutionTryLater` means the service does not have an up-to-date DID document of the DID referenced in the Signed Claims but is performing or will perform a DID resolution after which the client may retry the request. The response may contain the HTTP header `Retry-After` to inform the client about the expected wait time.

`InvalidInput` means either the Signed Claims message is syntactically malformed, violates the signing profile (e.g. signing algorithm), or has an invalid signature relative to the currently resolved DID document.

### Claims Registration Receipt Request

A Claims Registration Receipt Request is an HTTP `GET` message sent to the Ledger Service. The request URL contains a transaction identifier and is returned in the Claims Registration Response.

### Claims Registration Receipt Response

A Claims Registration Receipt Response is an HTTP message returned by the Ledger Service in response to a Claims Registration Receipt Request.

There are multiple cases:

- HTTP Status `200` - Registration was successful and the receipt is returned.
- HTTP Status `400` - Transaction exists but does not correspond to a Registration Request.
  - Error code `TransactionMismatch`
- HTTP Status `404` - Transaction is pending, unknown, or invalid.
  - Error code `TransactionPendingOrUnknown`
  - Error code `TransactionInvalid`

The `200` response contains the Claims Registration Receipt in the body.

The `400` and `404` responses return the error details as described earlier.

The Claims Registration Receipt represents Registered Claims and is a CBOR document with the following elements:

- version: Receipt format version as integer, currently `1`, maximum `23`
- transaction id: Transaction ID corresponding to the receipt as string, informational
- service key: Public key of the Ledger Service identity as a DER-encoded `SubjectPublicKeyInfo` structure ([RFC 5280 sec. 4.1](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1), [RFC 3279 sec. 2.3](https://datatracker.ietf.org/doc/html/rfc3279#section-2.3))
- signature: ECDSA with SHA-256 signature over the Merkle tree root hash, DER-encoded as described in [RFC 3279 sec. 2.2.3](https://datatracker.ietf.org/doc/html/rfc3279.html#section-2.2.3)
- proof: Inclusion proof as an array of pairs (two-element array) where a pair contains the direction as boolean (`true` for left, `false` for right) and the SHA-256 hash as byte string
- leaf: SHA-256 Merkle tree leaf hash as byte string
- writeset: SHA-256 hash of the transaction write set as byte string (part of leaf data)
- signed claims type: Media type of the Signed Claims envelope as string, currently always `application/cose` (part of leaf data)
- signed claims: Signed Claims submitted to the  Ledger Service as a byte string (part of leaf data)

The CDDL of a Claims Registration Receipt is as follows:

```
Claims_Registration_Receipt = [
  version : Version,
  transaction_id : tstr,
  service_key : bstr,
  signature : bstr,
  leaf : SHA_256,
  proof : bstr .cbor [+ ProofElement],
  writeset : SHA_256,
  signed_claims_type : tstr,   ; always "application/cose"
  signed_claims : bstr
]

Version = 1..23  ; represented as single byte in CBOR

ProofElement = [
  left : bool,
  hash : SHA_256
]

SHA_256 = bstr .size 32
```

TODO: The receipt format relies on features that are quite CCF-specific, in particular a concept called "custom transaction claims" (covers `writeset` and the following custom fields). We could define that and propose it as a standard for other types of ledgers, but it may not be straight-forward.

# Issuers and Guaranteed Properties

## Component Properties and End-to-End Properties

You need sets of component properties to arrive at end-to-end properties.

### Integrity of the Ledger

* Role of Confidential Compute
* Roots of trusts
* Redundant Byzantine Fault Tolerance
  * what does it mean to be faithful?
  * what does it mean to be slow?
  * what does it mean to be malicious?

# CDDL

See {{-coswid}}.

~~~~ CDDL
<CODE BEGINS>
;{::include some.cddl}
<CODE ENDS>
~~~~

# Privacy Considerations

Privacy Considerations

# Security Considerations

Security Considerations

# IANA Considerations

See Body {{mybody}}.

--- back

# Mapping to RATS

~~~~
{::include scim-rats.ascii}
~~~~

Update