You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Routes can be configured as requiring a valid authentication token by by specifying a blanket `default_public` rule and then explicit overrides (`private_endpoints` or `public_endpoints`) when exceptions are necessary.
66
+
Routes can be configured as requiring a valid authentication token by by specifying a blanket `default_public` rule and then explicit overrides (`private_endpoints` or `public_endpoints`).
42
67
43
68
-`DEFAULT_PUBLIC`
44
69
@@ -49,8 +74,8 @@ Routes can be configured as requiring a valid authentication token by by specify
49
74
50
75
-`PRIVATE_ENDPOINTS`
51
76
52
-
-**Description:** Endpoints explicitely marked as requiring authentication
53
-
-**Type:** JSON object mapping regex patterns to HTTP methods
77
+
-**Description:** Endpoints explicitely marked as requiring authentication, for use when `DEFAULT_PUBLIC == True`
78
+
-**Type:** JSON object mapping regex patterns to HTTP methods OR to tuples of HTTP methods and an array of strings representing required scopes.
54
79
-**Default:**
55
80
```json
56
81
{
@@ -63,7 +88,7 @@ Routes can be configured as requiring a valid authentication token by by specify
63
88
```
64
89
65
90
- `PUBLIC_ENDPOINTS`
66
-
- **Description:** Endpoints explicitely marked as not requiring authentication
91
+
- **Description:** Endpoints explicitely marked as not requiring authentication, for use when `DEFAULT_PUBLIC == False`
67
92
- **Type:** JSON object mapping regex patterns to HTTP methods
68
93
- **Default:**
69
94
```json
@@ -116,14 +141,6 @@ Routes can be configured as requiring a valid authentication token by by specify
116
141
117
142
## Architecture
118
143
119
-
### Application Structure
120
-
121
-
```mermaid
122
-
graph TD
123
-
Client --> Proxy[STAC Auth Proxy]
124
-
Proxy --> STAC[Internal STAC API]
125
-
```
126
-
127
144
### Middleware Stack
128
145
129
146
The middleware stack is processed in reverse order (bottom to top):
@@ -136,17 +153,17 @@ The middleware stack is processed in reverse order (bottom to top):
136
153
137
154
2. **BuildCql2FilterMiddleware**
138
155
139
-
- Builds CQL2 filters based on user context
140
-
- Different handling for GET vs POST/PUT/PATCH requests
156
+
- Builds CQL2 filters based on request context
141
157
- Stores filter in request state
142
158
143
159
3. **ApplyCql2FilterMiddleware**
144
160
161
+
- Retrieves filter from request state
145
162
- Applies the built CQL2 filter to requests
146
163
- Modifies query strings for GET requests
147
164
- Modifies JSON bodies for POST/PUT/PATCH requests
148
165
149
-
4.**OpenApiMiddleware** (optional)
166
+
4. **OpenApiMiddleware**
150
167
151
168
- Modifies OpenAPI specification
152
169
- Adds security requirements
@@ -156,104 +173,41 @@ The middleware stack is processed in reverse order (bottom to top):
156
173
- Adds processing time headers
157
174
- Useful for monitoring/debugging
158
175
159
-
### Request Flow
176
+
### Data filtering via CQL2
160
177
161
-
#### GET Request Flow
178
+
In order to provide row-level content filtering, the system supports generating CQL2 filters based on request context. These CQL2 filters are then set on outgoing requests prior to the upstream API.
179
+
180
+
> [!IMPORTANT]
181
+
> The upstream STAC API must support the [STAC API Filter Extension](https://github.com/stac-api-extensions/filter/blob/main/README.md).
182
+
183
+
> [!TIP]
184
+
> Integration with external authorization systems (e.g. [Open Policy Agent](https://www.openpolicyagent.org/)) can be achieved by replacing the default `BuildCql2FilterMiddleware` with a custom async middleware that is capable of generating [`cql2.Expr` objects](https://developmentseed.org/cql2-rs/latest/python/#cql2.Expr).
185
+
186
+
#### Example GET Request Flow
162
187
163
188
```mermaid
164
189
sequenceDiagram
165
190
Client->>Proxy: GET /collections
166
191
Note over Proxy: EnforceAuth checks credentials
167
192
Note over Proxy: BuildCql2Filter creates filter immediately
168
193
Note over Proxy: ApplyCql2Filter modifies query string
169
-
Proxy->>STAC API: Modified GET request
170
-
STAC API->>Client: Filtered response
194
+
Proxy->>STAC API: GET /collection?filter=(collection=landsat)
195
+
STAC API->>Client: Response
171
196
```
172
197
173
-
#### POST Request Flow
174
-
175
-
```mermaid
176
-
sequenceDiagram
177
-
Client->>Proxy: POST /search
178
-
Note over Proxy: EnforceAuth checks credentials
179
-
Note over Proxy: BuildCql2Filter accumulates body
180
-
Note over Proxy: BuildCql2Filter creates filter
181
-
Note over Proxy: ApplyCql2Filter modifies body
182
-
Proxy->>STAC API: Modified POST request
183
-
STAC API->>Client: Filtered response
184
-
```
185
-
186
-
## Key Components
187
-
188
-
### CQL2 Filter System
189
-
190
-
The CQL2 filtering system is split into two middlewares for separation of concerns:
- Debug endpoint for troubleshooting (when enabled)
224
-
225
-
This design provides a robust, secure, and efficient proxy layer for STAC APIs while maintaining flexibility for different deployment scenarios and requirements.
|`POST`|`/collections/{collection_id}/items`| Create | Item | Validate body with generated CQL2 query. |
235
-
|`PUT`|`/collections/{collection_id}/items/{item_id}`| Update | Item | Fetch STAC Item and validate CQL2 query; merge STAC Item with body and validate with generated CQL2 query. |
236
-
|`DELETE`|`/collections/{collection_id}/items/{item_id}`| Delete | Item | Fetch STAC Item and validate with CQL2 query. |
237
-
238
-
#### Recipes
239
-
240
-
Only return collections that are mentioned in a `collections` array encoded within the auth token.
| ❌ (#22) |`PUT`|`/collections/{collection_id}}`| Update | Collection | Fetch Collection and validate CQL2 query; merge Item with body and validate with generated CQL2 query. |
207
+
| ❌ (#22) |`DELETE`|`/collections/{collection_id}`| Delete | Collection | Fetch Collectiion and validate with CQL2 query. |
| ❌ (#21) |`POST`|`/collections/{collection_id}/items`| Create | Item | Validate body with generated CQL2 query. |
211
+
| ❌ (#21) |`PUT`|`/collections/{collection_id}/items/{item_id}`| Update | Item | Fetch Item and validate CQL2 query; merge Item with body and validate with generated CQL2 query. |
212
+
| ❌ (#21) |`DELETE`|`/collections/{collection_id}/items/{item_id}`| Delete | Item | Fetch Item and validate with CQL2 query. |
213
+
| ❌ (#21) |`POST`|`/collections/{collection_id}/bulk_items`| Create | Item | Validate items in body with generated CQL2 query. |
0 commit comments