Metadata-Version: 2.4
Name: zettabrain-teams
Version: 0.2.2
Summary: Multi-user RAG server with team access control — built on zettabrain-rag
Author-email: ZettaBrain <hello@zettabrain.ai>
License: Proprietary
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: zettabrain-rag
Requires-Dist: fastapi>=0.111.0
Requires-Dist: uvicorn[standard]>=0.29.0
Requires-Dist: python-jose[cryptography]>=3.3.0
Requires-Dist: bcrypt>=4.1.0
Requires-Dist: sqlmodel>=0.0.19
Requires-Dist: python-multipart>=0.0.9
Requires-Dist: aiofiles>=23.2.1
Requires-Dist: ldap3>=2.9.1

# ZettaBrain Teams

Multi-user RAG server with team access control — the enterprise layer built on [zettabrain-rag](https://github.com/zettabrain/zettabrain-rag).

Fully self-hosted, no cloud dependencies, runs entirely on your own infrastructure.

---

## Features

### Access Control
- JWT-based login with system-wide **admin** and **user** roles
- Teams with per-member **manager / member / viewer** roles
- Admins can create, deactivate, and delete users
- Forced password change on first login

### Multi-Tenant RAG
- **Per-team isolated document collections** (separate ChromaDB store per team)
- **Per-team BM25 keyword index** — IDF computed exclusively from each team's corpus, eliminating cross-team document leakage
- Hybrid retrieval: semantic MMR + BM25 keyword search + FlashRank re-ranking
- In-UI document ingestion — set a docs folder per team and click **Ingest Docs**
- Incremental ingestion with MD5 hash tracking (re-ingests only changed files)

### Active Directory / LDAP
- Connect to any Active Directory or LDAP server from the admin panel
- Test connection, run user searches, and preview results before importing
- Import AD users directly into teams with a chosen role
- Configurable base DN, bind credentials, and user filter

### ZettaBrain Verified — Answer Provenance
- Every chat answer produces a **cryptographically signed provenance bundle**
- Bundle covers: SHA-256 of the query, SHA-256 of each retrieved chunk, SHA-256 of the answer, model identifier, and team ID
- Signed with an **Ed25519 key** generated at first server start and stored at `/opt/zettabrain-teams/data/server_signing.key`
- Admin UI shows a **🛡 Verify** button on every audit log entry — one click confirms the answer bundle has not been altered
- Public key exposed at `GET /api/admin/keys/public` for out-of-band verification

### Audit Log
- Every query recorded with: user, team, query text, response preview, confidence score, duration, model, chunk count
- Full date-range filtering (last 24h / 3d / 7d / 30d / all time / custom)
- Provenance signature included in CSV export
- Admin-only access

### Admin Portal
- Dedicated `/admin` URL with sidebar navigation
- Dashboard with live stats: users, teams, total queries, average confidence
- System config panel — change LLM/embed models, Ollama host from the UI
- Pull new Ollama models directly from the admin panel
- One-page web UI for both chat portal and admin console

---

## Quick install (Linux server, run as root)

```bash
# 1. Install pipx if needed
python3 -m pip install pipx && python3 -m pipx ensurepath

# 2. Install zettabrain-teams
pipx install git+https://github.com/zettabrain/zettabrain-teams

# 3. Run the one-command setup (installs Ollama, pulls models, creates systemd service)
sudo zettabrain-teams-setup
```

That's it. The setup script:
- Installs [Ollama](https://ollama.com) if not present
- Interactively selects LLM and embedding models (defaults: `llama3.1:8b` + `nomic-embed-text`)
- Creates `/opt/zettabrain-teams/{data,chromadb,certs}`
- Registers and starts a `zettabrain-teams` systemd service

Then open **`http://<your-server-ip>:7861`** in a browser.  
Default credentials: **admin / P@ssword!** (you will be prompted to change on first login).

---

## Setup options

```bash
sudo zettabrain-teams-setup \
  --port  7861 \
  --llm   llama3.1:8b \
  --embed nomic-embed-text \
  --no-systemd        # skip systemd, start manually instead
```

---

## Starting / stopping

```bash
# Managed by systemd after setup
sudo systemctl start   zettabrain-teams
sudo systemctl stop    zettabrain-teams
sudo systemctl restart zettabrain-teams
sudo journalctl -u zettabrain-teams -f   # live logs

# Or start manually (dev / testing)
zettabrain-teams --port 7861
```

---

## Firewall

Open port **7861** on your firewall or cloud security group so users can reach the UI.

**AWS example:**
```bash
aws ec2 authorize-security-group-ingress \
  --group-id sg-xxxxxxxx \
  --protocol tcp --port 7861 --cidr 0.0.0.0/0
```

**UFW example:**
```bash
sudo ufw allow 7861/tcp
```

---

## Admin workflow

1. Log in at `http://<ip>:7861` with `admin` + your password
2. **Admin → Users & LDAP** — create user accounts or import from Active Directory
3. **Admin → Teams & Storage** — create a team, expand it, add users with roles, set the docs folder path
4. Click **Ingest Docs** in the team card to index documents from the configured folder
5. **Admin → Audit Log** — review all queries, filter by date, verify answer provenance, export CSV
6. Users log in at `http://<ip>:7861`, select their team from the sidebar, and start chatting

---

## Active Directory setup

In **Admin → Users & LDAP**, fill in:

| Field | Example |
|-------|---------|
| LDAP URL | `ldap://dc.company.local:389` |
| Base DN | `DC=company,DC=local` |
| Bind DN | `CN=svc-account,OU=Service Accounts,DC=company,DC=local` |
| Bind Password | your service account password |
| User Filter | `(&(objectClass=user)(sAMAccountName=*))` |

Use **Test Connection** to verify, then **Search Users** to preview, then **Import Selected** to add users to a team.

---

## ZettaBrain Verified — verification workflow

Every chat answer is stored with a provenance signature. To verify:

**In the UI:**
1. Go to **Admin → Audit Log**
2. Click **🛡 Verify** on any log entry with a signature
3. A green ✓ Valid or red ✗ Invalid result appears inline

**Via API (out-of-band):**
```bash
# Get server public key
curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:7861/api/admin/keys/public

# Verify a specific log entry
curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:7861/api/admin/audit/42/verify
```

The private key never leaves `/opt/zettabrain-teams/data/server_signing.key`. Back this file up — losing it means existing signatures can no longer be verified.

---

## Configuration

`/opt/zettabrain-teams/teams.env` is written on first setup:

| Variable | Default | Description |
|----------|---------|-------------|
| `ZBT_PORT` | `7861` | Server port |
| `ZETTABRAIN_LLM_MODEL` | `llama3.1:8b` | Ollama LLM model |
| `ZETTABRAIN_EMBED_MODEL` | `nomic-embed-text` | Ollama embed model |
| `OLLAMA_HOST` | `http://localhost:11434` | Remote Ollama if not local |
| `ZBT_JWT_SECRET` | auto-generated | JWT signing secret |
| `ZBT_TOKEN_EXPIRE` | `480` | Token expiry in minutes |
| `ZBT_TLS_CERT` | — | Path to TLS cert (enables HTTPS) |
| `ZBT_TLS_KEY` | — | Path to TLS private key |

All variables can also be overridden via shell environment. The admin **System Config** panel in the UI can update model and Ollama settings without editing the file.

---

## Requirements

- Linux (Ubuntu 20.04+ recommended)
- Python 3.9+
- 8 GB RAM minimum (16 GB recommended for `llama3.1:8b`)
- ~10 GB disk for models

GPU is optional — Ollama runs in CPU-only mode if no GPU is detected.

---

## Architecture

```
zettabrain-teams (port 7861)
├── FastAPI + SQLModel (SQLite)        — users, teams, audit log, system config
├── JWT auth + bcrypt                  — login / token / role enforcement
├── Active Directory / LDAP connector  — AD import + auth
├── ChromaDB (per team)                — /opt/zettabrain-teams/chromadb/<slug>/
├── BM25 index (per team)              — <slug>/bm25_index.pkl (team-scoped IDF)
├── Ed25519 signing key                — /opt/zettabrain-teams/data/server_signing.key
└── zettabrain-rag                     — hybrid_retrieve(), RAG prompt, embeddings
        └── Ollama (port 11434)        — LLM + embeddings (fully local)
```

---

## Upgrading

```bash
pipx upgrade zettabrain-teams
# or reinstall from GitHub for latest commit:
pipx reinstall zettabrain-teams
sudo systemctl restart zettabrain-teams
```

Database migrations run automatically on startup — existing data is preserved.
