simplify docs
Some checks failed
ci/woodpecker/pr/pr Pipeline failed

This commit is contained in:
Madison Grubb
2026-02-17 11:25:40 -05:00
parent 82bd51c3a4
commit c696f38f4d
6 changed files with 181 additions and 570 deletions

View File

@@ -1,20 +1,11 @@
# KestrelOS documentation # KestrelOS Documentation
KestrelOS is a Tactical Operations Center (TOC) for OSINT feeds: map view, cameras/devices, live sharing, and ATAK/iTAK integration. Tactical Operations Center (TOC) for OSINT feeds: map view, cameras/devices, live sharing, and ATAK/iTAK integration.
## Documentation index ## Quick Start
| Topic | Description | 1. [Installation](installation.md) — npm, Docker, or Helm
|-------|-------------| 2. [Authentication](auth.md) — First login (bootstrap admin or OIDC)
| [Installation](installation.md) | Install via npm, Docker, or Helm (Kubernetes) | 3. [Map and cameras](map-and-cameras.md) — Add devices and view streams
| [Authentication](auth.md) | Local login, OIDC config, and sign up | 4. [ATAK and iTAK](atak-itak.md) — Connect TAK clients (port 8089)
| [Map and cameras](map-and-cameras.md) | Using the map, adding and viewing cameras (IPTV, ALPR, CCTV, NVR, etc.) | 5. [Share live](live-streaming.md) — Stream from mobile device (HTTPS required)
| [ATAK and iTAK](atak-itak.md) | Connect ATAK (Android) and iTAK (iOS) to KestrelOS as a TAK Server |
| [Share live](live-streaming.md) | Add your mobile device as a live camera (WebRTC) |
## Quick links
- **First run**: [Installation](installation.md) → [Authentication](auth.md) (bootstrap admin or OIDC).
- **Add a camera**: [Map and cameras](map-and-cameras.md) (API or future UI).
- **Stream from phone**: [Share live](live-streaming.md) (HTTPS required).
- **Use ATAK/iTAK**: [ATAK and iTAK](atak-itak.md) (Server connection, port 8089 for CoT).

View File

