Skip to content

Commit d8c6b57

Browse files
authored
feat: Document cloud-native authentication for bucket access. (#364)
1 parent ec6d93f commit d8c6b57

File tree

6 files changed

+184
-1
lines changed

6 files changed

+184
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
- Added documentation for cloud-native bucket access [#364](https://github.com/developmentseed/eoapi-k8s/pull/364)
11+
1012
### Added
1113

1214
## Changed

docs/aws-eks.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,3 +216,78 @@ Assert that things are set up correctly:
216216
# service/nginx-ingress-nginx-controller LoadBalancer 10.100.36.152 eoapi-k8s-553d3ea234b-3eef2e6e61e5d161.elb.us-west-1.amazonaws.com 80:30342/TCP,443:30742/TCP 2d17h
217217
# service/nginx-ingress-nginx-controller-admission ClusterIP 10.100.34.22 <none> 443/TCP 2d17h
218218
```
219+
220+
---
221+
222+
## Configure IRSA for S3 Bucket Access
223+
224+
eoAPI services (especially the raster API) need to access COG files in S3 buckets. Instead of using long-lived credentials, use IRSA (IAM Roles for Service Accounts) for secure, temporary credential access:
225+
226+
1. **Create an IAM policy** for S3 bucket access:
227+
228+
```sh
229+
cat <<EOF > eoapi-s3-policy.json
230+
{
231+
"Version": "2012-10-17",
232+
"Statement": [
233+
{
234+
"Effect": "Allow",
235+
"Action": [
236+
"s3:GetObject",
237+
"s3:ListBucket"
238+
],
239+
"Resource": [
240+
"arn:aws:s3:::your-bucket-name/*",
241+
"arn:aws:s3:::your-bucket-name"
242+
]
243+
}
244+
]
245+
}
246+
EOF
247+
248+
aws iam create-policy \
249+
--policy-name eoapi-s3-access \
250+
--policy-document file://eoapi-s3-policy.json
251+
```
252+
253+
2. **Create an IAM role and service account**:
254+
255+
```sh
256+
eksctl create iamserviceaccount \
257+
--name eoapi-sa \
258+
--namespace default \
259+
--cluster $CLUSTER_NAME \
260+
--region $REGION \
261+
--attach-policy-arn arn:aws:iam::${AWS_ACCOUNT_ID}:policy/eoapi-s3-access \
262+
--approve
263+
```
264+
265+
This command automatically creates a service account with the necessary annotation:
266+
```yaml
267+
# This is what eksctl creates for you:
268+
apiVersion: v1
269+
kind: ServiceAccount
270+
metadata:
271+
name: eoapi-sa
272+
namespace: default
273+
annotations:
274+
eks.amazonaws.com/role-arn: arn:aws:iam::${AWS_ACCOUNT_ID}:role/eksctl-${CLUSTER_NAME}-addon-iamserviceaccount-default-eoapi-sa
275+
```
276+
277+
3. **Configure EOAPI** to use the service account in your `values.yaml`:
278+
279+
```yaml
280+
serviceAccount:
281+
create: false # We already created it with eksctl
282+
name: eoapi-sa
283+
```
284+
285+
**Alternative:** If you prefer to let the Helm chart create the service account, skip step 2 and use:
286+
```yaml
287+
serviceAccount:
288+
create: true
289+
annotations:
290+
eks.amazonaws.com/role-arn: arn:aws:iam::${AWS_ACCOUNT_ID}:role/your-existing-iam-role
291+
```
292+
293+
The raster service will automatically use IRSA credentials via the AWS SDK credential chain. No hardcoded credentials needed!

docs/azure.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,27 @@ multidim:
221221
<<: *commonVolumeConfig
222222
```
223223

224+
## Azure Blob Storage Authentication
225+
226+
eoAPI services (particularly the raster API) need to access COG files stored in Azure Blob Storage. With Azure Workload Identity configured (as shown above), authentication happens automatically:
227+
228+
1. **Grant storage access** to your managed identity:
229+
```bash
230+
CLIENT_ID=$(az identity show -g <resource-group> -n eoapi-identity --query clientId -o tsv)
231+
232+
az role assignment create \
233+
--role "Storage Blob Data Reader" \
234+
--assignee $CLIENT_ID \
235+
--scope /subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.Storage/storageAccounts/<storage-account>
236+
```
237+
238+
2. **Automatic authentication**: The raster service (titiler-pgstac) uses GDAL's `/vsiaz/` driver, which automatically authenticates using:
239+
- Workload Identity credentials (via service account annotations)
240+
- Managed Identity (if running on Azure VMs)
241+
- Environment variables (if set)
242+
243+
No additional configuration or hardcoded credentials needed!
244+
224245
## Azure Managed Identity Setup
225246

226247
To use Azure Managed Identity with your Kubernetes cluster:

docs/configuration.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,42 @@ pgstacBootstrap:
137137
context_stats_ttl: "12 hours"
138138
```
139139

140+
## Cloud Storage Authentication
141+
142+
eoAPI services access COG files in cloud storage buckets. Use cloud-native authentication instead of long-lived credentials:
143+
144+
### AWS (IRSA)
145+
146+
```yaml
147+
serviceAccount:
148+
create: true
149+
annotations:
150+
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/eoapi-s3-access
151+
```
152+
153+
The raster service automatically uses IRSA credentials via the AWS SDK credential chain.
154+
155+
### Azure (Workload Identity)
156+
157+
```yaml
158+
serviceAccount:
159+
create: true
160+
annotations:
161+
azure.workload.identity/client-id: "your-client-id"
162+
azure.workload.identity/tenant-id: "your-tenant-id"
163+
```
164+
165+
### GCP (Workload Identity)
166+
167+
```yaml
168+
serviceAccount:
169+
create: true
170+
annotations:
171+
iam.gke.io/gcp-service-account: eoapi-gcs-sa@project.iam.gserviceaccount.com
172+
```
173+
174+
All services using GDAL (raster API with titiler-pgstac) automatically use these credentials through their respective cloud SDKs. No environment variables or hardcoded credentials needed.
175+
140176
## Ingress Configuration
141177

142178
Unified ingress configuration supporting both NGINX and Traefik:

docs/gcp-gke.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,52 @@ helm upgrade --install cert-manager jetstack/cert-manager \
124124
```
125125

126126
Now we are ready to install eoapi. See the [eoapi installation instructions](./helm-install.md) for more details.
127+
128+
# Configure Workload Identity for GCS Bucket Access
129+
130+
eoAPI services need to access COG files in GCS buckets. Use Workload Identity for secure, temporary credential access instead of long-lived credentials:
131+
132+
1. **Enable Workload Identity on your cluster** (if not already enabled):
133+
```bash
134+
gcloud container clusters update sandbox \
135+
--workload-pool=PROJECT_ID.svc.id.goog \
136+
--zone=us-central1-a
137+
```
138+
139+
2. **Create a Google Service Account**:
140+
```bash
141+
gcloud iam service-accounts create eoapi-gcs-sa \
142+
--display-name="eoAPI GCS Service Account"
143+
```
144+
145+
3. **Grant GCS permissions** to the service account:
146+
```bash
147+
# For specific bucket access
148+
gsutil iam ch serviceAccount:eoapi-gcs-sa@PROJECT_ID.iam.gserviceaccount.com:objectViewer gs://your-bucket-name
149+
150+
# Or use IAM roles for multiple buckets
151+
gcloud projects add-iam-policy-binding PROJECT_ID \
152+
--member="serviceAccount:eoapi-gcs-sa@PROJECT_ID.iam.gserviceaccount.com" \
153+
--role="roles/storage.objectViewer"
154+
```
155+
156+
4. **Create Kubernetes service account** and bind it:
157+
```bash
158+
kubectl create serviceaccount eoapi-sa -n eoapi
159+
160+
gcloud iam service-accounts add-iam-policy-binding eoapi-gcs-sa@PROJECT_ID.iam.gserviceaccount.com \
161+
--role roles/iam.workloadIdentityUser \
162+
--member "serviceAccount:PROJECT_ID.svc.id.goog[eoapi/eoapi-sa]"
163+
164+
kubectl annotate serviceaccount eoapi-sa -n eoapi \
165+
iam.gke.io/gcp-service-account=eoapi-gcs-sa@PROJECT_ID.iam.gserviceaccount.com
166+
```
167+
168+
5. **Configure eoAPI** in your `values.yaml`:
169+
```yaml
170+
serviceAccount:
171+
create: false # We already created it
172+
name: eoapi-sa
173+
```
174+
175+
The raster service will automatically use Workload Identity credentials. No hardcoded credentials needed!

docs/stac-auth-proxy.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ external_links:
1212

1313
## Solution Overview
1414

15-
We have implemented support for STAC Auth Proxy integration with EOAPI-K8S through service-specific ingress control. This feature allows the STAC service to be accessible only internally while other services remain externally available.
15+
We have implemented support for STAC Auth Proxy integration with eoAPI-K8S through service-specific ingress control. This feature allows the STAC service to be accessible only internally while other services remain externally available.
1616

1717
## Implementation Details
1818

0 commit comments

Comments
 (0)