Skip to content

Commit 332f5aa

Browse files
committed
feat: well-known discovery via static json response
This commit: 1. Converts ./well-known/tea endpoint to a static json object with defined schema 2. Provides rules for discovery based on TEI and static well-known endpoint (see p.1) 3. Adds error type to 404 responses, which can be OBJECT_UNKNOWN or OBJECT_NOT_SHAREABLE Signed-off-by: Pavel Shukhman <[email protected]>
1 parent 1726b76 commit 332f5aa

File tree

3 files changed

+177
-15
lines changed

3 files changed

+177
-15
lines changed

discovery/readme.md

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -180,20 +180,65 @@ These point to the hosts available for the Transparency Exchange API.
180180
The TEA client connects to the host using HTTPS and validates the certificate.
181181
The URI is composed of the name with the `/.well-known/tea` prefix added.
182182

183-
This results in the base URI (without the product identifier)
184-
`https://tea.example.com/.well-known/tea/`
183+
This results in the base URI
184+
`https://tea.example.com/.well-known/tea`
185+
186+
This URI must contain static json that lists the available TEA server endpoints and supported versions.
187+
The json must conform to the [TEA Well-Known Schema](tea-well-known.schema.json).
188+
189+
Example:
190+
```json
191+
{
192+
"endpoints": [
193+
{
194+
"url": "https://api.teaexample.com",
195+
"versions":
196+
[
197+
"0.1.0-beta.1",
198+
"0.2.0-beta.2",
199+
"1.0"
200+
]
201+
},
202+
{
203+
"url": "https://api2.teaexample.com/mytea",
204+
"versions":
205+
[
206+
"1.0"
207+
]
208+
}
209+
]
210+
}
211+
```
185212

186213

187214
## Connecting to the API
188215

189-
When connecting to the `.well-known/tea` URI with the unique identifier
190-
a HTTP redirect is **required**.
216+
Clients must pick any one of the endpoints listed in the `.well-known/tea` json
217+
response. They must then construct the full URL to the API by appending the
218+
"/v" plus one of the versions listed in the `versions` array of the selected endpoint,
219+
plus "/discovery?tei=", plus the TEI that is url-encoded according to [RFC3986]
220+
and [RFC3986]).
221+
222+
Examples:
223+
1. For TEI `urn:tei:uuid:products.example.com:d4d9f54a-abcf-11ee-ac79-1a52914d44b`
224+
`https://api.teaexample.com/v0.2.0-beta.2/discovery?tei=urn%3Atei%3Auuid%3Aproducts.example.com%3Ad4d9f54a-abcf-11ee-ac79-1a52914d44b`
225+
2. For TEI `urn:tei:purl:products.example.com:pkg:deb/debian/[email protected]?arch=i386&distro=jessie`
226+
`https://api2.teaexample.com/mytea/v1.0/discovery?tei=urn%3Atei%3Apurl%3Aproducts.example.com%3Apkg%3Adeb%2Fdebian%2Fcurl%407.50.3-1%3Farch%3Di386%26distro%3Djessie`
227+
228+
The discovery endpoint is a part of the TEA OpenAPI specification.
229+
230+
If the TEI is known to the TEA server, the discovery endpoint must return at least
231+
the product release uuid, the root URL of the TEA server, the list of supported
232+
versions, plus the response may have other fields based on the current version of
233+
the TEA OpenAPI specification.
234+
235+
If the TEI is not known to the TEA server, the discovery endpoint must return a 404
236+
status code with a response describing the error.
237+
238+
TODO: Handle Auth errors (401, 403) and corresponding messages.
191239

192-
The server MUST redirect HTTP requests for that resource
193-
to the actual "context path" using one of the available mechanisms
194-
provided by HTTP (e.g., using a 301, 303, or 307 response). Clients
195-
MUST handle HTTP redirects on the `.well-known` URI. Servers MUST
196-
NOT locate the actual TEA service endpoint at the
240+
## Notes Regarding .well-known
241+
Servers MUST NOT locate the actual TEA service endpoint at the
197242
`.well-known` URI as per Section 1.1 of [RFC5785].
198243

199244
### Overview: Finding the Index using DNS result
@@ -203,7 +248,7 @@ Append the product part of the TEI to the URI found
203248
- TEI: `urn:tei:uuid:products.example.com:d4d9f54a-abcf-11ee-ac79-1a52914d44b1`
204249
- DNS record: `products.example.com`
205250
- URL: `https://products.example.com/.well-known/tea/d4d9f54a-abcf-11ee-ac79-1a52914d44b1/`
206-
- HTTP 302 redirect to "https://teapot02.consumer.example.com/tea/v2/product/d4d9f54a-abcf-11ee-ac79-1a52914d44b1'
251+
- HTTP 302 redirect to `https://teapot02.consumer.example.com/tea/v2/product/d4d9f54a-abcf-11ee-ac79-1a52914d44b1`
207252

