Files
cameleer-saas/docs/user-manual.md
hsiegeln 051f7fdae9
All checks were successful
CI / build (push) Successful in 38s
CI / docker (push) Successful in 39s
feat: auth hardening — scope enforcement, tenant isolation, and docs
Add @PreAuthorize annotations to all API controllers (14 endpoints
across 6 controllers) enforcing OAuth2 scopes: apps:manage, apps:deploy,
billing:manage, observe:read, platform:admin.

Enforce tenant isolation: TenantResolutionFilter now rejects cross-tenant
access on /api/tenants/{id}/* paths. New TenantOwnershipValidator checks
environment/app ownership for paths without tenantId. Platform admins
bypass both layers.

Fix frontend: OrgResolver split into two useEffect hooks so scopes
refresh on org switch. Scopes now served from /api/config (single source
of truth). Bootstrap cleaned — standalone org permissions removed.

Update docs/architecture.md, docs/user-manual.md, and CLAUDE.md to
reflect all auth hardening changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 15:32:53 +02:00

26 KiB

Cameleer SaaS User Manual

1. Introduction

Cameleer SaaS is a managed observability and runtime platform for Apache Camel applications. It lets you upload your Camel application JARs, deploy them as managed containers with the Cameleer agent automatically injected, and observe their behavior through route topology graphs, execution traces, processor metrics, and container logs -- all without running your own infrastructure.

Who This Manual Is For

This manual is written for:

  • SaaS customers who access a hosted Cameleer instance to deploy and monitor their Camel applications.
  • Self-hosted operators who run the full Cameleer SaaS stack on their own infrastructure using Docker Compose.

Both audiences share the same UI and workflows. The self-hosted setup section at the end covers the additional steps needed to run the platform yourself.

Two Deployment Modes

Mode You manage We manage
Managed SaaS Your Camel JARs Infrastructure, upgrades, identity, storage
Self-hosted Everything (Docker Compose stack) Nothing -- you own it all

2. Getting Started

Logging In

Cameleer SaaS uses Logto for single sign-on (SSO). To log in:

  1. Navigate to the Cameleer SaaS URL in your browser.
  2. You will see the login screen with the title "Cameleer SaaS" and a subtitle "Managed Apache Camel Runtime."
  3. Click Sign in with Logto.
  4. Authenticate with your Logto credentials (username/password or any configured social login).
  5. After successful authentication, you are redirected back to the dashboard.

Login page

Tip: If you are already authenticated, navigating to /login automatically redirects you to the dashboard.

First-Time Experience

After your first login, you land on the Dashboard. What you see depends on whether your organization has been set up:

  • If your account is linked to a tenant (organization), you see the tenant name, tier badge, and any existing environments.
  • If your account is not linked to a tenant, you see a message: "No tenant associated. Please contact your administrator."

For self-hosted deployments, the bootstrap process creates a default tenant and organization automatically (see Section 10).

Understanding the Dashboard

The dashboard provides an at-a-glance overview of your tenant:

  • Tenant header -- Your organization name and license tier badge (LOW, MID, HIGH, or BUSINESS).
  • KPI strip -- Four key metrics: total environments, total apps, running deployments, and stopped apps needing attention.
  • Environments list -- Each environment shows its name, slug, number of apps, running count, and status (ACTIVE or INACTIVE).
  • Recent Deployments -- A prompt to select an app to view its deployment history.

Dashboard overview

Sidebar Navigation

The sidebar provides access to all major sections:

Section Description
Dashboard Tenant overview and KPI metrics
Environments Expandable tree showing all environments and their apps
License License tier, features, limits, and token
Platform Platform-wide tenant management (visible only to platform admins)
View Dashboard Opens the observability dashboard (cameleer3-server) in a new tab
Account Log out of the current session

The Environments section in the sidebar renders as a collapsible tree: environments at the top level, with their applications nested underneath. Clicking any item navigates directly to its detail page.


3. Environments

What Environments Are

An environment is an isolated runtime context within your tenant. Environments let you separate concerns -- for example, you might create development, staging, and production environments. Each environment has its own set of applications and deployments.

Every environment has:

  • A slug (URL-safe identifier, e.g., production) -- immutable after creation.
  • A display name (human-readable, e.g., "Production") -- can be renamed.
  • A status -- typically ACTIVE.

Creating an Environment

Note: Creating environments requires the apps:manage scope. If you do not see the "Create Environment" button, contact your organization admin.

To create an environment:

  1. Navigate to Environments from the sidebar or click Create Environment on the dashboard.
  2. Click Create Environment in the top-right corner.
  3. In the modal dialog, enter:
    • Slug -- A URL-safe identifier (e.g., staging). Cannot be changed later.
    • Display Name -- A human-readable name (e.g., "Staging").
  4. Click Create.

Create environment modal

Tier Limits on Environments

Your license tier determines how many environments you can create:

Tier Max Environments
LOW 1
MID 2
HIGH Unlimited
BUSINESS Unlimited

If you attempt to create an environment beyond your tier limit, the request will be rejected.

Managing Environments

From the environment detail page you can:

  • Rename the environment by clicking its display name (inline edit). Requires the apps:manage scope.
  • Delete the environment using the "Delete Environment" button. An environment can only be deleted after all its apps have been removed. Requires the apps:manage scope.

4. Applications

What an Application Represents

An application in Cameleer SaaS represents one of your Apache Camel applications. It tracks the uploaded JAR file, deployment state, routing configuration, and observability status. Applications live inside environments.

Creating an Application

Note: Creating applications requires the apps:deploy scope.

To create an application:

  1. Navigate to the environment where you want to add the app.
  2. Click New App.
  3. In the modal dialog, fill in:
    • Slug -- A URL-safe identifier (e.g., order-router). Cannot be changed later.
    • Display Name -- A human-readable name (e.g., "Order Router").
    • JAR File (optional) -- Select your Camel application JAR. You can also upload or re-upload the JAR later.
  4. Click Create App.

New app modal

Uploading a JAR File

You can upload a JAR at creation time or re-upload it later:

  1. Navigate to the app detail page.
  2. In the Actions card on the Overview tab, click Re-upload JAR.
  3. Select the new JAR file and click Upload.

The platform stores the original filename, file size, and a checksum for each upload.

Understanding Agent Injection

When you deploy an application, the platform builds a Docker image from your JAR with the Cameleer agent automatically injected as a -javaagent. This means:

  • You do not need to modify your application code or build process.
  • The agent instruments your Camel routes at runtime using bytecode manipulation.
  • The agent connects to the observability server and begins reporting route topology, execution traces, and processor metrics.

5. Deployments

Deploying an Application

Note: Deploying requires the apps:deploy scope.

To deploy an application:

  1. Navigate to the app detail page (via the sidebar tree or the environment's app list).
  2. On the Overview tab, in the Actions card, click Deploy.
  3. The deployment starts asynchronously. The status will transition through the deployment lifecycle.

Viewing Deployment Status

After triggering a deployment, the Current Deployment card on the Overview tab shows:

  • Version -- An incrementing deployment version number.
  • Status -- The observed status of the deployment.
  • Image -- The Docker image reference built for this deployment.
  • Deployed -- The timestamp when the deployment started.
  • Error -- If the deployment failed, the error message appears here.

The deployment lifecycle follows these status transitions:

BUILDING --> STARTING --> RUNNING
                |
                +--> FAILED
  • BUILDING -- The Docker image is being built with your JAR and the Cameleer agent.
  • STARTING -- The container has been created and is starting up.
  • RUNNING -- The container is running and healthy.
  • FAILED -- The deployment encountered an error (image build failure, container crash, etc.).

Stopping and Restarting

From the Actions card:

  • Stop -- Stops the running container. A confirmation dialog appears before stopping.
  • Restart -- Stops and redeploys the application with the same JAR version.

Both actions require the apps:deploy scope and are only available when the app has an active deployment.

Reading Container Logs

To view container logs:

  1. Navigate to the app detail page.
  2. Click the Logs tab.
  3. Logs appear in a scrollable viewer with timestamps.
  4. Filter by stream using the buttons at the top: All, stdout, or stderr.

Container logs

Tip: If no logs appear, the app may not have been deployed yet or the container may have exited immediately.

Deployment History

To view the full deployment history:

  1. Navigate to the app detail page.
  2. Click the Deployments tab.
  3. A table shows all past and current deployments with: version, observed status, desired status, deployed timestamp, stopped timestamp, and any error message.

Failed deployments are highlighted with a red accent for quick identification.


6. Observability

Accessing the Observability Dashboard

The observability dashboard is provided by cameleer3-server and opens in a separate browser tab:

  1. In the sidebar footer, click View Dashboard.
  2. The dashboard opens at the cameleer3-server URL.

Alternatively, from any app detail page, the Agent Status card includes a "View in Dashboard" link.

What You Can See

The observability dashboard provides:

  • Route topology -- Visual graph of your Camel routes showing processors, endpoints, and data flow.
  • Execution traces -- Individual route execution traces with timing, payload snapshots, and processor-level detail.
  • Processor metrics -- Throughput, latency, and error rates per processor node.

Agent Connection Status

The Agent Status card on each app detail page shows:

  • Registration state -- Whether the agent has registered with the observability server.
  • Connection state -- CONNECTED (live, with a pulsing indicator) or DISCONNECTED.
  • Last heartbeat -- Timestamp of the most recent agent heartbeat.
  • Routes -- List of Camel route IDs discovered by the agent.
  • Observability data -- Whether traces, metrics, and diagrams are being produced, with a 24-hour trace count.

7. Licenses

Understanding Tiers

Cameleer SaaS uses four license tiers that control available features and resource limits:

Tier Features Max Agents Max Environments Retention
LOW Topology 3 1 7 days
MID Topology, Lineage, Correlation 10 2 30 days
HIGH All (including Debugger, Replay) 50 Unlimited 90 days
BUSINESS All Unlimited Unlimited 365 days

Feature Gating

Each feature is either Enabled or Disabled based on your tier:

Feature LOW MID HIGH BUSINESS
Topology Enabled Enabled Enabled Enabled
Lineage Disabled Enabled Enabled Enabled
Correlation Disabled Enabled Enabled Enabled
Debugger Disabled Disabled Enabled Enabled
Replay Disabled Disabled Enabled Enabled

Viewing License Status and Expiry

To view your license:

  1. Click License in the sidebar.
  2. The license page displays:
    • Tier badge -- Your current tier.
    • Validity -- Issue date, expiration date, and days remaining. The days-remaining badge turns yellow when 30 or fewer days remain and red when expired.
    • Features -- Which observability features are enabled or disabled.
    • Limits -- Max agents, retention days, and max environments.
    • License token -- Click "Show token" to reveal the token used for agent registration.

License page

Warning: If your license expires, deployed applications continue to run but new deployments and agent registrations may be restricted. Contact your administrator to renew.


8. Platform Administration

Note: This section applies only to users with the platform:admin scope. The Platform section in the sidebar is not visible to regular users.

Managing Tenants

Platform administrators can view and manage all tenants across the platform:

  1. Click Platform in the sidebar.
  2. The All Tenants page displays a table of every tenant with: name, slug, tier, status, and creation date.
  3. Click on a tenant row to switch your active context to that tenant's dashboard.

Admin tenants page

Creating Tenants

New tenants can be created via the API (the UI currently provides read-only access to the tenant list):

POST /api/tenants
Content-Type: application/json

{
  "name": "Acme Corp",
  "slug": "acme-corp",
  "tier": "MID"
}

This requires a valid token with the platform:admin scope. A default environment is automatically created with each new tenant.

Creating Organizations in Logto

Each tenant in Cameleer SaaS corresponds to an organization in Logto. When you create a tenant, a corresponding Logto organization should be created and users assigned to it. For self-hosted deployments, the bootstrap script handles this automatically for the initial tenant.

To create additional organizations:

  1. Open the Logto admin console.
  2. Navigate to Organizations and create a new organization.
  3. Add users to the organization and assign them the appropriate role (admin or member).
  4. Create the corresponding tenant in Cameleer SaaS via the API with a matching slug.

9. Roles and Permissions

Organization Roles

Cameleer SaaS uses two organization-level roles managed in Logto:

Role Description
admin Full access to all tenant operations
member Can deploy apps and view observability data

What Each Role Can Do

Scope Admin Member Description
tenant:manage Yes No Manage tenant settings
billing:manage Yes No Manage billing
team:manage Yes No Manage team members
apps:manage Yes No Create/delete apps and environments
apps:deploy Yes Yes Deploy, stop, and restart apps
secrets:manage Yes No Manage secrets
observe:read Yes Yes View observability data
observe:debug Yes Yes Debug and replay operations
settings:manage Yes No Manage settings

In the UI, buttons and actions that require a scope you do not have are automatically hidden. For example, members will not see "Create Environment" or "Delete App" buttons.

How Permissions Are Managed

All role and permission management happens in Logto, not in the Cameleer SaaS application itself:

  • Organization roles and their scopes are configured in Logto during the bootstrap process.
  • To change a user's role, update their organization role assignment in the Logto admin console.
  • To add a user to a tenant, add them to the corresponding Logto organization and assign a role.

There is also a global platform:admin scope (separate from organization roles) that grants access to the Platform section for cross-tenant administration.

The full list of 10 scopes is also available programmatically via the GET /api/config endpoint, which the frontend uses to discover available scopes at runtime.


10. Self-Hosted Setup

Prerequisites

  • Docker Desktop (Windows/Mac) or Docker Engine 24+ (Linux)
  • Docker Compose v2 (included with Docker Desktop)
  • Git for cloning the repository
  • curl or any HTTP client for verification

Quick Start

# 1. Clone the repository
git clone https://gitea.siegeln.net/cameleer/cameleer-saas.git
cd cameleer-saas

# 2. Create your environment file
cp .env.example .env

# 3. Start the stack
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d

# 4. Wait for services (~30-60 seconds for first boot)
docker compose logs -f cameleer-saas --since 10s
# Look for: "Started CameleerSaasApplication"

# 5. Verify
curl http://localhost:8080/actuator/health
# Expected: {"status":"UP"}

Environment Variables Reference

Copy .env.example to .env and configure as needed:

Variable Purpose Default
VERSION Docker image tag latest
POSTGRES_USER PostgreSQL username cameleer
POSTGRES_PASSWORD PostgreSQL password change_me_in_production
POSTGRES_DB PostgreSQL database name cameleer_saas
LOGTO_ENDPOINT Internal Logto URL (container-to-container) http://logto:3001
LOGTO_PUBLIC_ENDPOINT Public-facing Logto URL http://localhost:3001
LOGTO_ISSUER_URI OIDC issuer URI http://localhost:3001/oidc
LOGTO_JWK_SET_URI OIDC JWK set URI http://logto:3001/oidc/jwks
LOGTO_M2M_CLIENT_ID Machine-to-machine client ID (auto-set by bootstrap) (empty)
LOGTO_M2M_CLIENT_SECRET Machine-to-machine client secret (auto-set by bootstrap) (empty)
LOGTO_SPA_CLIENT_ID SPA client ID for the frontend (empty)
CAMELEER_AUTH_TOKEN Bootstrap token for agent registration change_me_bootstrap_token
CAMELEER_CONTAINER_MEMORY_LIMIT Memory limit for deployed containers 512m
CAMELEER_CONTAINER_CPU_SHARES CPU shares for deployed containers 512
CAMELEER_TENANT_SLUG Default tenant slug default
DOMAIN Domain for Traefik TLS and route URLs localhost
SAAS_ADMIN_USER Platform admin username admin
SAAS_ADMIN_PASS Platform admin password admin
TENANT_ADMIN_USER Tenant admin username camel
TENANT_ADMIN_PASS Tenant admin password camel

Warning: Change all default passwords before running in production. The defaults (admin/admin, camel/camel) are for development only.

The Services

The platform runs as a Docker Compose stack with these services:

Service Purpose Dev Port
traefik Reverse proxy and TLS termination 80, 443
postgres Database for platform data, Logto, and cameleer3-server 5432
logto Identity provider (OIDC/SSO) 3001, 3002
logto-bootstrap One-time setup (runs and exits) --
cameleer-saas SaaS API server and frontend 8080
cameleer3-server Observability backend 8081
clickhouse Trace, metrics, and log storage 8123

In production mode (docker compose up), only ports 80 and 443 are exposed via Traefik. In development mode (docker compose -f docker-compose.yml -f docker-compose.dev.yml up), individual service ports are exposed directly for debugging.

The Bootstrap Process

On first boot, the logto-bootstrap container automatically:

  1. Waits for Logto and cameleer3-server to be healthy.
  2. Creates three Logto applications:
    • Cameleer SaaS (SPA) -- for the management UI frontend.
    • Cameleer SaaS Backend (Machine-to-Machine) -- for server-to-Logto API calls.
    • Cameleer Dashboard (Traditional Web App) -- for cameleer3-server OIDC login.
  3. Creates an API resource (https://api.cameleer.local) with 10 OAuth2 scopes (see Section 9).
  4. Creates organization roles with API resource scopes (not standalone org permissions):
    • admin -- 9 tenant scopes (all except platform:admin).
    • member -- 3 scopes: apps:deploy, observe:read, observe:debug.
  5. Creates two users:
    • Platform admin (default: admin / admin) -- has the admin org role plus the global platform-admin role (which grants platform:admin scope).
    • Demo user (default: camel / camel) -- added to the default organization with the member role.
  6. Creates a Logto organization ("Example Tenant") and assigns both users.
  7. Configures cameleer3-server with Logto OIDC settings for dashboard authentication.
  8. Writes all generated IDs and secrets to /data/logto-bootstrap.json for the SaaS backend to consume.

The bootstrap is idempotent -- re-running it will skip resources that already exist.

Logto Admin Console Access

For self-hosted deployments, the Logto admin console is available at:

  • Development: http://localhost:3002
  • Production: Accessible only if you configure a Traefik route for port 3002.

Use the admin console to:

  • Manage users and their roles.
  • Configure social login connectors (Google, GitHub, etc.).
  • View and manage applications and API resources.
  • Create additional organizations for new tenants.

Connecting to an External OIDC Provider

To use an external identity provider instead of Logto's built-in username/password:

  1. Open the Logto admin console.
  2. Navigate to Connectors > Social or Enterprise SSO.
  3. Configure your provider (e.g., Google, Azure AD, Okta).
  4. Users can then sign in through the configured provider on the Logto login page.

The Cameleer SaaS application itself does not need any changes -- all identity configuration is handled in Logto.


11. Troubleshooting

Login Fails or Redirect Loop

Symptoms: Clicking "Sign in with Logto" redirects you in a loop, or you see an error page.

Possible causes:

  • The Logto endpoint is unreachable. Verify that Logto is running: docker compose ps logto.
  • The SPA client ID is incorrect. Check that VITE_LOGTO_CLIENT_ID (or the auto-configured value from bootstrap) matches the SPA application ID in Logto.
  • The redirect URI is not registered. The SPA app in Logto must have your current URL's /callback path as an allowed redirect URI. The bootstrap registers http://localhost/callback, http://localhost:8080/callback, and http://localhost:5173/callback by default.

Resolution:

  1. Check Logto logs: docker compose logs logto.
  2. Open the Logto admin console and verify the SPA application's redirect URIs.
  3. If running on a custom domain, add your callback URL to the SPA application's redirect URI list.

401 Errors After Login

Symptoms: You log in successfully but API calls return 401 Unauthorized.

Possible causes:

  • Token audience mismatch. The backend expects tokens issued for https://api.cameleer.local.
  • The Logto issuer URI configured in the backend does not match the actual Logto endpoint.
  • Clock skew between the Logto container and the backend container.

Resolution:

  1. Check backend logs: docker compose logs cameleer-saas.
  2. Verify that LOGTO_ISSUER_URI and LOGTO_JWK_SET_URI in .env are correct.
  3. If the issue persists, restart the services: docker compose restart cameleer-saas logto.

Deployment Stuck in BUILDING

Symptoms: A deployment stays in BUILDING status indefinitely.

Possible causes:

  • The Docker socket is not mounted. The cameleer-saas container needs access to /var/run/docker.sock to build images and create containers.
  • The base runtime image is not available. The platform builds on top of cameleer-runtime-base.
  • Insufficient disk space for the Docker image build.

Resolution:

  1. Check backend logs: docker compose logs cameleer-saas.
  2. Verify Docker socket access: docker compose exec cameleer-saas ls -la /var/run/docker.sock.
  3. Pull the runtime base image manually: docker pull gitea.siegeln.net/cameleer/cameleer-runtime-base:latest.
  4. Check available disk space: docker system df.

Agent Not Connecting to Server

Symptoms: The app is running but the Agent Status card shows "Not registered."

Possible causes:

  • The agent cannot reach the cameleer3-server endpoint. Check network connectivity between the deployed container and the observability server.
  • The bootstrap token does not match. The agent uses CAMELEER_AUTH_TOKEN to register with the server.
  • The cameleer3-server is not healthy.

Resolution:

  1. Check cameleer3-server health: docker compose logs cameleer3-server.
  2. Verify the app container's logs for agent connection errors (use the Logs tab on the app detail page).
  3. Confirm that CAMELEER_AUTH_TOKEN is the same in both the cameleer-saas and cameleer3-server service configurations.

Container Health Check Failing

Symptoms: A deployed container shows as unhealthy or keeps restarting.

Possible causes:

  • The Camel application fails to start (missing dependencies, configuration errors).
  • The application requires environment variables that are not set.
  • The container runs out of memory (default limit is 512 MB).

Resolution:

  1. Check the container logs from the Logs tab on the app detail page.
  2. If the app crashes immediately, verify the JAR file is a valid executable Spring Boot or Camel application.
  3. To increase memory limits, set CAMELEER_CONTAINER_MEMORY_LIMIT to a higher value (e.g., 1g) in .env and restart the stack.

Bootstrap Script Errors

Symptoms: The logto-bootstrap container exits with an error, and the cameleer-saas service fails to start.

Possible causes:

  • PostgreSQL is not ready when the bootstrap runs. This is unusual because the bootstrap waits for Logto, which itself waits for PostgreSQL.
  • Network issues between containers.
  • Logto database is in an inconsistent state.

Resolution:

  1. Check bootstrap logs: docker compose logs logto-bootstrap.
  2. If the error is transient, re-run the bootstrap: docker compose restart logto-bootstrap.
  3. For a fresh start, remove all volumes and restart:
    docker compose down -v
    docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d
    

Warning: The command above (docker compose down -v) destroys all data including databases. Only use it if you want a clean slate.