diff --git a/.dprint.json b/.dprint.json new file mode 100644 index 0000000..085691f --- /dev/null +++ b/.dprint.json @@ -0,0 +1,16 @@ +{ + "lineWidth": 80, + "markdown": { + "textWrap": "always", + "lineWidth": 80 + }, + "includes": ["**/*.md"], + "excludes": [ + "**/node_modules", + "**/*-lock.json", + "**/target" + ], + "plugins": [ + "https://plugins.dprint.dev/markdown-0.16.3.wasm" + ] +} diff --git a/.github/workflows/markdown-lint.yaml b/.github/workflows/markdown-lint.yaml new file mode 100644 index 0000000..c79ffd2 --- /dev/null +++ b/.github/workflows/markdown-lint.yaml @@ -0,0 +1,39 @@ +name: Markdown Lint + +on: + pull_request: + paths: + - '**/*.md' + - '.github/workflows/markdown-lint.yaml' + - '.dprint.json' + +jobs: + markdown-lint: + name: Lint Markdown Files + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Rust + uses: dtolnay/rust-toolchain@stable + with: + toolchain: stable + components: rustfmt, clippy + + - name: Cache Rust dependencies + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo- + + - name: Install dprint + run: cargo install dprint + + - name: Run dprint check + run: dprint check "**/*.md" \ No newline at end of file diff --git a/README.md b/README.md index 0bea225..5661361 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,9 @@ # CycloneDX Transparency Exchange API Standard The Transparency Exchange API is being worked on within the CycloneDX community -with the goal to standardise the API in ECMA. A working group within ECMA TC54 has been -formed - TC54 TG1. The working group has a slack channel in the CycloneDX slack space. +with the goal to standardise the API in ECMA. A working group within ECMA TC54 +has been formed - TC54 TG1. The working group has a slack channel in the +CycloneDX slack space. ![](images/tealogo.png) @@ -19,64 +20,98 @@ formed - TC54 TG1. The working group has a slack channel in the CycloneDX slack This specification defines a standard, format agnostic, API for the exchange of product related artefacts, like BOMs, between systems. The work includes: -- [Discovery of servers](/discovery/readme.md): Describes discovery using the Transparency Exchange Identifier (TEI) +- [Discovery of servers](/discovery/readme.md): Describes discovery using the + Transparency Exchange Identifier (TEI) - Retrieval of artefacts - Publication of artefacts - Authentication and authorization - Querying System and tooling implementors are encouraged to adopt this API standard for -sending/receiving transparency artefacts between systems. -This will enable more widespread -"out of the box" integration support in the BOM ecosystem. +sending/receiving transparency artefacts between systems. This will enable more +widespread "out of the box" integration support in the BOM ecosystem. ## Use cases and requirements -The working group has produced a list of use cases and requirements for the protocol. +The working group has produced a list of use cases and requirements for the +protocol. - [TEA requirements](doc/tea-requirements.md) - [TEA use cases](doc/tea-usecases.md) ## Data model -- [TEA Product index](tea-index/tea-index.md): This is the starting point. A "product" is something for sale. The [Transparency Exchange Identifier, TEI](/discovery/readme.md) points to a single product. -- [TEA Leaf index](tea-leaf/tea-leaf.md): A leaf is a version entry. The leaf index has one entry per version of the product. -- [TEA Collection](tea-collection/tea-collection.md): The collection is a list of artefacts for a specific version. The collection can be dynamic or static, depending on the implemenation. +- [TEA Product index](tea-index/tea-index.md): This is the starting point. A + "product" is something for sale. The + [Transparency Exchange Identifier, TEI](/discovery/readme.md) points to a + single product. +- [TEA Leaf index](tea-leaf/tea-leaf.md): A leaf is a version entry. The leaf + index has one entry per version of the product. +- [TEA Collection](tea-collection/tea-collection.md): The collection is a list + of artefacts for a specific version. The collection can be dynamic or static, + depending on the implemenation. ## Artefacts available of the API -The Transparency Exchange API (TEA) supports publication and retrieval of a set of transparency exchange artefacts. The API itself should not be restricting the types of the artefacts. A few examples: +The Transparency Exchange API (TEA) supports publication and retrieval of a set +of transparency exchange artefacts. The API itself should not be restricting the +types of the artefacts. A few examples: ### xBOM -Bill of materials for any type of component and service are supported. This includes, but is not limited to, SBOM, HBOM, AI/ML-BOM, SaaSBOM, and CBOM. The API provides a BOM format agnostic way of publishing, searching, and retrieval of xBOM artifacts. +Bill of materials for any type of component and service are supported. This +includes, but is not limited to, SBOM, HBOM, AI/ML-BOM, SaaSBOM, and CBOM. The +API provides a BOM format agnostic way of publishing, searching, and retrieval +of xBOM artifacts. ### CDXA -Standards and requirements along with attestations to those standards and requirements are captured and supported by CycloneDX Attestations (CDXA). Much like xBOM, these are supply chain artifacts that are captured allowing for consistent publishing, searching, and retrieval. +Standards and requirements along with attestations to those standards and +requirements are captured and supported by CycloneDX Attestations (CDXA). Much +like xBOM, these are supply chain artifacts that are captured allowing for +consistent publishing, searching, and retrieval. ### VDR/VEX -Vulnerability Disclosure Reports (VDR) and Vulnerability Exploitability eXchange (VEX) are supported artifact types. Like the xBOM element, the VDR/VEX support is format agnostic. However, CSAF has its own distribution requirements that may not be compatible with APIs. Therefore, the initial focus will be on CycloneDX (VDR and VEX) and OpenVEX. +Vulnerability Disclosure Reports (VDR) and Vulnerability Exploitability eXchange +(VEX) are supported artifact types. Like the xBOM element, the VDR/VEX support +is format agnostic. However, CSAF has its own distribution requirements that may +not be compatible with APIs. Therefore, the initial focus will be on CycloneDX +(VDR and VEX) and OpenVEX. ### CLE -Product lifecycle events that are captured and communicated through the Common Lifecycle Enumeration will be supported. This includes product rebranding, repackaging, mergers and acquisitions, and product milestone events such as end-of-life and end-of-support. +Product lifecycle events that are captured and communicated through the Common +Lifecycle Enumeration will be supported. This includes product rebranding, +repackaging, mergers and acquisitions, and product milestone events such as +end-of-life and end-of-support. ### Insights -Much of the focus on Software Transparency from the U.S. Government and others center around the concept of “full transparency”. Consumers often need to ingest, process, and analyze SBOMs or VEXs just to be able to answer simple questions such as: +Much of the focus on Software Transparency from the U.S. Government and others +center around the concept of "full transparency". Consumers often need to +ingest, process, and analyze SBOMs or VEXs just to be able to answer simple +questions such as: - Do any of my licensed products from Vendor A use Apache Struts? -- Are any of my licensed products from Vendor A vulnerable to log4shell and is there any action I need to take? +- Are any of my licensed products from Vendor A vulnerable to log4shell and is + there any action I need to take? -Insights allows for “limited transparency” that can be asked and answered using an expression language that can be tightly scoped or outcome-driven. Insights also removes the complexities of BOM format conversion away from the consumers. An object model derived from CycloneDX will be an integral part of this API, since the objects within CycloneDX are self-contained (thus API friendly) and the specification supports all the necessary xBOM types along with CDXA. +Insights allows for "limited transparency" that can be asked and answered using +an expression language that can be tightly scoped or outcome-driven. Insights +also removes the complexities of BOM format conversion away from the consumers. +An object model derived from CycloneDX will be an integral part of this API, +since the objects within CycloneDX are self-contained (thus API friendly) and +the specification supports all the necessary xBOM types along with CDXA. ## Presentations and videos -- You can find presentations in the repository in the [Presentations](/presentations) directory -- Our biweekly meetings are available on [YouTube playlist: Project Koala](https://www.youtube.com/playlist?list=PLqjEqUxHjy1XtSzGYL7Dj_WJbiLu_ty58) -- KoalaCon 2024 - an introduction to the project - can be [viewed on YouTube](https://youtu.be/NStzYW4WnEE?si=ihLirpGVjHc7K4bL) +- You can find presentations in the repository in the + [Presentations](/presentations) directory +- Our biweekly meetings are available on + [YouTube playlist: Project Koala](https://www.youtube.com/playlist?list=PLqjEqUxHjy1XtSzGYL7Dj_WJbiLu_ty58) +- KoalaCon 2024 - an introduction to the project - can be + [viewed on YouTube](https://youtu.be/NStzYW4WnEE?si=ihLirpGVjHc7K4bL) ## Terminology @@ -92,5 +127,33 @@ Insights allows for “limited transparency” that can be asked and answered us ## Previous work -- [The CycloneDX BOM Exchange API](/api/bomexchangeapi.md) - Implemented in the [CycloneDX BOM Repo Server](https://github.com/CycloneDX/cyclonedx-bom-repo-server) +- [The CycloneDX BOM Exchange API](/api/bomexchangeapi.md) Implemented in the + [CycloneDX BOM Repo Server](https://github.com/CycloneDX/cyclonedx-bom-repo-server) + +## Contributing + +### Markdown Formatting + +This repository uses a Rust-based Markdown formatter (dprint) to ensure +consistent documentation formatting. When submitting pull requests that include +Markdown files, the formatter will automatically check for formatting issues. + +To run the formatter locally: + +1. Install dprint: + ```bash + cargo install dprint + ``` + +2. Check for formatting issues: + ```bash + dprint check "**/*.md" + ``` + +3. Automatically format all Markdown files: + ```bash + dprint fmt "**/*.md" + ``` + +The formatter enforces a maximum line length of 80 characters and consistent +formatting across all Markdown files. diff --git a/api-flow/consumer.md b/api-flow/consumer.md index 24a6380..5ec324f 100644 --- a/api-flow/consumer.md +++ b/api-flow/consumer.md @@ -1,24 +1,33 @@ # Transparency Exchange API: Consumer access - -The consumer access starts with a TEI, A transparency Exchange Identifier. This is used to find the API server as -described in the [discovery document](/discovery/readme.md). +The consumer access starts with a TEI, A transparency Exchange Identifier. This +is used to find the API server as described in the +[discovery document](/discovery/readme.md). ## API usage The standard TEI points to a product. -- __List of TEA leafs__: Leafs are components of something sold. Each leaf has it's own versioning and it's own set of artefacts. Note that a single artefact can belong to multiple versions of a leaf and multiple leafs. -- __List of TEA collections__: For each leaf, there is a list of TEA collections as indicated by release date and a version string. The TEA API has no requirements of type of version string (semantic or any other scheme) - it's just an identifier set by the manufacturer. It's sorted by release date as a default. -- __List of TEA artefacts__: The collection is unique for a version and contains a list of artefacts. This can be SBOM files, VEX, SCITT, IN-TOTO or other documents. -- __List of artefact formats__: An artefact can be published in multiple formats. - -The user has to know product TEI and version of each component (TEA LEAF) to find the list of artefacts for the used version. +- **List of TEA leafs**: Leafs are components of something sold. Each leaf has + it's own versioning and it's own set of artefacts. Note that a single artefact + can belong to multiple versions of a leaf and multiple leafs. +- **List of TEA collections**: For each leaf, there is a list of TEA collections + as indicated by release date and a version string. The TEA API has no + requirements of type of version string (semantic or any other scheme) - it's + just an identifier set by the manufacturer. It's sorted by release date as a + default. +- **List of TEA artefacts**: The collection is unique for a version and contains + a list of artefacts. This can be SBOM files, VEX, SCITT, IN-TOTO or other + documents. +- **List of artefact formats**: An artefact can be published in multiple + formats. + +The user has to know product TEI and version of each component (TEA LEAF) to +find the list of artefacts for the used version. ## API flow ```mermaid - --- title: TEA consumer --- @@ -47,7 +56,4 @@ sequenceDiagram tea_collection ->> user: List of artefacts and formats available for each artefact user ->> tea_artifact: Download artefact - - - ``` diff --git a/api-flow/publisher.md b/api-flow/publisher.md index ea1395f..4959786 100644 --- a/api-flow/publisher.md +++ b/api-flow/publisher.md @@ -3,7 +3,6 @@ ## Bootstrapping ```mermaid - sequenceDiagram autonumber actor Vendor @@ -19,7 +18,6 @@ sequenceDiagram Vendor ->> tea_collection: POST to /v1/collection with the TEA Leaf ID as the and the artifact as payload tea_collection ->> Vendor: Collection is created with the collection ID returned - ``` ## Release life cycle @@ -40,7 +38,6 @@ sequenceDiagram Note over Vendor,TEA Leaf: Add an artifact (e.g. SBOM) Vendor ->> tea_collection: POST to /v1/collection with the TEA Leaf ID as the and the artifact as payload tea_collection ->> Vendor: Collection is created with the collection ID returned - ``` ## Adding a new artifact @@ -58,4 +55,4 @@ sequenceDiagram Vendor ->> tea_collection: POST to /v1/collection with the TEA Leaf ID as the and the artifact as payload tea_collection ->> Vendor: Collection is created with the collection ID returned -``` \ No newline at end of file +``` diff --git a/api/bomexchangeapi.md b/api/bomexchangeapi.md index 36e8a8c..1ece677 100644 --- a/api/bomexchangeapi.md +++ b/api/bomexchangeapi.md @@ -1,7 +1,7 @@ # CycloneDX BOM exchange API -__Note:__ this is an older version of the API not being worked on any more. This work -will be replaced by the Transparency Exchange API. +**Note:** this is an older version of the API not being worked on any more. This +work will be replaced by the Transparency Exchange API. ## Conventions @@ -14,7 +14,8 @@ interpreted as described in [RFC2119](http://www.ietf.org/rfc/rfc2119.txt). ABNF syntax used as per [RFC5234: Augmented BNF for Syntax Specifications: ABNF](https://datatracker.ietf.org/doc/html/rfc5234). -ABNF rules are used from [RFC3986: Uniform Resource Identifier (URI): Generic Syntax - Appendix A. Collected ABNF for URI](https://datatracker.ietf.org/doc/html/rfc3986/#appendix-A). +ABNF rules are used from +[RFC3986: Uniform Resource Identifier (URI): Generic Syntax - Appendix A. Collected ABNF for URI](https://datatracker.ietf.org/doc/html/rfc3986/#appendix-A). These additional rules are defined: @@ -25,13 +26,14 @@ system-url = supported-scheme ":" hier-part supported-scheme = "http" / "https" ``` -See also: [RFC7231: Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content](https://datatracker.ietf.org/doc/html/rfc7231) +See also: +[RFC7231: Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content](https://datatracker.ietf.org/doc/html/rfc7231) ## Specification Compliance An API server/client can be referred to as compliant if it correctly implements -any of the methods described within this specification. It is not a -requirement to implement all the methods described. +any of the methods described within this specification. It is not a requirement +to implement all the methods described. ## BOM Retrieval @@ -49,21 +51,22 @@ bom-identifier = *( pchar / "/" / "?" ) The HTTP request method MUST be `GET`. -For CycloneDX BOMs the `bom-identifier` MUST be either a CDX URN (https://www.iana.org/assignments/urn-formal/cdx) -or a BOM serial number UUID URN (https://cyclonedx.org/docs/1.4/json/#serialNumber). +For CycloneDX BOMs the `bom-identifier` MUST be either a CDX URN +(https://www.iana.org/assignments/urn-formal/cdx) or a BOM serial number UUID +URN (https://cyclonedx.org/docs/1.4/json/#serialNumber). For SPDX documents the `bom-identifier` MUST be the SPDX Document Namespace (https://spdx.github.io/spdx-spec/document-creation-information/#65-spdx-document-namespace-field). ### Server Requirements -Servers MAY require authorization. If authorization is required it MUST -use the HTTP `Authorization` header. If a server requires authorization, and -no `Authorization` request header is supplied by the client, the server -MUST respond with a 401 Unauthorized response. +Servers MAY require authorization. If authorization is required it MUST use the +HTTP `Authorization` header. If a server requires authorization, and no +`Authorization` request header is supplied by the client, the server MUST +respond with a 401 Unauthorized response. -Servers MUST honour the requested content types in the `Accept` header. If -the server does not support any of the requested content types a HTTP 406 response +Servers MUST honour the requested content types in the `Accept` header. If the +server does not support any of the requested content types a HTTP 406 response MUST be returned. The 406 response body MUST contain a list of server supported content types in the below format with `text/plain` content type. @@ -71,16 +74,18 @@ content types in the below format with `text/plain` content type. media-type *(", " media-type) ``` -e.g. `application/vnd.cyclonedx+xml; version=1.4, application/vnd.cyclonedx+xml; version=1.3` +e.g. +`application/vnd.cyclonedx+xml; version=1.4, application/vnd.cyclonedx+xml; version=1.3` -API servers MUST provide the correct `Content-Type` HTTP response header. For example: +API servers MUST provide the correct `Content-Type` HTTP response header. For +example: ```http Content-Type: application/vnd.cyclonedx+xml; version=1.4 ``` -If a BOM serial number UUID URN is used as the `bom-identifier`, the server -MUST respond with the latest available version of the BOM. +If a BOM serial number UUID URN is used as the `bom-identifier`, the server MUST +respond with the latest available version of the BOM. ### Client Requirements @@ -105,30 +110,33 @@ The HTTP request method MUST be `POST`. ### Server Requirements -Servers MAY require authorization. If authorization is required it MUST -use the HTTP `Authorization` header. If a server requires authorization, and -no `Authorization` request header is supplied by the client, the server -MUST respond with a 401 Unauthorized response. +Servers MAY require authorization. If authorization is required it MUST use the +HTTP `Authorization` header. If a server requires authorization, and no +`Authorization` request header is supplied by the client, the server MUST +respond with a 401 Unauthorized response. Servers MUST honour the specified content type in the `Content-Type` header. If the server does not support the supplied content type a HTTP 415 Unsupported Media Type response MUST be returned. The 415 response body MUST contain a list -of server supported content types in the below format with `text/plain` content type. +of server supported content types in the below format with `text/plain` content +type. ```abnf media-type *(", " media-type) ``` -e.g. `application/vnd.cyclonedx+xml; version=1.4, application/vnd.cyclonedx+xml; version=1.3` +e.g. +`application/vnd.cyclonedx+xml; version=1.4, application/vnd.cyclonedx+xml; version=1.3` -If the submitted BOM has been successfully submitted the API server MUST -respond with an appropriate 2xx HTTP status code. +If the submitted BOM has been successfully submitted the API server MUST respond +with an appropriate 2xx HTTP status code. ### Client Requirements Clients MUST support an optional `Authorization` header being specified. -Clients MUST provide the correct `Content-Type` HTTP request header. For example: +Clients MUST provide the correct `Content-Type` HTTP request header. For +example: ```http Content-Type: application/vnd.cyclonedx+xml; version=1.4 diff --git a/discovery/readme.md b/discovery/readme.md index 550b336..1695f2e 100644 --- a/discovery/readme.md +++ b/discovery/readme.md @@ -14,18 +14,18 @@ ## From product identifier to API endpoint -TEA Discovery is the connection between a product identifier and the API endpoint. -A "product" is something that the customer aquires or downloads. It can be a bundle -of many digital devices or software applications. A "product" normally also has an -entry in a large corporation's asset inventory system. +TEA Discovery is the connection between a product identifier and the API +endpoint. A "product" is something that the customer aquires or downloads. It +can be a bundle of many digital devices or software applications. A "product" +normally also has an entry in a large corporation's asset inventory system. -A product identifier is embedded in a URN where the identifier is one of many existing -identifiers or a random string - like an EAN or UPC bar code, UUID, product -number or PURL. +A product identifier is embedded in a URN where the identifier is one of many +existing identifiers or a random string - like an EAN or UPC bar code, UUID, +product number or PURL. -The goal is for a user to add this URN to the transparency platform (sometimes with an -associated authentication token) and have the platform access the required artifacts -in a highly automated fashion. +The goal is for a user to add this URN to the transparency platform (sometimes +with an associated authentication token) and have the platform access the +required artifacts in a highly automated fashion. ## Advertising the TEI @@ -37,46 +37,54 @@ The TEI for a product can be communicated to the user in many ways. ## TEA Discovery - defining an extensible identifier -TEA discovery is the process where a user with a product identifier can discover and download -artifacts automatically, with or without authentication. A globally unique identifier is -required for a given product. This identifier is called the Transparency Exchange Identifier (TEI). +TEA discovery is the process where a user with a product identifier can discover +and download artifacts automatically, with or without authentication. A globally +unique identifier is required for a given product. This identifier is called the +Transparency Exchange Identifier (TEI). -The TEI identifier is based on DNS, which assures a uniqueness per vendor (or open source project) -and gives the vendor a name space to define product identifiers based on existing or new identifiers -like EAN/UPC bar code, PURLs or other existing schemes. A given product may have multiple identifiers -as long as they all resolve into the same destination. +The TEI identifier is based on DNS, which assures a uniqueness per vendor (or +open source project) and gives the vendor a name space to define product +identifiers based on existing or new identifiers like EAN/UPC bar code, PURLs or +other existing schemes. A given product may have multiple identifiers as long as +they all resolve into the same destination. ## The TEI URN: An extensible identifier -The TEI, Transparency Exchange Identifier, is a URN schema that is extensible based on existing -identifiers like EAN codes, PURL and other identifiers. It is based on a DNS name, which leads -to global uniqueness without new registries. +The TEI, Transparency Exchange Identifier, is a URN schema that is extensible +based on existing identifiers like EAN codes, PURL and other identifiers. It is +based on a DNS name, which leads to global uniqueness without new registries. -The TEI can be shown in the software itself, in shipping documentation, in web pages and app stores. -TEI is unique for a product, not a version of a software. The TEI consist of three core parts +The TEI can be shown in the software itself, in shipping documentation, in web +pages and app stores. TEI is unique for a product, not a version of a software. +The TEI consist of three core parts -A TEI belongs to a single product. A product can have multiple TEIs - like one with a EAN/UPC -barcode and one with the vendor's product number. +A TEI belongs to a single product. A product can have multiple TEIs - like one +with a EAN/UPC barcode and one with the vendor's product number. ### TEI syntax ```text urn:tei::: -```` +``` - The **`type`** which defines the syntax of the unique identifier part -- The **`domain-name`** part resolves into a web server, which may not be the API host. - - The uniqueness of the name is the domain name part that has to be registred at creation of the TEI. +- The **`domain-name`** part resolves into a web server, which may not be the + API host. + - The uniqueness of the name is the domain name part that has to be registred + at creation of the TEI. - The **`unique-identifier`** has to be unique within the `domain-name`. Recommendation is to use a UUID but it can be an existing article code too -**Note**: this requires a registration of the TEI URN schema with IANA - [see here](https://github.com/CycloneDX/transparency-exchange-api/issues/18) +**Note**: this requires a registration of the TEI URN schema with IANA - +[see here](https://github.com/CycloneDX/transparency-exchange-api/issues/18) ### TEI types -The below show examples of TEI where the types are specific known formats or types. +The below show examples of TEI where the types are specific known formats or +types. -Reminder: the `unique-identifer` component of the TEI needs only be unique within the `domain-name`. +Reminder: the `unique-identifer` component of the TEI needs only be unique +within the `domain-name`. #### PURL - Package URL @@ -86,7 +94,7 @@ Syntax: ```text urn:tei:purl:: -```` +``` Example: @@ -102,7 +110,7 @@ Syntax: ```text urn:tei:swid:: -```` +``` Note that there is a TEI SWID type as well as a PURL SWID type. @@ -116,9 +124,10 @@ Where the `unique-identifier` is a Hash. Supports the following hash types: ```text urn:tei:hash::: -```` +``` Example: + ```text urn:tei:hash:cyclonedx.org:SHA256:fd44efd601f651c8865acf0dfeacb0df19a2b50ec69ead0262096fd2f67197b9 ``` @@ -133,14 +142,14 @@ Syntax: ```text urn:tei:uuid:: -```` +``` Example: + ```text urn:tei:uuid:cyclonedx.org:d4d9f54a-abcf-11ee-ac79-1a52914d44b1 ``` - #### Other types to be defined - EAN @@ -149,37 +158,36 @@ urn:tei:uuid:cyclonedx.org:d4d9f54a-abcf-11ee-ac79-1a52914d44b1 ### TEI resolution using DNS -The `domain-name` part of the TEI is used in a DNS query to find one or multiple locations for -product transparency exchange information. +The `domain-name` part of the TEI is used in a DNS query to find one or multiple +locations for product transparency exchange information. -At the URL a well-known name space is used to find out where the API endpoint is hosted. -This is solved by using the ".well-known" name space as defined by the IETF. +At the URL a well-known name space is used to find out where the API endpoint is +hosted. This is solved by using the ".well-known" name space as defined by the +IETF. - `urn:tei:uuid:products.example.com:d4d9f54a-abcf-11ee-ac79-1a52914d44b1` - Syntax: `urn:tei:uuid::` The name in the DNS name part points to a set of DNS records. -A TEI with name `tea.example.com` queries for `tea.example.com` `A` and `AAAA` records. -These point to the hosts available for the Transparency Exchange API. +A TEI with name `tea.example.com` queries for `tea.example.com` `A` and `AAAA` +records. These point to the hosts available for the Transparency Exchange API. The TEA client connects to the host using HTTPS and validates the certificate. The URI is composed of the name with the `/.well-known/tea` prefix added. -This results in the base URI (without the product identifier) -`https://tea.example.com/.well-known/tea/` - +This results in the base URI (without the product identifier) +`https://tea.example.com/.well-known/tea/` ## Connecting to the API -When connecting to the `.well-known/tea` URI with the unique identifier -a HTTP redirect is **required**. +When connecting to the `.well-known/tea` URI with the unique identifier a HTTP +redirect is **required**. -The server MUST redirect HTTP requests for that resource -to the actual "context path" using one of the available mechanisms -provided by HTTP (e.g., using a 301, 303, or 307 response). Clients -MUST handle HTTP redirects on the `.well-known` URI. Servers MUST -NOT locate the actual TEA service endpoint at the +The server MUST redirect HTTP requests for that resource to the actual "context +path" using one of the available mechanisms provided by HTTP (e.g., using a 301, +303, or 307 response). Clients MUST handle HTTP redirects on the `.well-known` +URI. Servers MUST NOT locate the actual TEA service endpoint at the `.well-known` URI as per Section 1.1 of [RFC5785]. ### Overview: Finding the Index using DNS result @@ -188,21 +196,25 @@ Append the product part of the TEI to the URI found - TEI: `urn:tei:uuid:products.example.com:d4d9f54a-abcf-11ee-ac79-1a52914d44b1` - DNS record: `products.example.com` -- URL: `https://products.example.com/.well-known/tea/d4d9f54a-abcf-11ee-ac79-1a52914d44b1/` -- HTTP 302 redirect to "https://teapot02.consumer.example.com/tea/v2/product-index/d4d9f54a-abcf-11ee-ac79-1a52914d44b1' +- URL: + `https://products.example.com/.well-known/tea/d4d9f54a-abcf-11ee-ac79-1a52914d44b1/` +- HTTP 302 redirect to + "https://teapot02.consumer.example.com/tea/v2/product-index/d4d9f54a-abcf-11ee-ac79-1a52914d44b1' Always prefix with the https:// scheme. http (unencrypted) is not valid. - TEI: `urn:tei:uuid:products.example.com:d4d9f54a-abcf-11ee-ac79-1a52914d44b1` -- URL: `https://products.example.com/.well-known/tea/d4d9f54a-abcf-11ee-ac79-1a52914d44b1/` +- URL: + `https://products.example.com/.well-known/tea/d4d9f54a-abcf-11ee-ac79-1a52914d44b1/` **NOTE:** The `/.well-known/tea`names space needs to be registred. ## The TEA Version Index -The resulting URL leads to the TEA version index, which is documented in another document. -One redirect (302) is allowed in order to provide for aliasing, where a single product -has many identifiers. The redirect should not lead to a separate web server. +The resulting URL leads to the TEA version index, which is documented in another +document. One redirect (302) is allowed in order to provide for aliasing, where +a single product has many identifiers. The redirect should not lead to a +separate web server. ## References diff --git a/doc/tea-requirements.md b/doc/tea-requirements.md index 2bf8e91..7fa79a5 100644 --- a/doc/tea-requirements.md +++ b/doc/tea-requirements.md @@ -1,32 +1,35 @@ # TEA Requirements ## Repository discovery -Based on an identifier a repository URL needs to be found. The identifier can be: + +Based on an identifier a repository URL needs to be found. The identifier can +be: - PURL - Product name or Product SKU and vendor name - EAN bar code -- Product SKU +- Product SKU - Vendor UUID - Hash of object At the base URL well known URLs (ref) needs to point to - A lifecycle status document (using OWASP Common Lifecycle Enumeration, CLE) -- A version list. For each version, a URL will point to where a **collection** can be found +- A version list. For each version, a URL will point to where a **collection** + can be found - Vendor Discovery, returns a list of Vendors represented in the repository - Vendor Name - Vendor ID -As an alternative, discovery using a company's ordinary web site should be supported. -This can be handled using the file security.txt (IETF RFC 9116) +As an alternative, discovery using a company's ordinary web site should be +supported. This can be handled using the file security.txt (IETF RFC 9116) ## Artifact Discovery based on TEA collections -The API MUST provide a way to discover the artifacts that are available for retrieval or further query. -Discovery SHOULD group artifacts together that represent a **collection** -that are directly applicable to a given product with a given version. -Collections are OPTIONAL. +The API MUST provide a way to discover the artifacts that are available for +retrieval or further query. Discovery SHOULD group artifacts together that +represent a **collection** that are directly applicable to a given product with +a given version. Collections are OPTIONAL. - SBOM - Software Bill of Material - CBOM - Cryptography Bill of Material @@ -39,59 +42,61 @@ Authn/Authz MUST be supported ## Collection Management -The API SHOULD provide a method to manage collections, such as adding new collections, -modifying collections, or deleting existing collections. +The API SHOULD provide a method to manage collections, such as adding new +collections, modifying collections, or deleting existing collections. - Authn/Authz MUST be supported ## Artifact Retrieval -The API MUST provide a method in which to retrieve an artifact based on the identity of the artifact. -For example, using CycloneDX BOM-Link to retrieve either the -latest version or specific version of an artifact. +The API MUST provide a method in which to retrieve an artifact based on the +identity of the artifact. For example, using CycloneDX BOM-Link to retrieve +either the latest version or specific version of an artifact. ```text urn:cdx:serialNumber urn:cdx:serialNumber/version ``` -The API needs to provide support for update checks, i.e. to check if a document is -updated without downloading. (possibly etag or HEAD method or similar) +The API needs to provide support for update checks, i.e. to check if a document +is updated without downloading. (possibly etag or HEAD method or similar) Authn/Authz MUST be supported ## Artifact Publishing -The API MUST provide a way to publish an artifact, either standalone or to a collection. -The detection of duplicate artifacts with the same identity MUST be handled and prevented. -Authn/Authz MUST be supported +The API MUST provide a way to publish an artifact, either standalone or to a +collection. The detection of duplicate artifacts with the same identity MUST be +handled and prevented. Authn/Authz MUST be supported ## Artifact Versioning The system and API must support artifact versioning for formats that support versioning such as CycloneDX. For example: -- The ability to retrieve the latest SBOM vs a previous (uncorrected) version of the same SBOM. - Corrections to SBOMs is a supported use case in the NTIA framing document. -- The ability to retrieve the latest VEX along with previous VEX for the same product so - that time-series decisions are transparently available. +- The ability to retrieve the latest SBOM vs a previous (uncorrected) version of + the same SBOM. Corrections to SBOMs is a supported use case in the NTIA + framing document. +- The ability to retrieve the latest VEX along with previous VEX for the same + product so that time-series decisions are transparently available. Authn/Authz MUST be supported ## insights: Search Artifact Inventory -The API MUST provide a way to search the inventory of a specific BOM or all available BOMs -for a given component or service. The API SHOULD support multiple identity formats including -PURL, CPE, SWID, GAV, GTIN, and GMN. +The API MUST provide a way to search the inventory of a specific BOM or all +available BOMs for a given component or service. The API SHOULD support multiple +identity formats including PURL, CPE, SWID, GAV, GTIN, and GMN. For example: -- Return the identity of all BOMs that have a vulnerable version of Apache Log4J: - `pkg:maven/org.apache.logging.log4j/log4j-core@2.10.0` +- Return the identity of all BOMs that have a vulnerable version of Apache + Log4J: `pkg:maven/org.apache.logging.log4j/log4j-core@2.10.0` -The API MUST provide a way to search for the metadata component across all available BOMs. -The API SHOULD support multiple identity formats including PURL, CPE, SWID, GAV, GTIN, and GMN. -For example: +The API MUST provide a way to search for the metadata component across all +available BOMs. The API SHOULD support multiple identity formats including PURL, +CPE, SWID, GAV, GTIN, and GMN. For example: -- Return the identity of all artifacts that describe `cpe:/a:acme:commerce_suite:1.0`. +- Return the identity of all artifacts that describe + `cpe:/a:acme:commerce_suite:1.0`. Authn/Authz MUST be supported diff --git a/doc/tea-usecases.md b/doc/tea-usecases.md index 1d97748..8f16974 100644 --- a/doc/tea-usecases.md +++ b/doc/tea-usecases.md @@ -1,92 +1,112 @@ # TEA Use Cases -An overview of use cases to consider for the Transparency Exchange API. The use cases -are marked with a short code for reference. All use cases needs a story like "Alice has bought -a..." +An overview of use cases to consider for the Transparency Exchange API. The use +cases are marked with a short code for reference. All use cases needs a story +like "Alice has bought a..." The use cases are divided in two categories: -* Use cases for __customers__ (end-users, manufacturers) to find a repository with - Transparency Artefacts for a single unit purchased -* Use cases where there are different __products__ - * This applies after discovery where we need to handle various things a customer may - buy as a single unit +- Use cases for **customers** (end-users, manufacturers) to find a repository + with Transparency Artefacts for a single unit purchased +- Use cases where there are different **products** + - This applies after discovery where we need to handle various things a + customer may buy as a single unit ## Customer focused use cases ### C1: Consumer: Automated discovery based on SBOM identifier -As a consumer that has an SBOM for a product, I want to be able to retrieve VEX and VDR files automatically both for current and old versions of the software. In the SBOM the product is identified by a PURL or other means (CPE, …) - +As a consumer that has an SBOM for a product, I want to be able to retrieve VEX +and VDR files automatically both for current and old versions of the software. +In the SBOM the product is identified by a PURL or other means (CPE, …) ### C2: Consumer: Automation based on product name/identifier -As a consumer, I want to download artifacts for a product based on known data. -A combination of manufacturer, product name, vendor product ID, EAN bar code or other unique identifier. -After discovering the base repository URL I want to be able to find a specific -product variant and version. +As a consumer, I want to download artifacts for a product based on known data. A +combination of manufacturer, product name, vendor product ID, EAN bar code or +other unique identifier. After discovering the base repository URL I want to be +able to find a specific product variant and version. -If the consumer is a business, then the procurement process may include delivery of an SBOM with proper identifiers and possibly URLs or identifiers in another document, which may bootstrap the discovery process in a more exact way than in the case of buying a product in a retail market. -Alice bought a gadget at the gadget store that contains a full Linux system. Where and how will she find the SBOM and VEX for the gadget? +If the consumer is a business, then the procurement process may include delivery +of an SBOM with proper identifiers and possibly URLs or identifiers in another +document, which may bootstrap the discovery process in a more exact way than in +the case of buying a product in a retail market. Alice bought a gadget at the +gadget store that contains a full Linux system. Where and how will she find the +SBOM and VEX for the gadget? -### C3: Consumer: Artifact retrieval +### C3: Consumer: Artifact retrieval -As a consumer, I want to retrieve one or more supply chain artifacts for the products that I have access to, possibly through licensing or other means. As a consumer, I should be able to retrieve all source artifacts such as xBOMs, VDR/VEX, CDXA, and CLE. +As a consumer, I want to retrieve one or more supply chain artifacts for the +products that I have access to, possibly through licensing or other means. As a +consumer, I should be able to retrieve all source artifacts such as xBOMs, +VDR/VEX, CDXA, and CLE. ### C4: Consumer: Summarized CLE -As a consumer, I want the ability to get the current lifecycle values for a given product. -A CLE captures all lifecycle events over time, however, there is a need to retrieve only the current values for things like product name, vendor name, and milestone events. +As a consumer, I want the ability to get the current lifecycle values for a +given product. A CLE captures all lifecycle events over time, however, there is +a need to retrieve only the current values for things like product name, vendor +name, and milestone events. ### C5: Consumer: Insights -As a consumer, I want the ability to simply ask the API questions rather than having to download, -process, and analyze raw supply chain artifacts on my own systems. Common questions should be -provided by the API by default along with the ability to query for more complex answers using -the Common Expression Language (CEL). +As a consumer, I want the ability to simply ask the API questions rather than +having to download, process, and analyze raw supply chain artifacts on my own +systems. Common questions should be provided by the API by default along with +the ability to query for more complex answers using the Common Expression +Language (CEL). -_NOTE_: Project Hyades (Dependency-Track v5) already implements CEL with the CycloneDX object model and has proven that this approach works for complex queries. +_NOTE_: Project Hyades (Dependency-Track v5) already implements CEL with the +CycloneDX object model and has proven that this approach works for complex +queries. ### D1: Developer/PM - Components for inclusion in products by other projects/developers -A developer needs a component - software, library (open source and/or proprietary) to include -in a product - publicly available (may be commercial) or in an internal system. -Developer can be individual, company or public sector. -They need insight into the library or component and be able to automatically keep upstream -artefacts up to date. +A developer needs a component - software, library (open source and/or +proprietary) to include in a product - publicly available (may be commercial) or +in an internal system. Developer can be individual, company or public sector. +They need insight into the library or component and be able to automatically +keep upstream artefacts up to date. ### B1: Business consumer -Acme LLC buys 3 000 gadgetrons from Emca LTD to be distributed over a retail chain. Acme runs an in-house vulnerability management system (Dependency Track) to manage SBOMs and download VEX files to check for vulnerabilities. Acme has products from exactly 14.385 vendors in the system. -How will their systems get continuous access to current and old documents - attestations, SBOM, VEX and other files? +Acme LLC buys 3 000 gadgetrons from Emca LTD to be distributed over a retail +chain. Acme runs an in-house vulnerability management system (Dependency Track) +to manage SBOMs and download VEX files to check for vulnerabilities. Acme has +products from exactly 14.385 vendors in the system. How will their systems get +continuous access to current and old documents - attestations, SBOM, VEX and +other files? ### E1: Third party: Regulators -Alice & Bob Enterprises AB has gotten a EUCC certification to get their Whola Firewall certified -for CRA-compatible CE labeling. In order to maintain the certification the certifying body needs -access to SBOM and VEX updates from A&BE in an automated way. +Alice & Bob Enterprises AB has gotten a EUCC certification to get their Whola +Firewall certified for CRA-compatible CE labeling. In order to maintain the +certification the certifying body needs access to SBOM and VEX updates from A&BE +in an automated way. ### E2: External potential customer - insights before purchase -Palme Auditors INC wants to buy the ACME SWISH product from a vendor. They want to examine vulnerability handling and get some insights into the products before making a decision. +Palme Auditors INC wants to buy the ACME SWISH product from a vendor. They want +to examine vulnerability handling and get some insights into the products before +making a decision. ### E3: Hacker or competition -There are non-customers and not-to-be-customers that wants to get insight into how a product is -composed by getting the transparency docs. +There are non-customers and not-to-be-customers that wants to get insight into +how a product is composed by getting the transparency docs. ### E4: Open Source user -Palme Inc considers using the asterisk.org open source telephony PBX. -They need to make an assessment before starting tests and possible production use. -The can either use the Debian package, the Alpine Linux Package or build a binary themselves from source code. -How can they find the transparency exchange data sets? - +Palme Inc considers using the asterisk.org open source telephony PBX. They need +to make an assessment before starting tests and possible production use. The can +either use the Debian package, the Alpine Linux Package or build a binary +themselves from source code. How can they find the transparency exchange data +sets? ### O1: Open Source project -The hatturl open source project publish a library and a server side software on Github. This is -later packaged as packages in many Linux distributions. +The hatturl open source project publish a library and a server side software on +Github. This is later packaged as packages in many Linux distributions. How does the project publish artefacts? What are the requirements? @@ -98,8 +118,8 @@ Customer buys a standalone application that is delivered as a binary ### P2: A OCI container -Customer gets a container with many third party components and a binary -software developed by the manufacturer +Customer gets a container with many third party components and a binary software +developed by the manufacturer ### P3: Embedded system diff --git a/spec/README.md b/spec/README.md index 4eff65a..eac747c 100644 --- a/spec/README.md +++ b/spec/README.md @@ -1,12 +1,14 @@ # TEA OpenAPI Spec -The OpenAPI 3.1 specification for the Transparency Exchange API is available in [openapi.json](./openapi.json). +The OpenAPI 3.1 specification for the Transparency Exchange API is available in +[openapi.json](./openapi.json). - [Generating API Clients from OpenAPI Spec](#generating-api-clients-from-openapi-spec) ## Generating API Clients from OpenAPI Spec -We use the OpenAPI Generator with configuration per language/framework in the `generators` folder. An example is: +We use the OpenAPI Generator with configuration per language/framework in the +`generators` folder. An example is: ```bash docker run \ @@ -27,4 +29,4 @@ docker run \ -v $(pwd):/koala swaggerapi/swagger-ui ``` -And browse to [http://localhost:8080](http://localhost:8080). \ No newline at end of file +And browse to [http://localhost:8080](http://localhost:8080). diff --git a/tea-collection/tea-collection.md b/tea-collection/tea-collection.md index 691af4c..7c04894 100644 --- a/tea-collection/tea-collection.md +++ b/tea-collection/tea-collection.md @@ -1,81 +1,79 @@ # The TEA Collection object (TCO) For each product and version there is a Tea Collection object, which is a list -of available artifacts for this specific version. The TEA Index is a list of -TEA collections. +of available artifacts for this specific version. The TEA Index is a list of TEA +collections. The TEA collection is normally created by the TEA application server at -publication time of artifacts. The publisher may sign the collection -object as a JSON file at time of publication. +publication time of artifacts. The publisher may sign the collection object as a +JSON file at time of publication. -If there are any updates of artifacts within a collection for the same -version of a product, then a new TEA Collection object is created and signed. -This update will have the same UUID, but a new version number. A reason -for the update will have to be provided. This shall be used to -correct mistakes, spelling errors as well as to provide new information -on dynamic artifact types such as LCE or VEX. If the product -is modified, that is a new product version and that should generate -a new collection object with a new UUID and updated metadata. +If there are any updates of artifacts within a collection for the same version +of a product, then a new TEA Collection object is created and signed. This +update will have the same UUID, but a new version number. A reason for the +update will have to be provided. This shall be used to correct mistakes, +spelling errors as well as to provide new information on dynamic artifact types +such as LCE or VEX. If the product is modified, that is a new product version +and that should generate a new collection object with a new UUID and updated +metadata. ## Dynamic or static Collection objects -The TCO is produced by the TEA software platform. There are two ways -to implement this: +The TCO is produced by the TEA software platform. There are two ways to +implement this: -* __Dynamic__: The TCO is built for each API request and created - dynamically. -* __Static__: The TCO is built at publication time as a static - object by the publisher. This object can be digitally signed at - publication time. +- **Dynamic**: The TCO is built for each API request and created dynamically. +- **Static**: The TCO is built at publication time as a static object by the + publisher. This object can be digitally signed at publication time. ## Collection object The TEA Collection object has the following parts -* Preamble - * UUID of the TEA collection object (TCO) - * Product name - * Product version - * Product Release date (timestamp) - * Author of the collection object - * Name - * Email - * Organisation - * Reason for update/release of TCO - * ENUM reason - * clear text - * "New product release" - * "Corrected dependency in SBOM that was faulty" - * "Added missing In-Toto build attestation" -* List of artifact objects (see below) -* Optional Signature of the collection object +- Preamble + - UUID of the TEA collection object (TCO) + - Product name + - Product version + - Product Release date (timestamp) + - Author of the collection object + - Name + - Email + - Organisation + - Reason for update/release of TCO + - ENUM reason + - clear text + - "New product release" + - "Corrected dependency in SBOM that was faulty" + - "Added missing In-Toto build attestation" +- List of artifact objects (see below) +- Optional Signature of the collection object The artifact object has the following parts -* Artifact UUID -* Artifact name -* Author of the artifact object - * Name - * Email - * Organisation -* List of objects with the same content, but in different formats. - The order of the list has no significance. - * UUID for subdoc - * Optional BOM identifier - * SPDX or CycloneDX reference to BOM - * MIME media type - * Artifact category (enum) - * - * Description in clear text - * Direct URL for downloads of artefact - * Direct URL for download of external signature - * Size in bytes - * SHA384 checksum +- Artifact UUID +- Artifact name +- Author of the artifact object + - Name + - Email + - Organisation +- List of objects with the same content, but in different formats. The order of + the list has no significance. + - UUID for subdoc + - Optional BOM identifier + - SPDX or CycloneDX reference to BOM + - MIME media type + - Artifact category (enum) + - + - Description in clear text + - Direct URL for downloads of artefact + - Direct URL for download of external signature + - Size in bytes + - SHA384 checksum ## The reason for TCO update enum | ENUM | Explanation | -|-------------|--------------------------------| +| ----------- | ------------------------------ | | VEXUPDATE | Updated the VEX artefact(s) | | SBOMUPDATE | Updated the SBOM artefact(s) | | OTHERUPDATE | Updated another artefact | diff --git a/tea-index/tea-index.md b/tea-index/tea-index.md index 748ef58..7c4f6ca 100644 --- a/tea-index/tea-index.md +++ b/tea-index/tea-index.md @@ -19,13 +19,12 @@ which products and versions are supported for a specific user. ## Composite products -If a product consists of a set of products, each with a different -version number and update scheme, a TEA bundle will be the starting -point of discovery. The TEA bundle will list all included parts -and include pointers (URLs) to the TEA index for these. +If a product consists of a set of products, each with a different version number +and update scheme, a TEA bundle will be the starting point of discovery. The TEA +bundle will list all included parts and include pointers (URLs) to the TEA index +for these. -The URL can be to a different vendor or different site with the -same vendor. +The URL can be to a different vendor or different site with the same vendor. ## TEA Product object @@ -40,14 +39,24 @@ same vendor. The TEA LEAF UUID is used in the LEAF API to find out which versions of the LEAF that exists. -The goal of the TEA index is to provide a selection of product -versions to assist the user software in finding a match for the -owned version. +The goal of the TEA index is to provide a selection of product versions to +assist the user software in finding a match for the owned version. ### API usage The user will find this API end point using TEA discovery. +A user will approach the API just to discover data before purchase, or with a +specific product and product version in scope. The format of the version may +follow many syntaxes, so maybe the API needs to be able to provide some sort of +format for the version string. + +An automated system may want to provide the user with a GUI, listing versions +and being able to scroll to the next page until the user selects a version. +### API usage + +The user will find this API end point using TEA discovery. + A user will approach the API just to discover data before purchase, or with a specific product and product version in scope. The format of the version may follow many syntaxes, so maybe @@ -67,5 +76,3 @@ until the user selects a version. * max per page * start page * Default value defined - - diff --git a/tea-leaf/tea-leaf.md b/tea-leaf/tea-leaf.md index 435089a..6429fdb 100644 --- a/tea-leaf/tea-leaf.md +++ b/tea-leaf/tea-leaf.md @@ -1,39 +1,43 @@ # The TEA Leaf Object (TLO) The TEA LEAF is the object that indicates a product version. The API should be -very agnostic as to how a "version" is indicated - semver, vers, name, hash or anything else. +very agnostic as to how a "version" is indicated - semver, vers, name, hash or +anything else. ## Major and minor versions -Each leaf is for a sub-version or minor version (using semver definitions). A new -major version counts as a new product with a separate product object (TPO). Each -product object has one or multiple TEI URNs. +Each leaf is for a sub-version or minor version (using semver definitions). A +new major version counts as a new product with a separate product object (TPO). +Each product object has one or multiple TEI URNs. -For the API to be able to present a list of versions in a cronological order, -a timestamp for a release is required. +For the API to be able to present a list of versions in a cronological order, a +timestamp for a release is required. ## The Leaf Object -- __Uuid__ unique for this object -- __Product name__: A text field -- __Product version__: A text field, no required syntax -- __Release date__: A unix timestamp -- __Pre-release__: A boolean flag indicating a pre-release (beta, rc) -- __Tco_uuid__: A reference to the TEA Collection objet for this release +- **Uuid** unique for this object +- **Product name**: A text field +- **Product version**: A text field, no required syntax +- **Release date**: A unix timestamp +- **Pre-release**: A boolean flag indicating a pre-release (beta, rc) +- **Tco_uuid**: A reference to the TEA Collection objet for this release ## Handling the Pre-Release flag -The "Pre-release" flag is used to indicate that this is not a final release. -For a given Leaf with a UUID, the flag can be set to indicate a "test", "beta", "alpha" -or similar non-deployed release. It can only be set when creating the LEAF. The TEA implementation -may allow it to be unset (False) once. This is to support -situations where a object is promoted as is after testing to production version. The flag can not -be set after initial creation and publication of the leaf. +The "Pre-release" flag is used to indicate that this is not a final release. For +a given Leaf with a UUID, the flag can be set to indicate a "test", "beta", +"alpha" or similar non-deployed release. It can only be set when creating the +LEAF. The TEA implementation may allow it to be unset (False) once. This is to +support situations where a object is promoted as is after testing to production +version. The flag can not be set after initial creation and publication of the +leaf. -If the final version is different from the pre-release (bugs fixed, code changed, different binary) -a new leaf with a new UUID and version needs to be created. +If the final version is different from the pre-release (bugs fixed, code +changed, different binary) a new leaf with a new UUID and version needs to be +created. ## References - Semantic versioning (Semver): -- PURL VERS +- PURL VERS +