Skip to content

Commit 665245d

Browse files
committed
Rework readme
1 parent 89d6a3f commit 665245d

File tree

1 file changed

+219
-5
lines changed

1 file changed

+219
-5
lines changed

README.md

Lines changed: 219 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,226 @@
33
> [!WARNING]
44
> This project is currently in active development and may change drastically in the near future while we work towards solidifying a first release.
55
6-
STAC Auth Proxy is a proxy API that mediates between the client and and some internally accessible STAC API in order to provide a flexible authentication mechanism.
6+
STAC Auth Proxy is a proxy API that mediates between the client and an internally accessible STAC API in order to provide a flexible authentication, authorization, and content filtering mechanism.
77

88
## Features
99

10-
- 🔐 Selectively apply OIDC auth to some or all endpoints & methods
11-
- 📖 Augments [OpenAPI](https://swagger.io/specification/) with auth information, keeping auto-generated docs (e.g. [Swagger UI](https://swagger.io/tools/swagger-ui/)) accurate
10+
- 🔐 Authentication: Selectively apply OIDC auth to some or all endpoints & methods
11+
- 🎟️ Content Filtering: Apply CQL2 filters to client requests, filtering API content based on user context
12+
- 📖 OpenAPI Augmentation: Update [OpenAPI](https://swagger.io/specification/) with security requirements, keeping auto-generated docs (e.g. [Swagger UI](https://swagger.io/tools/swagger-ui/)) accurate
13+
14+
## Configuration
15+
16+
### Core Settings
17+
18+
- `DEBUG`
19+
20+
- Enables debug mode and `/_debug` endpoint
21+
- **Type:** boolean
22+
- **Default:** `false`
23+
- **Example:** `true`
24+
25+
- `UPSTREAM_URL`
26+
- The STAC API to proxy requests to
27+
- **Type:** HTTP(S) URL
28+
- **Required:** Yes
29+
- **Example:** `https://your-stac-api.com/stac`
30+
31+
### Authentication
32+
33+
- `OIDC_DISCOVERY_URL`
34+
- OpenID Connect discovery document URL
35+
- **Type:** HTTP(S) URL
36+
- **Required:** Yes
37+
- **Example:** `https://auth.example.com/.well-known/openid-configuration`
38+
39+
### Access Control
40+
41+
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.
42+
43+
- `DEFAULT_PUBLIC`
44+
45+
- **Description:** Default access policy for endpoints
46+
- **Type:** boolean
47+
- **Default:** `false`
48+
- **Example:** `false`, `1`, `True`
49+
50+
- `PRIVATE_ENDPOINTS`
51+
52+
- **Description:** Endpoints explicitely marked as requiring authentication
53+
- **Type:** JSON object mapping regex patterns to HTTP methods
54+
- **Default:**
55+
```json
56+
{
57+
"^/collections$": ["POST"],
58+
"^/collections/([^/]+)$": ["PUT", "PATCH", "DELETE"],
59+
"^/collections/([^/]+)/items$": ["POST"],
60+
"^/collections/([^/]+)/items/([^/]+)$": ["PUT", "PATCH", "DELETE"],
61+
"^/collections/([^/]+)/bulk_items$": ["POST"]
62+
}
63+
```
64+
65+
- `PUBLIC_ENDPOINTS`
66+
- **Description:** Endpoints explicitely marked as not requiring authentication
67+
- **Type:** JSON object mapping regex patterns to HTTP methods
68+
- **Default:**
69+
```json
70+
{
71+
"^/api.html$": ["GET"],
72+
"^/api$": ["GET"]
73+
}
74+
```
75+
76+
### API Documentation
77+
78+
- `OPENAPI_SPEC_ENDPOINT`
79+
- Path to serve OpenAPI specification
80+
- **Type:** string or null
81+
- **Default:** `null` (disabled)
82+
- **Example:** `/api`
83+
84+
### Filtering
85+
86+
- `ITEMS_FILTER`
87+
88+
- Configuration for item-level filtering
89+
- **Type:** JSON object with class configuration
90+
- **Default:** `null`
91+
- Components:
92+
- `cls`: Python import path
93+
- `args`: List of positional arguments
94+
- `kwargs`: Dictionary of keyword arguments
95+
- **Example:**
96+
```json
97+
{
98+
"cls": "my_package.filters.OrganizationFilter",
99+
"args": ["org1"],
100+
"kwargs": {
101+
"field_name": "properties.organization"
102+
}
103+
}
104+
```
105+
106+
- `ITEMS_FILTER_ENDPOINTS`
107+
- Where to apply item filtering
108+
- **Type:** JSON object mapping regex patterns to HTTP methods
109+
- **Default:**
110+
```json
111+
{
112+
"^/search$": ["POST"],
113+
"^/collections/([^/]+)/items$": ["GET", "POST"]
114+
}
115+
```
116+
117+
## Architecture
118+
119+
### Application Structure
120+
121+
```mermaid
122+
graph TD
123+
Client --> Proxy[STAC Auth Proxy]
124+
Proxy --> STAC[Internal STAC API]
125+
```
126+
127+
### Middleware Stack
128+
129+
The middleware stack is processed in reverse order (bottom to top):
130+
131+
1. **EnforceAuthMiddleware**
132+
133+
- Handles authentication and authorization
134+
- Configurable public/private endpoints
135+
- OIDC integration
136+
137+
2. **BuildCql2FilterMiddleware**
138+
139+
- Builds CQL2 filters based on user context
140+
- Different handling for GET vs POST/PUT/PATCH requests
141+
- Stores filter in request state
142+
143+
3. **ApplyCql2FilterMiddleware**
144+
145+
- Applies the built CQL2 filter to requests
146+
- Modifies query strings for GET requests
147+
- Modifies JSON bodies for POST/PUT/PATCH requests
148+
149+
4. **OpenApiMiddleware** (optional)
150+
151+
- Modifies OpenAPI specification
152+
- Adds security requirements
153+
- Only active if `openapi_spec_endpoint` is configured
154+
155+
5. **AddProcessTimeHeaderMiddleware**
156+
- Adds processing time headers
157+
- Useful for monitoring/debugging
158+
159+
### Request Flow
160+
161+
#### GET Request Flow
162+
163+
```mermaid
164+
sequenceDiagram
165+
Client->>Proxy: GET /collections
166+
Note over Proxy: EnforceAuth checks credentials
167+
Note over Proxy: BuildCql2Filter creates filter immediately
168+
Note over Proxy: ApplyCql2Filter modifies query string
169+
Proxy->>STAC API: Modified GET request
170+
STAC API->>Client: Filtered response
171+
```
172+
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:
191+
192+
1. **Builder (`BuildCql2FilterMiddleware`)**
193+
194+
```python
195+
async def set_filter(body: Optional[dict] = None) -> None:
196+
cql2_filter = await filter_builder({
197+
"req": {
198+
"path": request.url.path,
199+
"method": request.method,
200+
"query_params": dict(request.query_params),
201+
"path_params": requests.extract_variables(request.url.path),
202+
"headers": dict(request.headers),
203+
"body": body,
204+
},
205+
**scope["state"],
206+
})
207+
```
208+
209+
- Creates filters based on request context
210+
- Handles both GET and POST requests differently
211+
- Validates filters before applying
212+
213+
2. **Applier (`ApplyCql2FilterMiddleware`)**
214+
- Modifies requests to include the built filter
215+
- GET: Modifies query string
216+
- POST/PUT/PATCH: Modifies JSON body
217+
218+
## Error Handling
219+
220+
- JSON parsing errors are caught and logged
221+
- Filter validation before application
222+
- Authentication errors handled by middleware
223+
- 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.
12226

13227
### CQL2 Filters
14228

@@ -34,8 +248,8 @@ Only return collections that are mentioned in a `collections` array encoded with
34248
Set up connection to upstream STAC API and the OpenID Connect provider by setting the following environment variables:
35249

36250
```bash
37-
export STAC_AUTH_PROXY_UPSTREAM_URL="https://some.url"
38-
export STAC_AUTH_PROXY_OIDC_DISCOVERY_URL="https://your-openid-connect-provider.com/.well-known/openid-configuration"
251+
export UPSTREAM_URL="https://some.url"
252+
export OIDC_DISCOVERY_URL="https://your-openid-connect-provider.com/.well-known/openid-configuration"
39253
```
40254

41255
Install software:

0 commit comments

Comments
 (0)