Skip to content

Commit c7bd6e4

Browse files
second draft jaf
1 parent 5bcb94d commit c7bd6e4

File tree

4 files changed

+152
-21
lines changed

4 files changed

+152
-21
lines changed

README.md

+103-4
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ The fields in the table below can be used in these parts of STAC documents:
3333

3434
| Field Name | Type | Description |
3535
| -------------------- | ------------------------- | ----------- |
36-
| sa:security | Map<string, [SecureAsset Object](#secure-asset-object)> | Keyword for asset security level. |
36+
| security | Map<string, [SecureAsset Object](#secure-asset-object)> | Object that desribes the authenticated scheme and href |
3737

3838
### Additional Field Information
3939

@@ -48,9 +48,108 @@ An Asset with the Secure Assets extension will have the following fields
4848

4949
| Field Name | Type | Description |
5050
| ----------- | ------ | ----------- |
51-
| href | string | **REQUIRED**. URI to the asset. Relative and abolsolute URI are both allowed |
52-
| title | string | The displayed title for clients and users. |
53-
| sa:security | string | Keyword for asset security level |
51+
| scheme | string | **REQUIRED**. The authentification scheme used to access the data (`HttpClient` \| `S3Client` \| `PlanetaryComputerClient` \| `EarthdataClient` \| `SignedUrlClient`). |
52+
| description | string | Additional instructions for authentification |
53+
54+
### Schemes
55+
56+
The authentification schemes align with the relevant clients included in the [stac-asset](https://github.com/stac-utils/stac-asset) library.
57+
58+
| Name | Description
59+
| -- | -- |
60+
| `HttpClient` | Simple HTTP client without any authentication |
61+
| `S3Client` | Simple S3 client
62+
| `PlanetaryComputerClient` | Signs URLs with the [Planetary Computer Authentication API](https://planetarycomputer.microsoft.com/docs/reference/sas/)
63+
| `EarthdataClient` | Uses a token-based authentication to download data, from _some_ Earthdata providers, e.g. DAACs
64+
| `SignedUrlClient` | Signs URLs with a user-defined Authentification API
65+
66+
### URL Signing
67+
68+
The `SignedUrlClient` scheme indicates that authentification will be handled by an API which generates and returns a signed URL. For example, a signed URL for assets in AWS S3 can be generated with the following Lambda function code.
69+
70+
```python
71+
import boto3
72+
from botocore.client import Config
73+
import os
74+
import json
75+
76+
def lambda_handler(event, context):
77+
try:
78+
s3Client = boto3.client("s3")
79+
except Exception as e:
80+
return {
81+
"statusCode": 400,
82+
"body": json.dumps({
83+
"error": (e)
84+
})
85+
}
86+
87+
body = json.loads(event["body"])
88+
key = body["key"]
89+
bucketName = body["bucket"]
90+
91+
try:
92+
URL = s3Client.generate_presigned_url(
93+
"get_object",
94+
Params = {"Bucket": bucketName, "Key":key},
95+
ExpiresIn = 360
96+
)
97+
98+
return ({
99+
"statusCode": 200,
100+
"body": json.dumps({
101+
"signed_url": URL
102+
}),
103+
"headers":{
104+
"Access-Control-Allow-Origin": "*",
105+
"Access-Control-Allow-Headers": "*"
106+
}
107+
108+
})
109+
except Exception as e:
110+
return {
111+
"statusCode": 400,
112+
"body": json.dumps({
113+
"error": (e)
114+
})
115+
}
116+
```
117+
Where the response looks like
118+
119+
```json
120+
{
121+
"signed_url": "https://<bucket>.s3.<region>.amazonaws.com/<key>?AWSAccessKeyId=<aws access key>&Signature=<signature>&x-amz-security-token=<auth token>&Expires=<epoch expiration time>"
122+
}
123+
```
124+
125+
The authentication API can be called clientside using an AWS S3 href (`https://<bucket>.s3.<region>.amazonaws.com/<key>`) with the following code snippet.
126+
127+
```javascript
128+
let signed_url
129+
const auth_api = "";
130+
131+
function createSignedRequestBody(href) {
132+
const bucket = href.split(".")[0].split("//")[1];
133+
const key = href.split("/").slice(3).join("/").replace(/\+/g, " ");
134+
return {
135+
method: "POST",
136+
headers: {
137+
Accept: "application/json",
138+
"Content-Type": "application/json",
139+
},
140+
body: JSON.stringify({ bucket: bucket, key: key }),
141+
redirect: "follow",
142+
};
143+
};
144+
145+
Promise(
146+
fetch(auth_api, createSignedRequestBody(href))
147+
.then((resp) => resp.json())
148+
.then((respJson) => {
149+
signed_url = respJson.signed_url;
150+
})
151+
);
152+
```
54153

55154
## Contributing
56155

examples/collection.json

+9-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"stac_version": "1.0.0",
33
"stac_extensions": [
44
"https://stac-extensions.github.io/item-assets/v1.0.0/schema.json",
5-
"https://github.com/AtomicMaps/secure-assets/blob/main/json-schema/schema.json"
5+
"https://stac-extensions.github.io/secure-assets/v1.1.0/schema.json"
66
],
77
"type": "Collection",
88
"id": "collection",
@@ -47,13 +47,20 @@
4747
"roles": [
4848
"data"
4949
],
50-
"sa:security": "private"
50+
"security": {
51+
"scheme": "SignedUrlClient",
52+
"description": "Requires an authentification API"
53+
}
5154
}
5255
},
5356
"summaries": {
5457
"datetime": {
5558
"minimum": "2015-06-23T00:00:00Z",
5659
"maximum": "2019-07-10T13:44:56Z"
60+
},
61+
"security": {
62+
"scheme": ["SignedUrlClient"],
63+
"description": ["Requires an authentification API"]
5764
}
5865
},
5966
"links": [

examples/item.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"stac_version": "1.0.0",
33
"stac_extensions": [
4-
"https://github.com/AtomicMaps/secure-assets/blob/main/json-schema/schema.json"
4+
"https://stac-extensions.github.io/secure-assets/v1.1.0/schema.json"
55
],
66
"type": "Feature",
77
"id": "item",
@@ -55,7 +55,10 @@
5555
"roles": [
5656
"data"
5757
],
58-
"sa:security": "private"
58+
"security": {
59+
"scheme": "EarthdataClient",
60+
"description": "Requires a Personal Access Token"
61+
}
5962
}
6063
}
6164
}

