Files
CASAN/docs/guides/CASAN_LOCAL_FULL_STACK.md
T
2026-07-20 23:47:09 +07:00

8.6 KiB

CASAN local full stack (macOS)

Nếu bạn chưa rõ CASAN được dùng thế nào trong một dự án thực tế, đọc Dùng CASAN để làm dự án trước tài liệu cài đặt này.

This guide runs the entire currently implemented CASAN stack on one Mac. It is a local production-like lab, not a production compliance claim. The Linux server is deliberately not used in this phase.

What runs locally

Component Address Role
Vault dev / Transit http://127.0.0.1:18200 KMS signing and rotation exercises
Mock OIDC / JWKS http://127.0.0.1:18081 Approval JWT validation
MinIO S3 API http://127.0.0.1:19090 S3-compatible object storage
MinIO Console http://127.0.0.1:19091 S3 administration UI
MinIO WORM bucket casan-worm Object Lock / 1-day compliance retention
Alert mock http://127.0.0.1:19092 Alert webhook target
Billing mock http://127.0.0.1:19093/usage Provider-usage import target
AgentOps dashboard http://127.0.0.1:18080 Dashboard behind nginx basic auth
CASAN Control Panel https://localhost:18443 TLS + mock OIDC + oauth2-proxy + nginx + NestJS + React
OmniRoute http://127.0.0.1:20128/v1 Existing local OpenAI-compatible model gateway

The Control Panel uses a different mock IdP port (18082) so it can run at the same time as the approval IdP (18081).

1. Prerequisites

  • Docker Desktop running, with at least 6 GB RAM allocated.
  • Node.js 20+ and npm (needed only for host-side development and CASAN pipeline execution; the local services run in Docker).
  • OmniRoute already reachable at http://127.0.0.1:20128/v1 when model mode is required.

Confirm Docker first:

docker version
docker compose version

2. Start every local service

From the repository root:

bash packages/casan-harness/scripts/bash/local-full.sh start

The first run builds the mock services and Control Panel images. Open:

  • Dashboard: http://127.0.0.1:18080 — credentials casan / casan.
  • MinIO Console: http://127.0.0.1:19091 — credentials casanadmin / casanadmin123.
  • Control Panel: https://localhost:18443 — accept the local self-signed certificate. The mock OIDC flow signs in automatically as oidc-ops with org-admin for local testing only.

Check running services at any time:

bash packages/casan-harness/scripts/bash/local-full.sh status

3. Verify infrastructure controls

bash packages/casan-harness/scripts/bash/local-full.sh verify

This performs live Vault Transit sign/verify, gets an RS256 JWT from the mock OIDC IdP and validates it via JWKS, writes a retained object to MinIO, sends an alert, imports billing telemetry, and accesses the authenticated dashboard.

For the stricter TLS/OIDC Control Panel browser smoke:

bash packages/casan-harness/scripts/bash/local-full.sh smoke

smoke is intentionally isolated and stops its temporary Control Panel stack when complete. Run start again if you want the UI to remain up afterwards.

4. Connect CASAN to OmniRoute

CASAN now supports an explicit OpenAI-compatible gateway model syntax. It does not relax the public OpenAI endpoint hardening: the custom URL is required and, by default, may only be localhost. Keep secrets out of shell history and Git.

First load your key into the current shell using the mechanism you normally use (for example a password manager or a non-tracked .env.local). Then list model IDs that OmniRoute exposes:

curl -fsS http://127.0.0.1:20128/v1/models | python3 -m json.tool

Configure a returned model ID. CASAN_OPENAI_COMPATIBLE_API_KEY may be a dedicated OmniRoute key; if omitted, the router falls back to OPENAI_API_KEY.

export CASAN_OPENAI_COMPATIBLE_BASE_URL=http://127.0.0.1:20128/v1
export CASAN_OPENAI_COMPATIBLE_API_KEY="$OPENAI_API_KEY"
export CASAN_MODEL_PRIMARY='openai-compatible:auto/best-coding'
export CASAN_CHAT_MODEL_MODE=model
export CASAN_CHAT_MODEL_PROVIDER=omniroute
export CASAN_PREFLIGHT=1

