?uem/p1-90`Discovery is the first step in all TEA interactions, enabling a consumer to map an identifier to a service endpoint.
This Standard defines:
TEA separates:
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 user 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 URL where the identifier is one of many existing identifiers or a random string - like an EAN or UPC bar code,
The goal is for a user to add this URL to the transparency platform (sometimes with credentials for the selected TEA service, such as an API key) and have the platform access the required artefacts in a highly automated fashion. Those credentials are provisioned separately and are not embedded in the TEI.
The TEI for a product release can be communicated to the user in many ways.
The user obtains the TEI from the vendor, through a reseller, or directly. The TEI is defined by the vendor and cannot normally be derived from known information.
TEA discovery is the process where a user with a product release identifier can discover and download artefacts automatically, with or without authentication. A globally unique identifier is required for a given product release. This identifier is called the Transparency Exchange Identifier (TEI).
"Vendor" means the party that publishes TEIs for its product releases, whether a commercial company or an open source project.
The TEI is based on DNS. The domain name provides a namespace in which the vendor defines product release identifiers using existing or new identifier schemes, such as EAN/UPC bar codes or
There is no registry of TEIs; only TEI types are registered.
The TEI, Transparency Exchange Identifier, is a URL schema that is extensible based on existing identifiers like EAN codes,
The TEI can be shown in the software itself, in shipping documentation, in web pages and app stores.
A product release can have multiple TEIs — for example one with an EAN/UPC barcode and one with the vendor's product number.
A TEI is a
tei://<domain-name>/<type>/<unique-identifier>
tei.domain-name is a DNS name under the vendor's control. It is the namespace of the TEI and resolves to a web server, which may not be the API host. A port number is not allowed.type consists of lowercase ASCII letters and digits and starts with a letter. It names the identifier scheme of the unique-identifier and is registered as described in the next section.unique-identifier is a single path segment in the syntax its type defines and identifies one or more product releases within the domain-name. It shall not contain /, neither literally nor percent-encoded as %2F. Other characters that are not allowed in a path segment are percent-encoded with uppercase hexadecimal digits.A TEI may identify several product releases, for example when a boxed product keeps its EAN across firmware versions. A successful /discovery response is always a non-empty JSON array, including when it contains only one result. Clients shall treat the array order as priority (first entry highest). See Discovery response. A vendor should make each TEI identify a single product release; a type such as uuid or hash always allows this.
TEI types are defined in the TEI type registry at https://github.com/CycloneDX/transparency-exchange-api/tree/main/tei-types. Registration refers to the TEA community process for adding a type, described in the registry.
The following table is informative. It illustrates the types registered at the time of writing; the registry is the authoritative list.
| Type | Unique identifier | Example |
|---|---|---|
purl |
tei://example.com/purl/cGtnOm1hdmVuL2Nv |
|
hash |
Hash of an object, <hashtype>:<hex> |
tei://example.com/hash/SHA-256:fd44efd601f6 |
uuid |
tei://example.com/uuid/d4d9f54a-abcf-11ee-ac79-1a52914d44b1 |
|
eanupc |
EAN or UPC number | tei://example.com/eanupc/1234567890128 |
gtin |
GTIN | tei://example.com/gtin/0234567890129 |
asin |
Amazon Standard Identification Number | tei://example.com/asin/B07FZ8S74R |
udi |
Unique Device Identifier | tei://example.com/udi/00123456789012 |
For comparison, a TEI is an opaque identifier, not a locator. Two TEIs are equal if and only if they are the same sequence of characters. The comparison is case-sensitive and applies to the TEI as written:
The following TEIs are therefore all distinct:
tei://example.com/uuid/62f2cf92-ae88-11f1-a698-1a52914d44b2
tei://Example.com/uuid/62f2cf92-ae88-11f1-a698-1a52914d44b2
tei://example.com/uuid/62F2CF92-AE88-11F1-A698-1A52914D44B2
tei://example.com/purl/cGtnOnB5cGkvY3ljbG9uZWR4LXB5dGhvbi1saWI
tei://example.com/purl/cGtnOnB5cGkvY3ljbG9uZWR4LXB5dGhvbi1saWI=
So that one identifier has one spelling, a vendor shall publish a TEI in the following form:
tei in lowercase,A client shall use a TEI exactly as received and shall not rewrite it.
When a TEI is carried inside another URL, for example as the tei query parameter of the discovery endpoint, it is percent-encoded for transport. The comparison applies to the TEI after that transport encoding is removed, and a server matching a received TEI against the TEIs it publishes applies this rule.
This rule defines identity only. Resolving a TEI to an API endpoint follows the rules below, where the domain name is used as a DNS name and is therefore case-insensitive.
The domain-name part of the TEI is used in a DNS query to find one or multiple locations for product transparency exchange information.
At the URL a well-known name space is used to find out where the API endpoint is hosted. This is solved by using the ".well-known" name space as defined by the IETF.
tei://<domain-name>/uuid/62f2cf92-ae88-11f1-a698-1a52914d44b2tei://<domain-name>/uuid/<unique identifier>The name in the DNS name part points to a set of DNS records.
A TEI with domain-name tea.example.com queries DNS for tea.example.com, considering A, AAAA and CNAME records. These point to the hosts available for the Transparency Exchange API.
The TEA client connects to the host using HTTPS and shall verify the server certificate, including the server identity check of RFC 9525. The URL is composed of the host name with the /.well-known/tea path added. The "tea" well-known
This results in the base URL such as https://products.example.com/.well-known/tea
This response shall contain a JSON object that lists the available TEA server endpoints and supported versions. The JSON shall conform to the
Example:
{
"schemaVersion": 1,
"endpoints": [
{
"url": "https://api.example.com",
"versions":
[
"1.0.0"
],
"priority": 1
},
{
"url": "https://api2.example.com/mytea",
"versions":
[
"1.0.0"
],
"priority": 0.5
}
]
}
Discovery documents may be cached.
Implementations should:
Currently, the port number is not part of the TEI but it is needed to connect to the API.
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. In the JSON file found there, the server URLs may contain port numbers.
If the clients are known to support HTTPS/SVCB DNS records for failover and load balancing, these may be used to redirect to other ports and servers.
Public servers are recommended to have the server hosting the DNS name used in the TEI
Discovery proceeds in two stages that share the same retry, backoff, and attempt-bound rules below:
/.well-known/tea for the TEI’s domain host/discovery on a selected API base URL constructed from a well-known endpoint entry.well-known/teaClients shall pick an endpoint from the .well-known/tea JSON response that lists at least one API version supported by the client. The client shall prefer endpoints whose highest mutually supported version is greatest, based on MAJOR.MINOR.PATCH with optional prerelease and build metadata). Build metadata is ignored when comparing versions (SemVer 2.0.0 §10), both for precedence and for determining whether the client supports a version. If the highest mutually supported version is advertised with more than one build-metadata spelling, the client may select any of them, and shall use the selected string exactly as advertised when constructing the path (for example /v1.0.0+build.5; + is a valid path character per [priority value (a float between 0 and 1). If priority is absent on a well-known endpoint object, the client shall treat it as 1 for ordering (JSON Schema default does not populate omitted fields in the JSON response).
The client shall then construct the full URL to the API by selecting that highest mutually supported version and appending /v followed by that exact advertised version string (for example /v1.0.0), then /discovery?tei= plus the TEI, url-encoded according to [
Examples:
tei://products.example.com/uuid/d4d9f54a-abcf-11ee-ac79-1a52914d44b1 https://api.example.com/v1.0.0/discovery?tei=tei%3A//products.example.com/uuid/d4d9f54a-abcf-11ee-ac79-1a52914d44b1tei://products.example.com/purl/cGtnOmRlYi9kZWJpYW4vY3VybEA3LjUwLjMtMT9hcmNoPWkzODYmZGlzdHJvPWplc3NpZQ https://api2.example.com/mytea/v1.0.0/discovery?tei=tei%3A//products.example.com/purl/cGtnOmRlYi9kZWJpYW4vY3VybEA3LjUwLjMtMT9hcmNoPWkzODYmZGlzdHJvPWplc3NpZQThe discovery endpoint is a part of the TEA /token, /discovery is required on a conforming TEA API base: a conforming server that exposes a given API version shall implement it.
A successful /discovery response is a non-empty JSON array of discovery-info objects, including when it contains only one result. Each element identifies one resolved product release and the TEA servers that serve it:
productReleaseUuid — servers — non-empty array of server-info objects (rootUrl, versions, and optional priority).well-known/tea and servers[] are related but distinct:
/discovery (after appending /v{version}).servers[] in the discovery response lists API bases that serve the resolved product release. The client selects among them with the same version-preference and priority rules as for well-known endpoints. A rootUrl need not appear in the well-known endpoint list. All further requests for that product release are built as rootUrl + /v + the selected version + path. The API base used for /discovery is not used again for that release unless it is also listed in servers[].When multiple product releases match, the array is ordered by priority (first entry highest). Vendors should prefer returning a single release when possible.
A successful lookup shall return a non-empty array. If the server does not resolve the identifier, the server shall respond with 404 and a TEA error body with error: OBJECT_UNKNOWN — not 200 with an empty array. If priority is absent on a discovery servers[] entry, the client shall treat it as 1 for ordering, the same as for well-known endpoints.
Example (one match):
[
{
"productReleaseUuid": "d4d9f54a-abcf-11ee-ac79-1a52914d44b1",
"servers": [
{
"rootUrl": "https://api.example.com",
"versions": ["1.0.0"]
}
]
}
]
Clients that already know a TEA API base URL (for example from a prior TEI discovery, configuration, or cache) may call /discovery with the purl query parameter instead of tei. Exactly one of tei or purl shall be provided; a request with neither or both is rejected with 400.
Discovery by .well-known discovery for finding an API host from an identifier alone.
Example:
https://api.example.com/v1.0.0/discovery?purl=pkg%3Amaven%2Forg.apache.logging.log4j%2Flog4j-core%402.24.3
The response shape, non-empty success array, and 404 with OBJECT_UNKNOWN when the server does not resolve the identifier are the same as for TEI lookup.
If the server does not resolve the requested TEI or /discovery endpoint shall return 404 with a TEA error response (see the 404-object-by-id-not-found response).
A response is a TEA error response only when its Content-Type is application/json (optionally with parameters such as charset) and its body is a JSON object with a string error property, typically OBJECT_UNKNOWN. Clients shall ignore properties they do not recognize and shall not reject the response for an error value they do not know, so that a later TEA version can extend error-response without turning its 404 responses into failover triggers. Other JSON 404 bodies, such as {"message":"Not Found"}, are not TEA error responses.
On a 404 TEA error response from /discovery, the client:
/discovery is missing, and shall not fail over to another endpoint solely because of the response;error value received; andA 404 that is not a TEA error response is a failed attempt; see Failover, invalid documents, and attempt bounds.
The following failure classes count as a failed attempt for the current candidate and are subject to the same total attempt bound, backoff, and TLS verification rules, whether they occur in the well-known stage or the API discovery stage:
5xx from the host being contacted404 that is not a TEA error response as defined in Unresolved identifiers (for example a web server answering for an unmounted path, or a JSON body without an error property).well-known/tea, or an invalid /discovery success body)A conforming TEA /discovery 404 (error-response, typically OBJECT_UNKNOWN) is not a failover trigger; see Unresolved identifiers.
On such a failure, the client shall select the next untried well-known endpoint that supports a compatible API version, if one is available. While doing so the client should preserve priority order from highest to lowest (applying the absent-priority equals 1 rule). Each failover connection is subject to the same TLS verification requirement. Clients should limit the total number of attempts across both stages for a discovery operation. Additional attempts should use exponential backoff. When a retry limit is reached, the client shall report that discovery could not be completed, indicating which stage failed when that is known.
Where authentication is required, clients use credentials configured for the selected TEA service, such as an API key, to obtain a TEA access token from that service’s /token endpoint. Credentials shall not be embedded in a TEI. API keys are exchanged only at the selected API’s /token endpoint; clients shall not probe /token to discover whether authentication is required.
A protected TEA resource endpoint (excluding /token) shall respond to a request without valid authentication with 401 Unauthorized and a WWW-Authenticate: Bearer challenge. When that challenge contains error="invalid_token" (
A TEA server that requires no authentication on any endpoint need not implement the /token endpoint, shall not answer any resource request with 401, and shall ignore, rather than reject, an Authorization: Bearer header a client presents anyway.
If authentication cannot be completed or recovery fails, the client shall indicate that update status could not be determined. Failures that may require user or administrator intervention include rejected or revoked credentials, expired client certificates, persistent rejection of a replacement token, and insufficient permissions. A 403 Forbidden response indicates denied authorization and shall not trigger token-replacement attempts solely because of that status. Clients shall not fail over to another endpoint solely in response to 401 or 403.
Clients shall verify server certificates for every HTTPS connection used in discovery and subsequent API access, including the server identity check of RFC 9525, and shall not use connections that fail validation.
Clients shall not automatically forward a TEA access token to a different origin, or outside the authorized API base URL of the service that issued it. API-key Basic credentials shall not be forwarded based merely on a discovery redirect; a different service requires independently configured credentials. Redirect targets used during discovery or API access shall use HTTPS and are subject to the same certificate verification requirement.
The full client authentication flow is described in Authentication. The rules above align discovery with that model and do not replace it.
How authentication or authorization failures are presented to end users is implementation specific, but they shall not be reported as evidence that no updates are available.
WWW-Authenticate: Bearer challenge without an error parameter indicates that authentication is required. A client with configured credentials may obtain an access token from the selected API’s /token endpoint and retry the resource request.error="invalid_token", the client may obtain a replacement access token from the same service and retry the original request once. Clients should not repeat this recovery attempt for the same request.Other challenges shall not be interpreted as instructions to repeatedly obtain replacement tokens.
Common errors:
/discovery, a TEA error response (application/json body with a string error property, typically OBJECT_UNKNOWN): this server does not resolve the TEI or error value; do not report that as evidence that no updates are available.404 that is not a TEA error response may mean the path is not mounted or the host is not a TEA API base; treat that as a failed discovery attempt and failover if another compatible endpoint remains. This is distinct from /token, where 404 means only that the token endpoint is not implemented.Clients should:
Servers shall not locate the actual TEA service endpoint at the /.well-known/tea
HTTP is the protocol. http and https are https://. The https scheme identifies HTTP over TLS, which this document calls HTTPS.
The .well-known endpoint shall only be available via HTTPS. The client shall verify the server certificate for that connection against the TEI domain-name, using the server identity check of RFC 9525, so that the host is the one named in the TEI.
Example of resolving a TEI to the well-known URL:
tei://products.example.com/uuid/d4d9f54a-abcf-11ee-ac79-1a52914d44b1https://products.example.com/.well-known/teaConforming deployments shall advertise only lowercase https base URLs, in .well-known/tea endpoints[].url and in /discovery servers[].rootUrl alike. A client shall reject an http base URL unless it has been explicitly configured to allow that specific base for local testing. The allowance is per configured base URL, never a global setting, so it cannot apply to a base the client learned from discovery. Credentials may be sent to a base allowed this way; a deployment that relies on it is not conforming.