├── .github ├── CODEOWNERS └── workflows │ └── test-generate-api-clients.yaml ├── .gitignore ├── LICENSE ├── NOTICE ├── README.md ├── api-flow ├── consumer.md └── publisher.md ├── api └── bomexchangeapi.md ├── auth └── readme.md ├── contributors.md ├── discovery └── readme.md ├── doc ├── tea-requirements.md └── tea-usecases.md ├── images ├── Project-Koala.svg ├── tealogo-big.png ├── tealogo-on-black.png └── tealogo.png ├── out └── .gitkeep ├── presentations ├── koalacon2024 │ ├── 00-welcome.pdf │ ├── 01-introduction-overview.pdf │ ├── 02-tea-data-model.pdf │ ├── 03-dependency-track.pdf │ ├── 04-tea-sbomify.pdf │ └── 05-tea-and-java.pdf ├── oej │ ├── koala-beta-one-cisa-sbom-community.pdf │ ├── koala-tea-intro-normal-format.pdf │ ├── koala-tea-intro-sbomarama.pdf │ ├── koala-transparency-exchange.pdf │ ├── tea-collection.key.pdf │ └── tea-publish.pdf └── steve.springett │ ├── Ecma TC54 + CycloneDX Brief (June 2024).pdf │ └── Transparency Exchange API Kickoff.pdf ├── signatures └── signature.md ├── spec ├── README.md ├── generators │ ├── common.yaml │ ├── go.yaml │ ├── java-webclient.yaml │ ├── python.yaml │ ├── typescript.yaml │ └── update-pom.sh ├── openapi.yaml └── publisher │ ├── README.md │ └── openapi.json ├── tea-artifact └── tea-artifact.md ├── tea-collection └── tea-collection.md ├── tea-component └── tea-component.md └── tea-product └── tea-product.md /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # see https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners 2 | 3 | * @oej @madpah 4 | -------------------------------------------------------------------------------- /.github/workflows/test-generate-api-clients.yaml: -------------------------------------------------------------------------------- 1 | name: Build & Test Generated API Clients 2 | 3 | on: 4 | push: 5 | branches: ['main'] 6 | workflow_dispatch: 7 | 8 | concurrency: 9 | group: ${{ github.workflow }}-${{ github.ref }} 10 | cancel-in-progress: true 11 | 12 | env: 13 | OPEN_API_GENERATOR_VERSION: 'v7.12.0' 14 | PYTHON_VERSION_DEFAULT: '3.12' 15 | POETRY_VERSION: '1.8.1' 16 | 17 | jobs: 18 | generate-library-code: 19 | name: Generate Library Code ${{ matrix.language }} 20 | runs-on: ubuntu-latest 21 | strategy: 22 | matrix: 23 | language: ['go', 'java-webclient', 'python', 'typescript'] 24 | steps: 25 | - name: Checkout 26 | # see https://github.com/actions/checkout 27 | uses: actions/checkout@v4 28 | 29 | - name: Create Output Directory 30 | run: mkdir out/${{ matrix.language }} 31 | 32 | - name: Run OpenAPI Generator 33 | uses: addnab/docker-run-action@v3 34 | with: 35 | image: openapitools/openapi-generator-cli:${{ env.OPEN_API_GENERATOR_VERSION }} 36 | options: -v ${{ github.workspace }}:/local 37 | run: /usr/local/bin/docker-entrypoint.sh batch --clean /local/spec/generators/${{ matrix.language }}.yaml 38 | 39 | - name: Copy our scripts across too 40 | run: cp spec/generators/*.sh ./out/${{ matrix.language }} 41 | 42 | - name: Save to Cache 43 | uses: actions/cache/save@v4 44 | with: 45 | path: out/${{ matrix.language }} 46 | key: '${{ matrix.language }}-${{ github.run_id }}' 47 | 48 | validate-go: 49 | name: Validate Go Library 50 | runs-on: ubuntu-latest 51 | needs: generate-library-code 52 | 53 | steps: 54 | - name: Setup Go 55 | uses: actions/setup-go@v5 56 | with: 57 | go-version: 1.22 58 | 59 | - name: Get generated code from cache 60 | uses: actions/cache/restore@v4 61 | with: 62 | path: out/go 63 | key: 'go-${{ github.run_id }}' 64 | fail-on-cache-miss: true 65 | 66 | - name: Build Go API Client 67 | run: go build -v ./ 68 | working-directory: out/go 69 | 70 | - name: Install test dependencies & run generated tests 71 | run: | 72 | go get github.com/stretchr/testify/assert 73 | go test -v ./test/ 74 | working-directory: out/go 75 | 76 | validate-java-webclient: 77 | name: Validate Java Webclient 78 | runs-on: ubuntu-latest 79 | needs: generate-library-code 80 | 81 | steps: 82 | - name: Set up JDK 17 for x64 83 | uses: actions/setup-java@v4 84 | with: 85 | java-version: '17' 86 | distribution: 'temurin' 87 | architecture: x64 88 | 89 | - name: Set up Maven 90 | uses: stCarolas/setup-maven@v5 91 | with: 92 | maven-version: 3.9.4 93 | 94 | - name: Get generated code from cache 95 | uses: actions/cache/restore@v4 96 | with: 97 | path: out/java-webclient 98 | key: 'java-webclient-${{ github.run_id }}' 99 | fail-on-cache-miss: true 100 | 101 | - name: Build & Test Java Webclient API Client 102 | run: | 103 | ./update-pom.sh pom.xml 104 | mvn clean test 105 | working-directory: out/java-webclient 106 | 107 | validate-python: 108 | name: Validate Python Library 109 | runs-on: ubuntu-latest 110 | needs: generate-library-code 111 | 112 | steps: 113 | - name: Set up Python 114 | uses: actions/setup-python@v5 115 | with: 116 | python-version: ${{ env.PYTHON_VERSION_DEFAULT }} 117 | 118 | - name: Install poetry 119 | # see https://github.com/marketplace/actions/setup-poetry 120 | uses: Gr1N/setup-poetry@v9 121 | with: 122 | poetry-version: ${{ env.POETRY_VERSION }} 123 | 124 | - name: Get generated code from cache 125 | uses: actions/cache/restore@v4 126 | with: 127 | path: out/python 128 | key: 'python-${{ github.run_id }}' 129 | fail-on-cache-miss: true 130 | 131 | - name: Install dependencies 132 | run: poetry install --no-root 133 | working-directory: out/python 134 | 135 | - name: Ensure build successful 136 | run: poetry build 137 | working-directory: out/python 138 | 139 | - name: Run Tests 140 | run: | 141 | pip install -r test-requirements.txt 142 | poetry run pytest 143 | working-directory: out/python 144 | 145 | validate-typescript: 146 | name: Validate Typescript Library 147 | runs-on: ubuntu-latest 148 | needs: generate-library-code 149 | 150 | steps: 151 | - name: Setup Node 152 | uses: actions/setup-node@v4 153 | with: 154 | node-version: latest 155 | 156 | - name: Get generated code from cache 157 | uses: actions/cache/restore@v4 158 | with: 159 | path: out/typescript 160 | key: 'typescript-${{ github.run_id }}' 161 | fail-on-cache-miss: true 162 | 163 | - name: Build Typescript API Client 164 | run: npm i && npm run build 165 | working-directory: out/typescript -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | out/* 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright OWASP Foundation 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | CycloneDX BOM Exchange API Standard 2 | Copyright (c) OWASP Foundation 3 | 4 | This product includes software developed by the 5 | CycloneDX community (https://cyclonedx.org/). 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![License](https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg)](LICENSE) 2 | [![Website](https://img.shields.io/badge/https://-cyclonedx.org-blue.svg)](https://cyclonedx.org/) 3 | [![Slack Invite](https://img.shields.io/badge/Slack-Join-blue?logo=slack&labelColor=393939)](https://cyclonedx.org/slack/invite) 4 | [![Group Discussion](https://img.shields.io/badge/discussion-groups.io-blue.svg)](https://groups.io/g/CycloneDX) 5 | [![Twitter](https://img.shields.io/twitter/url/http/shields.io.svg?style=social&label=Follow)](https://twitter.com/CycloneDX_Spec) 6 | [![ECMA TC54](https://img.shields.io/badge/ECMA-TC54-FC7C00?labelColor=404040)](https://tc54.org) 7 | [![ECMA TC54](https://img.shields.io/badge/ECMA-TC54--TG1-FC7C00?labelColor=404040)](https://ecma-international.org/task-groups/tc54-tg1/) 8 | 9 | # CycloneDX Transparency Exchange API Standard 10 | 11 | The Transparency Exchange API (TEA) is being worked on within the CycloneDX community 12 | with the goal to standardise the API in ECMA. A working group within ECMA TC54 has been 13 | formed - TC54 TG1. The working group has a slack channel in the CycloneDX slack space. 14 | 15 | ![](images/tealogo.png) 16 | 17 | ## Status of the standard: Beta 1 18 | 19 | TEA is now in beta 1. This beta focuses on the consumer side of the API. Work on the 20 | publisher API will start after the beta. The idea is to get implementation feedback 21 | early on the current specification in order to move forward towards a first official 22 | version of the standard. Feedback will be gathered in the Hackathon at OWASP AppSec 23 | Global in Barcelona May 28 as well as in the meetings and slack channel. 24 | 25 | We encourage developers to start with both client and server implementations of TEA and 26 | participate in interoperability tests. These will be organised both as hackathons and 27 | informally using the Slack channel. 28 | 29 | There will likely be multiple beta releases. We will announce these by adding new 30 | tags in the repository as well as in the slack channel. 31 | 32 | ## Introduction 33 | 34 | This specification defines a standard, format agnostic, API for the exchange of 35 | product related artefacts, like BOMs, between systems. The work includes: 36 | 37 | - [Discovery of servers](/discovery/readme.md): Describes discovery using the Transparency Exchange Identifier (TEI) 38 | - Retrieval of artefacts 39 | - Publication of artefacts 40 | - Authentication and authorization 41 | - Querying 42 | 43 | System and tooling implementors are encouraged to adopt this API standard for 44 | sending/receiving transparency artefacts between systems. 45 | This will enable more widespread 46 | "out of the box" integration support in the BOM ecosystem. 47 | 48 | ## Use cases and requirements 49 | 50 | The working group has produced a list of use cases and requirements for the protocol. 51 | 52 | - [TEA requirements](doc/tea-requirements.md) 53 | - [TEA use cases](doc/tea-usecases.md) 54 | 55 | ## Data model 56 | 57 | - [TEA Product](tea-product/tea-product): This is the starting point. A "product" is something for sale or distributed as an Open Source project. The [Transparency Exchange Identifier, TEI](/discovery/readme.md) points to a single product. 58 | - [TEA Component index](tea-component/tea-component.md): A Component index is a version entry. The Component version index has one entry per version of the product. 59 | - [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. 60 | 61 | ## Artefacts available of the API 62 | 63 | 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: 64 | 65 | ### xBOM 66 | 67 | 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. 68 | 69 | ### CDXA 70 | 71 | 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. 72 | 73 | ### VDR/VEX 74 | 75 | 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. 76 | 77 | ### CLE 78 | 79 | 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. 80 | 81 | ### Insights 82 | 83 | 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: 84 | 85 | - Do any of my licensed products from Vendor A use Apache Struts? 86 | - Are any of my licensed products from Vendor A vulnerable to log4shell and is there any action I need to take? 87 | 88 | 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. 89 | 90 | ## Presentations and videos 91 | 92 | - You can find presentations in the repository in the [Presentations](/presentations) directory 93 | - Our biweekly meetings are available on [YouTube playlist: Project Koala](https://www.youtube.com/playlist?list=PLqjEqUxHjy1XtSzGYL7Dj_WJbiLu_ty58) 94 | - KoalaCon 2024 - an introduction to the project - can be [viewed on YouTube](https://youtu.be/NStzYW4WnEE?si=ihLirpGVjHc7K4bL) 95 | 96 | ## Contributors 97 | 98 | Contributors are listed in the [Contributors](contributors.md) file. 99 | 100 | ## Terminology 101 | 102 | - API: Application programming interface 103 | - Authorization (authz): 104 | - Authentication (authn): 105 | - Collection: A set of artifacts representing a version of a product 106 | - Product: An item sold or delivered under one name 107 | - Product variant: A variant of a product 108 | - Version: 109 | 110 | ![](images/Project-Koala.svg) 111 | 112 | ## Previous work 113 | 114 | - [The CycloneDX BOM Exchange API](/api/bomexchangeapi.md) 115 | Implemented in the [CycloneDX BOM Repo Server](https://github.com/CycloneDX/cyclonedx-bom-repo-server) 116 | -------------------------------------------------------------------------------- /api-flow/consumer.md: -------------------------------------------------------------------------------- 1 | # Transparency Exchange API: Consumer access 2 | 3 | 4 | The consumer access starts with a TEI, A transparency Exchange Identifier. This is used to find the API server as 5 | described in the [discovery document](/discovery/readme.md). 6 | 7 | ## API usage 8 | 9 | The standard TEI points to a product. A product is something sold, downloaded as an opensource project or aquired 10 | by other means. It contains one or multiple components. 11 | 12 | - __List of TEA Components__: Components are components of something that is part of a product. 13 | Each Component has it's own versioning and it's own set of artifacts. 14 | - __List of TEA Releases__: Each component has a list of releases where each release has a timestamp and 15 | a lifecycle enumeration. They are normally sorted by timestamps. The TEA API has no requirements of 16 | type of version string (semantic or any other scheme) - it's just an identifier set by the manufacturer. 17 | - __List of TEA Collections__: For each release, there is a list of TEA collections as indicated 18 | by release date and a version integer starting with collection version 1. 19 | - __List of TEA Artifacts__: The collection is unique for a version and contains a list of artifacts. 20 | This can be SBOM files, VEX, SCITT, IN-TOTO or other documents. Note that a single artifact 21 | can belong to multiple versionsof a Component and multiple Components. 22 | - __List of artifact formats__: An artifact can be published in multiple formats. 23 | 24 | The user has to know product TEI and version of each component (TEA Component) to find the list of 25 | artifacts for the used version. 26 | 27 | ## API flow based on TEI discovery 28 | 29 | ```mermaid 30 | 31 | --- 32 | title: TEA consumer 33 | --- 34 | 35 | sequenceDiagram 36 | autonumber 37 | actor user 38 | participant discovery as TEA Discovery with TEI 39 | 40 | participant tea_product as TEA Product 41 | participant tea_component as TEA Component 42 | participant tea_release as TEA Release 43 | participant tea_collection as TEA Collection 44 | participant tea_artifact as TEA Artefact 45 | 46 | 47 | user ->> discovery: Discovery using DNS 48 | discovery ->> user: List of API servers 49 | 50 | user ->> tea_product: Finding all product parts (TEA Components) and facts about the product 51 | tea_product ->> user: List of product parts 52 | 53 | user ->> tea_component: Finding information of a component 54 | tea_component ->> user: List of component metadata 55 | 56 | user ->> tea_release: Finding a specific version/release 57 | tea_release ->> user: List of releases and collection id for each release 58 | 59 | user ->> tea_collection: Finding all artefacts for version in scope 60 | tea_collection ->> user: List of artefacts and formats available for each artefact 61 | 62 | user ->> tea_artifact: Request to download artifact 63 | tea_artifact ->> user: Artifact 64 | 65 | 66 | 67 | ``` 68 | 69 | ## API flow based on direct access to API 70 | 71 | In this case, the client wants to search for a specific product using the API 72 | 73 | ```mermaid 74 | 75 | --- 76 | title: TEA client flow with search 77 | --- 78 | 79 | sequenceDiagram 80 | autonumber 81 | actor user 82 | 83 | participant tea_product as TEA Product 84 | participant tea_component as TEA Component 85 | participant tea_release as TEA Release 86 | participant tea_collection as TEA Collection 87 | participant tea_artifact as TEA Artefact 88 | 89 | 90 | user ->> tea_product: Search for product based on identifier (CPE, PURL, name) 91 | tea_product ->> user: List of products 92 | 93 | user ->> tea_product: Finding all product parts (TEA Components) and facts about choosen product 94 | tea_product ->> user: List of product parts 95 | 96 | user ->> tea_component: Finding information of a component 97 | tea_component ->> user: List of component metadata 98 | 99 | user ->> tea_release: Finding a specific version/release 100 | tea_release ->> user: List of releases and collection id for each release 101 | 102 | user ->> tea_collection: Finding all artefacts for version in scope 103 | tea_collection ->> user: List of artefacts and formats available for each artefact 104 | 105 | user ->> tea_artifact: Request to download artifact 106 | tea_artifact ->> user: Artifact 107 | 108 | ``` 109 | 110 | ## API flow based on cached data - checking for a new release 111 | 112 | In this case a TEA client knows the component UUID and wants to check the status of the 113 | used release and if there's a new release. The client may limit the query with a given date 114 | for a release. 115 | 116 | ```mermaid 117 | 118 | --- 119 | title: TEA client flow with direct query for release 120 | --- 121 | 122 | sequenceDiagram 123 | autonumber 124 | actor user 125 | 126 | participant tea_product as TEA Product 127 | participant tea_component as TEA Component 128 | participant tea_release as TEA Release 129 | participant tea_collection as TEA Collection 130 | participant tea_artifact as TEA Artefact 131 | 132 | user ->> tea_release: Finding a specific version/release 133 | tea_release ->> user: List of releases and collection id for each release 134 | 135 | ``` 136 | 137 | ## API flow based on cached data - checking if a collection changed 138 | 139 | In this case a TEA client knows the release UUID, the collection UUID, and the 140 | collection version from previous queries. If the given version is not the same, 141 | another query is done to get reason for update and new collection list of artifacts. 142 | 143 | 144 | ```mermaid 145 | 146 | --- 147 | title: TEA client collection query 148 | --- 149 | 150 | sequenceDiagram 151 | autonumber 152 | actor user 153 | 154 | participant tea_product as TEA Product 155 | participant tea_component as TEA Component 156 | participant tea_release as TEA Release 157 | participant tea_collection as TEA Collection 158 | participant tea_artifact as TEA Artefact 159 | 160 | 161 | user ->> tea_collection: Finding the current collection, including version 162 | tea_collection ->> user: List of artefacts and formats available for each artefact 163 | 164 | user ->> tea_collection: Request to access previous version of the collection to compare 165 | tea_collection ->> user: Previous version of collection 166 | 167 | ``` -------------------------------------------------------------------------------- /api-flow/publisher.md: -------------------------------------------------------------------------------- 1 | # Overview of the TEA API from a producer standpoint 2 | 3 | This is input for the working group. 4 | 5 | ## Bootstrapping 6 | 7 | ```mermaid 8 | 9 | sequenceDiagram 10 | autonumber 11 | actor Vendor 12 | participant tea_product as TEA Product 13 | participant tea_component as TEA Component 14 | participant tea_collection as TEA Collection 15 | 16 | Vendor ->> tea_product: POST to /v1/product to create new product 17 | tea_product -->> Vendor: Product is created and TEA Product Identifier (PI) returned 18 | 19 | Vendor ->> tea_component: POST to /v1/component with the TEA PI and component version as the payload 20 | tea_component ->> Vendor: Component is created and a TEA Component ID is returned 21 | 22 | Vendor ->> tea_collection: POST to /v1/collection with the TEA Component ID as the and the artifact as payload 23 | tea_collection ->> Vendor: Collection is created with the collection ID returned 24 | 25 | ``` 26 | 27 | ## Release life cycle 28 | 29 | ```mermaid 30 | sequenceDiagram 31 | autonumber 32 | actor Vendor 33 | participant tea_product as TEA Product 34 | participant tea_component as TEA Component 35 | participant tea_collection as TEA Collection 36 | 37 | Note over Vendor,tea_component: Create new release 38 | 39 | Vendor ->> tea_component: POST to /v1/component with the TEA PI and component version as the payload 40 | tea_component ->> Vendor: Component is created and a TEA Component ID is returned 41 | 42 | Note over Vendor,TEA Component: Add an artifact (e.g. SBOM) 43 | Vendor ->> tea_collection: POST to /v1/collection with the TEA Component ID as the and the artifact as payload 44 | tea_collection ->> Vendor: Collection is created with the collection ID returned 45 | 46 | ``` 47 | 48 | ## Adding a new artifact 49 | 50 | ```mermaid 51 | sequenceDiagram 52 | autonumber 53 | actor Vendor 54 | participant tea_product as TEA Product 55 | participant tea_component as TEA Component 56 | participant tea_collection as TEA Collection 57 | 58 | Vendor ->> tea_component: GET to /v1/component with the TEA PI to get the latest version 59 | tea_component ->> Vendor: Component will be returned 60 | 61 | Vendor ->> tea_collection: POST to /v1/collection with the TEA Component ID as the and the artifact as payload 62 | tea_collection ->> Vendor: Collection is created with the collection ID returned 63 | ``` -------------------------------------------------------------------------------- /api/bomexchangeapi.md: -------------------------------------------------------------------------------- 1 | # CycloneDX BOM exchange API 2 | 3 | __Note:__ this is an older version of the API not being worked on any more. This work 4 | will be replaced by the Transparency Exchange API. 5 | 6 | ## Conventions 7 | 8 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", 9 | "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be 10 | interpreted as described in [RFC2119](http://www.ietf.org/rfc/rfc2119.txt). 11 | 12 | ### ABNF Syntax 13 | 14 | ABNF syntax used as per 15 | [RFC5234: Augmented BNF for Syntax Specifications: ABNF](https://datatracker.ietf.org/doc/html/rfc5234). 16 | 17 | 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). 18 | 19 | These additional rules are defined: 20 | 21 | ```abnf 22 | system-url = supported-scheme ":" hier-part 23 | ; a system defined URL 24 | ; hier-part as defined in RFC3986 25 | supported-scheme = "http" / "https" 26 | ``` 27 | 28 | See also: [RFC7231: Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content](https://datatracker.ietf.org/doc/html/rfc7231) 29 | 30 | ## Specification Compliance 31 | 32 | An API server/client can be referred to as compliant if it correctly implements 33 | any of the methods described within this specification. It is not a 34 | requirement to implement all the methods described. 35 | 36 | ## BOM Retrieval 37 | 38 | This method is for retrieving a BOM from a system. 39 | 40 | The BOM retrieval URL MUST comply with this syntax: 41 | 42 | ```abnf 43 | bom-retrieval-url = system-url "?" bom-identifier-query 44 | bom-identifier-query = "bomIdentifier=" bom-identifier 45 | bom-identifier = *( pchar / "/" / "?" ) 46 | ; an identifier that uniquely identifies a BOM 47 | ; pchar as defined in RFC3986 48 | ``` 49 | 50 | The HTTP request method MUST be `GET`. 51 | 52 | For CycloneDX BOMs the `bom-identifier` MUST be either a CDX URN (https://www.iana.org/assignments/urn-formal/cdx) 53 | or a BOM serial number UUID URN (https://cyclonedx.org/docs/1.4/json/#serialNumber). 54 | 55 | For SPDX documents the `bom-identifier` MUST be the SPDX Document Namespace 56 | (https://spdx.github.io/spdx-spec/document-creation-information/#65-spdx-document-namespace-field). 57 | 58 | ### Server Requirements 59 | 60 | Servers MAY require authorization. If authorization is required it MUST 61 | use the HTTP `Authorization` header. If a server requires authorization, and 62 | no `Authorization` request header is supplied by the client, the server 63 | MUST respond with a 401 Unauthorized response. 64 | 65 | Servers MUST honour the requested content types in the `Accept` header. If 66 | the server does not support any of the requested content types a HTTP 406 response 67 | MUST be returned. The 406 response body MUST contain a list of server supported 68 | content types in the below format with `text/plain` content type. 69 | 70 | ```abnf 71 | media-type *(", " media-type) 72 | ``` 73 | 74 | e.g. `application/vnd.cyclonedx+xml; version=1.4, application/vnd.cyclonedx+xml; version=1.3` 75 | 76 | API servers MUST provide the correct `Content-Type` HTTP response header. For example: 77 | 78 | ```http 79 | Content-Type: application/vnd.cyclonedx+xml; version=1.4 80 | ``` 81 | 82 | If a BOM serial number UUID URN is used as the `bom-identifier`, the server 83 | MUST respond with the latest available version of the BOM. 84 | 85 | ### Client Requirements 86 | 87 | - Clients MUST support an optional `Authorization` header being specified. 88 | - Clients MUST provide a `Accept` HTTP request header. For example: 89 | 90 | ```http 91 | Accept: application/vnd.cyclonedx+xml; version=1.4, application/vnd.cyclonedx+xml; version=1.3 92 | ``` 93 | 94 | ## BOM Submission Endpoint 95 | 96 | This method is for submitting a BOM to a system. 97 | 98 | The BOM submission URL MUST comply with this syntax: 99 | 100 | ```abnf 101 | bom-submission-url = system-url 102 | ``` 103 | 104 | The HTTP request method MUST be `POST`. 105 | 106 | ### Server Requirements 107 | 108 | Servers MAY require authorization. If authorization is required it MUST 109 | use the HTTP `Authorization` header. If a server requires authorization, and 110 | no `Authorization` request header is supplied by the client, the server 111 | MUST respond with a 401 Unauthorized response. 112 | 113 | Servers MUST honour the specified content type in the `Content-Type` header. If 114 | the server does not support the supplied content type a HTTP 415 Unsupported 115 | Media Type response MUST be returned. The 415 response body MUST contain a list 116 | of server supported content types in the below format with `text/plain` content type. 117 | 118 | ```abnf 119 | media-type *(", " media-type) 120 | ``` 121 | 122 | e.g. `application/vnd.cyclonedx+xml; version=1.4, application/vnd.cyclonedx+xml; version=1.3` 123 | 124 | If the submitted BOM has been successfully submitted the API server MUST 125 | respond with an appropriate 2xx HTTP status code. 126 | 127 | ### Client Requirements 128 | 129 | Clients MUST support an optional `Authorization` header being specified. 130 | 131 | Clients MUST provide the correct `Content-Type` HTTP request header. For example: 132 | 133 | ```http 134 | Content-Type: application/vnd.cyclonedx+xml; version=1.4 135 | ``` 136 | -------------------------------------------------------------------------------- /auth/readme.md: -------------------------------------------------------------------------------- 1 | # Transparency Exchange API - Authentication and authorization 2 | 3 | This document covers authentication and authorization on the consumer side 4 | of a TEA service - the discovery and download of software transparency artefacts. 5 | 6 | ## Requirements 7 | 8 | __Authorization__: A user of a TEA service may get access to all objects (components, collections) and 9 | artefacts or just a subset, depending on the publisher of the data. Authorization is connected 10 | to __authentication__. 11 | 12 | The level of authorization is up to the implementer of the TEA implementation and the publisher, 13 | whether an identity gets access to all objects in a service or just a subset. 14 | 15 | In order to get interoperability between clients and servers implementing the protocol, the 16 | specification focuses on the authentication. After successful authentication, the authorization 17 | may be implemented in multiple ways - on various levels of the API - depending on what information 18 | the user can access. 19 | 20 | As an example, one implementation may publish all information about existing artefacts and software 21 | versions openly, but restrict access to artefacts to those that match the customers installation. 22 | Another implementation can implement a filter that does not show products and versions ("components") that 23 | the customer has not aquired. 24 | 25 | For most Open Source projects, implementing authentication - setting up accounts and managing 26 | authorization - does not make much sense, since the information is usually in the open any way. 27 | 28 | This specification does not impose any requirement on authentication on a TEA service. But should 29 | the provider implement authentication, two methods are supported in order to promote interoperability. 30 | 31 | * HTTP Bearer Token Authentication 32 | * Mutual TLS with verifiable client and server certificates 33 | 34 | A client may use both HTTP bearer token auth and TLS client certificates 35 | when accessing multiple TEA services. It is up to the service provider to select authentication. 36 | 37 | ## HTTP bearer token auth 38 | 39 | The API will support HTTP bearer token in the __Authorization:__ http header. 40 | How the token is aquired is out of scope for this 41 | specification, as is the potential content of the token. 42 | 43 | As an example the token can be downloaded from a customer support portal with a long-term 44 | validity. This token is then installed into the software transparency platform (the TEA client) 45 | and used to automatically retrieve software transparency artefacts. 46 | 47 | For each TEA service, one bearer token is needed. The token itself (or the backend) should 48 | specify authorization for the token. 49 | 50 | ## Mutual TLS 51 | 52 | For Mutual TLS the client certificates will be managed by the service and provided 53 | in a service-specific way. Clients should be able to configure a separate client certificate 54 | (and private key) on a per-service level, not assuming that a client certificate 55 | for one service is trusted anywhere else. 56 | 57 | ## References 58 | 59 | * RFC 6750: The Oauth 2.0 Authorization Framework: Bearer Token 60 | Usage (https://www.rfc-editor.org/rfc/rfc6750) 61 | -------------------------------------------------------------------------------- /contributors.md: -------------------------------------------------------------------------------- 1 | # Contributors 2 | 3 | Many people have contributed with good ideas during meetings, feedback during personal 4 | interactions. A huge Thank You to everyone that has supported the work in 5 | this project! 6 | 7 | A few persons have contributed with documentation, API specifications and other 8 | work during our meetings and workshops. They are noted here in alphabetic order: 9 | 10 | * Anthony Harrison, APH10, United Kingdom 11 | * Olle E. Johansson, Project lead, Edvina AB, Sweden, oej@edvina.net 12 | * Mark Symons 13 | * Paul Horton, Sonatype Inc., paul.horton@owasp.org, [@madaph](https://github.com/madpah) 14 | * Pavel Shukhman, Reliza, Canada, pavel@reliza.io 15 | * Piotr P. Karwasz, The Apache Software Foundation, pkarwasz-ecma@apache.org 16 | * Steve Springett 17 | * Valerio Mulas 18 | * Viktor Petersson, sbomify, United Kingdom, hello@sbomify.com 19 | 20 | -------------------------------------------------------------------------------- /discovery/readme.md: -------------------------------------------------------------------------------- 1 | # Transparency Exchange API - Discovery 2 | 3 | **NOTE**: _This is a proposal for the WG_ 4 | 5 | - [From product identifier to API endpoint](#from-product-identifier-to-api-endpoint) 6 | - [Advertising the TEI](#advertising-the-tei) 7 | - [TEA Discovery - defining an extensible identifier](#tea-discovery---defining-an-extensible-identifier) 8 | - [The TEI URN: An extensible identifier](#the-tei-urn-an-extensible-identifier) 9 | - [TEI syntax](#tei-syntax) 10 | - [TEI types](#tei-types) 11 | - [TEI resolution using DNS](#tei-resolution-using-dns) 12 | - [Connecting to the API](#connecting-to-the-api) 13 | - [Overview: Finding the Index using DNS result](#overview-finding-the-index-using-dns-result) 14 | - [The TEA Version Index](#the-tea-version-index) 15 | - [References](#references) 16 | 17 | ## From product identifier to API endpoint 18 | 19 | TEA Discovery is the connection between a product identifier and the API endpoint. 20 | A "product" is something that the customer aquires or downloads. It can be a bundle 21 | of many digital devices or software applications. A "product" normally also has an 22 | entry in a large corporation's asset inventory system. 23 | 24 | A product identifier is embedded in a URN where the identifier is one of many existing 25 | identifiers or a random string - like an EAN or UPC bar code, UUID, product 26 | number or PURL. 27 | 28 | The goal is for a user to add this URN to the transparency platform (sometimes with an 29 | associated authentication token) and have the platform access the required artifacts 30 | in a highly automated fashion. 31 | 32 | ## Advertising the TEI 33 | 34 | The TEI for a product can be communicated to the user in many ways. 35 | 36 | - A QR code on a box 37 | - On the invoice or delivery note 38 | - For software with a GUI, in an "about" box 39 | 40 | ## TEA Discovery - defining an extensible identifier 41 | 42 | TEA discovery is the process where a user with a product identifier can discover and download 43 | artifacts automatically, with or without authentication. A globally unique identifier is 44 | required for a given product. This identifier is called the Transparency Exchange Identifier (TEI). 45 | 46 | The TEI identifier is based on DNS, which assures a uniqueness per vendor (or open source project) 47 | and gives the vendor a name space to define product identifiers based on existing or new identifiers 48 | like EAN/UPC bar code, PURLs or other existing schemes. A given product may have multiple identifiers 49 | as long as they all resolve into the same destination. 50 | 51 | ## The TEI URN: An extensible identifier 52 | 53 | The TEI, Transparency Exchange Identifier, is a URN schema that is extensible based on existing 54 | identifiers like EAN codes, PURL and other identifiers. It is based on a DNS name, which leads 55 | to global uniqueness without new registries. 56 | 57 | The TEI can be shown in the software itself, in shipping documentation, in web pages and app stores. 58 | TEI is unique for a product, not a version of a software. The TEI consist of three core parts 59 | 60 | A TEI belongs to a single product. A product can have multiple TEIs - like one with a EAN/UPC 61 | barcode and one with the vendor's product number. 62 | 63 | ### TEI syntax 64 | 65 | ```text 66 | urn:tei::: 67 | ```` 68 | 69 | - The **`type`** which defines the syntax of the unique identifier part 70 | - The **`domain-name`** part resolves into a web server, which may not be the API host. 71 | - The uniqueness of the name is the domain name part that has to be registred at creation of the TEI. 72 | - The **`unique-identifier`** has to be unique within the `domain-name`. 73 | Recommendation is to use a UUID but it can be an existing article code too 74 | 75 | **Note**: this requires a registration of the TEI URN schema with IANA - [see here](https://github.com/CycloneDX/transparency-exchange-api/issues/18) 76 | 77 | ### TEI types 78 | 79 | The below show examples of TEI where the types are specific known formats or types. 80 | 81 | Reminder: the `unique-identifer` component of the TEI needs only be unique within the `domain-name`. 82 | 83 | #### PURL - Package URL 84 | 85 | Where the `unique-identifier` is a PURL in it's canonical string form. 86 | 87 | Syntax: 88 | 89 | ```text 90 | urn:tei:purl:: 91 | ```` 92 | 93 | Example: 94 | 95 | ```text 96 | urn:tei:purl:cyclonedx.org:pkg:pypi/cyclonedx-python-lib@8.4.0?extension=whl&qualifier=py3-none-any 97 | ``` 98 | 99 | #### SWID 100 | 101 | Where the `unique-identifier` is a SWID. 102 | 103 | Syntax: 104 | 105 | ```text 106 | urn:tei:swid:: 107 | ```` 108 | 109 | Note that there is a TEI SWID type as well as a PURL SWID type. 110 | 111 | #### HASH 112 | 113 | Where the `unique-identifier` is a Hash. Supports the following hash types: 114 | 115 | - SHA256 116 | - SHA384 117 | - SHA512 118 | 119 | ```text 120 | urn:tei:hash::: 121 | ```` 122 | 123 | Example: 124 | ```text 125 | urn:tei:hash:cyclonedx.org:SHA256:fd44efd601f651c8865acf0dfeacb0df19a2b50ec69ead0262096fd2f67197b9 126 | ``` 127 | 128 | The origin of the hash is up to the vendor to define. 129 | 130 | #### UUID 131 | 132 | Where the `unique-identifier` is a UUID. 133 | 134 | Syntax: 135 | 136 | ```text 137 | urn:tei:uuid:: 138 | ```` 139 | 140 | Example: 141 | ```text 142 | urn:tei:uuid:cyclonedx.org:d4d9f54a-abcf-11ee-ac79-1a52914d44b1 143 | ``` 144 | 145 | 146 | #### Other types to be defined 147 | 148 | - EAN 149 | - GS1 150 | - STD 151 | 152 | ### TEI resolution using DNS 153 | 154 | The `domain-name` part of the TEI is used in a DNS query to find one or multiple locations for 155 | product transparency exchange information. 156 | 157 | At the URL a well-known name space is used to find out where the API endpoint is hosted. 158 | This is solved by using the ".well-known" name space as defined by the IETF. 159 | 160 | - `urn:tei:uuid:products.example.com:d4d9f54a-abcf-11ee-ac79-1a52914d44b1` 161 | - Syntax: `urn:tei:uuid::` 162 | 163 | The name in the DNS name part points to a set of DNS records. 164 | 165 | A TEI with `domain-name` `tea.example.com` queries DNS for `tea.example.com`, considering `A`, `AAAA` and `CNAME` records. 166 | These point to the hosts available for the Transparency Exchange API. 167 | 168 | The TEA client connects to the host using HTTPS and validates the certificate. 169 | The URI is composed of the name with the `/.well-known/tea` prefix added. 170 | 171 | This results in the base URI (without the product identifier) 172 | `https://tea.example.com/.well-known/tea/` 173 | 174 | 175 | ## Connecting to the API 176 | 177 | When connecting to the `.well-known/tea` URI with the unique identifier 178 | a HTTP redirect is **required**. 179 | 180 | The server MUST redirect HTTP requests for that resource 181 | to the actual "context path" using one of the available mechanisms 182 | provided by HTTP (e.g., using a 301, 303, or 307 response). Clients 183 | MUST handle HTTP redirects on the `.well-known` URI. Servers MUST 184 | NOT locate the actual TEA service endpoint at the 185 | `.well-known` URI as per Section 1.1 of [RFC5785]. 186 | 187 | ### Overview: Finding the Index using DNS result 188 | 189 | Append the product part of the TEI to the URI found 190 | 191 | - TEI: `urn:tei:uuid:products.example.com:d4d9f54a-abcf-11ee-ac79-1a52914d44b1` 192 | - DNS record: `products.example.com` 193 | - URL: `https://products.example.com/.well-known/tea/d4d9f54a-abcf-11ee-ac79-1a52914d44b1/` 194 | - HTTP 302 redirect to "https://teapot02.consumer.example.com/tea/v2/product/d4d9f54a-abcf-11ee-ac79-1a52914d44b1' 195 | 196 | Always prefix with the https:// scheme. http (unencrypted) is not valid. 197 | 198 | - TEI: `urn:tei:uuid:products.example.com:d4d9f54a-abcf-11ee-ac79-1a52914d44b1` 199 | - URL: `https://products.example.com/.well-known/tea/d4d9f54a-abcf-11ee-ac79-1a52914d44b1/` 200 | 201 | **NOTE:** The `/.well-known/tea` names space needs to be registred. 202 | 203 | ## The TEA Version Index 204 | 205 | The resulting URL leads to the TEA version index, which is documented in another document. 206 | One redirect (302) is allowed in order to provide for aliasing, where a single product 207 | has many identifiers. The redirect should not lead to a separate web server. 208 | 209 | ## References 210 | 211 | - [IANA .well-known registry](https://www.iana.org/assignments/well-known-uris/well-known-uris.xhtml) 212 | - [IANA URI registry](https://www.iana.org/assignments/urn-namespaces/urn-namespaces.xhtml#urn-namespaces-1) 213 | -------------------------------------------------------------------------------- /doc/tea-requirements.md: -------------------------------------------------------------------------------- 1 | # TEA Requirements 2 | 3 | ## Repository discovery 4 | Based on an identifier a repository URL needs to be found. The identifier can be: 5 | 6 | - PURL 7 | - Product name or Product SKU and vendor name 8 | - EAN bar code 9 | - Product SKU 10 | - Vendor UUID 11 | - Hash of object 12 | 13 | At the base URL well known URLs (ref) needs to point to 14 | 15 | - A lifecycle status document (using OWASP Common Lifecycle Enumeration, CLE) 16 | - A version list. For each version, a URL will point to where a **collection** can be found 17 | - Vendor Discovery, returns a list of Vendors represented in the repository 18 | - Vendor Name 19 | - Vendor ID 20 | 21 | As an alternative, discovery using a company's ordinary web site should be supported. 22 | This can be handled using the file security.txt (IETF RFC 9116) 23 | 24 | ## Artifact Discovery based on TEA collections 25 | 26 | The API MUST provide a way to discover the artifacts that are available for retrieval or further query. 27 | Discovery SHOULD group artifacts together that represent a **collection** 28 | that are directly applicable to a given product with a given version. 29 | Collections are OPTIONAL. 30 | 31 | - SBOM - Software Bill of Material 32 | - CBOM - Cryptography Bill of Material 33 | - HBOM - Hardware Bill of Material 34 | - VDR - Vulnerability Disclosure Report 35 | - VEX - Vulnerability Exploitability eXchange 36 | - CDXA - Attestation 37 | 38 | Authn/Authz MUST be supported 39 | 40 | ## Collection Management 41 | 42 | The API SHOULD provide a method to manage collections, such as adding new collections, 43 | modifying collections, or deleting existing collections. 44 | 45 | - Authn/Authz MUST be supported 46 | 47 | ## Artifact Retrieval 48 | 49 | The API MUST provide a method in which to retrieve an artifact based on the identity of the artifact. 50 | For example, using CycloneDX BOM-Link to retrieve either the 51 | latest version or specific version of an artifact. 52 | 53 | ```text 54 | urn:cdx:serialNumber 55 | urn:cdx:serialNumber/version 56 | ``` 57 | 58 | The API needs to provide support for update checks, i.e. to check if a document is 59 | updated without downloading. (possibly etag or HEAD method or similar) 60 | Authn/Authz MUST be supported 61 | 62 | ## Artifact Publishing 63 | 64 | The API MUST provide a way to publish an artifact, either standalone or to a collection. 65 | The detection of duplicate artifacts with the same identity MUST be handled and prevented. 66 | Authn/Authz MUST be supported 67 | 68 | ## Artifact Versioning 69 | 70 | The system and API must support artifact versioning for formats that support 71 | versioning such as CycloneDX. For example: 72 | 73 | - The ability to retrieve the latest SBOM vs a previous (uncorrected) version of the same SBOM. 74 | Corrections to SBOMs is a supported use case in the NTIA framing document. 75 | - The ability to retrieve the latest VEX along with previous VEX for the same product so 76 | that time-series decisions are transparently available. 77 | 78 | Authn/Authz MUST be supported 79 | 80 | ## insights: Search Artifact Inventory 81 | 82 | The API MUST provide a way to search the inventory of a specific BOM or all available BOMs 83 | for a given component or service. The API SHOULD support multiple identity formats including 84 | PURL, CPE, SWID, GAV, GTIN, and GMN. 85 | 86 | For example: 87 | 88 | - Return the identity of all BOMs that have a vulnerable version of Apache Log4J: 89 | `pkg:maven/org.apache.logging.log4j/log4j-core@2.10.0` 90 | 91 | The API MUST provide a way to search for the metadata component across all available BOMs. 92 | The API SHOULD support multiple identity formats including PURL, CPE, SWID, GAV, GTIN, and GMN. 93 | For example: 94 | 95 | - Return the identity of all artifacts that describe `cpe:/a:acme:commerce_suite:1.0`. 96 | 97 | Authn/Authz MUST be supported 98 | -------------------------------------------------------------------------------- /doc/tea-usecases.md: -------------------------------------------------------------------------------- 1 | # TEA Use Cases 2 | 3 | An overview of use cases to consider for the Transparency Exchange API. The use cases 4 | are marked with a short code for reference. All use cases needs a story like "Alice has bought 5 | a..." 6 | 7 | The use cases are divided in two categories: 8 | 9 | * Use cases for __customers__ (end-users, manufacturers) to find a repository with 10 | Transparency Artefacts for a single unit purchased 11 | * Use cases where there are different __products__ 12 | * This applies after discovery where we need to handle various things a customer may 13 | buy as a single unit 14 | 15 | ## Customer focused use cases 16 | 17 | ### C1: Consumer: Automated discovery based on SBOM identifier 18 | 19 | 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, …) 20 | 21 | 22 | ### C2: Consumer: Automation based on product name/identifier 23 | 24 | As a consumer, I want to download artifacts for a product based on known data. 25 | A combination of manufacturer, product name, vendor product ID, EAN bar code or other unique identifier. 26 | After discovering the base repository URL I want to be able to find a specific 27 | product variant and version. 28 | 29 | 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. 30 | 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? 31 | 32 | ### C3: Consumer: Artifact retrieval 33 | 34 | 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. 35 | 36 | ### C4: Consumer: Summarized CLE 37 | 38 | As a consumer, I want the ability to get the current lifecycle values for a given product. 39 | 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. 40 | 41 | ### C5: Consumer: Insights 42 | 43 | As a consumer, I want the ability to simply ask the API questions rather than having to download, 44 | process, and analyze raw supply chain artifacts on my own systems. Common questions should be 45 | provided by the API by default along with the ability to query for more complex answers using 46 | the Common Expression Language (CEL). 47 | 48 | _NOTE_: Project Hyades (Dependency-Track v5) already implements CEL with the CycloneDX object model and has proven that this approach works for complex queries. 49 | 50 | ### D1: Developer/PM - Components for inclusion in products by other projects/developers 51 | 52 | A developer needs a component - software, library (open source and/or proprietary) to include 53 | in a product - publicly available (may be commercial) or in an internal system. 54 | Developer can be individual, company or public sector. 55 | They need insight into the library or component and be able to automatically keep upstream 56 | artefacts up to date. 57 | 58 | ### B1: Business consumer 59 | 60 | 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. 61 | How will their systems get continuous access to current and old documents - attestations, SBOM, VEX and other files? 62 | 63 | ### E1: Third party: Regulators 64 | 65 | Alice & Bob Enterprises AB has gotten a EUCC certification to get their Whola Firewall certified 66 | for CRA-compatible CE labeling. In order to maintain the certification the certifying body needs 67 | access to SBOM and VEX updates from A&BE in an automated way. 68 | 69 | ### E2: External potential customer - insights before purchase 70 | 71 | 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. 72 | 73 | ### E3: Hacker or competition 74 | 75 | There are non-customers and not-to-be-customers that wants to get insight into how a product is 76 | composed by getting the transparency docs. 77 | 78 | ### E4: Open Source user 79 | 80 | Palme Inc considers using the asterisk.org open source telephony PBX. 81 | They need to make an assessment before starting tests and possible production use. 82 | The can either use the Debian package, the Alpine Linux Package or build a binary themselves from source code. 83 | How can they find the transparency exchange data sets? 84 | 85 | 86 | ### O1: Open Source project 87 | 88 | The hatturl open source project publish a library and a server side software on Github. This is 89 | later packaged as packages in many Linux distributions. 90 | 91 | How does the project publish artefacts? What are the requirements? 92 | 93 | ## Product focused use cases 94 | 95 | ### P1: A standalone app 96 | 97 | Customer buys a standalone application that is delivered as a binary 98 | 99 | ### P2: A OCI container 100 | 101 | Customer gets a container with many third party components and a binary 102 | software developed by the manufacturer 103 | 104 | ### P3: Embedded system 105 | 106 | ### P4: Package with many devices 107 | 108 | ### P5: An Open Source software library 109 | -------------------------------------------------------------------------------- /images/Project-Koala.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /images/tealogo-big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CycloneDX/transparency-exchange-api/b3d81f6486e75c84b78e35e46e80e4a4db277e02/images/tealogo-big.png -------------------------------------------------------------------------------- /images/tealogo-on-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CycloneDX/transparency-exchange-api/b3d81f6486e75c84b78e35e46e80e4a4db277e02/images/tealogo-on-black.png -------------------------------------------------------------------------------- /images/tealogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CycloneDX/transparency-exchange-api/b3d81f6486e75c84b78e35e46e80e4a4db277e02/images/tealogo.png -------------------------------------------------------------------------------- /out/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CycloneDX/transparency-exchange-api/b3d81f6486e75c84b78e35e46e80e4a4db277e02/out/.gitkeep -------------------------------------------------------------------------------- /presentations/koalacon2024/00-welcome.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CycloneDX/transparency-exchange-api/b3d81f6486e75c84b78e35e46e80e4a4db277e02/presentations/koalacon2024/00-welcome.pdf -------------------------------------------------------------------------------- /presentations/koalacon2024/01-introduction-overview.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CycloneDX/transparency-exchange-api/b3d81f6486e75c84b78e35e46e80e4a4db277e02/presentations/koalacon2024/01-introduction-overview.pdf -------------------------------------------------------------------------------- /presentations/koalacon2024/02-tea-data-model.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CycloneDX/transparency-exchange-api/b3d81f6486e75c84b78e35e46e80e4a4db277e02/presentations/koalacon2024/02-tea-data-model.pdf -------------------------------------------------------------------------------- /presentations/koalacon2024/03-dependency-track.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CycloneDX/transparency-exchange-api/b3d81f6486e75c84b78e35e46e80e4a4db277e02/presentations/koalacon2024/03-dependency-track.pdf -------------------------------------------------------------------------------- /presentations/koalacon2024/04-tea-sbomify.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CycloneDX/transparency-exchange-api/b3d81f6486e75c84b78e35e46e80e4a4db277e02/presentations/koalacon2024/04-tea-sbomify.pdf -------------------------------------------------------------------------------- /presentations/koalacon2024/05-tea-and-java.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CycloneDX/transparency-exchange-api/b3d81f6486e75c84b78e35e46e80e4a4db277e02/presentations/koalacon2024/05-tea-and-java.pdf -------------------------------------------------------------------------------- /presentations/oej/koala-beta-one-cisa-sbom-community.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CycloneDX/transparency-exchange-api/b3d81f6486e75c84b78e35e46e80e4a4db277e02/presentations/oej/koala-beta-one-cisa-sbom-community.pdf -------------------------------------------------------------------------------- /presentations/oej/koala-tea-intro-normal-format.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CycloneDX/transparency-exchange-api/b3d81f6486e75c84b78e35e46e80e4a4db277e02/presentations/oej/koala-tea-intro-normal-format.pdf -------------------------------------------------------------------------------- /presentations/oej/koala-tea-intro-sbomarama.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CycloneDX/transparency-exchange-api/b3d81f6486e75c84b78e35e46e80e4a4db277e02/presentations/oej/koala-tea-intro-sbomarama.pdf -------------------------------------------------------------------------------- /presentations/oej/koala-transparency-exchange.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CycloneDX/transparency-exchange-api/b3d81f6486e75c84b78e35e46e80e4a4db277e02/presentations/oej/koala-transparency-exchange.pdf -------------------------------------------------------------------------------- /presentations/oej/tea-collection.key.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CycloneDX/transparency-exchange-api/b3d81f6486e75c84b78e35e46e80e4a4db277e02/presentations/oej/tea-collection.key.pdf -------------------------------------------------------------------------------- /presentations/oej/tea-publish.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CycloneDX/transparency-exchange-api/b3d81f6486e75c84b78e35e46e80e4a4db277e02/presentations/oej/tea-publish.pdf -------------------------------------------------------------------------------- /presentations/steve.springett/Ecma TC54 + CycloneDX Brief (June 2024).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CycloneDX/transparency-exchange-api/b3d81f6486e75c84b78e35e46e80e4a4db277e02/presentations/steve.springett/Ecma TC54 + CycloneDX Brief (June 2024).pdf -------------------------------------------------------------------------------- /presentations/steve.springett/Transparency Exchange API Kickoff.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CycloneDX/transparency-exchange-api/b3d81f6486e75c84b78e35e46e80e4a4db277e02/presentations/steve.springett/Transparency Exchange API Kickoff.pdf -------------------------------------------------------------------------------- /signatures/signature.md: -------------------------------------------------------------------------------- 1 | # Transparency Exchange API - Trusting digital signatures in TEA 2 | 3 | Software transparency requires a trust platform so that users 4 | can validate the information and artefacts published. Given 5 | the situation today any information published is better than 6 | none, so the framework for digital signatures will not 7 | be mandatory for API compliance. Implementations may 8 | require all published information to be signed and 9 | validated. In some vertical markets branch standards may require 10 | digital signatures. 11 | 12 | Within the TEA API documents may be signed with an electronic 13 | signature. CycloneDX Documents support [signatures](https://cyclonedx.org/use-cases/#authenticity) within 14 | the JSON and XML files, but other artefacts may need external 15 | signature files, a detached signature. 16 | 17 | ## Requirements 18 | 19 | Digital signatures provide integrity and identity to published data. 20 | 21 | - __Integrity__: Documents dowloaded must be the same 22 | as documents published 23 | - __Identity__: Customers need to be able to verify the 24 | publisher of the documents and verify that it is 25 | the expected publisher. 26 | A TEA server may want to verify that published 27 | documents are signed by the expected publisher 28 | and that signatures are valid. 29 | 30 | In order to sign an object, a pair of asymmetric keys will be 31 | needed. The public key is used to create a certificate, signed 32 | by a certificate authority (CA). The private key is used for 33 | signing and needs to be protected. 34 | 35 | A software publisher may buy CA services from a commercial vendor 36 | or set up an internal PKI solution. The issue with internal PKIs is that 37 | external parties do not automatically trust that internal PKI. 38 | 39 | This document outlines a proposal on how to build that trust and 40 | make it possible for publishers to use an internal PKI. It is 41 | of course important that this PKI is maintained according to 42 | best current practise. 43 | 44 | ## API trust 45 | 46 | The TEA API is built on the HTTP protocol with TLS encryption 47 | and authentication, using the `https://` URL scheme. 48 | 49 | The TLS server certificate is normally issued by a public Certificate 50 | Authority that is part of the Web PKI. The client needs to validate 51 | the TLS server certificate to make sure 52 | 53 | - that the certificate name (CN or Subject Alt Name) matches the 54 | host part of the URI. 55 | - that the certificate is valid, i.e. the not-before date and the 56 | not-after date is not out of range 57 | - that the certificate is signed by a trusted CA 58 | 59 | If the certificate validates properly, the API can be trusted. 60 | Validation proves that the server is the right server for the 61 | given host name in the URL. 62 | 63 | This trust can be used to implement trust in a private PKI 64 | used to sign documents delivered over the API. 65 | 66 | In addition, trust anchors can be 67 | published in DNSsec as an extra level of validation. 68 | 69 | ## Getting trust anchors 70 | 71 | Much like the EST protocol, the TEA protocol can be used 72 | to download trust anchors for a private PKI. These are 73 | PEM-encoded certificates in one single text file. 74 | 75 | The TEA API has a `/trust-anchors/` API that will download 76 | the current trust anchor APIs. This file is not signed, 77 | that would cause a chicken-and-egg problem. The certificates 78 | in the file are all signed. 79 | 80 | An implementation should download these and apply them only 81 | for this service, not in global scope. A PKI valid for example.com 82 | is not valid for example.net. 83 | 84 | Note that the TEA api can host many years of documents for 85 | published versions. Old and expired trust anchors may be needed 86 | to validate digital signatures on old documents. 87 | 88 | ## Validating the trust anchors using DNSsec (DANE) 89 | 90 | ## Digital signatures 91 | 92 | ### Digital signatures as specified for CycloneDX 93 | 94 | > "Digital signatures may be applied to a BOM or to an assembly within a BOM. 95 | > CycloneDX supports XML Signature, JSON Web Signature (JWS), and JSON Signature Format (JSF). 96 | > Signed BOMs benefit by providing advanced integrity and non-repudiation capabilities." 97 | 98 | 99 | ### External (detached) digital signatures for other documents 100 | 101 | - indication of hash algorithm 102 | - indicator of cert used 103 | - intermediate cert and sign cert 104 | 105 | ### Validating the digital signature 106 | 107 | ## Using Sigstore for signing 108 | 109 | Sigstore is an excellent free service for both signing of GIT commits as well 110 | as artefacts by using ephemeral certificates (very shortlived) and a 111 | certificate transparency log for validation and verification. 112 | Sigstore signatures contain timestamps from a timestamping service. 113 | 114 | Sigstore lends itself very well to Open Source projects but not really 115 | commercial projects. The Sigstore platform can be deployed internally 116 | for enterprise use, but in that case will have the same problem as any 117 | internal PKI with establishing trust. 118 | 119 | ## Suggested PKI setup 120 | 121 | ### Root cert 122 | 123 | #### Root cert validity and renewal 124 | 125 | ### Intermediate cert 126 | 127 | #### Intermediate cert validity and renewal 128 | 129 | ### Signature 130 | 131 | #### Time stamp services 132 | 133 | ### DNS entry 134 | 135 | ## References 136 | 137 | - IETF RFC DANE 138 | - IETF DANCE architecture (IETF draft) 139 | - IETF Digital signature 140 | - JSON web signatures (JWS) - 141 | - JSON signature format (JSF) - 142 | - [IETF Enrollment over Secure Transport (EST) RFC 7030](https://www.rfc-editor.org/rfc/rfc7030) 143 | -------------------------------------------------------------------------------- /spec/README.md: -------------------------------------------------------------------------------- 1 | # TEA OpenAPI Spec 2 | 3 | The OpenAPI 3.1 specification for the Transparency Exchange API is available in [openapi.yaml](./openapi.yaml). 4 | 5 | - [Generating API Clients from OpenAPI Spec](#generating-api-clients-from-openapi-spec) 6 | 7 | ## Generating API Clients from OpenAPI Spec 8 | 9 | We use the OpenAPI Generator with configuration per language/framework in the `generators` folder. An example is: 10 | 11 | ```bash 12 | docker run \ 13 | --rm \ 14 | -v "$(PWD):/local" \ 15 | openapitools/openapi-generator-cli \ 16 | batch --clean /local/spec/generators/typescript.yaml 17 | ``` 18 | 19 | ## Preview Specs 20 | 21 | Fire up the `swagger-ui` with Docker from the root of the repository: 22 | 23 | ```bash 24 | docker run \ 25 | -p 8080:8080 \ 26 | -e SWAGGER_JSON=/koala/spec/openapi.yaml \ 27 | -v $(pwd):/koala swaggerapi/swagger-ui 28 | ``` 29 | 30 | And browse to [http://localhost:8080](http://localhost:8080). 31 | -------------------------------------------------------------------------------- /spec/generators/common.yaml: -------------------------------------------------------------------------------- 1 | inputSpec: /local/spec/openapi.yaml 2 | gitUserId: CycloneDX 3 | gitRepoId: transparency-exchange-api 4 | 5 | globalProperties: 6 | skipFormModel: false -------------------------------------------------------------------------------- /spec/generators/go.yaml: -------------------------------------------------------------------------------- 1 | '!include': 'common.yaml' 2 | outputDir: /local/out/go 3 | generatorName: go 4 | gitRepoId: transparency-exchange-api-go 5 | additionalProperties: 6 | goImportAlias: tea_client 7 | packageName: tea_client -------------------------------------------------------------------------------- /spec/generators/java-webclient.yaml: -------------------------------------------------------------------------------- 1 | '!include': 'common.yaml' 2 | outputDir: /local/out/java-webclient 3 | generatorName: java 4 | additionalProperties: 5 | library: webclient 6 | artifactDescription: Transparency Exchange API Java Webclient 7 | artifactId: tea-api-webclient 8 | artifactUrl: https://github.com/CycloneDX/transparency-exchange-api 9 | invokerPackage: org.cyclonedx.tea.webclient 10 | apiPackage: org.cyclonedx.tea.webclient.api 11 | modelPackage: org.cyclonedx.tea.webclient.model 12 | developerEmail: community@sonatype.com 13 | developerName: OWASP Foundation 14 | developerOrganization: OWASP Foundation 15 | developerOrganizationUrl: https://cyclonedx.org/ 16 | groupId: org.cyclonedx.tea 17 | licenseName: Apache-2.0 18 | licenseUrl: https://github.com/CycloneDX/transparency-exchange-api/blob/main/LICENSE 19 | scmConnection: scm:git:git@github.com:CycloneDX/transparency-exchange-api.git 20 | scmDeveloperConnection: scm:git:git@github.com:CycloneDX/transparency-exchange-api.git 21 | scmUrl: https://github.com/CycloneDX/transparency-exchange-api 22 | useJakartaEe: true 23 | asyncNative: true 24 | generateBuilders: true 25 | parentGroupId: org.sonatype.buildsupport 26 | parentArtifactId: public-parent 27 | parentVersion: 50 -------------------------------------------------------------------------------- /spec/generators/python.yaml: -------------------------------------------------------------------------------- 1 | '!include': 'common.yaml' 2 | outputDir: /local/out/python 3 | generatorName: python 4 | additionalProperties: 5 | library: urllib3 6 | licenseInfo: "Apache-2.0" 7 | packageName: "tea_api_client" 8 | projectName: "Transparency Exchange API (TEA)" -------------------------------------------------------------------------------- /spec/generators/typescript.yaml: -------------------------------------------------------------------------------- 1 | '!include': 'common.yaml' 2 | outputDir: /local/out/typescript 3 | generatorName: typescript-fetch 4 | additionalProperties: 5 | npmName: "@cyclonedx/tea-api-client" 6 | supportsES6: true 7 | withInterfaces: true -------------------------------------------------------------------------------- /spec/generators/update-pom.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Check if the file path is provided 4 | if [ -z "$1" ]; then 5 | echo "Usage: $0 " 6 | exit 1 7 | fi 8 | 9 | # File path 10 | FILE=$1 11 | 12 | # Use sed to remove the tag and its content 13 | sed -i.bak '//,/<\/build>/d' "$FILE" 14 | 15 | echo "The tag has been removed from $FILE. A backup has been saved as $FILE.bak." -------------------------------------------------------------------------------- /spec/openapi.yaml: -------------------------------------------------------------------------------- 1 | # $schema: https://spec.openapis.org/oas/3.1/schema-base/2025-02-13 2 | openapi: 3.1.1 3 | jsonSchemaDialect: https://spec.openapis.org/oas/3.1/dialect/base 4 | info: 5 | title: Transparency Exchange API 6 | summary: The OWASP Transparency Exchange API specification for consumers and publishers 7 | description: TBC 8 | contact: 9 | name: TEA Working Group 10 | email: tbc@somewhere.tld 11 | url: https://github.com/CycloneDX/transparency-exchange-api 12 | license: 13 | name: Apache 2.0 14 | url: https://github.com/CycloneDX/transparency-exchange-api/blob/main/LICENSE 15 | version: 0.1.0-beta.1 16 | servers: 17 | - url: http://localhost/tea/v1 18 | description: Local development 19 | paths: 20 | /product/{uuid}: 21 | get: 22 | description: Returns the corresponding TEA components for a given TEA product UUID. 23 | operationId: getTeaProductByUuid 24 | parameters: 25 | - name: uuid 26 | in: path 27 | required: true 28 | description: UUID of the TEA product in the TEA server 29 | schema: 30 | type: string 31 | format: uuid 32 | responses: 33 | '200': 34 | description: Requested TEA Product found and returned 35 | content: 36 | application/json: 37 | schema: 38 | $ref: "#/components/schemas/product" 39 | '400': 40 | $ref: "#/components/responses/400-invalid-request" 41 | '404': 42 | $ref: "#/components/responses/404-object-by-id-not-found" 43 | tags: 44 | - TEA Product 45 | /products: 46 | get: 47 | description: Returns a list of TEA products. Note that multiple products may 48 | match. 49 | operationId: getTeaProductByIdentifier 50 | parameters: 51 | - $ref: "#/components/parameters/page-offset" 52 | - $ref: "#/components/parameters/page-size" 53 | - $ref: "#/components/parameters/id-type" 54 | - $ref: "#/components/parameters/id-value" 55 | responses: 56 | '200': 57 | $ref: "#/components/responses/paginated-product" 58 | '400': 59 | $ref: "#/components/responses/400-invalid-request" 60 | tags: 61 | - TEA Product 62 | /component/{uuid}: 63 | get: 64 | description: Get a TEA Component 65 | operationId: getTeaComponentById 66 | parameters: 67 | - name: uuid 68 | in: path 69 | required: true 70 | description: UUID of TEA Component in the TEA server 71 | schema: 72 | type: string 73 | format: uuid 74 | responses: 75 | '200': 76 | description: Requested TEA Component found and returned 77 | content: 78 | application/json: 79 | schema: 80 | "$ref": "#/components/schemas/component" 81 | '400': 82 | $ref: "#/components/responses/400-invalid-request" 83 | '404': 84 | $ref: "#/components/responses/404-object-by-id-not-found" 85 | tags: 86 | - TEA Component 87 | /component/{uuid}/releases: 88 | get: 89 | description: Get releases of the component 90 | operationId: getReleasesByComponentId 91 | parameters: 92 | - name: uuid 93 | in: path 94 | required: true 95 | description: UUID of TEA Component in the TEA server 96 | schema: 97 | type: string 98 | format: uuid 99 | responses: 100 | '200': 101 | description: Requested Releases of TEA Component found and returned 102 | content: 103 | application/json: 104 | schema: 105 | type: array 106 | items: 107 | "$ref": "#/components/schemas/release" 108 | '400': 109 | $ref: "#/components/responses/400-invalid-request" 110 | '404': 111 | $ref: "#/components/responses/404-object-by-id-not-found" 112 | tags: 113 | - TEA Component 114 | /release/{uuid}/collection/latest: 115 | get: 116 | description: Get the latest TEA Collection belonging to the TEA Release 117 | operationId: getLatestCollection 118 | parameters: 119 | - name: uuid 120 | in: path 121 | required: true 122 | description: UUID of TEA Release in the TEA server 123 | schema: 124 | type: string 125 | format: uuid 126 | responses: 127 | '200': 128 | description: Requested TEA Collection found and returned 129 | content: 130 | application/json: 131 | schema: 132 | "$ref": "#/components/schemas/collection" 133 | '400': 134 | $ref: "#/components/responses/400-invalid-request" 135 | '404': 136 | $ref: "#/components/responses/404-object-by-id-not-found" 137 | tags: 138 | - TEA Release 139 | /release/{uuid}/collections: 140 | get: 141 | description: Get the TEA Collections belonging to the TEA Release 142 | operationId: getCollectionsByReleaseId 143 | parameters: 144 | - name: uuid 145 | in: path 146 | required: true 147 | description: UUID of TEA Release in the TEA server 148 | schema: 149 | type: string 150 | format: uuid 151 | responses: 152 | '200': 153 | description: Requested TEA Collection found and returned 154 | content: 155 | application/json: 156 | schema: 157 | type: array 158 | items: 159 | "$ref": "#/components/schemas/collection" 160 | '400': 161 | $ref: "#/components/responses/400-invalid-request" 162 | '404': 163 | $ref: "#/components/responses/404-object-by-id-not-found" 164 | tags: 165 | - TEA Release 166 | /release/{uuid}/collection/{collectionVersion}: 167 | get: 168 | description: Get a specific Collection (by version) for a TEA Release by its UUID 169 | operationId: getCollection 170 | parameters: 171 | - name: uuid 172 | in: path 173 | required: true 174 | description: UUID of TEA Collection in the TEA server 175 | schema: 176 | "$ref": "#/components/schemas/uuid" 177 | - name: collectionVersion 178 | in: path 179 | required: true 180 | description: Version of TEA Collection 181 | schema: 182 | type: integer 183 | responses: 184 | '200': 185 | description: Requested TEA Collection Version found and returned 186 | content: 187 | application/json: 188 | schema: 189 | "$ref": "#/components/schemas/collection" 190 | '400': 191 | $ref: "#/components/responses/400-invalid-request" 192 | '404': 193 | $ref: "#/components/responses/404-object-by-id-not-found" 194 | tags: 195 | - TEA Release 196 | /artifact/{uuid}: 197 | get: 198 | description: Get metadata for specific TEA artifact 199 | operationId: getArtifact 200 | parameters: 201 | - name: uuid 202 | in: path 203 | required: true 204 | description: UUID of TEA Artifact in the TEA server 205 | schema: 206 | "$ref": "#/components/schemas/uuid" 207 | responses: 208 | '200': 209 | description: Requested TEA Artifact metadata found and returned 210 | content: 211 | application/json: 212 | schema: 213 | "$ref": "#/components/schemas/artifact" 214 | '400': 215 | $ref: "#/components/responses/400-invalid-request" 216 | '404': 217 | $ref: "#/components/responses/404-object-by-id-not-found" 218 | tags: 219 | - TEA Artifact 220 | components: 221 | schemas: 222 | # 223 | # Definitions reused in multiple domain objects 224 | # 225 | date-time: 226 | type: string 227 | description: Timestamp 228 | format: date-time 229 | pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$" 230 | example: '2024-03-20T15:30:00Z' 231 | identifier: 232 | type: object 233 | description: An identifier with a specified type 234 | properties: 235 | idType: 236 | description: Type of identifier, e.g. `TEI`, `PURL`, `CPE` 237 | "$ref": "#/components/schemas/identifier-type" 238 | idValue: 239 | description: Identifier value 240 | type: string 241 | identifier-type: 242 | type: string 243 | description: Enumeration of identifiers types 244 | enum: 245 | - CPE 246 | - TEI 247 | - PURL 248 | uuid: 249 | type: string 250 | description: A UUID 251 | format: uuid 252 | pattern: "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$" 253 | 254 | # 255 | # TEA Product 256 | # 257 | product: 258 | type: object 259 | description: A TEA product 260 | properties: 261 | uuid: 262 | description: A unique identifier for the TEA product 263 | "$ref": "#/components/schemas/uuid" 264 | name: 265 | type: string 266 | description: Product name 267 | identifiers: 268 | type: array 269 | description: List of identifiers for the product 270 | items: 271 | "$ref": "#/components/schemas/identifier" 272 | components: 273 | type: array 274 | description: List of TEA components for the product 275 | items: 276 | description: Unique identifier of the TEA component 277 | "$ref": "#/components/schemas/uuid" 278 | required: 279 | - uuid 280 | - name 281 | - identifiers 282 | - components 283 | examples: 284 | - uuid: 09e8c73b-ac45-4475-acac-33e6a7314e6d 285 | name: Apache Log4j 2 286 | identifiers: 287 | - idType: CPE 288 | idValue: cpe:2.3:a:apache:log4j 289 | - idType: PURL 290 | idValue: pkg:maven/org.apache.logging.log4j/log4j-api 291 | - idType: PURL 292 | idValue: pkg:maven/org.apache.logging.log4j/log4j-core 293 | - idType: PURL 294 | idValue: pkg:maven/org.apache.logging.log4j/log4j-layout-template-json 295 | components: 296 | - 3910e0fd-aff4-48d6-b75f-8bf6b84687f0 297 | - b844c9bd-55d6-478c-af59-954a932b6ad3 298 | - d6d3f754-d4f4-4672-b096-b994b064ca2d 299 | 300 | # 301 | # TEA Component and related objects 302 | # 303 | component: 304 | type: object 305 | description: A TEA component 306 | properties: 307 | uuid: 308 | description: A unique identifier for the TEA component 309 | "$ref": "#/components/schemas/uuid" 310 | name: 311 | type: string 312 | description: Component name 313 | identifiers: 314 | type: array 315 | description: List of identifiers for the component 316 | items: 317 | "$ref": "#/components/schemas/identifier" 318 | required: 319 | - uuid 320 | - name 321 | - identifiers 322 | - versions 323 | examples: 324 | - uuid: 3910e0fd-aff4-48d6-b75f-8bf6b84687f0 325 | name: Apache Log4j API 326 | identifiers: 327 | - idType: PURL 328 | idValue: pkg:maven/org.apache.logging.log4j/log4j-api 329 | - uuid: b844c9bd-55d6-478c-af59-954a932b6ad3 330 | name: Apache Log4j Core 331 | identifiers: 332 | - idType: CPE 333 | idValue: cpe:2.3:a:apache:log4j 334 | - idType: PURL 335 | idValue: pkg:maven/org.apache.logging.log4j/log4j-core 336 | 337 | # 338 | # TEA Release and related objects 339 | # 340 | release: 341 | type: object 342 | properties: 343 | uuid: 344 | description: A unique identifier for the TEA Component Release 345 | "$ref": "#/components/schemas/uuid" 346 | version: 347 | description: Version number 348 | type: string 349 | example: 1.2.3 350 | createdDate: 351 | description: Timestamp when this Release was created in TEA (for sorting purposes) 352 | "$ref": "#/components/schemas/date-time" 353 | releaseDate: 354 | description: Timestamp of the release 355 | "$ref": "#/components/schemas/date-time" 356 | preRelease: 357 | type: boolean 358 | description: | 359 | A flag indicating pre-release (or beta) status. 360 | May be disabled after the creation of the release object, but can't be enabled after creation of an object. 361 | identifiers: 362 | type: array 363 | description: List of identifiers for the component 364 | items: 365 | "$ref": "#/components/schemas/identifier" 366 | # add lifecycle here 367 | required: 368 | - uuid 369 | - version 370 | - createdDate 371 | examples: 372 | # Apache Tomcat 11.0.6 373 | - uuid: 605d0ecb-1057-40e4-9abf-c400b10f0345 374 | version: "11.0.6" 375 | createdDate: 2025-04-01T15:43:00Z 376 | releaseDate: 2025-04-01T15:43:00Z 377 | identifiers: 378 | - idType: PURL 379 | idValue: pkg:maven/org.apache.tomcat/tomcat@11.0.6 380 | # Different release of Apache Tomcat 381 | - uuid: da89e38e-95e7-44ca-aa7d-f3b6b34c7fab 382 | version: "10.1.40" 383 | createdDate: 2025-04-01T18:20:00Z 384 | releaseDate: 2025-04-01T18:20:00Z 385 | identifiers: 386 | - idType: PURL 387 | idValue: pkg:maven/org.apache.tomcat/tomcat@10.1.40 388 | # A pre-release of Apache Tomcat 389 | - uuid: 95f481df-f760-47f4-b2f2-f8b76d858450 390 | version: "11.0.0-M26" 391 | createdDate: 2024-09-13T17:49:00Z 392 | preRelease: true 393 | identifiers: 394 | - idType: PURL 395 | idValue: pkg:maven/org.apache.tomcat/tomcat@11.0.0-M26 396 | 397 | # 398 | # TEA Collection and related objects 399 | # 400 | collection: 401 | type: object 402 | description: A collection of security-related documents 403 | properties: 404 | uuid: 405 | description: | 406 | UUID of the TEA Collection object. 407 | Note that this is equal to the UUID of the associated TEA Component Release object. 408 | When updating a collection, only the `version` is changed. 409 | "$ref": "#/components/schemas/uuid" 410 | version: 411 | type: integer 412 | description: | 413 | TEA Collection version, incremented each time its content changes. 414 | Versions start with 1. 415 | date: 416 | description: The date when the TEA Collection version was created. 417 | "$ref": "#/components/schemas/date-time" 418 | updateReason: 419 | description: Reason for the update/release of the TEA Collection object. 420 | "$ref": "#/components/schemas/collection-update-reason" 421 | artifacts: 422 | type: array 423 | description: List of TEA artifact objects. 424 | items: 425 | "$ref": "#/components/schemas/artifact" 426 | examples: 427 | # Documents in the latest release of Log4j Core 428 | - uuid: 4c72fe22-9d83-4c2f-8eba-d6db484f32c8 429 | version: 3 430 | date: 2024-12-13T00:00:00Z 431 | updateReason: 432 | type: ARTIFACT_UPDATED 433 | comment: VDR file updated 434 | artifacts: 435 | - uuid: 1cb47b95-8bf8-3bad-a5a4-0d54d86e10ce 436 | name: Build SBOM 437 | type: BOM 438 | formats: 439 | - mime_type: application/vnd.cyclonedx+xml 440 | description: CycloneDX SBOM (XML) 441 | url: https://repo.maven.apache.org/maven2/org/apache/logging/log4j/log4j-core/2.24.3/log4j-core-2.24.3-cyclonedx.xml 442 | signature_url: https://repo.maven.apache.org/maven2/org/apache/logging/log4j/log4j-core/2.24.3/log4j-core-2.24.3-cyclonedx.xml.asc 443 | checksums: 444 | - algType: MD5 445 | algValue: 2e1a525afc81b0a8ecff114b8b743de9 446 | - algType: SHA-1 447 | algValue: 5a7d4caef63c5c5ccdf07c39337323529eb5a770 448 | - uuid: dfa35519-9734-4259-bba1-3e825cf4be06 449 | name: Vulnerability Disclosure Report 450 | type: vulnerability-assertion 451 | formats: 452 | - mime_type: application/vnd.cyclonedx+xml 453 | description: CycloneDX VDR (XML) 454 | url: https://logging.apache.org/cyclonedx/vdr.xml 455 | checksums: 456 | - algType: SHA-256 457 | algValue: 75b81020b3917cb682b1a7605ade431e062f7a4c01a412f0b87543b6e995ad2a 458 | 459 | collection-update-reason: 460 | type: object 461 | description: Reason for the update to the TEA collection 462 | properties: 463 | type: 464 | description: Type of update reason. 465 | "$ref": "#/components/schemas/collection-update-reason-type" 466 | comment: 467 | type: string 468 | description: Free text description 469 | collection-update-reason-type: 470 | type: string 471 | description: Type of TEA collection update 472 | enum: 473 | - INITIAL_RELEASE 474 | - VEX_UPDATED 475 | - ARTIFACT_UPDATED 476 | - ARTIFACT_ADDED 477 | - ARTIFACT_REMOVED 478 | 479 | # 480 | # TEA Artifact and related objects 481 | # 482 | artifact: 483 | type: object 484 | description: A security-related document 485 | properties: 486 | uuid: 487 | description: UUID of the TEA Artifact object. 488 | "$ref": "#/components/schemas/uuid" 489 | name: 490 | type: string 491 | description: Artifact name 492 | type: 493 | description: Type of artifact 494 | "$ref": "#/components/schemas/artifact-type" 495 | formats: 496 | type: array 497 | description: | 498 | List of objects with the same content, but in different formats. 499 | The order of the list has no significance. 500 | items: 501 | "$ref": "#/components/schemas/artifact-format" 502 | artifact-type: 503 | type: string 504 | description: Specifies the type of external reference. 505 | enum: 506 | - ATTESTATION 507 | - BOM 508 | - BUILD_META 509 | - CERTIFICATION 510 | - FORMULATION 511 | - LICENSE 512 | - RELEASE_NOTES 513 | - SECURITY_TXT 514 | - THREAT_MODEL 515 | - VULNERABILITIES 516 | - OTHER 517 | artifact-format: 518 | type: object 519 | description: A security-related document in a specific format 520 | properties: 521 | mime_type: 522 | type: string 523 | description: The MIME type of the document 524 | description: 525 | type: string 526 | description: A free text describing the artifact 527 | url: 528 | type: string 529 | description: Direct download URL for the artifact 530 | format: url 531 | signatureUrl: 532 | type: string 533 | description: Direct download URL for an external signature of the artifact 534 | format: url 535 | checksums: 536 | type: array 537 | description: List of checksums for the artifact 538 | items: 539 | "$ref": "#/components/schemas/artifact-checksum" 540 | artifact-checksum: 541 | type: object 542 | properties: 543 | algType: 544 | description: Checksum algorithm 545 | "$ref": "#/components/schemas/artifact-checksum-type" 546 | algValue: 547 | type: string 548 | description: Checksum value 549 | artifact-checksum-type: 550 | type: string 551 | description: Checksum algorithm 552 | enum: 553 | - MD5 554 | - SHA-1 555 | - SHA-256 556 | - SHA-384 557 | - SHA-512 558 | - SHA3-256 559 | - SHA3-384 560 | - SHA3-512 561 | - BLAKE2b-256 562 | - BLAKE2b-384 563 | - BLAKE2b-512 564 | - BLAKE3 565 | # 566 | # Types used in API responses 567 | # 568 | pagination-details: 569 | type: object 570 | properties: 571 | timestamp: 572 | type: string 573 | format: date-time 574 | example: '2024-03-20T15:30:00Z' 575 | pageStartIndex: 576 | type: integer 577 | format: int64 578 | default: 0 579 | pageSize: 580 | type: integer 581 | format: int64 582 | default: 100 583 | totalResults: 584 | type: integer 585 | format: int64 586 | required: 587 | - timestamp 588 | - pageStartIndex 589 | - pageSize 590 | - totalResults 591 | responses: 592 | 204-common-delete: 593 | description: Object deleted successfully 594 | content: 595 | application/json: {} 596 | 400-invalid-request: 597 | description: Request was Invalid 598 | content: 599 | application/json: {} 600 | 401-unauthorized: 601 | description: Authentication required 602 | content: 603 | application/json: {} 604 | 404-object-by-id-not-found: 605 | description: Object requested by identifier not found 606 | content: 607 | application/json: {} 608 | paginated-product: 609 | description: A paginated response containing TEA Products 610 | content: 611 | application/json: 612 | schema: 613 | allOf: 614 | - $ref: "#/components/schemas/pagination-details" 615 | - type: object 616 | properties: 617 | results: 618 | type: array 619 | items: 620 | "$ref": "#/components/schemas/product" 621 | parameters: 622 | # Pagination 623 | page-offset: 624 | name: pageOffset 625 | description: Pagination offset 626 | in: query 627 | required: false 628 | schema: 629 | type: integer 630 | format: int64 631 | default: 0 632 | page-size: 633 | name: pageSize 634 | description: Pagination offset 635 | in: query 636 | required: false 637 | schema: 638 | type: integer 639 | format: int64 640 | default: 100 641 | # 642 | # Query by identifier 643 | # 644 | # Since OpenAPI 3.0 it is possible to use RFC 6570-based serialization for JSON parameters of type array or object: 645 | # https://swagger.io/docs/specification/v3_0/serialization/ 646 | # 647 | # Unfortunately many tools don't support it, for example, 648 | # the `openapi-generator` for Java does not handle this correctly. 649 | # https://github.com/OpenAPITools/openapi-generator/issues/4808 650 | # 651 | # This can be uncommented, when RFC 6570-base serialization reaches a wider adoption: 652 | # 653 | # identifier-param: 654 | # name: identifierParam 655 | # description: If present, only the objects with the given identifier will be returned. 656 | # in: query 657 | # schema: 658 | # $ref: "#/components/schemas/identifier" 659 | # style: form 660 | # explode: true 661 | # 662 | # In the meantime we explode the object manually: 663 | id-type: 664 | # To allow RFC 6570 in the future without breaking changes to the HTTP API, 665 | # the name of this parameter should be identical to the equivalent property in /components/schemas/identifier 666 | name: idType 667 | description: Type of identifier specified in the `idValue` parameter 668 | in: query 669 | schema: 670 | $ref: "#/components/schemas/identifier-type" 671 | id-value: 672 | # To allow RFC 6570 in the future without breaking changes to the HTTP API, 673 | # the name of this parameter should be identical to the equivalent property in /components/schemas/identifier 674 | name: idValue 675 | description: If present, only the objects with the given identifier value will be returned. 676 | in: query 677 | schema: 678 | type: string 679 | 680 | securitySchemes: 681 | bearerAuth: 682 | type: http 683 | scheme: bearer 684 | basicAuth: 685 | type: http 686 | scheme: basic 687 | security: 688 | - bearerAuth: [] 689 | - basicAuth: [] 690 | tags: 691 | - name: TEA Product 692 | - name: TEA Component 693 | - name: TEA Release 694 | - name: TEA Artifact 695 | externalDocs: 696 | description: Transparency Exchange API specification 697 | url: https://github.com/CycloneDX/transparency-exchange-api 698 | -------------------------------------------------------------------------------- /spec/publisher/README.md: -------------------------------------------------------------------------------- 1 | This specification will be a recommended TEA publisher API. 2 | 3 | The TEA specification is focused on the consumption API, which is the base of 4 | conformance with the specification. 5 | 6 | NOTE: This is a copy of the OpenAPI specification including both consumption and publication APIs. 7 | -------------------------------------------------------------------------------- /tea-artifact/tea-artifact.md: -------------------------------------------------------------------------------- 1 | ## Known types 2 | 3 | meta:enum: 4 | - vcs: Version Control System 5 | - issue-tracker: Issue or defect tracking system, or an Application Lifecycle 6 | Management (ALM) system 7 | - website: Website 8 | - advisories: Security advisories 9 | - bom: Bill of Materials (SBOM, OBOM, HBOM, SaaSBOM, etc) 10 | - mailing-list: Mailing list or discussion group 11 | - social: Social media account 12 | - chat: Real-time chat platform 13 | - documentation: Documentation, guides, or how-to instructions 14 | - support: Community or commercial support 15 | - source-distribution: 16 | description: The location where the source code distributable can be obtained. 17 | This is often an archive format such as zip or tgz. The source-distribution 18 | type complements use of the version control (vcs) type. 19 | - distribution: Direct or repository download location 20 | - distribution-intake: The location where a component was published to. This 21 | is often the same as "distribution" but may also include specialized publishing 22 | processes that act as an intermediary. 23 | - license: The reference to the license file. If a license URL has been defined 24 | in the license node, it should also be defined as an external reference 25 | for completeness. 26 | - build-meta: Build-system specific meta file (i.e. pom.xml, package.json, .nuspec, 27 | etc) 28 | - build-system: Reference to an automated build system 29 | - release-notes: Reference to release notes 30 | - security-contact: Specifies a way to contact the maintainer, supplier, or 31 | provider in the event of a security incident. Common URIs include links 32 | to a disclosure procedure, a mailto (RFC-2368) that specifies an email address, 33 | a tel (RFC-3966) that specifies a phone number, or dns (RFC-4501) that specifies 34 | the records containing DNS Security TXT. 35 | - model-card: A model card describes the intended uses of a machine learning 36 | model, potential limitations, biases, ethical considerations, training parameters, 37 | datasets used to train the model, performance metrics, and other relevant 38 | data useful for ML transparency. 39 | - log: A record of events that occurred in a computer system or application, 40 | such as problems, errors, or information on current operations. 41 | configuration: Parameters or settings that may be used by other components 42 | or services. 43 | - evidence: Information used to substantiate a claim. 44 | - formulation: Describes how a component or service was manufactured or deployed. 45 | - attestation: Human or machine-readable statements containing facts, evidence, 46 | or testimony. 47 | - threat-model: An enumeration of identified weaknesses, threats, and countermeasures, 48 | dataflow diagram (DFD), attack tree, and other supporting documentation 49 | in human-readable or machine-readable format. 50 | - adversary-model: The defined assumptions, goals, and capabilities of an adversary. 51 | - risk-assessment: Identifies and analyzes the potential of future events that 52 | may negatively impact individuals, assets, and/or the environment. Risk 53 | assessments may also include judgments on the tolerability of each risk. 54 | - vulnerability-assertion: A Vulnerability Disclosure Report (VDR) which asserts 55 | the known and previously unknown vulnerabilities that affect a component, 56 | service, or product including the analysis and findings describing the impact 57 | (or lack of impact) that the reported vulnerability has on a component, 58 | service, or product. 59 | - exploitability-statement: A Vulnerability Exploitability eXchange (VEX) which 60 | asserts the known vulnerabilities that do not affect a product, product 61 | family, or organization, and optionally the ones that do. The VEX should 62 | include the analysis and findings describing the impact (or lack of impact) 63 | that the reported vulnerability has on the product, product family, or organization. 64 | - pentest-report: Results from an authorized simulated cyberattack on a component 65 | or service, otherwise known as a penetration test. 66 | - static-analysis-report: SARIF or proprietary machine or human-readable report 67 | for which static analysis has identified code quality, security, and other 68 | potential issues with the source code. 69 | - dynamic-analysis-report: Dynamic analysis report that has identified issues 70 | such as vulnerabilities and misconfigurations. 71 | - runtime-analysis-report: Report generated by analyzing the call stack of a 72 | running application. 73 | - component-analysis-report: Report generated by Software Composition Analysis 74 | (SCA), container analysis, or other forms of component analysis. 75 | - maturity-report: Report containing a formal assessment of an organization, 76 | business unit, or team against a maturity model. 77 | - certification-report: Industry, regulatory, or other certification from an 78 | accredited (if applicable) certification body. 79 | - codified-infrastructure: Code or configuration that defines and provisions 80 | virtualized infrastructure, commonly referred to as Infrastructure as Code 81 | (IaC). 82 | - quality-metrics: Report or system in which quality metrics can be obtained. 83 | - poam: Plans of Action and Milestones (POAM) complement an "attestation" external 84 | reference. POAM is defined by NIST as a "document that identifies tasks 85 | needing to be accomplished. It details resources required to accomplish 86 | the elements of the plan, any milestones in meeting the tasks and scheduled 87 | completion dates for the milestones". 88 | - electronic-signature: An e-signature is commonly a scanned representation 89 | of a written signature or a stylized script of the person's name. 90 | - digital-signature: A signature that leverages cryptography, typically public/private 91 | key pairs, which provides strong authenticity verification. 92 | - rfc-9116: Document that complies with RFC-9116 (A File Format to Aid in Security 93 | Vulnerability Disclosure) 94 | - other: Use this if no other types accurately describe the purpose of the external 95 | reference. -------------------------------------------------------------------------------- /tea-collection/tea-collection.md: -------------------------------------------------------------------------------- 1 | # TEA release and collections 2 | 3 | ## The TEA release object (TRO) 4 | 5 | The TEA Component Release object corresponds to a specific variant 6 | (version) of a component with a release identifier (string), 7 | release timestamp and a lifecycle enumeration for the release. 8 | The UUID of the TEA Component Release object matches the UUID of the associated TEA Collection objects (TCO). 9 | 10 | A TEA Component Release object has the following parts: 11 | 12 | - __uuid__: A unique identifier for the TEA Component Release 13 | - __version__: Version number 14 | - __releaseDate__: Timestamp of the release (for sorting purposes) 15 | - __preRelease__: A flag indicating pre-release (or beta) status. 16 | May be disabled after the creation of the release object, but can't be enabled after creation of an object. 17 | - __identifiers__: List of identifiers for the component 18 | - __idType__: Type of identifier, e.g. `tei`, `purl`, `cpe` 19 | - __idValue__: Identifier value 20 | 21 | ### Examples 22 | 23 | A TEA Component Release object of the binary distribution of Apache Tomcat 11.0.6 will look like: 24 | 25 | ```json 26 | { 27 | "uuid": "605d0ecb-1057-40e4-9abf-c400b10f0345", 28 | "version": "11.0.6", 29 | "releaseDate": "2025-04-01T15:43:00Z", 30 | "identifiers": [ 31 | { 32 | "idType": "purl", 33 | "idValue": "pkg:maven/org.apache.tomcat/tomcat@11.0.6" 34 | } 35 | ] 36 | } 37 | ``` 38 | 39 | Different versions of Apache Tomcat should have separate TEA Component Release objects: 40 | 41 | ```json 42 | { 43 | "uuid": "da89e38e-95e7-44ca-aa7d-f3b6b34c7fab", 44 | "version": "10.1.4", 45 | "releaseDate": "2025-04-01T18:20:00Z", 46 | "identifiers": [ 47 | { 48 | "idType": "purl", 49 | "idValue": "pkg:maven/org.apache.tomcat/tomcat@10.1.4" 50 | } 51 | ] 52 | } 53 | ``` 54 | 55 | The pre-release flag is used to mark versions not production ready 56 | and does not require users to know the version naming scheme adopted by the project. 57 | 58 | ```json 59 | { 60 | "uuid": "95f481df-f760-47f4-b2f2-f8b76d858450", 61 | "version": "11.0.0-M26", 62 | "releaseDate": "2024-09-13T17:49:00Z", 63 | "preRelease": true, 64 | "identifiers": [ 65 | { 66 | "idType": "purl", 67 | "idValue": "pkg:maven/org.apache.tomcat/tomcat@11.0.0-M26" 68 | } 69 | ] 70 | } 71 | ``` 72 | 73 | ## The TEA Collection object (TCO) 74 | 75 | For each product and version there is a Tea Collection object, which is a list 76 | of available artifacts for this specific version. The TEA Index is a list of 77 | TEA collections. 78 | 79 | The TEA collection is normally created by the TEA application server at 80 | publication time of artifacts. The publisher may sign the collection 81 | object as a JSON file at time of publication. 82 | 83 | If there are any updates of artifacts within a collection for the same 84 | version of a product, then a new TEA Collection object is created and signed. 85 | This update will have the same UUID, but a new version number. A reason 86 | for the update will have to be provided. This shall be used to 87 | correct mistakes, spelling errors as well as to provide new information 88 | on dynamic artifact types such as LCE or VEX. If the product 89 | is modified, that is a new product version and that should generate 90 | a new collection object with a new UUID and updated metadata. 91 | 92 | The API allows for retrieving the latest version of the collection, 93 | or a specific version. 94 | 95 | ### Dynamic or static Collection objects 96 | 97 | The TCO is produced by the TEA software platform. There are two ways 98 | to implement this: 99 | 100 | * __Dynamic__: The TCO is built for each API request and created 101 | dynamically. 102 | * __Static__: The TCO is built at publication time as a static 103 | object by the publisher. This object can be digitally signed at 104 | publication time and version controlled. 105 | 106 | ### Collection object 107 | 108 | The TEA Collection object has the following parts: 109 | 110 | - Preamble 111 | - __uuid__: UUID of the TEA Collection object. 112 | Note that this is equal to the UUID of the associated TEA Component Release object. 113 | When updating a collection, only the `version` is changed. 114 | - __version__: TEA Collection version, incremented each time its content changes. 115 | Versions start with 1. 116 | - __releaseDate__: TEA Collection version release date. 117 | - __updateReason__: Reason for the update/release of the TEA Collection object. 118 | - __type__: Type of update reason. 119 | See [reasons for TEA Collection update](#the-reason-for-tco-update-enum) below. 120 | - __comment__: Free text description. 121 | - __artifacts__: List of TEA artifact objects. 122 | See [below](#artifact-object). 123 | 124 | ### Artifact object 125 | 126 | The TEA Artifact object has the following parts: 127 | 128 | - __uuid__: UUID of the TEA Artifact object. 129 | - __name__: Artifact name. 130 | - __type__: Type of artifact. 131 | See [TEA Artifact types](#tea-artifact-types) for a list. 132 | - __formats__: List of objects with the same content, but in different formats. 133 | The order of the list has no significance. 134 | - __mime_type__: The MIME type of the document 135 | - __description__: A free text describing the artifact 136 | - __url__: Direct download URL for the artifact 137 | - __signature_url__: Direct download URL for an external signature of the artifact 138 | - __checksums__: List of checksums for the artifact 139 | - __algType__: Checksum algorithm 140 | See [CycloneDX checksum algorithms](https://cyclonedx.org/docs/1.6/json/#components_items_hashes_items_alg) for a list of supported values. 141 | - __algValue__: Checksum value 142 | 143 | ### The reason for TCO update enum 144 | 145 | | ENUM | Description | 146 | |------------------|----------------------------------------| 147 | | INITIAL_RELEASE | Initial release of the collection | 148 | | VEX_UPDATED | Updated the VEX artifact(s) | 149 | | ARTIFACT_UPDATED | Updated the artifact(s) other than VEX | 150 | | ARTIFACT_REMOVED | Removal of artifact | 151 | | ARTIFACT_ADDED | Addition of an artifact | 152 | 153 | Updates of VEX (CSAF) files may be handled in a different way by a TEA client, 154 | producing different alerts than other changes of a collection. 155 | 156 | ### TEA Artifact types 157 | 158 | | ENUM | Description | 159 | |-----------------|-------------------------------------------------------------------------------------| 160 | | ATTESTATION | Machine-readable statements containing facts, evidence, or testimony. | 161 | | BOM | Bill of Materials: SBOM, OBOM, HBOM, SaaSBOM, etc. | 162 | | BUILD_META | Build-system specific metadata file: `pom.xml`, `package.json`, `.nuspec`, etc. | 163 | | CERTIFICATION | Industry, regulatory, or other certification from an accredited certification body. | 164 | | FORMULATION | Describes how a component or service was manufactured or deployed. | 165 | | LICENSE | License file | 166 | | RELEASE_NOTES | Release notes document | 167 | | SECURITY_TXT | A `security.txt` file | 168 | | THREAT_MODEL | A threat model | 169 | | VULNERABILITIES | A list of vulnerabilities: VDR/VEX | 170 | | OTHER | Document that does not fall into any of the above categories | 171 | 172 | ### Examples 173 | 174 | ```json 175 | { 176 | "uuid": "4c72fe22-9d83-4c2f-8eba-d6db484f32c8", 177 | "version": 1, 178 | "releaseDate": "2024-12-13T00:00:00Z", 179 | "updateReason": { 180 | "type": "ARTIFACT_UPDATED", 181 | "comment": "VDR file updated" 182 | }, 183 | "artifacts": [ 184 | { 185 | "uuid": "1cb47b95-8bf8-3bad-a5a4-0d54d86e10ce", 186 | "name": "Build SBOM", 187 | "type": "bom", 188 | "formats": [ 189 | { 190 | "mime_type": "application/vnd.cyclonedx+xml", 191 | "description": "CycloneDX SBOM (XML)", 192 | "url": "https://repo.maven.apache.org/maven2/org/apache/logging/log4j/log4j-core/2.24.3/log4j-core-2.24.3-cyclonedx.xml", 193 | "signature_url": "https://repo.maven.apache.org/maven2/org/apache/logging/log4j/log4j-core/2.24.3/log4j-core-2.24.3-cyclonedx.xml.asc", 194 | "checksums": [ 195 | { 196 | "algType": "MD5", 197 | "algValue": "2e1a525afc81b0a8ecff114b8b743de9" 198 | }, 199 | { 200 | "algType": "SHA-1", 201 | "algValue": "5a7d4caef63c5c5ccdf07c39337323529eb5a770" 202 | } 203 | ] 204 | } 205 | ] 206 | }, 207 | { 208 | "uuid": "dfa35519-9734-4259-bba1-3e825cf4be06", 209 | "name": "Vulnerability Disclosure Report", 210 | "type": "vulnerability-assertion", 211 | "formats": [ 212 | { 213 | "mime_type": "application/vnd.cyclonedx+xml", 214 | "description": "CycloneDX VDR (XML)", 215 | "url": "https://logging.apache.org/cyclonedx/vdr.xml", 216 | "checksums": [ 217 | { 218 | "algType": "SHA-256", 219 | "algValue": "75b81020b3917cb682b1a7605ade431e062f7a4c01a412f0b87543b6e995ad2a" 220 | } 221 | ] 222 | } 223 | ] 224 | } 225 | ] 226 | } 227 | ``` 228 | -------------------------------------------------------------------------------- /tea-component/tea-component.md: -------------------------------------------------------------------------------- 1 | # The TEA Component API 2 | 3 | The TEA Component object is the object that indicates a product component. The product may 4 | be constructed with one or multiple Tea Components, each with their own set of 5 | related artefacts. 6 | 7 | For each TEA COMPONENT there is a TEA COMPONENT INDEX, which is a list of all versions 8 | for that component. 9 | 10 | The API should be very agnostic as to how a "version" is indicated - semver, vers, 11 | name, hash or anything else. 12 | 13 | ## Major and minor versions 14 | 15 | Each component is for a sub-version or minor version (using semver definitions). A new 16 | major version counts as a new product with a separate product object (TPO). Each 17 | product object has one or multiple TEI URNs. 18 | 19 | For the API to be able to present a list of versions in a cronological order, 20 | a timestamp for a release is required. 21 | 22 | ## TEA Component Object 23 | 24 | A TEA Component object has the following parts: 25 | 26 | - __uuid__: A unique identifier for the TEA component 27 | - __name__: Component name 28 | - __identifiers__: List of identifiers for the component 29 | - __idType__: Type of identifier, e.g. `tei`, `purl`, `cpe` 30 | - __idValue__: Identifier value 31 | 32 | Note: In coming versions, there may be a flag indicating lifecycle status 33 | for a component. 34 | 35 | ### Examples 36 | 37 | Some examples of Maven artifacts as TEA Components: 38 | 39 | ```json 40 | { 41 | "uuid": "3910e0fd-aff4-48d6-b75f-8bf6b84687f0", 42 | "name": "Apache Log4j API", 43 | "identifiers": [ 44 | { 45 | "idType": "purl", 46 | "idValue": "pkg:maven/org.apache.logging.log4j/log4j-api" 47 | } 48 | ] 49 | } 50 | ``` 51 | 52 | ```json 53 | { 54 | "uuid": "b844c9bd-55d6-478c-af59-954a932b6ad3", 55 | "name": "Apache Log4j Core", 56 | "identifiers": [ 57 | { 58 | "idType": "cpe", 59 | "idValue": "cpe:2.3:a:apache:log4j" 60 | }, 61 | { 62 | "idType": "purl", 63 | "idValue": "pkg:maven/org.apache.logging.log4j/log4j-core" 64 | } 65 | ] 66 | } 67 | ``` 68 | 69 | ## Handling the Pre-Release flag 70 | 71 | The "Pre-release" flag is used to indicate that this is not a final release. 72 | For a given Component with a UUID, the flag can be set to indicate a "test", "beta", "alpha" 73 | or similar non-deployed release. It can only be set when creating the Component. 74 | The TEA implementation may allow it to be unset (False) once. This is to support 75 | situations where a object is promoted as is after testing to production version. The flag can not 76 | be set after initial creation and publication of the Component. 77 | 78 | If the final version is different from the pre-release (bugs fixed, code changed, different binary) 79 | a new Component with a new UUID and version needs to be created. 80 | 81 | ## References 82 | 83 | - Semantic versioning (Semver): 84 | - PURL VERS 85 | -------------------------------------------------------------------------------- /tea-product/tea-product.md: -------------------------------------------------------------------------------- 1 | # The TEA product API 2 | 3 | After TEA discovery, a user has a URL to the TEA product API where 4 | the TEI is used to query for data. The TEI marks the product sold, 5 | which can be a single unit or multiple units in a bundle. 6 | 7 | - For a single product, the output will be metadata about the 8 | product and a TEA COMPONENT object. 9 | - For a composed product consisting of a bundle, the response 10 | will be multiple TEA COMPONENT objects. 11 | 12 | In addition, all known TEIs for the product will be returned, 13 | in order for a TEA client to avoid duplication. 14 | 15 | ## Authorization 16 | 17 | Authorization can be done on multiple levels, including 18 | which products and versions are supported for a specific user. 19 | 20 | ## Composite products 21 | 22 | If a product consists of a set of products, each with a different 23 | version number and update scheme, a TEA bundle will be the starting 24 | point of discovery. The TEA bundle will list all included parts 25 | and include pointers (URLs) to the TEA index for these. 26 | 27 | The URL can be to a different vendor or different site with the 28 | same vendor. 29 | 30 | ## TEA Product object 31 | 32 | A TEA Product object has the following parts: 33 | 34 | - __uuid__: A unique identifier for the TEA product 35 | - __name__: Product name 36 | - __identifiers__: List of identifiers for the product 37 | - __idType__: Type of identifier, e.g. `tei`, `purl`, `cpe` 38 | - __idValue__: Identifier value 39 | - __components__: List of TEA components for the product 40 | - __uuid__: Unique identifier of the TEA component 41 | 42 | The TEA Component UUID is used in the Component API to find out which versions 43 | of the Component that exists. 44 | 45 | The goal of the TEA Product API is to provide a selection of product 46 | versions to assist the user software in finding a match for the 47 | owned version. 48 | 49 | ### Example 50 | 51 | An example of a product consisting of an OSS project and all its Maven artifacts: 52 | 53 | ```json 54 | { 55 | "uuid": "09e8c73b-ac45-4475-acac-33e6a7314e6d", 56 | "name": "Apache Log4j 2", 57 | "identifiers": [ 58 | { 59 | "idType": "cpe", 60 | "idValue": "cpe:2.3:a:apache:log4j" 61 | }, 62 | { 63 | "idType": "purl", 64 | "idValue": "pkg:maven/org.apache.logging.log4j/log4j-api" 65 | }, 66 | { 67 | "idType": "purl", 68 | "idValue": "pkg:maven/org.apache.logging.log4j/log4j-core" 69 | }, 70 | { 71 | "idType": "purl", 72 | "idValue": "pkg:maven/org.apache.logging.log4j/log4j-layout-template-json" 73 | } 74 | ], 75 | "components": [ 76 | "3910e0fd-aff4-48d6-b75f-8bf6b84687f0", 77 | "b844c9bd-55d6-478c-af59-954a932b6ad3", 78 | "d6d3f754-d4f4-4672-b096-b994b064ca2d" 79 | ] 80 | } 81 | ``` 82 | 83 | ### API usage 84 | 85 | The user will find this API end point using TEA discovery. 86 | 87 | A user will approach the API just to discover data before purchase, 88 | or with a specific product and product version in scope. 89 | The format of the version may follow many syntaxes, so maybe 90 | the API needs to be able to provide some sort of format 91 | for the version string. 92 | 93 | An automated system may want to provide the user with a GUI, 94 | listing versions and being able to scroll to the next page 95 | until the user selects a version. 96 | 97 | ### Tea API operation 98 | 99 | * Recommendation: Support HTTP compression 100 | * Recommendation: HTTP content negotiation 101 | * Like "I prefer JSON, but can accept XML" 102 | * Pagination support 103 | * max per page 104 | * start page 105 | * Default value defined 106 | 107 | 108 | --------------------------------------------------------------------------------