From 1480c2e65b4ab9eead603a50889ef3546c862a2c Mon Sep 17 00:00:00 2001 From: "Olle E. Johansson" Date: Wed, 26 Aug 2026 14:10:45 +0200 Subject: [PATCH 1/2] Updating discovery to use TEI: URL Signed-off-by: Olle E. Johansson --- discovery/readme.md | 83 ++++++++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 32 deletions(-) diff --git a/discovery/readme.md b/discovery/readme.md index 05e9e84..904813d 100644 --- a/discovery/readme.md +++ b/discovery/readme.md @@ -20,11 +20,11 @@ A "product release" is something that the customer aquires or downloads - hardwa It can be a bundle of many digital devices or software applications. A "product release" normally also has an entry in a large corporation's asset inventory system. -A product release identifier is embedded in a URN where the identifier is one of many existing +A product release identifier is embedded in a URL where the identifier is one of many existing identifiers or a random string - like an EAN or UPC bar code, UUID, product number or PURL. -The goal is for a user to add this URN to the transparency platform (sometimes with an +The goal is for a user to add this URL to the transparency platform (sometimes with an associated authentication token) and have the platform access the required artefacts in a highly automated fashion. @@ -53,9 +53,9 @@ as long as they all resolve into the same destination. The vendor needs to make sure that the TEI is unique within the vendor's namespace. There is no intention to create any TEI registries. -## The TEI URN: An extensible identifier +## The TEI: URL - An extensible identifier -The TEI, __Transparency Exchange Identifier__, is a URN schema that is extensible based on existing +The TEI, __Transparency Exchange Identifier__, is a URL schema that is extensible based on existing identifiers like EAN codes, PURL and other identifiers. It is based on a DNS name, which leads to global uniqueness without new registries. @@ -69,16 +69,16 @@ barcode and one with the vendor's product number. The TEI consists of three core parts ```text -urn:tei::: +tei://// ```` -- The **`type`** which defines the syntax of the unique identifier part - The **`domain-name`** part resolves into a web server, which may not be the API host. - The uniqueness of the name is the domain name part that has to be registred at creation of the TEI. +- The **`type`** which defines the syntax of the unique identifier part - The **`unique-identifier`** has to be unique within the `domain-name`. - Recommendation is to use a UUID but it can be an existing article code too + Recommendation is to use a UUID but it can be an existing article code too. The + identifier is encoded using BASE64URL encoding (RFC 4648 section 5). -**Note**: this requires a registration of the TEI URN schema with IANA - [see here](https://github.com/CycloneDX/transparency-exchange-api/issues/18) ### TEI types @@ -93,13 +93,15 @@ Where the `unique-identifier` is a PURL in it's canonical string form. Syntax: ```text -urn:tei:purl:: +tei:///purl/ ```` Example: +PURL: pkg:pypi/cyclonedx-python-lib@8.4.0?extension=whl&qualifier=py3-none-any + ```text -urn:tei:purl:cyclonedx.org:pkg:pypi/cyclonedx-python-lib@8.4.0?extension=whl&qualifier=py3-none-any +tei://cyclonedx.org/purl/cGtnOnB5cGkvY3ljbG9uZWR4LXB5dGhvbi1saWJAOC40LjA_ZXh0ZW5zaW9uPXdobCZxdWFsaWZpZXI9cHkzLW5vbmUtYW55 ``` #### SWID @@ -109,7 +111,7 @@ Where the `unique-identifier` is a SWID. Syntax: ```text -urn:tei:swid:: +tei:///swid/ ``` Note that there is a TEI SWID type as well as a PURL SWID type. @@ -123,12 +125,15 @@ Where the `unique-identifier` is a Hash. Supports the following hash types: - SHA512 ```text -urn:tei:hash::: +tei:///hash// ```` Example: + +HASH fd44efd601f651c8865acf0dfeacb0df19a2b50ec69ead0262096fd2f67197b9 + ```text -urn:tei:hash:cyclonedx.org:SHA256:fd44efd601f651c8865acf0dfeacb0df19a2b50ec69ead0262096fd2f67197b9 +tei://cyclonedx.org/hash/SHA256/ZmQ0NGVmZDYwMWY2NTFjODg2NWFjZjBkZmVhY2IwZGYxOWEyYjUwZWM2OWVhZDAyNjIwOTZmZDJmNjcxOTdiOQ ``` The origin of the hash is up to the vendor to define. @@ -140,12 +145,15 @@ Where the `unique-identifier` is a UUID. Syntax: ```text -urn:tei:uuid:: +tei:///uuid/ ```` Example: + +UUID d4d9f54a-abcf-11ee-ac79-1a52914d44b1 + ```text -urn:tei:uuid:cyclonedx.org:d4d9f54a-abcf-11ee-ac79-1a52914d44b1 +tei://cyclonedx.org/uuid/ZDRkOWY1NGEtYWJjZi0xMWVlLWFjNzktMWE1MjkxNGQ0NGIxCg ``` #### EAN/UPC @@ -155,12 +163,15 @@ Where the `unique-identifier` is a EAN/UPC. Syntax: ```text -urn:tei:eanupc:: +tei:///eanupc/ ```` Example: + +EAN 1234567890123 + ```text -urn:tei:eanupc:cyclonedx.org:1234567890123 +tei://example.com/eanupc/MTIzNDU2Nzg5MDEyMw ``` #### GTIN @@ -170,12 +181,15 @@ Where the `unique-identifier` is a [GTIN](https://www.gs1.org/standards/id-keys/ Syntax: ```text -urn:tei:gtin:: +tei:///gtin/ ```` Example: + +GTIN 0234567890123 + ```text -urn:tei:gtin:cyclonedx.org:0234567890123 +tei://example.org/gtin:/MDIzNDU2Nzg5MDEyMw ``` #### ASIN @@ -185,12 +199,15 @@ Where the `unique-identifier` is a [ASIN](https://sell.amazon.com/blog/what-is-a Syntax: ```text -urn:tei:asin:: +tei:///asin/ ```` Example: + +ASIN B07FZ8S74R + ```text -urn:tei:asin:cyclonedx.org:B07FZ8S74R +tei://example.com/asin/QjA3Rlo4Uzc0Ug ``` @@ -201,12 +218,15 @@ Where the `unique-identifier` is a [UDI](https://www.gs1.org/industries/healthca Syntax: ```text -urn:tei:udi:: +tei:///udi/ ```` Example: + +UDI 00123456789012 + ```text -urn:tei:udi:cyclonedx.org:00123456789012 +tei://cyclonedx.org/udi/MDAxMjM0NTY3ODkwMTI ``` Note that if the same identifier, like EAN, is used for multiple different product releases @@ -224,8 +244,8 @@ product transparency exchange information. At the URL a well-known name space is used to find out where the API endpoint is hosted. This is solved by using the ".well-known" name space as defined by the IETF. -- `urn:tei:uuid:products.example.com:d4d9f54a-abcf-11ee-ac79-1a52914d44b1` -- Syntax: `urn:tei:uuid::` +- `tei:///uuid/ZDRkOWY1NGEtYWJjZi0xMWVlLWFjNzktMWE1MjkxNGQ0NGIx` +- Syntax: `tei:///uuid/` The name in the DNS name part points to a set of DNS records. @@ -271,8 +291,6 @@ Example: ## Port resolution Currently, the port number is not part of the TEI but it is needed to connect to the API. -A port number cannot be added to the TEI URN spec as it breaks the location independence -requirement of URN. The TEA API server may be hosted on any port, but the server that is part of the first step of discovery will by default be running on the default HTTPS port 443. @@ -301,10 +319,10 @@ plus "/discovery?tei=", plus the TEI that is url-encoded according to [RFC3986] and [RFC3986]). Examples: -1. For TEI `urn:tei:uuid:products.example.com:d4d9f54a-abcf-11ee-ac79-1a52914d44b` -`https://api.teaexample.com/v0.2.0-beta.2/discovery?tei=urn%3Atei%3Auuid%3Aproducts.example.com%3Ad4d9f54a-abcf-11ee-ac79-1a52914d44b` -2. For TEI `urn:tei:purl:products.example.com:pkg:deb/debian/curl@7.50.3-1?arch=i386&distro=jessie` -`https://api2.teaexample.com/mytea/v1.0.0/discovery?tei=urn%3Atei%3Apurl%3Aproducts.example.com%3Apkg%3Adeb%2Fdebian%2Fcurl%407.50.3-1%3Farch%3Di386%26distro%3Djessie` +1. For TEI `tei:///uuid:products.example.com:d4d9f54a-abcf-11ee-ac79-1a52914d44b` +`https://api.teaexample.com/v0.2.0-beta.2/discovery?tei=tei%3A//products.example.com/uuid/d4d9f54a-abcf-11ee-ac79-1a52914d44b` +2. For TEI `tei:///purl:products.example.com:pkg:deb/debian/curl@7.50.3-1?arch=i386&distro=jessie` +`https://api2.teaexample.com/mytea/v1.0.0/discovery?tei=tei%3A//products.example.com%3Apurl%3Apkg%3Adeb%2Fdebian%2Fcurl%407.50.3-1%3Farch%3Di386%26distro%3Djessie` The discovery endpoint is a part of the TEA OpenAPI specification. @@ -333,6 +351,7 @@ in the list. How this is communicated to the client users is implementation specific. ## Notes Regarding .well-known + Servers MUST NOT locate the actual TEA service endpoint at the `.well-known` URI as per Section 1.1 of [RFC5785]. @@ -340,7 +359,7 @@ Servers MUST NOT locate the actual TEA service endpoint at the The .well-known endpoint must only be available via HTTPS. Using unencrypted HTTP is not valid. -- TEI: `urn:tei:uuid:products.example.com:d4d9f54a-abcf-11ee-ac79-1a52914d44b1` +- TEI: `tei://products.example.com/uuid/d4d9f54a-abcf-11ee-ac79-1a52914d44b1` - URL: `https://products.example.com/.well-known/tea` ## References From be64bc72d9e736ef3406e07bd3e213efd652ad21 Mon Sep 17 00:00:00 2001 From: "Olle E. Johansson" Date: Wed, 26 Aug 2026 14:25:07 +0200 Subject: [PATCH 2/2] Updates to discovery Signed-off-by: Olle E. Johansson --- discovery/readme.md | 53 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/discovery/readme.md b/discovery/readme.md index 904813d..b21a388 100644 --- a/discovery/readme.md +++ b/discovery/readme.md @@ -14,6 +14,24 @@ ## From product identifier to API endpoint +Discovery is the **first step in all TEA interactions**, enabling a consumer to map an identifier to a service endpoint. + +This specification defines: + +- how discovery is initiated +- how discovery documents are retrieved +- how API endpoints are obtained + +TEA separates: + +- **identity** → TEI +- **location** → discovery +- **data retrieval** → API + +Discovery answers the question: + +> “Where can I retrieve authoritative TEA data for this identifier?” + TEA Discovery is the connection between a product release identifier and the API endpoint. A "product release" is something that the customer aquires or downloads - hardware and/or software. @@ -288,6 +306,16 @@ Example: } ``` +### Discovery data caching and freshness + +Discovery documents MAY be cached. + +Implementations SHOULD: + +- respect HTTP caching headers +- periodically refresh discovery data +- handle endpoint changes gracefully + ## Port resolution Currently, the port number is not part of the TEI but it is needed to connect to the API. @@ -345,11 +373,36 @@ exponential backoff strategy for retries. Client implementations needs to indicate authentication errors clearly to the users, to indicate that there are no updates. An expired token or TLS Client Cert will mean that new versions of a product or updated artefacts will not be accessed. + +### Error handling + Authentication error codes (401, 403) should not lead to failover to the next endpoint in the list. How this is communicated to the client users is implementation specific. +Common errors: + +#### 404 Not Found + +- discovery endpoint not present + +#### 503 Service Unavailable + +- temporary failure + +#### TLS failure + +- certificate validation error + +### Client behavior + +Clients SHOULD: + +- retry with backoff +- validate TLS certificates +- fail closed if discovery cannot be validated + ## Notes Regarding .well-known Servers MUST NOT locate the actual TEA service endpoint at the