docs: update architecture with bootstrap phases, scopes, branding
All checks were successful
CI / build (push) Successful in 40s
CI / docker (push) Successful in 11s

- CLAUDE.md: add bootstrap phase listing, document 13 scopes (10
  platform + 3 server), server role mapping via scope claim, admin
  console access, sign-in branding
- Mark server-role-mapping and logto-admin-branding specs as implemented

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-06 10:46:39 +02:00
parent 51cdca95c4
commit b1c2832245
3 changed files with 22 additions and 3 deletions

View File

@@ -46,7 +46,9 @@ All services on one hostname. Two env vars control everything: `PUBLIC_HOST` + `
- All API endpoints enforce OAuth2 scopes via `@PreAuthorize("hasAuthority('SCOPE_xxx')")` annotations
- Tenant isolation enforced by `TenantIsolationInterceptor` (a single `HandlerInterceptor` on `/api/**` that resolves JWT org_id to TenantContext and validates `{tenantId}`, `{environmentId}`, `{appId}` path variables; fail-closed, platform admins bypass)
- 10 OAuth2 scopes defined on the Logto API resource (`https://api.cameleer.local`), served to the frontend from `GET /platform/api/config`
- 13 OAuth2 scopes on the Logto API resource (`https://api.cameleer.local`): 10 platform scopes + 3 server scopes (`server:admin`, `server:operator`, `server:viewer`), served to the frontend from `GET /platform/api/config`
- Server scopes map to server RBAC roles via JWT `scope` claim (server reads `rolesClaim: "scope"`)
- Org role `admin` gets `server:admin`, org role `member` gets `server:viewer`
- Custom `JwtDecoder` in `SecurityConfig.java` — ES384 algorithm, `at+jwt` token type, split issuer-uri (string validation) / jwk-set-uri (Docker-internal fetch)
### Server integration (cameleer3-server env vars)
@@ -59,6 +61,23 @@ All services on one hostname. Two env vars control everything: `PUBLIC_HOST` + `
| `CAMELEER_CORS_ALLOWED_ORIGINS` | `${PUBLIC_PROTOCOL}://${PUBLIC_HOST}` | Allow browser requests through Traefik |
| `BASE_PATH` (server-ui) | `/server` | React Router basename + `<base>` tag |
### Bootstrap (`docker/logto-bootstrap.sh`)
Idempotent script run via `logto-bootstrap` init container. Phases:
1. Wait for Logto + server health
2. Get Management API token (reads `m-default` secret from DB)
3. Create Logto apps (SPA, Traditional with `skipConsent`, M2M with Management API role)
3b. Create API resource scopes (10 platform + 3 server scopes)
4. Create roles (platform-admin, org admin/member with API resource scope assignments)
5. Create users (SaaS admin with platform-admin role + Logto console access, tenant admin)
6. Create organization, add users with org roles
7. Configure cameleer3-server OIDC (`rolesClaim: "scope"`, `audience`, `defaultRoles: ["VIEWER"]`)
8. Configure Logto sign-in branding (Cameleer colors `#C6820E`/`#D4941E`, logo from `/platform/logo.svg`)
9. Cleanup seeded Logto apps
10. Write bootstrap results to `/data/logto-bootstrap.json`
SaaS admin credentials (`SAAS_ADMIN_USER`/`SAAS_ADMIN_PASS`) work for both the SaaS platform and the Logto console (port 3002).
## Related Conventions
- Gitea-hosted: `gitea.siegeln.net/cameleer/`

View File

@@ -1,4 +1,4 @@
# Logto Admin Credentials + Sign-In Branding
# Logto Admin Credentials + Sign-In Branding — IMPLEMENTED
## Problem

View File

@@ -1,4 +1,4 @@
# Server Role Mapping via Logto Scopes
# Server Role Mapping via Logto Scopes — IMPLEMENTED
## Problem