json-schema/schema.json

+35-13
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"$schema": "http://json-schema.org/draft-07/schema#",
33
"$id": "https://stac-extensions.github.io/secure-assets/v1.0.0/schema.json#",
44
"title": "Secure Assets Extension",
5-
"description": "STAC Secure Assets Extension for STAC Items and STAC Collections.",
5+
"description": "Secure Assets STAC Extension for STAC Items and STAC Collections.",
66
"oneOf": [
77
{
88
"$comment": "This is the schema for STAC Items.",
@@ -14,6 +14,7 @@
1414
"type": "object",
1515
"required": [
1616
"type",
17+
"properties",
1718
"assets"
1819
],
1920
"properties": {
@@ -24,7 +25,7 @@
2425
"$comment": "This validates the fields in Item Assets, but does not require them.",
2526
"type": "object",
2627
"additionalProperties": {
27-
"$ref": "#/definitions/fields"
28+
"$ref": "#/definitions/secure_asset"
2829
}
2930
}
3031
}
@@ -63,7 +64,10 @@
6364
"not": {
6465
"allOf": [
6566
{
66-
"$ref": "#/definitions/fields"
67+
"$ref": "#/definitions/require_any_field"
68+
},
69+
{
70+
"$ref": "#/definitions/secure_asset"
6771
}
6872
]
6973
}
@@ -85,14 +89,28 @@
8589
"not": {
8690
"allOf": [
8791
{
88-
"$ref": "#/definitions/fields"
92+
"$ref": "#/definitions/require_any_field"
93+
},
94+
{
95+
"$ref": "#/definitions/secure_asset"
8996
}
9097
]
9198
}
9299
}
93100
}
94101
}
95102
}
103+
},
104+
{
105+
"$comment": "This is the schema for the fields in Summaries. By default, only checks the existence of the properties, but not the schema of the summaries.",
106+
"required": [
107+
"summaries"
108+
],
109+
"properties": {
110+
"summaries": {
111+
"$ref": "#/definitions/require_any_field"
112+
}
113+
}
96114
}
97115
]
98116
}
@@ -115,21 +133,25 @@
115133
"require_any_field": {
116134
"$comment": "Please list all fields here so that we can force the existence of one of them in other parts of the schemas.",
117135
"anyOf": [
118-
{"required": ["sa:security"]}
136+
{"required": ["security", "secure_asset:scheme"]}
119137
]
120138
},
121-
"fields": {
139+
"secure_asset": {
122140
"$comment": "Add your new fields here. Don't require them here, do that above in the corresponding schema.",
123141
"type": "object",
124142
"properties": {
125-
"sa:security": {
126-
"type": "string"
143+
"security": {
144+
"type": "object",
145+
"properties": {
146+
"scheme": {
147+
"type": "string"
148+
},
149+
"description": {
150+
"type": "string"
151+
}
152+
}
127153
}
128-
},
129-
"patternProperties": {
130-
"^(?!sa:)": {}
131-
},
132-
"additionalProperties": false
154+
}
133155
}
134156
}
135157
}

0 commit comments

Comments
 (0)