2026-04-15 15:28:42 +02:00
# Cameleer Server — Capabilities Reference
2026-04-04 20:30:42 +02:00
2026-04-15 15:28:42 +02:00
> Standalone reference for systems integrating with or managing Cameleer Server instances.
2026-04-04 20:30:42 +02:00
> Generated 2026-04-04. Source of truth: the codebase and OpenAPI spec at `/api/v1/api-docs`.
## What It Does
2026-04-15 15:28:42 +02:00
Cameleer Server is an observability platform for Apache Camel applications. It receives execution traces, metrics, logs, and route diagrams from instrumented Camel agents, stores them in ClickHouse, and serves a web UI for searching, visualizing, and controlling routes.
2026-04-04 20:30:42 +02:00
**Core capabilities:**
- Real-time execution tracing with processor-level detail
- Full-text search across executions, logs, and attributes
- Route topology diagrams with live execution overlays
- Application configuration push via SSE
- Route control (start/stop/suspend) and exchange replay
- Agent lifecycle management with auto-heal on server restart
- RBAC with local users, groups, roles, and OIDC federation
- Multi-tenant isolation (one tenant per server instance)
---
## Multi-Tenancy Model
Each server instance serves exactly one tenant. Multiple tenants share infrastructure but are isolated at the data layer.
| Concern | Isolation |
|---------|-----------|
| PostgreSQL | Schema-per-tenant (`?currentSchema=tenant_{id}` ) |
| ClickHouse | Shared DB, `tenant_id` column on all tables, partitioned by `(tenant_id, toYYYYMM(timestamp))` |
Migrate config to cameleer.server.* naming convention
Move all configuration properties under the cameleer.server.* namespace
with all-lowercase dot-separated names and mechanical env var mapping
(dots→underscores, uppercase). This aligns with the agent's convention
(cameleer.agent.*) and establishes a predictable pattern across all
components.
Changes:
- Move 6 config prefixes under cameleer.server.*: agent-registry,
ingestion, security, license, clickhouse, and cameleer.tenant/runtime/indexer
- Rename all kebab-case properties to concatenated lowercase
(e.g., bootstrap-token → bootstraptoken, jar-storage-path → jarstoragepath)
- Update all env vars to CAMELEER_SERVER_* mechanical mapping
- Fix container-cpu-request/container-cpu-shares mismatch bug
- Remove displayName from AgentRegistrationRequest (redundant with instanceId)
- Update agent container env vars to CAMELEER_AGENT_* convention
- Update K8s manifests and CI workflow for new env var names
- Update CLAUDE.md, HOWTO.md, SERVER-CAPABILITIES.md documentation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 18:10:51 +02:00
| Configuration | `CAMELEER_SERVER_TENANT_ID` env var (default: `"default"` ) |
2026-04-04 20:30:42 +02:00
| Agents | Each agent belongs to one tenant, one environment |
**Environments** (dev/staging/prod) are first-class within a tenant. Agents send `environmentId` at registration and in every heartbeat. The UI filters by environment. JWT tokens carry an `env` claim for persistence across restarts.
---
## Agent Protocol
### Lifecycle
```
Register (bootstrap token) → Receive JWT + SSE URL
↓
Connect SSE ← Receive commands (config-update, deep-trace, replay, route-control)
↓
Heartbeat (every 30s) → Send capabilities, environmentId, routeStates
↓
Deregister (graceful shutdown)
```
### State Machine
```
LIVE ──(no heartbeat for 90s)──→ STALE ──(300s more)──→ DEAD
↑ │
└────(heartbeat arrives)──────────┘
```
2026-04-11 21:56:19 +02:00
Thresholds are configurable via `cameleer.server.agentregistry.*` properties.
2026-04-04 20:30:42 +02:00
### Registration
**`POST /api/v1/agents/register` ** — requires bootstrap token in `Authorization: Bearer` header.
Request:
```json
{
"instanceId": "agent-abc-123",
"applicationId": "order-service",
"environmentId": "production",
"version": "3.2.1",
"routeIds": ["processOrder", "handlePayment"],
"capabilities": { "replay": true, "routeControl": true }
}
```
Response:
```json
{
"instanceId": "agent-abc-123",
"eventStreamUrl": "/api/v1/agents/agent-abc-123/events",
"heartbeatIntervalMs": 30000,
"signingPublicKeyBase64": "<ed25519-public-key>",
"accessToken": "<jwt>",
"refreshToken": "<jwt>"
}
```
### Heartbeat
**`POST /api/v1/agents/{id}/heartbeat` ** — JWT auth.
```json
{
"capabilities": { "replay": true, "routeControl": true },
"environmentId": "production",
"routeStates": { "processOrder": "Started", "handlePayment": "Suspended" }
}
```
Auto-heals after server restart: if agent not in registry, re-registers from JWT claims + heartbeat body. Environment priority: heartbeat `environmentId` > JWT `env` claim > `"default"` .
### SSE Event Stream
**`GET /api/v1/agents/{id}/events` ** — long-lived SSE connection. Keepalive ping every 15s.
Event types pushed to agents: `config-update` , `deep-trace` , `replay` , `set-traced-processors` , `test-expression` , `route-control` .
### Token Refresh
**`POST /api/v1/agents/{id}/refresh` ** — public endpoint, validates refresh token.
```json
{ "refreshToken": "<refresh-jwt>" }
```
Returns new `accessToken` + `refreshToken` . Preserves roles, application, and environment from the original token.
---
## Data Ingestion
All ingestion endpoints require JWT with `AGENT` role.
| Endpoint | Data | Notes |
|----------|------|-------|
| `POST /api/v1/data/executions` | Execution chunks (route + processor traces) | Buffered, flushed periodically |
| `POST /api/v1/data/diagrams` | Route graph definitions | Single or array |
| `POST /api/v1/data/events` | Agent lifecycle events | Triggers registry state transitions |
2026-04-12 10:33:03 +02:00
| `POST /api/v1/data/logs` | Log entries (JSON array, `source` : app/agent) | Buffered, 503 if buffer full |
2026-04-04 20:30:42 +02:00
| `POST /api/v1/data/metrics` | Metrics snapshots | Buffered, 503 if buffer full |
---
## Command System
Commands are delivered to agents via SSE. Three dispatch modes:
| Mode | Endpoint | Behavior |
|------|----------|----------|
| Single agent | `POST /api/v1/agents/{id}/commands` | Async (202), DELIVERED or PENDING |
| Group (application) | `POST /api/v1/agents/groups/{group}/commands` | Sync wait (10s), returns per-agent results |
| Broadcast (all LIVE) | `POST /api/v1/agents/commands` | Fire-and-forget (202) |
**Command types:** `config-update` , `deep-trace` , `replay` , `set-traced-processors` , `test-expression` , `route-control`
**Replay** has a dedicated sync endpoint: `POST /api/v1/agents/{id}/replay` (30s timeout, returns result or 504).
**Acknowledgment:** `POST /api/v1/agents/{id}/commands/{commandId}/ack` — agent confirms receipt with status/message/data.
---
## Query & Analytics API
All query endpoints require JWT with `VIEWER` role or higher.
### Execution Search
| Endpoint | Description |
|----------|-------------|
| `GET /api/v1/search/executions` | Search by status, time, text, route, app, environment |
| `POST /api/v1/search/executions` | Advanced search with full filter object |
| `GET /api/v1/executions/{id}` | Execution detail with processor tree |
| `GET /api/v1/executions/{id}/processors/by-id/{pid}/snapshot` | Exchange data at processor |
### Statistics & Analytics
| Endpoint | Description |
|----------|-------------|
| `GET /api/v1/search/stats` | Aggregated stats (P99, error rate, SLA compliance) |
| `GET /api/v1/search/stats/timeseries` | Bucketed time-series |
| `GET /api/v1/search/stats/timeseries/by-app` | Time series grouped by application |
| `GET /api/v1/search/stats/timeseries/by-route` | Time series grouped by route |
| `GET /api/v1/search/stats/punchcard` | Transaction heatmap (weekday x hour) |
| `GET /api/v1/search/errors/top` | Top N errors with velocity trends |
| `GET /api/v1/search/attributes/keys` | Distinct attribute key names |
### Route Catalog & Metrics
| Endpoint | Description |
|----------|-------------|
| `GET /api/v1/routes/catalog` | Applications with routes, agents, health |
| `GET /api/v1/routes/metrics` | Per-route performance (TPS, P99, error rate) |
| `GET /api/v1/routes/metrics/processors` | Per-processor metrics for a route |
### Logs
| Endpoint | Description |
|----------|-------------|
2026-04-12 10:33:03 +02:00
| `GET /api/v1/logs` | Cursor-based log search with level aggregation. Filters: `source` (app/agent), `application` , `agentId` , `exchangeId` , `level` , `logger` , `q` (text), `environment` , time range |
2026-04-04 20:30:42 +02:00
### Diagrams
| Endpoint | Description |
|----------|-------------|
| `GET /api/v1/diagrams` | Find diagram by application + routeId |
| `GET /api/v1/diagrams/{hash}/render` | SVG or JSON layout |
### Agent Monitoring
| Endpoint | Description |
|----------|-------------|
| `GET /api/v1/agents` | List agents (filter by status, app, environment) |
| `GET /api/v1/agents/events-log` | Agent lifecycle event history |
| `GET /api/v1/agents/{id}/metrics` | Agent-level metrics time series |
---
## Application Configuration
| Endpoint | Role | Description |
|----------|------|-------------|
| `GET /api/v1/config` | VIEWER | List all app configs |
| `GET /api/v1/config/{app}` | VIEWER | Get config (returns defaults if none stored) |
| `PUT /api/v1/config/{app}` | OPERATOR | Save config + push to all LIVE agents |
| `GET /api/v1/config/{app}/processor-routes` | VIEWER | Processor-to-route mapping |
| `POST /api/v1/config/{app}/test-expression` | VIEWER | Test Camel expression via live agent |
Config fields: `metricsEnabled` , `samplingRate` , `tracedProcessors` , `logLevels` , `engineLevel` , `payloadCaptureMode` , `version` .
---
## Security
### Authentication
| Method | Endpoint | Purpose |
|--------|----------|---------|
| Bootstrap token | `POST /agents/register` | One-time agent registration |
| Local credentials | `POST /auth/login` | UI login (username/password) |
| OIDC code exchange | `POST /auth/oidc/callback` | External identity provider |
2026-04-05 13:15:09 +02:00
| OIDC access token | Bearer token in Authorization header | SaaS M2M / external OIDC |
2026-04-04 20:30:42 +02:00
| Token refresh | `POST /auth/refresh` | UI token refresh |
| Token refresh | `POST /agents/{id}/refresh` | Agent token refresh |
### JWT Structure
- Algorithm: HMAC-SHA256
- Access token: 1 hour (configurable)
- Refresh token: 7 days (configurable)
- Claims: `sub` (agent ID or `user:<username>` ), `group` (application), `env` (environment), `roles` (array), `type` (access/refresh)
### RBAC Roles
| Role | Permissions |
|------|-------------|
| `AGENT` | Data ingestion, heartbeat, SSE, command ack |
| `VIEWER` | Read-only: executions, search, diagrams, metrics, logs, config |
| `OPERATOR` | VIEWER + send commands, modify config, replay |
| `ADMIN` | OPERATOR + user/group/role management, OIDC config, database admin |
2026-04-06 15:52:25 +02:00
### UI Role Gating
The UI enforces role-based visibility (backend ACLs remain the authoritative check):
| UI element | VIEWER | OPERATOR | ADMIN |
|-----------|--------|----------|-------|
| Exchanges, Dashboard, Runtime, Logs | Yes | Yes | Yes |
2026-04-06 16:29:20 +02:00
| Config tab | Read-only | Edit | Edit |
2026-04-06 15:52:25 +02:00
| Route control bar | Hidden | Yes | Yes |
| Diagram node toolbar | Hidden | Yes | Yes |
| Admin sidebar section | Hidden | Hidden | Yes |
| Admin pages (`/admin/*` ) | Redirect to `/` | Redirect to `/` | Yes |
2026-04-06 16:29:20 +02:00
Config tab is a main tab alongside Exchanges/Dashboard/Runtime/Logs. Navigation: `/config` shows all-app config table; `/config/:appId` filters to that app with detail panel open. Sidebar clicks while on Config stay on the config tab — route clicks resolve to the parent app's config (config is per-app).
2026-04-04 20:30:42 +02:00
### Ed25519 Config Signing
Server derives an Ed25519 keypair deterministically from the JWT secret. Public key is shared with agents at registration. Config-update payloads are signed so agents can verify authenticity.
### OIDC Integration
2026-04-07 10:56:40 +02:00
Configured via admin API (`/api/v1/admin/oidc` ) or admin UI. Supports any OpenID Connect provider. Features: configurable user ID claim (`userIdClaim` , default `sub` — e.g., `email` , `preferred_username` ), role claim extraction from access_token then id_token (supports nested paths like `realm_access.roles` and space-delimited scope strings), auto-signup (auto-provisions new users on first OIDC login), configurable display name claim, constant-time token rotation via dual bootstrap tokens, RFC 8707 resource indicators (`audience` config). Backend is a confidential client (client_secret authentication, no PKCE). Supports ES384 (Logto default), ES256, and RS256. Directly-assigned system roles are overwritten on every OIDC login (falls back to `defaultRoles` when OIDC returns none); uses `getDirectRolesForUser` so group-inherited roles are never touched. Role normalization via `SystemRole.normalizeScope()` (case-insensitive, strips `server:` prefix). Shared OIDC infrastructure (discovery, JWK source, algorithm set) centralized in `OidcProviderHelper` .
2026-04-06 01:45:45 +02:00
### SSO Auto-Redirect
2026-04-07 10:56:40 +02:00
When OIDC is configured and enabled, the login page automatically redirects to the OIDC provider with `prompt=none` for silent SSO. If the user has an active provider session, they are signed in without seeing a login form. If `consent_required` is returned (first login, scopes not yet granted), the flow retries without `prompt=none` so the user can grant consent once. If `login_required` (no provider session), falls back to the login form. Bypass auto-redirect with `/login?local` . Logout always redirects to `/login?local` — either via the OIDC `end_session_endpoint` (with `post_logout_redirect_uri` ) or as a direct fallback — preventing SSO re-login loops.
2026-04-04 20:30:42 +02:00
2026-04-05 13:15:09 +02:00
### OIDC Resource Server
Migrate config to cameleer.server.* naming convention
Move all configuration properties under the cameleer.server.* namespace
with all-lowercase dot-separated names and mechanical env var mapping
(dots→underscores, uppercase). This aligns with the agent's convention
(cameleer.agent.*) and establishes a predictable pattern across all
components.
Changes:
- Move 6 config prefixes under cameleer.server.*: agent-registry,
ingestion, security, license, clickhouse, and cameleer.tenant/runtime/indexer
- Rename all kebab-case properties to concatenated lowercase
(e.g., bootstrap-token → bootstraptoken, jar-storage-path → jarstoragepath)
- Update all env vars to CAMELEER_SERVER_* mechanical mapping
- Fix container-cpu-request/container-cpu-shares mismatch bug
- Remove displayName from AgentRegistrationRequest (redundant with instanceId)
- Update agent container env vars to CAMELEER_AGENT_* convention
- Update K8s manifests and CI workflow for new env var names
- Update CLAUDE.md, HOWTO.md, SERVER-CAPABILITIES.md documentation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 18:10:51 +02:00
When `CAMELEER_SERVER_SECURITY_OIDCISSUERURI` 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.
2026-04-06 10:06:11 +02:00
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.
2026-04-05 13:15:09 +02:00
| Variable | Purpose |
|----------|---------|
Migrate config to cameleer.server.* naming convention
Move all configuration properties under the cameleer.server.* namespace
with all-lowercase dot-separated names and mechanical env var mapping
(dots→underscores, uppercase). This aligns with the agent's convention
(cameleer.agent.*) and establishes a predictable pattern across all
components.
Changes:
- Move 6 config prefixes under cameleer.server.*: agent-registry,
ingestion, security, license, clickhouse, and cameleer.tenant/runtime/indexer
- Rename all kebab-case properties to concatenated lowercase
(e.g., bootstrap-token → bootstraptoken, jar-storage-path → jarstoragepath)
- Update all env vars to CAMELEER_SERVER_* mechanical mapping
- Fix container-cpu-request/container-cpu-shares mismatch bug
- Remove displayName from AgentRegistrationRequest (redundant with instanceId)
- Update agent container env vars to CAMELEER_AGENT_* convention
- Update K8s manifests and CI workflow for new env var names
- Update CLAUDE.md, HOWTO.md, SERVER-CAPABILITIES.md documentation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 18:10:51 +02:00
| `CAMELEER_SERVER_SECURITY_OIDCISSUERURI` | OIDC issuer URI for token validation (e.g., `https://auth.example.com/oidc` ) |
2026-04-13 22:51:08 +02:00
| `CAMELEER_SERVER_SECURITY_OIDCJWKSETURI` | Direct JWKS URL (e.g., `http://cameleer-logto:3001/oidc/jwks` ) — use when public issuer isn't reachable from inside containers |
Migrate config to cameleer.server.* naming convention
Move all configuration properties under the cameleer.server.* namespace
with all-lowercase dot-separated names and mechanical env var mapping
(dots→underscores, uppercase). This aligns with the agent's convention
(cameleer.agent.*) and establishes a predictable pattern across all
components.
Changes:
- Move 6 config prefixes under cameleer.server.*: agent-registry,
ingestion, security, license, clickhouse, and cameleer.tenant/runtime/indexer
- Rename all kebab-case properties to concatenated lowercase
(e.g., bootstrap-token → bootstraptoken, jar-storage-path → jarstoragepath)
- Update all env vars to CAMELEER_SERVER_* mechanical mapping
- Fix container-cpu-request/container-cpu-shares mismatch bug
- Remove displayName from AgentRegistrationRequest (redundant with instanceId)
- Update agent container env vars to CAMELEER_AGENT_* convention
- Update K8s manifests and CI workflow for new env var names
- Update CLAUDE.md, HOWTO.md, SERVER-CAPABILITIES.md documentation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 18:10:51 +02:00
| `CAMELEER_SERVER_SECURITY_OIDCAUDIENCE` | Expected audience (API resource indicator) |
| `CAMELEER_SERVER_SECURITY_OIDCTLSSKIPVERIFY` | Skip TLS certificate verification for OIDC calls (default `false` ) — use when provider has a self-signed CA |
2026-04-05 13:15:09 +02:00
2026-04-05 13:31:17 +02:00
Logto is proxy-aware (`TRUST_PROXY_HEADER=1` ). The `LOGTO_ENDPOINT` env var sets the public-facing URL used in OIDC discovery, issuer URI, and redirect URLs. Logto requires its own subdomain (not a path prefix).
2026-04-04 20:30:42 +02:00
---
## Admin API
All admin endpoints require `ADMIN` role. Prefix: `/api/v1/admin/` .
### User Management
| Endpoint | Method | Description |
|----------|--------|-------------|
| `/users` | GET | List all users |
| `/users` | POST | Create local user |
| `/users/{id}` | GET/PUT/DELETE | Get/update/delete user |
| `/users/{id}/password` | POST | Reset password |
| `/users/{id}/roles/{roleId}` | POST/DELETE | Assign/remove role |
| `/users/{id}/groups/{groupId}` | POST/DELETE | Add/remove from group |
### Group & Role Management
| Endpoint | Method | Description |
|----------|--------|-------------|
| `/groups` | GET/POST | List/create groups |
| `/groups/{id}` | GET/PUT/DELETE | Manage group (cycle detection on parent change) |
| `/groups/{id}/roles/{roleId}` | POST/DELETE | Assign/remove role from group |
| `/roles` | GET/POST | List/create roles |
| `/roles/{id}` | GET/PUT/DELETE | Manage role (system roles protected) |
| `/rbac/stats` | GET | RBAC statistics |
### Infrastructure
| Endpoint | Description |
|----------|-------------|
| `/database/status` | PostgreSQL version, schema, health |
| `/database/pool` | HikariCP connection pool stats |
| `/database/tables` | Table sizes and row counts |
| `/database/queries` | Active queries (with kill) |
| `/clickhouse/status` | ClickHouse version, uptime |
| `/clickhouse/tables` | Table info, row counts, sizes |
| `/clickhouse/performance` | Disk, memory, compression, partitions |
| `/clickhouse/queries` | Active ClickHouse queries |
| `/clickhouse/pipeline` | Ingestion pipeline stats |
### Settings & Configuration
| Endpoint | Description |
|----------|-------------|
| `/app-settings` | Per-application settings (CRUD) |
| `/thresholds` | Monitoring threshold configuration |
| `/oidc` | OIDC provider configuration (CRUD + test) |
| `/audit` | Paginated audit log search |
| `/usage` | UI usage analytics (ClickHouse) |
---
## Storage
### PostgreSQL
Used for RBAC, configuration, and audit. Schema-per-tenant isolation via `?currentSchema=tenant_{id}` .
Tables: `users` , `groups` , `roles` , `user_roles` , `user_groups` , `group_roles` , `server_config` , `application_config` , `audit_log` .
Flyway migrations (V1-V11) manage schema evolution.
### ClickHouse
Used for all observability data. Schema managed by `ClickHouseSchemaInitializer` (idempotent on startup).
| Table | Engine | Purpose | TTL |
|-------|--------|---------|-----|
| `executions` | ReplacingMergeTree | Route execution records | 365d |
| `processor_executions` | MergeTree | Per-processor trace data | 365d |
| `agent_events` | MergeTree | Agent lifecycle audit trail | 365d |
| `route_diagrams` | ReplacingMergeTree | Route graph definitions | - |
2026-04-12 10:33:03 +02:00
| `logs` | MergeTree | Application + agent logs (`source` column: app/agent, `mdc` Map) | 365d |
2026-04-04 20:30:42 +02:00
| `usage_events` | MergeTree | UI action tracking | 90d |
| `stats_1m_all` | AggregatingMergeTree | Global 1-minute rollups | - |
| `stats_1m_app` | AggregatingMergeTree | Per-application rollups | - |
| `stats_1m_route` | AggregatingMergeTree | Per-route rollups | - |
| `stats_1m_processor` | AggregatingMergeTree | Per-processor-type rollups | - |
| `stats_1m_processor_detail` | AggregatingMergeTree | Per-processor-instance rollups | - |
All tables include `tenant_id` and `environment` columns. Partitioned by `(tenant_id, toYYYYMM(timestamp))` .
Stats tables are fed by Materialized Views from base tables. Query with `-Merge()` combinators (e.g., `countMerge(total_count)` ).
---
## Deployment
### Container Image
2026-04-06 22:08:58 +02:00
Multi-stage Docker build: Maven 3.9 + JDK 17 (build) → JRE 17 (runtime). Port 8081. No default credentials baked in — all database config comes from env vars at runtime.
2026-04-04 20:30:42 +02:00
2026-04-15 15:28:42 +02:00
Registry: `gitea.siegeln.net/cameleer/cameleer-server`
2026-04-04 20:30:42 +02:00
### Infrastructure Requirements
| Component | Version | Purpose |
|-----------|---------|---------|
| PostgreSQL | 16+ | RBAC, config, audit |
| ClickHouse | 24.12+ | All observability data |
### Required Environment Variables
| Variable | Required | Default | Purpose |
|----------|----------|---------|---------|
Migrate config to cameleer.server.* naming convention
Move all configuration properties under the cameleer.server.* namespace
with all-lowercase dot-separated names and mechanical env var mapping
(dots→underscores, uppercase). This aligns with the agent's convention
(cameleer.agent.*) and establishes a predictable pattern across all
components.
Changes:
- Move 6 config prefixes under cameleer.server.*: agent-registry,
ingestion, security, license, clickhouse, and cameleer.tenant/runtime/indexer
- Rename all kebab-case properties to concatenated lowercase
(e.g., bootstrap-token → bootstraptoken, jar-storage-path → jarstoragepath)
- Update all env vars to CAMELEER_SERVER_* mechanical mapping
- Fix container-cpu-request/container-cpu-shares mismatch bug
- Remove displayName from AgentRegistrationRequest (redundant with instanceId)
- Update agent container env vars to CAMELEER_AGENT_* convention
- Update K8s manifests and CI workflow for new env var names
- Update CLAUDE.md, HOWTO.md, SERVER-CAPABILITIES.md documentation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 18:10:51 +02:00
| `CAMELEER_SERVER_SECURITY_BOOTSTRAPTOKEN` | Yes | - | Bootstrap token for agent registration |
| `CAMELEER_SERVER_SECURITY_JWTSECRET` | Recommended | Random (ephemeral) | JWT signing secret |
| `CAMELEER_SERVER_TENANT_ID` | No | `default` | Tenant identifier |
| `CAMELEER_SERVER_SECURITY_UIUSER` | No | `admin` | Default admin username |
| `CAMELEER_SERVER_SECURITY_UIPASSWORD` | No | `admin` | Default admin password |
| `CAMELEER_SERVER_SECURITY_UIORIGIN` | No | `http://localhost:5173` | CORS allowed origin (single, legacy) |
| `CAMELEER_SERVER_SECURITY_CORSALLOWEDORIGINS` | No | (empty) | Comma-separated CORS origins — overrides `UIORIGIN` when set |
| `CAMELEER_SERVER_CLICKHOUSE_URL` | No | `jdbc:clickhouse://localhost:8123/cameleer` | ClickHouse JDBC URL |
| `CAMELEER_SERVER_CLICKHOUSE_USERNAME` | No | `default` | ClickHouse user |
| `CAMELEER_SERVER_CLICKHOUSE_PASSWORD` | No | (empty) | ClickHouse password |
2026-04-15 15:28:42 +02:00
| `SPRING_DATASOURCE_URL` | No | `jdbc:postgresql://localhost:5432/cameleer` | PostgreSQL JDBC URL |
2026-04-04 20:30:42 +02:00
| `SPRING_DATASOURCE_USERNAME` | No | `cameleer` | PostgreSQL user |
| `SPRING_DATASOURCE_PASSWORD` | No | `cameleer_dev` | PostgreSQL password |
2026-04-11 21:56:19 +02:00
| `CAMELEER_SERVER_INGESTION_BODYSIZELIMIT` | No | `16384` | Max body size per execution (bytes) |
Migrate config to cameleer.server.* naming convention
Move all configuration properties under the cameleer.server.* namespace
with all-lowercase dot-separated names and mechanical env var mapping
(dots→underscores, uppercase). This aligns with the agent's convention
(cameleer.agent.*) and establishes a predictable pattern across all
components.
Changes:
- Move 6 config prefixes under cameleer.server.*: agent-registry,
ingestion, security, license, clickhouse, and cameleer.tenant/runtime/indexer
- Rename all kebab-case properties to concatenated lowercase
(e.g., bootstrap-token → bootstraptoken, jar-storage-path → jarstoragepath)
- Update all env vars to CAMELEER_SERVER_* mechanical mapping
- Fix container-cpu-request/container-cpu-shares mismatch bug
- Remove displayName from AgentRegistrationRequest (redundant with instanceId)
- Update agent container env vars to CAMELEER_AGENT_* convention
- Update K8s manifests and CI workflow for new env var names
- Update CLAUDE.md, HOWTO.md, SERVER-CAPABILITIES.md documentation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 18:10:51 +02:00
| `CAMELEER_SERVER_SECURITY_OIDCISSUERURI` | No | (empty) | OIDC issuer URI — enables resource server mode for M2M tokens |
| `CAMELEER_SERVER_SECURITY_OIDCJWKSETURI` | No | (empty) | Direct JWKS URL — bypasses OIDC discovery for container networking |
| `CAMELEER_SERVER_SECURITY_OIDCAUDIENCE` | No | (empty) | Expected JWT audience (API resource indicator) |
| `CAMELEER_SERVER_SECURITY_OIDCTLSSKIPVERIFY` | No | `false` | Skip TLS cert verification for OIDC calls (self-signed CAs) |
2026-04-04 20:30:42 +02:00
### Health Probes
- **Endpoint:** `GET /api/v1/health` (public, no auth)
- **Liveness:** 30s initial delay, 10s period
- **Readiness:** 10s initial delay, 5s period
### Ingestion Tuning
| Variable | Default | Purpose |
|----------|---------|---------|
2026-04-11 21:56:19 +02:00
| `CAMELEER_SERVER_INGESTION_BUFFERCAPACITY` | 50000 | Ring buffer size |
| `CAMELEER_SERVER_INGESTION_BATCHSIZE` | 5000 | Flush batch size |
| `CAMELEER_SERVER_INGESTION_FLUSHINTERVALMS` | 5000 | Periodic flush interval |
| `CAMELEER_SERVER_INGESTION_BODYSIZELIMIT` | 16384 | Max body size per execution (bytes) |
2026-04-04 20:30:42 +02:00
### Agent Registry Tuning
| Variable | Default | Purpose |
|----------|---------|---------|
2026-04-11 21:56:19 +02:00
| `CAMELEER_SERVER_AGENTREGISTRY_STALETHRESHOLDMS` | 90000 | Heartbeat miss → STALE |
| `CAMELEER_SERVER_AGENTREGISTRY_DEADTHRESHOLDMS` | 300000 | STALE duration → DEAD |
| `CAMELEER_SERVER_AGENTREGISTRY_PINGINTERVALMS` | 15000 | SSE keepalive interval |
| `CAMELEER_SERVER_AGENTREGISTRY_COMMANDEXPIRYMS` | 60000 | Pending command TTL |
2026-04-04 20:30:42 +02:00
---
## Public Endpoints (No Auth)
These endpoints do not require authentication:
- `GET /api/v1/health`
- `POST /api/v1/agents/register` (requires bootstrap token)
- `POST /api/v1/agents/*/refresh`
- `POST /api/v1/auth/login`
- `POST /api/v1/auth/refresh`
- `GET /api/v1/auth/oidc/config`
- `POST /api/v1/auth/oidc/callback`
- `GET /api/v1/api-docs/**` (OpenAPI spec)
- `GET /swagger-ui.html` (Swagger UI)
- Static resources: `/` , `/index.html` , `/config.js` , `/favicon.svg` , `/assets/**`
All other endpoints require a valid JWT with appropriate role.