208253
Always prefix with the https:// scheme. http (unencrypted) is not valid.
209254

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"$id": "https://cyclonedx.github.io/transparency-exchange-api/discovery/tea-well-known.schema.json",
4+
"title": "TEA .well-known discovery document",
5+
"description": "JSON Schema for the TEA .well-known/tea discovery payload that lists available TEA API endpoints and supported versions.",
6+
"type": "object",
7+
"additionalProperties": false,
8+
"required": ["endpoints"],
9+
"properties": {
10+
"endpoints": {
11+
"type": "array",
12+
"description": "List of available TEA service endpoints and their supported versions.",
13+
"minItems": 1,
14+
"items": { "$ref": "#/definitions/endpoint" }
15+
}
16+
},
17+
"definitions": {
18+
"endpoint": {
19+
"type": "object",
20+
"additionalProperties": false,
21+
"required": ["url", "versions"],
22+
"properties": {
23+
"url": {
24+
"type": "string",
25+
"format": "uri",
26+
"description": "Base URL of the TEA API endpoint (no trailing slash)."
27+
},
28+
"versions": {
29+
"type": "array",
30+
"description": "Supported TEA API versions for this endpoint. Use with the /v{version} prefix when constructing requests.",
31+
"minItems": 1,
32+
"items": {
33+
"type": "string",
34+
"pattern": "^\\d+\\.\\d+(?:\\.\\d+)?(?:-[0-9A-Za-z.-]+)?$",
35+
"examples": [
36+
"0.1.0-beta.1",
37+
"0.2.0-beta.2",
38+
"1.0.0",
39+
"1.0"
40+
],
41+
"description": "TEA OpenAPI Spec Version identifier, conforms to SemVer 2.0 (https://semver.org/)."
42+
}
43+
}
44+
}
45+
}
46+
},
47+
"examples": [
48+
{
49+
"endpoints": [
50+
{
51+
"url": "https://api.teaexample.com",
52+
"versions": ["0.1.0-beta.1", "0.2.0-beta.2", "1.0"]
53+
},
54+
{
55+
"url": "https://api2.teaexample.com/mytea",
56+
"versions": ["1.0"]
57+
}
58+
]
59+
}
60+
]
61+
}

spec/openapi.yaml

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,53 @@ paths:
378378
$ref: "#/components/responses/404-object-by-id-not-found"
379379
tags:
380380
- TEA Artifact
381+
/discovery:
382+
get:
383+
description: Discovery endpoint which resolves TEI into product release UUID.
384+
operationId: discoveryByTei
385+
parameters:
386+
- name: tei
387+
in: query
388+
required: true
389+
description: Transparency Exchange Identifier (TEI) for the product being discovered. Provide the TEI as a URL-encoded string per RFC 3986, RFC 3987.
390+
schema:
391+
type: string
392+
example: urn%3Atei%3Auuid%3Aproducts.example.com%3Ad4d9f54a-abcf-11ee-ac79-1a52914d44b
393+
responses:
394+
'200':
395+
description: Discovery information for the requested TEI
396+
content:
397+
application/json:
398+
schema:
399+
type: object
400+
additionalProperties: false
401+
properties:
402+
productReleaseUuid:
403+
description: UUID of the resolved TEA Product Release
404+
$ref: "#/components/schemas/uuid"
405+
example: d4d9f54a-abcf-11ee-ac79-1a52914d44b
406+
rootUrl:
407+
description: Root URL of the TEA server for this TEI without trailing slash
408+
type: string
409+
format: uri
410+
example: https://api.teaexample.com
411+
versions:
412+
description: Supported TEA API versions at this server without v prefix
413+
type: array
414+
minItems: 1
415+
items:
416+
type: string
417+
example: ["0.2.0-beta.2", "1.0"]
418+
required:
419+
- productReleaseUuid
420+
- rootUrl
421+
- versions
422+
'400':
423+
$ref: "#/components/responses/400-invalid-request"
424+
'404':
425+
$ref: "#/components/responses/404-object-by-id-not-found"
426+
tags:
427+
- TEA Discovery
381428
components:
382429
schemas:
383430
#
@@ -974,6 +1021,12 @@ components:
9741021
- BLAKE2b-384
9751022
- BLAKE2b-512
9761023
- BLAKE3
1024+
unknown-error-type:
1025+
type: string
1026+
description: Classification of TEA error response
1027+
enum:
1028+
- OBJECT_UNKNOWN
1029+
- OBJECT_NOT_SHAREABLE
9771030
#
9781031
# Types used in API responses
9791032
#
@@ -1039,14 +1092,16 @@ components:
10391092
application/json: {}
10401093
404-object-by-id-not-found:
10411094
description: Object requested by identifier not found
1042-
content:
1043-
application/json: {}
1044-
paginated-product:
1045-
description: A paginated response containing TEA Products
10461095
content:
10471096
application/json:
10481097
schema:
1049-
$ref: "#/components/schemas/paginated-product-response"
1098+
type: object
1099+
additionalProperties: false
1100+
properties:
1101+
error:
1102+
$ref: "#/components/schemas/unknown-error-type"
1103+
required:
1104+
- error
10501105
paginated-product-release:
10511106
description: A paginated response containing TEA Product Releases
10521107
content:
@@ -1128,6 +1183,7 @@ tags:
11281183
- name: TEA Component
11291184
- name: TEA Component Release
11301185
- name: TEA Artifact
1186+
- name: TEA Discovery
11311187
externalDocs:
11321188
description: Transparency Exchange API specification
11331189
url: https://github.com/CycloneDX/transparency-exchange-api

0 commit comments

Comments
 (0)