Skip to content

Commit 019204e

Browse files
authored
feat: Add custom filter logic for stac-auth-proxy (#388)
1 parent 6099bc9 commit 019204e

7 files changed

Lines changed: 371 additions & 156 deletions

File tree

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"""
2+
Sample custom filters for STAC Auth Proxy.
3+
This file demonstrates the structure needed for custom collection and item filters.
4+
"""
5+
6+
import dataclasses
7+
from typing import Any
8+
9+
10+
@dataclasses.dataclass
11+
class CollectionsFilter:
12+
"""Returns CQL2 filter for /collections endpoint."""
13+
14+
async def __call__(self, context: dict[str, Any]) -> str | dict[str, Any]:
15+
"""
16+
Return format:
17+
- CQL2-text string: "1=1" or "private = false"
18+
- CQL2-JSON dict: {"op": "=", "args": [{"property": "owner"}, "user123"]}
19+
20+
Examples:
21+
- Allow all: return "1=1"
22+
- User-specific: return f"owner = '{context['token']['sub']}'"
23+
- Public only: return "private = false" if not context["token"] else "1=1"
24+
- Complex: return {"op": "in", "args": [{"property": "id"}, ["col1", "col2"]]}
25+
"""
26+
return "1=1"
27+
28+
29+
@dataclasses.dataclass
30+
class ItemsFilter:
31+
"""Returns CQL2 filter for /search and /collections/{id}/items endpoints."""
32+
33+
async def __call__(self, context: dict[str, Any]) -> str | dict[str, Any]:
34+
"""
35+
Examples:
36+
- Allow all: return "1=1"
37+
- Collection-based: return f"collection = '{context['collection_id']}'"
38+
- User-specific: return f"properties.owner = '{context['token']['sub']}'"
39+
- Complex: return {"op": "in", "args": [{"property": "collection"}, approved_list]}
40+
"""
41+
return "1=1"

charts/eoapi/profiles/experimental.yaml

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,8 +369,25 @@ ingress:
369369
stac-auth-proxy:
370370
enabled: true
371371
# For testing this will be set dynamically; for production, point to your OIDC server
372-
# env:
373-
# OIDC_DISCOVERY_URL: "http://eoapi-mock-oidc-server.eoapi.svc.cluster.local:8080/.well-known/openid-configuration"
372+
env:
373+
# OIDC_DISCOVERY_URL: "http://eoapi-mock-oidc-server.eoapi.svc.cluster.local:8080/.well-known/openid-configuration"
374+
# Custom filter classes
375+
COLLECTIONS_FILTER_CLS: "stac_auth_proxy.custom_filters:CollectionsFilter"
376+
ITEMS_FILTER_CLS: "stac_auth_proxy.custom_filters:ItemsFilter"
377+
378+
# Custom filters configuration
379+
customFiltersFile: "data/stac-auth-proxy/custom_filters.py"
380+
381+
extraVolumes:
382+
- name: filters
383+
configMap:
384+
name: eoapi-stac-auth-proxy-custom-filters
385+
386+
extraVolumeMounts:
387+
- name: filters
388+
mountPath: /app/src/stac_auth_proxy/custom_filters.py
389+
subPath: custom_filters.py
390+
readOnly: true
374391

375392
######################
376393
# MOCK OIDC SERVER
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{{- if index .Values "stac-auth-proxy" "enabled" }}
2+
{{- $stacAuthProxy := index .Values "stac-auth-proxy" }}
3+
{{- if and (hasKey $stacAuthProxy "extraVolumes") $stacAuthProxy.extraVolumes }}
4+
{{- $filterFile := $stacAuthProxy.customFiltersFile | default "data/stac-auth-proxy/custom_filters.py" }}
5+
apiVersion: v1
6+
kind: ConfigMap
7+
metadata:
8+
name: eoapi-stac-auth-proxy-custom-filters
9+
labels:
10+
{{- include "eoapi.labels" . | nindent 4 }}
11+
app.kubernetes.io/component: stac-auth-proxy
12+
data:
13+
custom_filters.py: |
14+
{{ .Files.Get $filterFile | indent 4 }}
15+
{{- end }}
16+
{{- end }}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
suite: test stac-auth-proxy custom filters ConfigMap
2+
templates:
3+
- templates/_helpers/core.tpl
4+
- templates/core/stac-auth-proxy-filters-configmap.yaml
5+
6+
tests:
7+
- it: should create ConfigMap when stac-auth-proxy is enabled and extraVolumes is defined
8+
set:
9+
stac-auth-proxy.enabled: true
10+
stac-auth-proxy.extraVolumes:
11+
- name: filters
12+
configMap:
13+
name: test-filters
14+
template: templates/core/stac-auth-proxy-filters-configmap.yaml
15+
asserts:
16+
- isKind:
17+
of: ConfigMap
18+
- equal:
19+
path: metadata.name
20+
value: eoapi-stac-auth-proxy-custom-filters
21+
- isNotEmpty:
22+
path: data
23+
24+
- it: should not create ConfigMap when stac-auth-proxy is disabled
25+
set:
26+
stac-auth-proxy.enabled: false
27+
stac-auth-proxy.extraVolumes:
28+
- name: filters
29+
configMap:
30+
name: test-filters
31+
asserts:
32+
- hasDocuments:
33+
count: 0
34+
35+
- it: should not create ConfigMap when extraVolumes is not defined
36+
set:
37+
stac-auth-proxy.enabled: true
38+
asserts:
39+
- hasDocuments:
40+
count: 0
41+
42+
- it: should have correct labels
43+
set:
44+
stac-auth-proxy.enabled: true
45+
stac-auth-proxy.extraVolumes:
46+
- name: filters
47+
configMap:
48+
name: test-filters
49+
template: templates/core/stac-auth-proxy-filters-configmap.yaml
50+
asserts:
51+
- equal:
52+
path: metadata.labels["app.kubernetes.io/component"]
53+
value: stac-auth-proxy
54+
- exists:
55+
path: metadata.labels["app.kubernetes.io/name"]
56+
- exists:
57+
path: metadata.labels["app.kubernetes.io/instance"]
58+
- exists:
59+
path: metadata.labels["helm.sh/chart"]
60+
61+
- it: should use custom file path when customFiltersFile is specified
62+
set:
63+
stac-auth-proxy.enabled: true
64+
stac-auth-proxy.customFiltersFile: "data/eoepca_filters.py"
65+
stac-auth-proxy.extraVolumes:
66+
- name: filters
67+
configMap:
68+
name: test-filters
69+
template: templates/core/stac-auth-proxy-filters-configmap.yaml
70+
asserts:
71+
- isKind:
72+
of: ConfigMap
73+
- equal:
74+
path: metadata.name
75+
value: eoapi-stac-auth-proxy-custom-filters
76+
- isNotEmpty:
77+
path: data

charts/eoapi/values.yaml

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -417,17 +417,48 @@ stac-auth-proxy:
417417
enabled: false
418418
image:
419419
tag: "v0.11.1"
420-
env:
421-
ROOT_PATH: "/stac"
422-
OVERRIDE_HOST: "false"
423-
DEFAULT_PUBLIC: "true"
424-
# UPSTREAM_URL will be set dynamically in template to point to stac service
425-
# OIDC_DISCOVERY_URL must be configured when enabling auth
426420
ingress:
427421
enabled: false # Handled by main eoapi ingress
428422
service:
429423
port: 8080
430424
resources: {}
425+
env:
426+
# OIDC_DISCOVERY_URL must be configured when enabling auth (required)
427+
# UPSTREAM_URL must be set to "http://<release-name>-stac:8080" (required)
428+
ROOT_PATH: "/stac"
429+
OVERRIDE_HOST: "false"
430+
#
431+
# Authentication filters settings:
432+
DEFAULT_PUBLIC: "true" # This enables standard profile for authentication filters
433+
#
434+
# To use custom filters, ALL THREE of the following are required:
435+
# 1. Set filter class environment variables (uncomment lines below)
436+
# 2. Set customFiltersFile path (see below)
437+
# 3. Configure extraVolumes and extraVolumeMounts (see below)
438+
#
439+
# COLLECTIONS_FILTER_CLS: stac_auth_proxy.custom_filters:CollectionsFilter
440+
# ITEMS_FILTER_CLS: stac_auth_proxy.custom_filters:ItemsFilter
441+
442+
# Path to custom filters file (relative to chart root)
443+
# Creates a ConfigMap from this file - required for custom filters
444+
# customFiltersFile: "data/stac-auth-proxy/custom_filters.py"
445+
446+
# Volume referencing the ConfigMap - required for custom filters
447+
extraVolumes: []
448+
# Example (required for custom filters):
449+
# extraVolumes:
450+
# - name: filters
451+
# configMap:
452+
# name: stac-auth-proxy-filters
453+
454+
# Volume mount making filters available to container - required for custom filters
455+
extraVolumeMounts: []
456+
# Example (required for custom filters):
457+
# extraVolumeMounts:
458+
# - name: filters
459+
# mountPath: /app/src/stac_auth_proxy/custom_filters.py
460+
# subPath: custom_filters.py
461+
# readOnly: true
431462

432463
vector:
433464
enabled: true

0 commit comments

Comments
 (0)