mirror of
https://github.com/versity/versitygw.git
synced 2026-09-24 17:04:16 +00:00
feat: add standalone IAM support in WebGUI
Gates bucket listing behind an identity policy, lets browsers reach the standalone IAM API, and turns the WebUI into a dashboard for S3, IAM, or both.
**Bucket listing.** `ListBuckets` is now gated by the new `s3:ListAllMyBuckets` action, evaluated against `arn:aws:s3:::*`. The request names no bucket, so only identity policies apply — there is no resource policy to combine with, which is the same shape `CreateBucket` already had, so both now share one identity-only evaluation path. Root and admin bypass it, and backends with no identity-policy layer keep listing as before since their listing is already narrowed to the caller's own buckets. The action is IAM-only and is deliberately absent from the bucket-policy action list.
**Fixed bucket ownership.** The standalone IAM client has no per-user ownership to express — accounts are all plain users, cannot be enumerated, and access is decided by policy rather than ACL — so it now implements `auth.FixedBucketOwner` and every bucket is owned by root. Bucket creation stops resolving an owner, `ListBuckets` returns every bucket to every caller (what they may then do with one stays a per-request policy decision), and the admin `ChangeBucketOwner` reports method-not-supported. Other IAM backends are untouched.
**IAM service CORS.** `--cors-allow-origin` now applies to the `iam` command: it answers preflights and stamps the CORS headers, mirroring back the requested method and headers rather than enumerating the SigV4 header set. Without it no browser can reach the IAM API at all, so setting `--webui` without it falls back to `*` with a warning. The chart gets `iamServer.corsAllowOrigin`.
**WebUI.** New IAM pages for users, roles and OIDC providers, signing IAM/STS query-form requests directly from the browser. Navigation is capability-gated rather than role-gated: on sign-in the session probes the S3, admin and IAM endpoints independently and each page shows only what those credentials actually reach, so one build serves an IAM-only dashboard, an S3-only dashboard, and a combined one. The login page takes an optional IAM endpoint, seeded from the new `--webui-iam-gateways` (chart: `webui.iamGateways`) — never auto-detected, since the IAM service is a separate process. The WebUI can also be hosted by `versitygw iam` itself, for deployments with no S3 gateway behind it.
**The admin API is ignored once an IAM endpoint is in play.** The IAM service is then the user directory and bucket ownership is fixed, which leaves the admin API no job: the session is given no admin endpoint at all, its login field is hidden, `users.html` redirects to its IAM counterpart, and every admin-only surface stays off screen. Dashboard and Buckets remain available to any S3 session in such a deployment, running on the S3 and IAM APIs alone and surfacing each denial per action instead of redirecting.
Also fixes two WebUI bugs: embedded assets went out with a zero modification time and no `Cache-Control`, so browsers treated them as fresh for centuries and an upgraded gateway served new HTML against stale JS — they now revalidate against an ETag; and the login page's advanced-options section clipped its last field, since it animated to a height named in the stylesheet rather than the one it measures now.
**Usage**
IAM-only dashboard, served by the IAM service:
versitygw iam --port :7076 --webui :8080 --cors-allow-origin http://localhost:8080/
IAM + S3, dashboard served by the IAM service — point it at the gateway with `--webui-gateways`, and let the gateway accept the dashboard's origin:
versitygw iam --port :7076 --webui :8080 --webui-gateways http://localhost:7070/ --cors-allow-origin http://localhost:8080/
versitygw --port :7070 --cors-allow-origin http://localhost:8080/ posix /data
IAM + S3, dashboard served by the S3 gateway — point it at the IAM service with `--webui-iam-gateways`, and let the IAM service accept the dashboard's origin:
versitygw --port :7070 --webui :8080 --webui-iam-gateways http://localhost:7076/ posix /data
versitygw iam --port :7076 --cors-allow-origin http://localhost:8080/
This commit is contained in:
+1
-1
@@ -2,7 +2,7 @@ apiVersion: v2
|
||||
name: versitygw
|
||||
description: A Helm chart for deploying the Versity S3 Gateway on Kubernetes
|
||||
type: application
|
||||
version: 0.4.0
|
||||
version: 0.4.1
|
||||
sources:
|
||||
- https://github.com/versity/versitygw
|
||||
icon: https://raw.githubusercontent.com/versity/versitygw/main/webui/web/assets/images/Versity-logo-blue-horizontal.png
|
||||
|
||||
+2
-1
@@ -102,7 +102,7 @@ gateway:
|
||||
| **Ingress** | `ingress.enabled=true`, `ingress.className`, `ingress.hosts`, `ingress.tls` |
|
||||
| **HTTPRoute** | `httpRoute.enabled=true` — Gateway API successor to Ingress for S3 API; also `admin.httpRoute.enabled=true` and `webui.httpRoute.enabled=true` to expose the admin API and/or WebUI |
|
||||
| **Admin API** | `admin.enabled=true` — exposes a separate management API on `admin.port` (default `7071`) |
|
||||
| **WebUI** | `webui.enabled=true` — browser-based management UI on `webui.port` (default `8080`); set `webui.apiGateways` and `webui.adminGateways` to your externally reachable endpoints |
|
||||
| **WebUI** | `webui.enabled=true` — browser-based management UI on `webui.port` (default `8080`); set `webui.apiGateways` and `webui.adminGateways` to your externally reachable endpoints, and `webui.iamGateways` when `iam.type=standalone` so the login page offers the IAM service (the WebUI then ignores the admin API entirely — the IAM service manages users, and buckets are managed over the S3 API) |
|
||||
| **Website Hosting** | `website.enabled=true` — static website hosting endpoint on `website.port` (default `8090`); optionally set `website.domain` for virtual-host routing (e.g. `example.com`), or omit it for catch-all mode where the full hostname is the bucket name |
|
||||
| **IAM** | `iam.enabled=true` — identity and access management. `iam.type=internal` (default) stores accounts in a flat file alongside backend data; `iam.type=standalone` delegates to a separate standalone IAM API service — see [Standalone IAM Service](#standalone-iam-service) below |
|
||||
| **Persistence** | `persistence.enabled=true` — provisions a PVC for backend data and IAM storage; defaults to `10Gi`, or uses a hostPath volume specified by `persistence.hostPath` |
|
||||
@@ -146,6 +146,7 @@ Key points:
|
||||
- **Private mTLS endpoint**: gateways reach the standalone IAM service over a private endpoint (`iamServer.private.port`, default `7443`) that always requires mutual TLS on TCP. Provide certificates either via `existingSecret` (bring your own `tls.crt`/`tls.key`/`ca.crt`) or `certificate.create=true` to auto-provision via cert-manager.
|
||||
- **Shared CA requirement**: when using cert-manager auto-provisioning, `iamServer.private.certificate.issuerRef` and `iam.standalone.certificate.issuerRef` **must reference the same CA-type issuer** (an `Issuer`/`ClusterIssuer` of kind `CA`, or a Vault issuer) — one that populates `ca.crt` in the resulting Secret. Both sides verify their peer using their own certificate's `ca.crt`, which only works when both certificates share the same issuing CA.
|
||||
- **External IAM service**: to point a gateway at a standalone IAM service deployed outside this chart (or by a separate chart release), set `iam.standalone.endpoint` to its `host:port` and provide the mTLS material via `iam.standalone.certificate.existingSecret`.
|
||||
- **WebUI access**: to manage IAM users from the WebUI, set `webui.iamGateways` to the URL a browser can reach `iamServer` on, and `iamServer.corsAllowOrigin` to the WebUI's own origin. Every WebUI call to the IAM API is cross-origin, so without `corsAllowOrigin` the browser blocks it and the WebUI's IAM navigation silently never appears.
|
||||
- **Secret rotation**: the processes load mTLS material and environment-based credentials at startup. After a referenced Secret rotates, restart both Deployments or configure a Secret-reloader controller through `deploymentAnnotations` and `iamServer.deploymentAnnotations`.
|
||||
|
||||
## Scaling and Persistence
|
||||
|
||||
@@ -195,6 +195,10 @@ spec:
|
||||
- name: VGW_WEBUI_ADMIN_GATEWAYS
|
||||
value: {{ .Values.webui.adminGateways | join "," | quote }}
|
||||
{{- end }}
|
||||
{{- if .Values.webui.iamGateways }}
|
||||
- name: VGW_WEBUI_IAM_GATEWAYS
|
||||
value: {{ .Values.webui.iamGateways | join "," | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
# Website Hosting
|
||||
{{- if .Values.website.enabled }}
|
||||
|
||||
@@ -115,6 +115,10 @@ spec:
|
||||
- name: VGW_IAM_DISABLE_OIDC_THUMBPRINT_AUTOFETCH
|
||||
value: "true"
|
||||
{{- end }}
|
||||
{{- if .Values.iamServer.corsAllowOrigin }}
|
||||
- name: VGW_CORS_ALLOW_ORIGIN
|
||||
value: {{ .Values.iamServer.corsAllowOrigin | quote }}
|
||||
{{- end }}
|
||||
{{- if .Values.iamServer.tls.enabled }}
|
||||
- name: VGW_CERT
|
||||
value: /certs/tls.crt
|
||||
|
||||
@@ -246,6 +246,16 @@ webui:
|
||||
# Kubernetes because it uses the internal pod IP addresses.
|
||||
adminGateways: []
|
||||
# - s3-admin.example.com
|
||||
# List of standalone IAM service endpoints offered on the WebUI login page.
|
||||
# Unlike the two lists above there is nothing to auto-generate: the IAM
|
||||
# service is a separate process, so the gateway cannot discover its address.
|
||||
# Setting this also tells the WebUI that the standalone IAM service, not the
|
||||
# admin API, manages this deployment: the admin endpoint is ignored entirely
|
||||
# (hidden from the login page along with the Users tab and every other
|
||||
# admin-API surface), and bucket management runs over the S3 API instead.
|
||||
# Point it at iamServer.service (see the iamServer section) or its ingress.
|
||||
iamGateways: []
|
||||
# - https://iam.example.com
|
||||
# --- Ingress ---
|
||||
# Expose the WebUI via a Kubernetes Ingress resource.
|
||||
# Requires an ingress controller (e.g. nginx, traefik) to be installed in the cluster.
|
||||
@@ -401,6 +411,12 @@ iamServer:
|
||||
# instead of auto-fetching it over an outbound TLS connection to the
|
||||
# caller-supplied URL. Recommended for restricted/air-gapped clusters.
|
||||
disableOidcThumbprintAutofetch: false
|
||||
# Access-Control-Allow-Origin for the control-plane API. Required before a
|
||||
# browser can reach this service: the WebUI is served from another origin, so
|
||||
# every call it makes is cross-origin and is blocked without this. Set it to
|
||||
# the WebUI's own origin (see webui.ingress) when webui.iamGateways points
|
||||
# here. Empty leaves the API usable by CLI and SDK clients only.
|
||||
corsAllowOrigin: ""
|
||||
# Optional TLS for the public control-plane API. No cert-manager automation
|
||||
# here -- bring your own Secret (must contain tls.crt / tls.key).
|
||||
tls:
|
||||
|
||||
Reference in New Issue
Block a user