@@ -1,188 +1,79 @@
# ATAK and iTAK usage # ATAK and iTAK
KestrelOS can act as a **TAK Server**: ATAK (Android) and iTAK (iOS) devices connect to it the same way they connect to any TAK Server. No plugins are required. Once connected, devices relay Cursor on Target (CoT) to each other so team members see each other on the ATAK/iTAK map, and their positions appear on the KestrelOS web map. KestrelOS acts as a **TAK Server**. ATAK (Android) and iTAK (iOS) connect on **port 8089** (CoT). Devices relay positions to each other and appear on the KestrelOS map.
--- ## Connection
## Overview **Host:** KestrelOS hostname/IP
**Port:** `8089` (CoT)
**SSL:** Enable if server uses TLS (`.dev-certs/` or production cert)
- **ATAK** — Android Team Awareness Kit. **Authentication:**
- **iTAK** — iOS version; uses the same TAK Server connection flow. - **Username:** KestrelOS identifier
- **KestrelOS** — Web app and API use **port 3000**. CoT (TAK) uses **port 8089** (TLS when `.dev-certs/` or `COT_SSL_*` are set, else plain TCP). In ATAK/iTAK you connect to host and port **8089**; enable SSL if the server uses TLS. - **Password:** Login password (local) or ATAK password (OIDC; set in **Account**)
You add KestrelOS as a **Server** connection in ATAK or iTAK (host + port **8089**). If authentication is enabled, you use your **KestrelOS username** and a **password** (local users: login password; OIDC users: ATAK password set in the web app).
---
## ATAK (Android) ## ATAK (Android)
### 1. Add the server 1. **Settings****Network****Connections** → Add **TAK Server**
2. Set **Host** and **Port** (`8089`)
1. Open **ATAK**. 3. Enable **Use Authentication**, enter username/password
2. Go to **Settings** (or **Configuration**) → **Network****Connections** (or **Server Connections**). 4. Save and connect
3. Add a new connection:
- **Type:** TAK Server / Server.
- **Host:** Your KestrelOS hostname or IP (e.g. `kestrelos.example.com` or `192.168.1.10`).
- **Port:** **8089** (CoT port). Use SSL if the server runs with TLS (e.g. `.dev-certs/` or production cert).
4. If your KestrelOS instance requires authentication:
- Enable **Use Authentication** (or equivalent).
- **Username:** Your KestrelOS identifier (email or username).
- **Password:**
- **Local account:** Your KestrelOS login password.
- **OIDC account:** The **ATAK password** you set under **Account** in the KestrelOS web app (you must set it once before connecting).
5. Save and connect.
### 2. Verify
- After connecting, your device and other connected ATAK/iTAK devices should appear on the ATAK map.
- In KestrelOS, open the **Map** in a browser; you should see amber markers for connected TAK devices. They disappear after about 90 seconds without updates.
---
## iTAK (iOS) ## iTAK (iOS)
### 1. Add the server **Option A — QR code (easiest):**
1. KestrelOS **Settings****TAK Server** → Scan QR with iTAK
2. Enter username/password when prompted
**Option AScan QR code (easiest)** **Option BManual:**
In KestrelOS, open **Settings** and find the **TAK Server (ATAK / iTAK)** section. Scan the QR code with iTAK (Add Connection → Scan QR). iTAK will add the server; youll be prompted for your KestrelOS username and password. If the server uses a self-signed certificate, import the trust store first (see [Self-signed certificate: import the trust store](#2-self-signed-certificate-import-the-trust-store-required-for-ssl)). 1. **Settings****Network** → Add **TAK Server**
2. Set **Host**, **Port** (`8089`), enable SSL if needed
3. Enable **Use Authentication**, enter username/password
4. Save and connect
**Option B — Manual** ## Self-Signed Certificate (iTAK)
1. Open **iTAK**.
2. Go to **Settings****Network** / **Connections** (wording may vary by version).
3. Add a **TAK Server** (or **Server**) connection:
- **Host:** KestrelOS hostname or IP.
- **Port:** **8089** (CoT port). Use SSL when the server uses TLS.
4. If authentication is required:
- Turn on **Use Authentication**.
- **Username:** Your KestrelOS identifier.
- **Password:** KestrelOS login password (local) or ATAK password (OIDC; set in KestrelOS **Account**).
5. Save and connect.
### 2. Self-signed certificate (required for SSL) If server uses self-signed cert (`.dev-certs/`):
If KestrelOS uses a **self-signed certificate** (e.g. `.dev-certs/`), the client must trust it or the TLS handshake never completes. Youll see “Error authenticating with the server” and **no `[cot]` logs** on the server. **Upload server package:**
1. KestrelOS **Settings****TAK Server****Download server package (zip)**
2. Transfer to iPhone (AirDrop, email, Safari)
3. iTAK: **Settings****Network****Servers****+** → **Upload server package**
4. Enter username/password
**iTAK (iOS) — Upload server package (recommended):** **Or use plain TCP:**
Many iTAK builds only offer “Connect with credentials”, “Upload server package”, and “Scan QR”; there is no “Import Trust Store” or “Enroll with Preconfigured Trust”. Use the server package: 1. Stop KestrelOS, remove `.dev-certs/`, restart
2. Add server with **SSL disabled**
1. In **KestrelOS**, open **Settings****TAK Server (ATAK / iTAK)** and click **Download server package (zip)**. **ATAK (Android):** Download trust store from `https://your-server/api/cot/truststore`, import `.p12` (password: `kestrelos`), or use server package/plain TCP.
2. Transfer the zip to your iPhone (e.g. AirDrop, email, or open KestrelOS in Safari on the phone, log in, and download there).
3. In **iTAK**: **Settings****Network****Servers****+** → **Upload server package** → select the zip.
4. When prompted, enter your KestrelOS **username** and **password**. The package includes the server cert so iTAK can complete the TLS handshake.
**iTAK — Plain TCP (no SSL):** ## OIDC Users
If the server package does not work, run CoT without TLS: stop KestrelOS, rename or remove the `.dev-certs` folder, then restart. The CoT server will listen on 8089 with plain TCP. In **Settings** → TAK Server, the QR will show `tcp`. Scan it or add the server manually with **SSL disabled**. You wont get a cert prompt and the connection should reach the server.
**ATAK (Android):** If your build has **Enroll with Preconfigured Trust** and **Import Trust Store**, you can download the trust store from **https://your-server/api/cot/truststore** (when logged in), import the `.p12`, password `kestrelos`, then connect. Otherwise use the **server package** from Settings the same way as iTAK, or use plain TCP as above. OIDC users must set an **ATAK password** first:
1. Sign in with OIDC
2. **Account****ATAK / device password** → set password
3. Use KestrelOS username + ATAK password in TAK client
### 3. Verify ## Configuration
- Other TAK clients (ATAK and iTAK) that are connected to the same KestrelOS instance appear on your iTAK map. | Variable | Default | Description |
- KestrelOS web map shows all connected TAK devices as amber markers (position only; no video). |----------|---------|-------------|
| `COT_PORT` | `8089` | CoT server port |
--- | `COT_TTL_MS` | `90000` | Device timeout (~90s) |
| `COT_REQUIRE_AUTH` | `true` | Require authentication |
## OIDC users: set ATAK password first | `COT_SSL_CERT` | `.dev-certs/cert.pem` | TLS cert path |
| `COT_SSL_KEY` | `.dev-certs/key.pem` | TLS key path |
If you sign in to KestrelOS with **OIDC** (SSO), you do not have a KestrelOS login password. To use “Use Authentication” in ATAK/iTAK:
1. Sign in to the **KestrelOS web app** with OIDC.
2. Open **Account** (sidebar).
3. Under **ATAK / device password**, set and confirm a password, then save.
4. In ATAK or iTAK, use your **KestrelOS username** (identifier) and this **ATAK password**.
If you havent set an ATAK password, the TAK Server will reject your connection.
---
## Server configuration (optional)
| Environment variable | Default | Description |
|----------------------|---------|-------------|
| `PORT` | `3000` | Port for the web app and API. |
| `COT_PORT` | `8089` | Port for the CoT (TAK) server. |
| `COT_TTL_MS` | `90000` | How long (ms) a device stays on the map without updates (~90 s). |
| `COT_REQUIRE_AUTH` | `true` | Require username/password before relaying. |
| `COT_SSL_CERT` | — | Path to TLS cert for CoT (optional; default: `.dev-certs/cert.pem`). |
| `COT_SSL_KEY` | — | Path to TLS key (optional; default: `.dev-certs/key.pem`). |
When `.dev-certs/` exists (e.g. `./scripts/gen-dev-cert.sh`), the CoT server uses TLS on port 8089. For **Docker**, expose ports 3000 and 8089:
```bash
docker run -p 3000:3000 -p 8089:8089 kestrelos:latest
```
For **Helm**, expose ports 3000 and 8089 in the service or ingress.
---
## Testing the CoT endpoint
The web app is on **port 3000**, CoT on **port 8089**. From the same device (or any host with network access), you can confirm both work.
**Health (API):** `curl -k https://localhost:3000/health` (or `http://localhost:3000/health` if no TLS).
**CoT on port 8089:** If the server uses TLS (e.g. `.dev-certs/`), connect with TLS to port 8089 and send a CoT auth message:
```bash
echo '<event><detail><auth username="itak" password="yourpassword"/></detail></event>' | \
openssl s_client -connect localhost:8089 -quiet 2>/dev/null
```
If the server runs without TLS (plain TCP), use:
```bash
echo '<event><detail><auth username="itak" password="yourpassword"/></detail></event>' | \
nc localhost 8089
```
Replace `localhost` with your server host if testing remotely. **What to expect:** Server logs show `[cot] client connected`, `[cot] frame parsed as traditional`, `[cot] auth attempt username= itak`, and either `auth result valid= true` or `password match= false`.
---
## Troubleshooting ## Troubleshooting
### "Error authenticating with the server" and no `[cot]` logs on the server **"Error authenticating" with no `[cot]` logs:**
- Connection not reaching server (TLS handshake failed or firewall blocking)
- Check server logs show `[cot] CoT server listening on 0.0.0.0:8089`
- Verify port `8089` (not `3000`) and firewall allows it
- For TLS: trust cert (server package) or use plain TCP
If iTAK shows this message but you see **no** `[cot]` lines in the server log, the connection is almost certainly **not reaching** the CoT process. **"Error authenticating" with `[cot]` logs:**
- Username must be KestrelOS identifier
- Password must match (local: login password; OIDC: ATAK password)
**With SSL (TLS) and a self-signed cert:** The server only runs your connection handler **after** the TLS handshake completes. If the client does not trust the servers certificate (e.g. self-signed and not imported), the handshake fails on the client side and never completes, so the server never logs “client connected”. **Fix:** Use **Upload server package** (download from KestrelOS Settings) or import the trust store in iTAK (see [Self-signed certificate](#2-self-signed-certificate-required-for-ssl) above). No server logs until the client trusts the cert and the handshake succeeds. **Devices not on map:** They appear only while sending updates; drop off after TTL (~90s).
1. **Confirm CoT is listening**
- When the app starts you must see: `[cot] CoT server listening on 0.0.0.0:8089 (TLS)` or `(plain TCP)`.
- If you dont see that, the CoT server didnt start (e.g. port 8089 in use, or youre viewing logs for a different process).
2. **Port and host**
- In iTAK the **port must be 8089** (not 3000). Host = your server IP (e.g. 192.168.2.214).
3. **Reachability from the device**
- From the same network as your phone, run: `nc -zv 192.168.2.214 8089` (or use a "port check" app). If it doesnt connect, the firewall or network is blocking 8089.
4. **SSL and self-signed cert**
- If the server log says **(TLS)**, iTAK must trust the cert: use **Upload server package** (download the zip from KestrelOS Settings) or run CoT without TLS and add the server with SSL disabled (see [Self-signed certificate](#2-self-signed-certificate-required-for-ssl)).
- If the server says **(plain TCP)**, in iTAK **disable** SSL.
5. **Where to look for logs**
- Same terminal where you ran `npm run dev` or `node .output/server/index.mjs`. If you use Docker/systemd, check that processs stdout/stderr.
Once the connection reaches the server youll see at least: `[cot] client connected (TLS) from <ip>`.
---
- **Connection refused:** Ensure ports 3000 (web/API) and 8089 (CoT) are open on the server and in any firewall.
- **"Error authenticating" but you do see `[cot]` logs:** Username must be the KestrelOS **identifier** (login name) and password must match (local: login password; OIDC: ATAK password set in **Account**).
- **Authentication failed (OIDC user):** Set an **ATAK password** in KestrelOS under **Account**.
- **Devices not on KestrelOS map:** They appear only while sending position updates; they drop off after the TTL (~90 s) with no updates.
- **SSL:** If the server uses TLS (`.dev-certs/` or production cert), connect to port 8089 with SSL enabled in ATAK/iTAK.
---
## Summary
| Step | ATAK / iTAK |
|------|-------------|
| Add server | **QR:** KestrelOS **Settings** → scan TAK Server QR with iTAK/ATAK. Or add manually: **Host** = KestrelOS, **Port** = 8089 (CoT). |
| Self-signed SSL (iTAK) | **Settings** → Download **server package (zip)** → in iTAK: **Upload server package** and select it. Or run CoT without TLS (remove `.dev-certs`, restart) and add server with SSL disabled. |
| Auth | Enable “Use Authentication”; **Username** = KestrelOS identifier; **Password** = login password (local) or ATAK password (OIDC). |
| OIDC users | Set **ATAK password** once in KestrelOS **Account** before connecting. |
| Result | CoT is relayed between all connected TAK clients; positions show on the KestrelOS web map as amber markers. |

View File

@@ -1,106 +1,39 @@
# Authentication # Authentication
KestrelOS supports **local login** (username/email + password) and optional **OIDC** (single sign-on with an identity provider). All users must sign in to use the app. KestrelOS supports **local login** (username/email + password) and optional **OIDC** (SSO). All users must sign in.
--- ## Local Login
## Local login **First run:** On first start, KestrelOS creates an admin account:
- If `BOOTSTRAP_EMAIL` and `BOOTSTRAP_PASSWORD` are set → that account is created
- Otherwise → default admin (`admin`) with random password printed in terminal
### First run: bootstrap admin **Sign in:** Open `/login`, enter identifier and password. Change password or add users via **Members** (admin only).
On first start, if the database has no users, KestrelOS creates an **admin** account: ## OIDC (SSO)
- **If you set env vars:** **Enable:** Set `OIDC_ISSUER`, `OIDC_CLIENT_ID`, `OIDC_CLIENT_SECRET`. Optional: `OIDC_LABEL`, `OIDC_REDIRECT_URI`, `OIDC_SCOPES`.
`BOOTSTRAP_EMAIL` and `BOOTSTRAP_PASSWORD`
→ That account is created (identifier = email, role = admin).
- **If you do not set them:** **IdP setup:**
A default admin is created with identifier **`admin`** and a **random password**. 1. Create OIDC client in your IdP (Keycloak, Auth0, etc.)
The password is printed in the terminal—copy it and sign in at **/login**. 2. Set redirect URI: `https://<your-host>/api/auth/oidc/callback`
3. Copy Client ID and Secret to env vars
After first login, change the password or add users via **Members** (admin only). **Sign up:** Users sign up at the IdP. First OIDC login in KestrelOS creates their account automatically.
### Signing in (local) **Redirect URI:** Defaults to `{APP_URL}/api/auth/oidc/callback` (uses `NUXT_APP_URL`/`APP_URL` or falls back to `HOST`/`PORT`).
1. Open **/login** (or youll be redirected there when visiting a protected page). ## OIDC Users and ATAK/iTAK
2. Enter **Email or username** (identifier) and **Password**.
3. Click **Sign in**. Youre redirected to the map or the page you came from.
Local users can always use this form. Their password is stored hashed in the database. OIDC users don't have a KestrelOS password. To use ATAK/iTAK:
1. Sign in with OIDC
--- 2. Go to **Account** → set **ATAK password**
3. Use KestrelOS username + ATAK password in TAK client
## OIDC config and sign up
OIDC lets users sign in with an external identity provider (IdP), e.g. Keycloak, Auth0, or your organizations IdP. There is **no “sign up” inside KestrelOS** for OIDC: accounts are created when a user signs in for the first time (first-time OIDC login creates a KestrelOS user linked to that IdP identity).
### Enabling OIDC
Set these environment variables:
| Variable | Required | Description |
|----------|----------|-------------|
| `OIDC_ISSUER` | Yes | IdP issuer URL (e.g. `https://auth.example.com/realms/myrel`). |
| `OIDC_CLIENT_ID` | Yes | OIDC client ID. |
| `OIDC_CLIENT_SECRET` | Yes | OIDC client secret. |
| `OIDC_LABEL` | No | Button label (default: "Sign in with OIDC"). |
| `OIDC_REDIRECT_URI` | No | Callback URL (default: `{APP_URL}/api/auth/oidc/callback`). |
| `OIDC_SCOPES` | No | Scopes (default: `openid profile email`). |
The app derives the redirect URI if not set:
- Prefer **`NUXT_APP_URL`** or **`APP_URL`** (e.g. `https://kestrelos.example.com`).
Callback = `{that base}/api/auth/oidc/callback`.
- Otherwise it uses **`HOST`**, **`PORT`**, and **`NODE_ENV`** (e.g. `http://localhost:3000/api/auth/oidc/callback`).
### IdP configuration
In your IdP:
1. Create an **OIDC client** (confidential, or public with PKCE if supported).
2. Set **Redirect URI** to:
`https://<your-kestrelos-host>/api/auth/oidc/callback`
(or the same with `http` for local dev).
3. Copy **Client ID** and **Client Secret** into `OIDC_CLIENT_ID` and `OIDC_CLIENT_SECRET`.
4. Set **Issuer** in `OIDC_ISSUER` (issuer URL from the IdPs discovery document).
### OIDC sign-in flow
1. User opens **/login** and clicks the OIDC button (e.g. “Sign in with OIDC”).
2. They are redirected to the IdP to sign in (and sign up at the IdP if needed).
3. After success, the IdP redirects back to KestrelOS with an authorization code.
4. KestrelOS exchanges the code for tokens and creates or finds the user (by `oidc_issuer` + `oidc_sub`), then logs them in.
**Sign up:** Done at the IdP. The first time a user completes OIDC login, KestrelOS creates a new user; no separate “sign up” page in KestrelOS.
### OIDC and ATAK/iTAK
OIDC users dont have a KestrelOS password. To use **ATAK or iTAK** with “Use Authentication,” they must set an **ATAK password** once in the web app:
1. Sign in with OIDC.
2. Go to **Account**.
3. Under **ATAK / device password**, set and confirm a password, then save.
They then use their **KestrelOS username** (identifier) and this **ATAK password** in the TAK client. See [ATAK and iTAK](atak-itak.md).
---
## Roles ## Roles
- **Admin** — Can manage users (add, edit, delete, change roles), edit POIs, and add/edit devices (via API). - **Admin** — Manage users, edit POIs, add/edit devices (API)
- **Leader** — Can edit POIs and add/edit devices (via API). Cannot change user roles. - **Leader** — Edit POIs, add/edit devices (API)
- **Member** — Can view map, cameras, and POIs; can use Share live. Cannot edit POIs or manage devices. - **Member** — View map/cameras/POIs, use Share live
Only admins can change roles (Members page). Only admins can change roles (Members page).
---
## Summary
| Goal | Action |
|------|--------|
| First-time setup | Set `BOOTSTRAP_EMAIL` / `BOOTSTRAP_PASSWORD` or use printed default admin password. |
| Local sign-in | Use **/login** with identifier and password. |
| Enable SSO | Set `OIDC_ISSUER`, `OIDC_CLIENT_ID`, `OIDC_CLIENT_SECRET` (and optional `OIDC_LABEL`, `OIDC_REDIRECT_URI`). |
| “Sign up” with OIDC | Users sign up at the IdP; first OIDC login in KestrelOS creates their account. |
| Use ATAK/iTAK as OIDC user | Set **ATAK password** under **Account** in the web app. |

View File

@@ -1,128 +1,61 @@
# Installation # Installation
You can run KestrelOS from source (npm), as a Docker container, or on Kubernetes with Helm. Run KestrelOS from source (npm), Docker, or Kubernetes (Helm).
## Prerequisites
- **Node.js** 20+ (for npm install)
- **Docker** (optional, for container run)
- **Kubernetes** and **Helm 3** (optional, for Helm install)
---
## npm (from source) ## npm (from source)
Best for development or a single server. ```bash
git clone <repository-url> kestrelos
cd kestrelos
npm install
npm run dev
```
1. **Clone and install** Open **http://localhost:3000**. First run creates `data/kestrelos.db` and bootstraps an admin (see [Authentication](auth.md)).
```bash
git clone <repository-url> kestrelos
cd kestrelos
npm install
```
2. **Start the app** **Production:**
```bash ```bash
npm run dev npm run build
``` npm run preview
Open **http://localhost:3000**. The app will create a SQLite database at `data/kestrelos.db` on first run and bootstrap an admin user if none exist (see [Authentication](auth.md)). # or
node .output/server/index.mjs
```
3. **Production build** Set `HOST=0.0.0.0` and `PORT` for production.
```bash
npm run build
npm run preview
```
Or run the built app with Node:
```bash
node .output/server/index.mjs
```
For production, set `HOST=0.0.0.0` and `PORT` as needed (e.g. `PORT=3000`).
### Environment (npm)
| Variable | Description |
|----------|-------------|
| `HOST` | Bind address (default from Nuxt; use `0.0.0.0` for all interfaces). |
| `PORT` | Port (default `3000`). |
| `DB_PATH` | Path to SQLite file (default `data/kestrelos.db`). |
See [Authentication](auth.md) for `BOOTSTRAP_EMAIL`, `BOOTSTRAP_PASSWORD`, and OIDC variables. See [Map and cameras](map-and-cameras.md) and [ATAK and iTAK](atak-itak.md) for device and CoT options.
---
## Docker ## Docker
Best for a single server or CI.
1. **Build the image**
```bash
docker build -t kestrelos:latest .
```
2. **Run the container**
```bash
docker run -p 3000:3000 -p 8089:8089 kestrelos:latest
```
Open **http://localhost:3000**.
3. **Persist data and set env**
```bash
docker run -p 3000:3000 -p 8089:8089 \
-v kestrelos-data:/app/data \
-e HOST=0.0.0.0 \
-e BOOTSTRAP_EMAIL=admin@example.com \
-e BOOTSTRAP_PASSWORD=yourpassword \
kestrelos:latest
```
Use a volume so the SQLite DB and any uploaded data survive restarts.
### Docker environment
Same as npm; pass with `-e`. CoT (ATAK/iTAK) uses port 8089; expose both 3000 and 8089:
```bash ```bash
docker run -p 3000:3000 -p 8089:8089 -v kestrelos-data:/app/data kestrelos:latest docker build -t kestrelos:latest .
docker run -p 3000:3000 -p 8089:8089 \
-v kestrelos-data:/app/data \
kestrelos:latest
``` ```
--- Expose ports **3000** (web/API) and **8089** (CoT for ATAK/iTAK).
## Helm (Kubernetes) ## Helm (Kubernetes)
Best for production or multi-replica deployments. **From registry:**
### From a Helm registry (e.g. Gitea)
```bash ```bash
helm repo add keligrubb --username YOUR_USER --password YOUR_TOKEN https://git.keligrubb.com/api/packages/keligrubb/helm helm repo add keligrubb --username USER --password TOKEN \
helm repo update https://git.keligrubb.com/api/packages/keligrubb/helm
helm install kestrelos keligrubb/kestrelos helm install kestrelos keligrubb/kestrelos
``` ```
### From source **From source:**
```bash ```bash
helm install kestrelos ./helm/kestrelos helm install kestrelos ./helm/kestrelos
``` ```
### Configuration Configure in `helm/kestrelos/values.yaml`. Health: `GET /health`, `/health/live`, `/health/ready`.
- Edit **`helm/kestrelos/values.yaml`** for image, replica count, resources, and Ingress. ## Environment Variables
- Health endpoints: `GET /health` (overview), `GET /health/live` (liveness), `GET /health/ready` (readiness). The chart configures liveness and readiness probes.
- To expose the app, set **`ingress.enabled: true`** and set `ingress.host` (and TLS if needed).
- For ATAK/iTAK, expose port 8089 (CoT) in addition to 3000 (web/API) on the service or via Ingress.
### Upgrade | Variable | Default | Description |
|----------|---------|-------------|
| `HOST` | Nuxt default | Bind address (use `0.0.0.0` for all interfaces) |
| `PORT` | `3000` | Web/API port |
| `DB_PATH` | `data/kestrelos.db` | SQLite database path |
```bash See [Authentication](auth.md) for auth variables. See [ATAK and iTAK](atak-itak.md) for CoT options.
helm upgrade kestrelos keligrubb/kestrelos
# or
helm upgrade kestrelos ./helm/kestrelos
```
---
## Next steps
- [Authentication](auth.md) — First login (local or OIDC).
- [Map and cameras](map-and-cameras.md) — Add devices and use the map.
- [ATAK and iTAK](atak-itak.md) — Connect TAK clients.
- [Share live](live-streaming.md) — Stream from your phone.

View File

@@ -1,105 +1,44 @@
# Share live (mobile device as a live camera) # Share Live
**Share live** lets you stream your phones camera and location to KestrelOS. You appear as a **live session** on the map and in the **Cameras** list; others can click your marker to watch the stream in real time. Uses **WebRTC** (Mediasoup) and requires **HTTPS** when using the app from a phone. Stream your phone's camera and location to KestrelOS. Appears as a **live session** on the map and in **Cameras**. Uses **WebRTC** (Mediasoup) and requires **HTTPS** on mobile.
--- ## Usage
## How it works 1. Open **Share live** (sidebar → **Share live** or `/share-live`)
2. Tap **Start sharing**, allow camera/location permissions
3. Device appears on map and in **Cameras**
4. Tap **Stop sharing** to end
1. You open the **Share live** page on your mobile browser (sidebar → **Share live**; or **/share-live**). **Permissions:** Admin/leader can start sharing. All users can view live sessions.
2. You tap **Start sharing**. The app requests camera and location permission.
3. A **live session** is created on the server and your video/location is sent over WebRTC.
4. Your device appears on the **map** and in **Cameras**. Others click your marker or select you in the list to view the stream.
5. Tap **Stop sharing** to end the stream.
Only **admin** and **leader** roles see the **Share live** item in the sidebar; they are the ones who can start a live share. Any signed-in user can view live sessions on the map and Cameras page.
---
## Requirements ## Requirements
- **HTTPS** when using the app from a phone. Browsers require a secure context for camera and geolocation. Use: - **HTTPS** (browsers require secure context for camera/geolocation)
- A server with a real TLS certificate, or - **Camera and location permissions**
- For local testing: a self-signed cert and your machines LAN IP (see below). - **WebRTC ports:** UDP/TCP `4000049999` open on server
- **Camera and location permission** in the browser when prompted.
- **Network:** Server must be reachable from the phone. For WebRTC, **UDP and TCP ports 4000049999** must be open on the server (or the ports Mediasoup is configured to use).
--- ## Local Development
## Using Share live on your phone **Generate self-signed cert:**
```bash
chmod +x scripts/gen-dev-cert.sh
./scripts/gen-dev-cert.sh 192.168.1.123 # Your LAN IP
npm run dev
```
### 1. Open the app over HTTPS **On phone:** Open `https://192.168.1.123:3000`, accept cert warning, sign in, use Share live.
- **Production:** Open `https://your-kestrelos.example.com`, sign in, then go to **Share live** (sidebar). ## WebRTC Configuration
- **Local / LAN:** Use the same HTTPS URL you use for the server (e.g. `https://192.168.1.10:3000`). If you use a self-signed cert, accept the browser warning once (e.g. Advanced → Proceed).
### 2. Start sharing - Server auto-detects LAN IP for WebRTC
- **Docker/multiple NICs:** Set `MEDIASOUP_ANNOUNCED_IP` to client-reachable IP/hostname
1. Tap **Share live** in the sidebar (or open `/share-live`). - **"Wrong host" error:** Use same URL on phone/server, or set `MEDIASOUP_ANNOUNCED_IP`
2. Tap **Start sharing**.
3. Allow **camera** and **location** when the browser asks.
4. Wait for “Live — you appear on the map.” Your marker and stream are now visible to others.
### 3. View yourself on the map
- On another device (or in another tab), open the KestrelOS **map**. Your device appears as a live-session marker; click it to open the stream panel.
- Or open **Cameras** and select your session from the list (shown as “Live”).
### 4. Stop sharing
Tap **Stop sharing** on the Share live page. The session ends and your marker disappears after a short time.
---
## Local development: HTTPS and LAN
To test Share live from a phone on your LAN without a public domain or cert:
1. **Generate a self-signed cert** (once) using your machines LAN IP:
```bash
chmod +x scripts/gen-dev-cert.sh
./scripts/gen-dev-cert.sh 192.168.1.123
```
Use your machines actual LAN IP instead of `192.168.1.123`.
2. **Start the dev server** (it will use HTTPS if `.dev-certs/` exists):
```bash
npm run dev
```
3. **On your phone**, open **https://192.168.1.123:3000** (same IP as above). Accept the “untrusted certificate” warning once, then sign in and go to **Share live**.
If you see a warning about `NODE_TLS_REJECT_UNAUTHORIZED=0`, you can ignore it in local dev; the server still works.
---
## WebRTC and firewall
- The server uses **Mediasoup** and needs **UDP and TCP in the range 4000049999** (by default) open for WebRTC.
- The server tries to detect the LAN IP for WebRTC. If you run in **Docker** or have multiple NICs, set **`MEDIASOUP_ANNOUNCED_IP`** to the IP or hostname that clients use to reach the server.
- **Wrong host:** If the Share live page shows “Wrong host” (server hostname vs. client hostname), open the app using the same hostname the server reports, or set `MEDIASOUP_ANNOUNCED_IP` so the server advertises the correct address.
---
## Troubleshooting ## Troubleshooting
| Issue | What to do | | Issue | Fix |
|-------|------------| |-------|-----|
| HTTPS required” or camera/location not available | Open the app over **https://** (not http). On a phone, use a tunnel (e.g. ngrok) or a server with TLS. | | "HTTPS required" | Use `https://` (not `http://`) |
| Media devices not available | Ensure youre on HTTPS and that the browser has permission for camera (and location if needed). | | "Media devices not available" | Ensure HTTPS and browser permissions |
| WebRTC: failed / Wrong host | Use the same URL on phone and server, or set `MEDIASOUP_ANNOUNCED_IP`. Open firewall for ports 4000049999. | | "WebRTC: failed" / "Wrong host" | Set `MEDIASOUP_ANNOUNCED_IP`, open firewall ports `4000049999` |
| Stream doesnt appear for others | Check that the server is reachable and that no firewall blocks WebRTC ports. | | Stream not visible | Check server reachability and firewall |
---
## Summary
| Step | Action |
|------|--------|
| 1 | Open KestrelOS over **HTTPS** on your phone and sign in. |
| 2 | Go to **Share live** (sidebar). |
| 3 | Tap **Start sharing** and allow camera and location. |
| 4 | Your device appears on the **map** and **Cameras**; others click your marker or entry to view. |
| 5 | Tap **Stop sharing** when done. |
For local testing, use the dev cert script with your LAN IP and open `https://<LAN-IP>:3000` on the phone. For production, use a proper TLS setup and ensure WebRTC ports (4000049999) are open on the server.

View File

@@ -1,128 +1,52 @@
# Map and cameras # Map and Cameras
KestrelOS shows a **map** with **devices** (cameras, ALPR, NVR, etc.), **POIs**, **live sessions** (Share live), and **ATAK/iTAK** positions. You view streams by clicking markers or using the **Cameras** page. KestrelOS shows a **map** with devices, POIs, live sessions (Share live), and ATAK/iTAK positions. Click markers or use **Cameras** page to view streams.
--- ## Map Layers
## Using the map - **Devices** — Fixed feeds (IPTV, ALPR, CCTV, NVR, etc.) added via API
- **POIs** — Points of interest (admin/leader can edit)
- **Live sessions** — Mobile devices streaming via Share live
- **CoT (ATAK/iTAK)** — Amber markers for connected TAK devices (position only)
- **Home:** The main view is the map (**/**). It uses OpenStreetMap-style tiles and supports offline tile caching (Leaflet.offline). ## Cameras
- **Layers:**
- **Devices** — Cameras and feeds youve added (API). Click a device marker to open the live stream in a side panel.
- **POIs** — Points of interest (admin/leader can add/edit from **POI** page).
- **Live sessions** — Mobile devices streaming via **Share live**. Click to view the live stream.
- **CoT (ATAK/iTAK)** — Amber markers for connected ATAK/iTAK devices (position only; no stream).
- **Actions:** Pan and zoom as usual. If you have permission, you can add/edit POIs from the **POI** page; device editing is via API (see below).
--- A **camera** is either:
1. A **device** — Fixed feed with stream URL
2. A **live session** — Mobile device streaming via Share live
## What counts as a “camera” View via map markers or **Cameras** page (sidebar).
In KestrelOS, a **camera** is either: ## Device Types
1. A **device** — A fixed feed (IPTV, ALPR, CCTV, NVR, doorbell, traffic cam, etc.) with a **stream URL** and optional config. | device_type | Use case |
2. A **live session** — A mobile device streaming via **Share live** (WebRTC). These appear automatically while sharing. |-------------|----------|
| `alpr`, `nvr`, `doorbell`, `feed`, `traffic`, `ip`, `drone` | Labeling/filtering |
The **Cameras** page (sidebar → **Cameras**) lists both: select an entry to view its stream in the panel. The map shows the same sources as markers; clicking a marker also opens the stream. **source_type:** `mjpeg` (MJPEG over HTTP) or `hls` (HLS `.m3u8` playlist)
--- Stream URLs must be `http://` or `https://`.
## Device types and stream types ## API: Devices
When you add a **device** (via API), you set: **Create:** `POST /api/devices` (admin/leader)
```json
- **device_type** — One of: `alpr`, `nvr`, `doorbell`, `feed`, `traffic`, `ip`, `drone`. Used for labeling and filtering (e.g. “ALPR”, “NVR”). {
- **source_type** — How the stream is delivered:
- **`mjpeg`** — MJPEG over HTTP (single image or MJPEG stream URL).
- **`hls`** — HLS (HTTP Live Streaming); use an `https://` or `http://` URL to an `.m3u8` playlist.
Stream URLs must be **http://** or **https://**; other protocols are rejected.
Examples by use case:
| Use case | device_type | source_type | stream_url example |
|----------|-------------|-------------|---------------------|
| IP camera / CCTV | `ip` or `feed` | `mjpeg` or `hls` | `http://192.168.1.10/mjpg/video.mjpg` |
| ALPR camera | `alpr` | `mjpeg` or `hls` | `https://alpr.example.com/stream.m3u8` |
| NVR feed | `nvr` | `mjpeg` or `hls` | `http://nvr.local/cam1/video.mjpeg` |
| Traffic camera | `traffic` | `mjpeg` or `hls` | `https://traffic.gov/cam123.m3u8` |
| Doorbell | `doorbell` | `mjpeg` or `hls` | As provided by vendor. |
| IPTV channel | `feed` | `hls` | `https://iptv.example.com/channel.m3u8` |
| Drone feed | `drone` | `mjpeg` or `hls` | As provided. |
---
## Adding and editing devices (API)
Only **admin** or **leader** can create or update devices. There is no “Add camera” form in the UI yet; use the HTTP API (e.g. from a script or tool).
### Create a device
**POST** `/api/devices`
Requires auth (session cookie). Body (JSON):
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | Yes | Display name. |
| `device_type` | string | No | One of: `alpr`, `nvr`, `doorbell`, `feed`, `traffic`, `ip`, `drone`. Default `feed`. |
| `lat` | number | Yes | Latitude. |
| `lng` | number | Yes | Longitude. |
| `stream_url` | string | No | HTTP(S) URL for MJPEG or HLS. |
| `source_type` | string | No | `mjpeg` or `hls`. Default `mjpeg`. |
| `vendor` | string | No | Optional vendor/label. |
| `config` | string or object | No | Optional JSON config (stored as string). |
Example (curl, after logging in and saving cookie):
```bash
curl -X POST https://your-kestrelos.example.com/api/devices \
-H "Content-Type: application/json" \
-b "kestrelos.session=YOUR_SESSION_COOKIE" \
-d '{
"name": "Main gate ALPR", "name": "Main gate ALPR",
"device_type": "alpr", "device_type": "alpr",
"lat": 37.7749, "lat": 37.7749,
"lng": -122.4194, "lng": -122.4194,
"stream_url": "https://alpr.example.com/stream.m3u8", "stream_url": "https://alpr.example.com/stream.m3u8",
"source_type": "hls" "source_type": "hls"
}' }
``` ```
### List devices **List:** `GET /api/devices`
**Update:** `PATCH /api/devices/:id`
**Delete:** `DELETE /api/devices/:id`
**GET** `/api/devices` **Cameras endpoint:** `GET /api/cameras` returns devices + live sessions + CoT entities.
Returns all devices (auth required). The map and Cameras page use **GET** `/api/cameras`, which returns devices plus live sessions and CoT entities.
### Update a device ## POIs
**PATCH** `/api/devices/:id` Admins/leaders add/edit from **POI** page (sidebar). POIs appear as map pins (reference only, no stream).
Auth required. Send only the fields you want to change (e.g. `name`, `stream_url`, `lat`, `lng`, `device_type`, `source_type`).
### Delete a device
**DELETE** `/api/devices/:id`
Auth required.
---
## Viewing cameras
- **Map:** Click a device or live-session marker to open the stream in the side panel. Close the panel to return to the map.
- **Cameras page:** Open **Cameras** from the sidebar. The list shows all devices and live sessions; select one to view its stream in the right-hand panel. “Live” badge indicates an active Share live stream.
---
## POIs (points of interest)
Admins and leaders can add and edit POIs from the **POI** page (sidebar → **POI**). POIs appear on the map as pins. They are for reference only (no stream). Use **Map** for viewing and **POI** for managing the list and coordinates.
---
## Summary
| Task | How |
|------|-----|
| View map and streams | Open **/** and click markers, or use **Cameras** page. |
| Add IPTV/ALPR/CCTV/NVR/etc. | **POST** `/api/devices` with `name`, `lat`, `lng`, `stream_url`, `source_type` (`mjpeg` or `hls`), and optional `device_type`, `vendor`. |
| Edit or delete a device | **PATCH** or **DELETE** `/api/devices/:id` (admin/leader). |
| Add your phone as a live feed | Use **Share live** — see [Share live](live-streaming.md). |