docs: update CLAUDE.md and HOWTO.md for all session changes
- Certificate management (provider interface, lifecycle, bootstrap, UI) - Async tenant provisioning with polling UX - Server restart capability (vendor + tenant) - Audit log actor name resolution from Logto - SSO connector management, vendor audit page - Updated API reference with all current endpoints - Fixed architecture table (per-tenant containers are dynamic) - Updated migration list through V012 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
68
HOWTO.md
68
HOWTO.md
@@ -35,19 +35,21 @@ curl http://localhost:8080/actuator/health
|
||||
|
||||
## Architecture
|
||||
|
||||
The platform runs as a Docker Compose stack with 6 services:
|
||||
The platform runs as a Docker Compose stack:
|
||||
|
||||
| Service | Image | Port | Purpose |
|
||||
|---------|-------|------|---------|
|
||||
| **traefik** | traefik:v3 | 80, 443 | Reverse proxy, TLS, routing |
|
||||
| **traefik-certs** | alpine:latest | — | Init container: generates self-signed cert or copies user-supplied cert |
|
||||
| **traefik** | traefik:v3 | 80, 443, 3002 | Reverse proxy, TLS termination, routing |
|
||||
| **postgres** | postgres:16-alpine | 5432* | Platform database + Logto database |
|
||||
| **logto** | ghcr.io/logto-io/logto | 3001*, 3002* | Identity provider (OIDC) |
|
||||
| **cameleer-saas** | cameleer-saas:latest | 8080* | SaaS API server |
|
||||
| **cameleer3-server** | cameleer3-server:latest | 8081 | Observability backend |
|
||||
| **cameleer-saas** | cameleer-saas:latest | 8080* | SaaS API server + vendor UI |
|
||||
| **clickhouse** | clickhouse-server:latest | 8123* | Trace/metrics/log storage |
|
||||
|
||||
*Ports exposed to host only with `docker-compose.dev.yml` overlay.
|
||||
|
||||
Per-tenant `cameleer3-server` and `cameleer3-server-ui` containers are provisioned dynamically by `DockerTenantProvisioner` — they are NOT part of the compose stack.
|
||||
|
||||
## Installation
|
||||
|
||||
### 1. Environment Configuration
|
||||
@@ -83,7 +85,25 @@ This creates `keys/ed25519.key` (private) and `keys/ed25519.pub` (public). The k
|
||||
|
||||
If no key files are configured, the platform generates ephemeral keys on startup (suitable for development only -- keys change on every restart).
|
||||
|
||||
### 3. Start the Stack
|
||||
### 3. TLS Certificate (Optional)
|
||||
|
||||
By default, the `traefik-certs` init container generates a self-signed certificate for `PUBLIC_HOST`. To supply your own certificate at bootstrap time, set these env vars in `.env`:
|
||||
|
||||
```bash
|
||||
CERT_FILE=/path/to/cert.pem # PEM-encoded certificate
|
||||
KEY_FILE=/path/to/key.pem # PEM-encoded private key
|
||||
CA_FILE=/path/to/ca.pem # Optional: CA bundle (for private CA trust)
|
||||
```
|
||||
|
||||
The init container validates that the key matches the certificate before accepting. If validation fails, the container exits with an error.
|
||||
|
||||
**Runtime certificate replacement** is available via the vendor UI at `/vendor/certificates`:
|
||||
- Upload a new cert+key+CA bundle (staged, not yet active)
|
||||
- Validate and activate (atomic swap, Traefik hot-reloads)
|
||||
- Roll back to the previous certificate if needed
|
||||
- Track which tenants need a restart to pick up CA bundle changes
|
||||
|
||||
### 4. Start the Stack
|
||||
|
||||
**Development** (ports exposed for direct access):
|
||||
```bash
|
||||
@@ -95,7 +115,7 @@ docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### 4. Verify Services
|
||||
### 5. Verify Services
|
||||
|
||||
```bash
|
||||
# Health check
|
||||
@@ -287,6 +307,42 @@ Query params: `since`, `until` (ISO timestamps), `limit` (default 500), `stream`
|
||||
|------|-------------|
|
||||
| `/dashboard` | cameleer3-server observability dashboard (forward-auth protected) |
|
||||
|
||||
### Vendor: Certificates (platform:admin)
|
||||
| Method | Path | Description |
|
||||
|--------|------|-------------|
|
||||
| GET | `/api/vendor/certificates` | Overview (active, staged, archived, stale count) |
|
||||
| POST | `/api/vendor/certificates/stage` | Upload cert+key+CA (multipart) |
|
||||
| POST | `/api/vendor/certificates/activate` | Promote staged -> active |
|
||||
| POST | `/api/vendor/certificates/restore` | Swap archived <-> active |
|
||||
| DELETE | `/api/vendor/certificates/staged` | Discard staged cert |
|
||||
| GET | `/api/vendor/certificates/stale-tenants` | Count tenants needing CA restart |
|
||||
|
||||
### Vendor: Tenants (platform:admin)
|
||||
| Method | Path | Description |
|
||||
|--------|------|-------------|
|
||||
| GET | `/api/vendor/tenants` | List all tenants |
|
||||
| POST | `/api/vendor/tenants` | Create tenant (async provisioning) |
|
||||
| GET | `/api/vendor/tenants/{id}` | Tenant detail + server state |
|
||||
| POST | `/api/vendor/tenants/{id}/restart` | Restart server containers |
|
||||
| POST | `/api/vendor/tenants/{id}/suspend` | Suspend tenant |
|
||||
| POST | `/api/vendor/tenants/{id}/activate` | Activate tenant |
|
||||
| DELETE | `/api/vendor/tenants/{id}` | Delete tenant |
|
||||
| POST | `/api/vendor/tenants/{id}/license` | Renew license |
|
||||
|
||||
### Tenant Portal (org-scoped)
|
||||
| Method | Path | Description |
|
||||
|--------|------|-------------|
|
||||
| GET | `/api/tenant/dashboard` | Tenant dashboard data |
|
||||
| GET | `/api/tenant/license` | License details |
|
||||
| POST | `/api/tenant/server/restart` | Restart server |
|
||||
| GET | `/api/tenant/team` | List team members |
|
||||
| POST | `/api/tenant/team/invite` | Invite team member |
|
||||
| DELETE | `/api/tenant/team/{userId}` | Remove team member |
|
||||
| GET | `/api/tenant/settings` | Tenant settings |
|
||||
| GET | `/api/tenant/sso` | List SSO connectors |
|
||||
| POST | `/api/tenant/sso` | Create SSO connector |
|
||||
| GET | `/api/tenant/audit` | Tenant audit log |
|
||||
|
||||
### Health
|
||||
| Method | Path | Description |
|
||||
|--------|------|-------------|
|
||||
|
||||
Reference in New Issue
Block a user