For the Dockerized Control Panel, copy the provided template and replace only the key locally. Docker uses host.docker.internal so the Linux container can reach OmniRoute on the Mac host.

cp infra/local-prod/casan.local.env.example infra/local-prod/casan.local.env
# Edit casan.local.env in your editor and replace the placeholder key.
bash packages/casan-harness/scripts/bash/local-full.sh start

Do not set a bare localhost URL in this file: inside the Control Panel container, localhost means the container itself, not your Mac.

Run a non-destructive router smoke. A successful response records real token usage in .specify/logs/level5/provider-usage.jsonl.

printf 'Return exactly: CASAN_OK\n' >/tmp/casan-prompt.txt
bash packages/casan-harness/scripts/bash/model-router.sh \
  /tmp/casan-prompt.txt /tmp/casan-model-result.json --role generate \
  --model "$CASAN_MODEL_PRIMARY"
python3 -m json.tool /tmp/casan-model-result.json

The configured omniroute chat provider is classified as a gateway and always forces CASAN's preflight data-governance check before prompt content is sent. This is intentional: OmniRoute could route a request to a cloud model even when the first selected model is local.

To use a gateway on a private-LAN host later, explicitly name it; never use an open allowlist:

export CASAN_OPENAI_COMPATIBLE_BASE_URL=http://192.168.1.5:20128/v1
export CASAN_OPENAI_COMPATIBLE_ALLOWED_HOSTS=192.168.1.5

Use HTTPS and a real certificate before moving this beyond a trusted LAN.

Local Ornith default for the Control Panel

The local Docker Control Panel now defaults to the existing host Ollama model ornith:9b. It reaches Docker Desktop's host bridge at host.docker.internal:11434; CASAN permits only that exact bridge when the local compose profile explicitly enables it. If Ollama is unavailable, chat returns its deterministic evidence answer instead of fabricating a model result.

Use OmniRoute/OpenAI only when you deliberately want the gateway route. Create casan.local.env as described above and set:

CASAN_CHAT_MODEL_PROVIDER=omniroute
CASAN_OPENAI_COMPATIBLE_BASE_URL=http://host.docker.internal:20128/v1
CASAN_OPENAI_COMPATIBLE_API_KEY=your-key

5. Run CASAN with local models

For model-backed source generation, use the same environment and enable it only for the invocation:

CASAN_GEN_MODE=model CASAN_PREFLIGHT=1 \
  node scripts/casan-step.mjs 01-srs 1

CASAN continues to fall back safely to deterministic templates if the gateway is unavailable or the output is rejected by a harness gate. For governed chat, start the Control Panel and select the omniroute provider through the existing model configuration; the default remains deterministic/offline.

6. Stop and reset

Stop all containers while preserving MinIO data:

bash packages/casan-harness/scripts/bash/local-full.sh stop

To remove only the lab's persisted object-store data, first stop the lab, then:

docker volume rm casan-local-prod_minio-data

This is destructive and cannot be undone. Do not use it if the MinIO bucket has evidence you need to retain.

Python used by the local auth bridge

local-full.sh validates the Python interpreter before starting the host-side provider auth bridge. On macOS it prefers /usr/bin/python3, avoiding an old Intel-only framework Python that may be first in PATH but terminated by macOS. To select another working Python explicitly, set CASAN_PYTHON_BIN:

CASAN_PYTHON_BIN=/opt/homebrew/bin/python3 \
  bash packages/casan-harness/scripts/bash/local-full.sh start

The launcher also validates Docker's configured credential helper. If macOS terminates that helper, CASAN uses an isolated, temporary anonymous Docker configuration for this local stack's public images while preserving the active Docker Desktop socket and Compose plugin. The same fallback uses Docker's classic builder if the bundled BuildKit metadata helper is also terminated. It does not edit ~/.docker/config.json or delete stored registry credentials. Reinstall or update Docker Desktop later to repair the helper globally.

Current scope and next phase

This local environment includes every currently implemented CASAN component. It intentionally uses Vault dev mode, self-signed TLS, mock IdPs, local MinIO, and mock alert/billing endpoints. Production promotion to the Linux server should replace those with managed Vault/KMS or HSM, real S3 Object Lock, real OIDC, HTTPS certificates, a secret manager, backup/restore tests, and firewall rules; it is a separate deployment exercise.