This project consists in a web application to easily access file objects stored within Ceph Object Storage/RADOS Gateway, using the AWS S3 protocol for object handling, and the OAuth2/OpenID Connect for authorization and authentication via the Secure Token Service (STS).
The webapp is implemented using the React, Next.js, TypeScript and TailwindCSS, as core frameworks. The OAuth2 support is provided by the Auth.js framework. All S3 operations are implemented using the official AWS SDK for javascript.
The webapp acts as client OpenID Connect/OAuth2 client and thus, registering the client is required.
The following sections describe how to configure an OpenID Connect/OAuth2 client.
Redirect URIs must be in the form of
<WEBAPP_RGW_BASE_URL>/api/auth/oauth2/callback/indigo-iam
(without the trailing /), where <WEBAPP_RGW_BASE_URL> is the
hostname of the machine hosting the application.
It is possible to configure more than one redirect URI.
For development:
http://localhost:300/api/auth/oauth2/callback/indigo-iamFor a production deployment, the redirect uri will be, for example:
https://s3webui.cloud.infn.it/api/auth/oauth2/callback/indigo-iamEnable the following scopes
emailopenidprofile
The authorization_code grant type is required.
Enable the PKCE crypto feature with SHA-256 has algorithm.
Before start the application, an environment file is needed. An example can be found at envs/example.env.
WEBAPP_RGW_BASE_URL: hostname of your deployment, for example https://s3webui.cloud.infn.it or http://localhost:3000WEBAPP_RGW_AUTH_SECRET: secret to encrypt session cookies (see below)WEBAPP_RGW_OIDC_ISSUER: OpenID Connect IssuerWEBAPP_RGW_OIDC_CLIENT_ID: OpenID Connect Client IDWEBAPP_RGW_OIDC_CLIENT_SECRETOpenID Connect Client SecretWEBAPP_RGW_OIDC_AUDIENCE: OpenID Connect AudienceWEBAPP_RGW_S3_ENDPOINT: Rados Gateway/S3 API EndpointWEBAPP_RGW_S3_REGION: Rados Gateway/S3 Region NameWEBAPP_RGW_S3_ROLE_ARN: Rados Gateway Role/S3 ARNWEBAPP_RGW_S3_ROLE_DURATION_SECONDS: Rados Gateway/S3 Role duration in seconds
The application needs a secret to encrypt/decrypt session cookies.
N.B.: This is a real secret and must be kept secure.
You can generate an WEBAPP_RGW_AUTH_SECRET with the following command:
openssl rand -base64 32If you are are going to the deploy in high availability, thus in manifold
replicas, use the same WEBAPP_RGW_AUTH_SECRET for each replica. In this way,
sessions started from a replica can be maintained also with the other replicas.
This project is configured with a CI/CD pipeline which builds Docker images for development and production releases. The images are stored here.
To start the application run
docker run --rm --name s3webui -p 8080:80 --env-file .env indigopaas/webapp-rgwIf you have trouble in reaching the Rados Gateway endpoint from within the
container, you can specify the private IP address using the --add-host flag
to the docker run command, for example
docker run \
--rm \
--name s3webui \
-d \
--add-host rgw.cloud.infn.it=10.200.0.18 \
--add-host s3webui.cloud.infn.it=10.200.0.18 \
-p 127.0.0.1:8080:80 \
--env-file .env \
indigopaas/webapp-rgwSince the usage of encrypted JWT by Better-Auth, NGINX may fail to process larger headers returning error 502. In such case, add to your NGINX server configuration:
proxy_buffers 8 8k;
proxy_buffer_size 8k;For Kubernetes Ingress Controller, set the following annotations:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: s3webui-ingress
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-buffers: "8 8k"
nginx.ingress.kubernetes.io/proxy-buffer-size: "8k"The application supports Opentelemetry instrumentation and INFN-CNAF Otello service. Telemetry is enabled by default and sends traces to https://otello.cloud.cnaf.infn.it/collector/v1/traces.
To change the OpenTelemetry OTLP collector endpoint set the environment variable
WEBAPP_RGW_OTEL_EXPORTER_OTLP_ENDPOINT=https://otello.cloud.cnaf.infn.it/collector/v1/tracesTo completely disable telemetry set the following environment variable
WEBAPP_RGW_OTEL_DISABLE_TELEMETRY=1