Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 104 additions & 32 deletions discovery/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,35 @@

## 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.

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.

Expand Down Expand Up @@ -53,9 +71,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.

Expand All @@ -69,16 +87,16 @@ barcode and one with the vendor's product number.
The TEI consists of three core parts

```text
urn:tei:<type>:<domain-name>:<unique-identifier>
tei://<domain-name>/<type>/<unique-identifier-BASE64>
````

- 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

Expand All @@ -93,13 +111,15 @@ Where the `unique-identifier` is a PURL in it's canonical string form.
Syntax:

```text
urn:tei:purl:<domain-name>:<purl>
tei://<domain-name>/purl/<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
Expand All @@ -109,7 +129,7 @@ Where the `unique-identifier` is a SWID.
Syntax:

```text
urn:tei:swid:<domain-name>:<swid>
tei://<domain-name>/swid/<swid>
```

Note that there is a TEI SWID type as well as a PURL SWID type.
Expand All @@ -123,12 +143,15 @@ Where the `unique-identifier` is a Hash. Supports the following hash types:
- SHA512

```text
urn:tei:hash:<domain-name>:<hashtype>:<hash>
tei://<domain-name>/hash/<hashtype>/<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.
Expand All @@ -140,12 +163,15 @@ Where the `unique-identifier` is a UUID.
Syntax:

```text
urn:tei:uuid:<domain-name>:<uuid>
tei://<domain-name>/uuid/<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
Expand All @@ -155,12 +181,15 @@ Where the `unique-identifier` is a EAN/UPC.
Syntax:

```text
urn:tei:eanupc:<domain-name>:<ean/upc-number>
tei://<domain-name>/eanupc/<ean/upc-number>
````

Example:

EAN 1234567890123

```text
urn:tei:eanupc:cyclonedx.org:1234567890123
tei://example.com/eanupc/MTIzNDU2Nzg5MDEyMw
```

#### GTIN
Expand All @@ -170,12 +199,15 @@ Where the `unique-identifier` is a [GTIN](https://www.gs1.org/standards/id-keys/
Syntax:

```text
urn:tei:gtin:<domain-name>:<gtin-number>
tei://<domain-name>/gtin/<gtin-number>
````

Example:

GTIN 0234567890123

```text
urn:tei:gtin:cyclonedx.org:0234567890123
tei://example.org/gtin:/MDIzNDU2Nzg5MDEyMw

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the : after gain

```

#### ASIN
Expand All @@ -185,12 +217,15 @@ Where the `unique-identifier` is a [ASIN](https://sell.amazon.com/blog/what-is-a
Syntax:

```text
urn:tei:asin:<domain-name>:<asin-identifier>
tei://<domain-name>/asin/<asin-identifier>
````

Example:

ASIN B07FZ8S74R

```text
urn:tei:asin:cyclonedx.org:B07FZ8S74R
tei://example.com/asin/QjA3Rlo4Uzc0Ug
```


Expand All @@ -201,12 +236,15 @@ Where the `unique-identifier` is a [UDI](https://www.gs1.org/industries/healthca
Syntax:

```text
urn:tei:udi:<domain-name>:<udi-identifier>
tei://<domain-name>/udi/<udi-identifier>
````

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
Expand All @@ -224,8 +262,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:<name based on domain>:<unique identifier>`
- `tei://<domain-name>/uuid/ZDRkOWY1NGEtYWJjZi0xMWVlLWFjNzktMWE1MjkxNGQ0NGIx`
- Syntax: `tei://<domain-name>/uuid/<unique identifier>`

The name in the DNS name part points to a set of DNS records.

Expand Down Expand Up @@ -268,11 +306,19 @@ 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.
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.
Expand Down Expand Up @@ -301,10 +347,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://<domain-name>/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://<domain-name>/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.

Expand All @@ -327,20 +373,46 @@ 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
`.well-known` URI as per Section 1.1 of [RFC5785].

### TLS Encryption

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
Expand Down