kotlin-command-center / server /ACCESS_SETUP.md
SNAPKITTYWEST's picture
October 2026 main drop: mirror from GitHub
d9ee7c4 verified
|
Raw History Blame Contribute Delete
2.65 kB
# Cloudflare Access setup β€” service-token auth for the app
Both tunnel hostnames must sit behind Cloudflare Access so the open internet
cannot reach Ollama or SSH. The Kotlin app authenticates with a **service
token** (Client ID + Client Secret) β€” programmatic, no browser login on the
phone.
## 1. Create the Access applications
Cloudflare dashboard β†’ **Zero Trust β†’ Access β†’ Applications β†’ Add an application β†’ Self-hosted**.
Create one for each hostname (replace `yourdomain.com` with your domain):
| Application name | Domain |
|---|---|
| command-center-ollama | `ollama-internal.yourdomain.com` |
| command-center-ssh | `ssh.yourdomain.com` |
Session duration: 24h is fine (service tokens are not interactive sessions).
## 2. Create the service token
**Zero Trust β†’ Access β†’ Service Tokens β†’ Create Service Token.**
- Name: `kotlin-command-center`
- It shows a **Client ID** and **Client Secret** exactly once. Copy both now β€”
the secret cannot be retrieved later (generate a new token if lost).
## 3. Attach the Allow policy to both applications
For each application β†’ **Policies β†’ Add a policy**:
- Policy name: `app-service-token`
- Action: **Allow**
- Configure rules β†’ **Add require β†’ Service Token** β†’ select `kotlin-command-center`
- (Optional but recommended) Add an `AND` rule: **IP ranges** limited to the
egress ranges you actually use, if they are stable.
Result: any request without a valid `CF-Access-Client-Id` /
`CF-Access-Client-Secret` pair is rejected at the edge before it ever touches
your tunnel.
## 4. Wire the secrets into the stack
| Secret | Where it goes |
|---|---|
| Client ID + Client Secret | `worker/` via `wrangler secret put CF_CLIENT_ID` / `CF_CLIENT_SECRET` (Worker attaches them when calling the tunnel) |
| Client ID + Client Secret | Kotlin app config (`CC_CF_CLIENT_ID`, `CC_CF_CLIENT_SECRET`) β€” used on the **SSH WebSocket handshake** (`wss://ssh.yourdomain.com`) |
| `APP_SECRET` (you invent) | `wrangler secret put APP_SECRET` and the app's `CC_APP_SECRET` β€” authenticates the phone to the Worker |
The phone never talks to `ollama-internal.yourdomain.com` directly; only the
Worker holds the service token for that hostname. The phone uses the service
token only for the SSH WebSocket handshake.
## 5. Rotation
- Service token compromised or phone lost: **Access β†’ Service Tokens β†’ delete**
the token and create a new one, then `wrangler secret put` the new values and
update the app config. The old token stops working immediately.
- `APP_SECRET`: pick a fresh 32+ byte random value
(`openssl rand -hex 32`), rotate the same way.