From 4e12fcbe7a0d1dd7b62a1493d7d6affa6ea7bbad Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Mon, 6 Apr 2026 10:06:11 +0200 Subject: [PATCH] docs: document server:-prefixed scopes and case-insensitive role mapping Co-Authored-By: Claude Opus 4.6 (1M context) --- CLAUDE.md | 2 +- HOWTO.md | 4 ++-- docs/SERVER-CAPABILITIES.md | 12 +++++++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index b8286e75..d6ed5a51 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -42,7 +42,7 @@ java -jar cameleer3-server-app/target/cameleer3-server-app-1.0-SNAPSHOT.jar - Storage: PostgreSQL for RBAC, config, and audit; ClickHouse for all observability data (executions, search, logs, metrics, stats, diagrams). ClickHouse schema migrations in `clickhouse/*.sql`, run idempotently on startup by `ClickHouseSchemaInitializer`. Use `IF NOT EXISTS` for CREATE and ADD PROJECTION. - Logging: ClickHouse JDBC set to INFO (`com.clickhouse`), HTTP client to WARN (`org.apache.hc.client5`) in application.yml - Security: JWT auth with RBAC (AGENT/VIEWER/OPERATOR/ADMIN roles), Ed25519 config signing (key derived deterministically from JWT secret via HMAC-SHA256), bootstrap token for registration. CORS: `CAMELEER_CORS_ALLOWED_ORIGINS` (comma-separated) overrides `CAMELEER_UI_ORIGIN` for multi-origin setups (e.g., reverse proxy). -- OIDC: Optional external identity provider support (token exchange pattern). Configured via admin API, stored in database (`server_config` table). Resource server mode: accepts external access tokens (Logto M2M) via JWKS validation when `CAMELEER_OIDC_ISSUER_URI` is set. `CAMELEER_OIDC_JWK_SET_URI` overrides JWKS discovery for container networking. `CAMELEER_OIDC_TLS_SKIP_VERIFY=true` disables TLS cert verification for OIDC calls (self-signed CAs). Scope-based role mapping: `admin`/`operator`/`viewer` scopes map to RBAC roles. SSO: when OIDC enabled, UI auto-redirects to provider with `prompt=none` for silent sign-in; falls back to `/login?local` on `login_required`, retries without `prompt=none` on `consent_required`. Auto-signup provisions new OIDC users with default roles. Supports ES384, ES256, RS256. +- OIDC: Optional external identity provider support (token exchange pattern). Configured via admin API, stored in database (`server_config` table). Resource server mode: accepts external access tokens (Logto M2M) via JWKS validation when `CAMELEER_OIDC_ISSUER_URI` is set. `CAMELEER_OIDC_JWK_SET_URI` overrides JWKS discovery for container networking. `CAMELEER_OIDC_TLS_SKIP_VERIFY=true` disables TLS cert verification for OIDC calls (self-signed CAs). Scope-based role mapping (case-insensitive): `admin`/`server:admin` → ADMIN, `operator`/`server:operator` → OPERATOR, `viewer`/`server:viewer` → VIEWER. SSO: when OIDC enabled, UI auto-redirects to provider with `prompt=none` for silent sign-in; falls back to `/login?local` on `login_required`, retries without `prompt=none` on `consent_required`. Auto-signup provisions new OIDC users with default roles. Supports ES384, ES256, RS256. - User persistence: PostgreSQL `users` table, admin CRUD at `/api/v1/admin/users` - Usage analytics: ClickHouse `usage_events` table tracks authenticated UI requests, flushed every 5s diff --git a/HOWTO.md b/HOWTO.md index 58adea53..ff9d63d2 100644 --- a/HOWTO.md +++ b/HOWTO.md @@ -170,10 +170,10 @@ Logto is proxy-aware via `TRUST_PROXY_HEADER=1`. The `LOGTO_ENDPOINT` and `LOGTO 3. **Create API Resource**: API Resources → Create - Name: `Cameleer Server API` - Indicator: your API URL (e.g., `https://cameleer.siegeln.net/api`) - - Add permissions: `admin`, `operator`, `viewer` + - Add permissions: `server:admin`, `server:operator`, `server:viewer` 4. **Create M2M application** (for SaaS platform): Applications → Create → Machine-to-Machine - Name: `Cameleer SaaS` - - Assign the API Resource created above with `admin` scope + - Assign the API Resource created above with `server:admin` scope - Note the **Client ID** and **Client Secret** 5. **Configure Cameleer OIDC login**: Use the admin API (`PUT /api/v1/admin/oidc`) or set env vars for initial seeding: ``` diff --git a/docs/SERVER-CAPABILITIES.md b/docs/SERVER-CAPABILITIES.md index 574b0f2c..238393b7 100644 --- a/docs/SERVER-CAPABILITIES.md +++ b/docs/SERVER-CAPABILITIES.md @@ -264,7 +264,17 @@ When OIDC is configured and enabled, the login page automatically redirects to t ### OIDC Resource Server -When `CAMELEER_OIDC_ISSUER_URI` is configured, the server accepts external access tokens (e.g., Logto M2M tokens) in addition to internal HMAC JWTs. Dual-path validation: tries internal HMAC first, falls back to OIDC JWKS validation. OAuth2 scope-based role mapping: `admin` scope maps to ADMIN, `operator` to OPERATOR, `viewer` to VIEWER. Supports ES384, ES256, and RS256 algorithms. Handles RFC 9068 `at+jwt` token type. +When `CAMELEER_OIDC_ISSUER_URI` is configured, the server accepts external access tokens (e.g., Logto M2M tokens) in addition to internal HMAC JWTs. Dual-path validation: tries internal HMAC first, falls back to OIDC JWKS validation. Supports ES384, ES256, and RS256 algorithms. Handles RFC 9068 `at+jwt` token type. + +Role mapping is case-insensitive and accepts both bare and `server:`-prefixed names: + +| Scope/claim value | Maps to | +|-------------------|---------| +| `admin`, `server:admin`, `Server:Admin` | ADMIN | +| `operator`, `server:operator` | OPERATOR | +| `viewer`, `server:viewer` | VIEWER | + +This applies to both M2M tokens (`scope` claim) and OIDC user login (configurable `rolesClaim` from id_token). The `server:` prefix allows dedicated API resource scopes without colliding with other platform scopes. | Variable | Purpose | |----------|---------|