# HTTPS for MinIO (presigned URLs and mixed content)

If the SPA is served over **`https://`**, the browser blocks embedding or opening **`http://…:19000`** presigned MinIO URLs (mixed active content).

The built-in evidence viewer proxies through **`GET /api/v1/application-drafts/…/evidence/content`** so previews work without exposing MinIO to HTTPS.  

To restore **working direct presigned URLs** (new-tab open, integrations, downloads that bypass the API):

1. **Terminate TLS on a hostname that points at MinIO’s S3 port** (`MINIO_API_PORT`, default **19000**), e.g. `https://minio-api.example.com` → nginx → `127.0.0.1:19000`.
2. **Set the same public base URL** in `.env` (no trailing slash), then restart Compose so **`be0`** and **`minio`** pick it up:

| Variable | Role |
|---------|------|
| **`S3_PUBLIC_ENDPOINT_URL`** | Host used when **`be0`** signs presigned GET/PUT URLs (must match what the browser uses). |
| **`MINIO_SERVER_URL`** | MinIO server URL advertised to clients (console / redirects). Should match **`S3_PUBLIC_ENDPOINT_URL`** for the S3 API host. |
| **`MINIO_BROWSER_REDIRECT_URL`** | Optional HTTPS URL for the **console** if you terminate TLS separately (default remains `http://${PUBLIC_HOST}:${MINIO_CONSOLE_PORT}`). |

`docker-compose.prod.yml` wires:

- **`S3_PUBLIC_ENDPOINT_URL=${S3_PUBLIC_ENDPOINT_URL:-http://${PUBLIC_HOST}:${MINIO_API_PORT}}`**
- **`MINIO_SERVER_URL=${MINIO_SERVER_URL:-http://${PUBLIC_HOST}:${MINIO_API_PORT}}`**

Example `.env` after nginx + certificate:

```bash
S3_PUBLIC_ENDPOINT_URL=https://minio-api.example.com
MINIO_SERVER_URL=https://minio-api.example.com
```

3. **`proxy_set_header Host $http_host`** on nginx must preserve the **`Host`** the client sent — AWS Signature V4 on presigned URLs is bound to host + path.

4. **Operational hardening**: after nginx fronts MinIO publicly, bind the Docker publish to **`127.0.0.1:${MINIO_API_PORT}:9000`** so only nginx can reach bare HTTP on that port from outside.

5. **CORS**: on **community MinIO**, configure **`MINIO_API_CORS_ALLOW_ORIGIN`** on the **`minio`** service (comma-separated origins, or `*` for dev). Per-bucket **`mc cors set`** is **AiStor-only** and will fail with “not implemented” on the OSS image.

## Example nginx config

See **[deploy/nginx/minio-s3-proxy.conf.example](../deploy/nginx/minio-s3-proxy.conf.example)**.

## Stack diagram (prod)

- **Browser** → `https://minio-api…` → **nginx (TLS)** → `http://127.0.0.1:19000` → **MinIO**
- **be0** → `http://minio:9000` (Compose network) unchanged for server-side uploads and streaming.
