Metadata-Version: 2.4
Name: warp-server
Version: 0.3.3
Summary: WARP signature server API
Requires-Python: >=3.12
Requires-Dist: aiosqlite>=0.20
Requires-Dist: click>=8.1
Requires-Dist: fastapi>=0.115
Requires-Dist: flatbuffers>=25.12.19
Requires-Dist: pydantic-settings>=2.0
Requires-Dist: pydantic>=2.0
Requires-Dist: python-multipart>=0.0.9
Requires-Dist: sqlalchemy[asyncio]>=2.0
Requires-Dist: uvicorn[standard]>=0.30
Description-Content-Type: text/markdown

# warp-server

FastAPI implementation of the WARP signature server API.

## Development

```bash
git submodule update --init  # fetch warp/ schemas
uv sync
uv run warp-server        # start dev server on :8000
uv run pytest              # run tests
```

## Installation with `uvx`

If installed via `uvx`, use `--from warp-server` to run either command:

```bash
uvx --from warp-server warp-server           # start the server
uvx --from warp-server warp-ctl bootstrap    # manage users/sources/keys
```

### Regenerating FlatBuffer bindings

The Python FlatBuffer bindings are generated from the `.fbs` schemas in `warp/`. To regenerate:

```bash
brew install flatbuffers   # if not already installed
flatc --python -o src/warp_server/gen_flatbuffers warp/*.fbs
```

## Bootstrap: Create a User with an API Key

The server uses Bearer token auth via API keys. Use the `warp-ctl` CLI to manage users and keys.

### Quick bootstrap (admin + key in one step)

```bash
uv run warp-ctl bootstrap
# Created admin user id=1 username=admin
# API key: <key>
```

Options: `--email`, `--username` to customize the admin account.

### Managing users

```bash
# create a regular user
uv run warp-ctl user create --email alice@example.com --username alice

# create an admin
uv run warp-ctl user create --email ops@example.com --username ops --role Admin

# list all users
uv run warp-ctl user list

# delete a user
uv run warp-ctl user delete 2
```

### Managing API keys

```bash
# create a key for user id 1
uv run warp-ctl key create --user-id 1 --name dev-key

# list all keys (or filter by --user-id)
uv run warp-ctl key list
uv run warp-ctl key list --user-id 1

# revoke a key
uv run warp-ctl key revoke 3
```

### Managing sources

```bash
# create a source owned by user 1
uv run warp-ctl source create --name my-signatures --user-id 1

# list sources
uv run warp-ctl source list
```

### Ingesting `.warp` files directly

For large files or batch imports, use `warp-ctl ingest` to bypass the HTTP server
and insert directly into the SQLite database:

```bash
# ingest a single file (creates the source if it doesn't exist)
uv run warp-ctl ingest /path/to/file.warp --source my-signatures --user-id 1

# ingest multiple files at once
uv run warp-ctl ingest *.warp --source my-signatures --user-id 1

# with optional commit metadata
uv run warp-ctl ingest file.warp --source my-signatures --user-id 1 \
  --name "libc v2.38" --description "glibc signatures"
```

### Using the API key

```bash
# verify auth
curl -H "Authorization: Bearer <key>" http://localhost:8000/api/v1/users/me

# create a source via the API
curl -X POST http://localhost:8000/api/v1/sources \
  -H "Authorization: Bearer <key>" \
  -H "Content-Type: application/json" \
  -d '{"name": "my-source", "user_ids": []}'
```

## Web UI

A built-in web interface is available at `/web-ui` for managing the server:

```
http://localhost:8000/web-ui
```

Log in with your username and API key. The UI lets you:

- Browse and search symbols
- Create and delete sources
- Manage users (admin only)
- Create API keys
- Browse functions and commits
- Upload, browse, and download BNDBs

## BNDB Sharing

The server supports uploading and downloading Binary Ninja Database (`.bndb`) files.
Files are stored on disk as gzip-compressed blobs in a configurable directory, keeping
the SQLite metadata database lightweight.

Any authenticated user can upload or download BNDBs. Only the uploader (or an admin)
can delete them.

### API

```bash
# upload a BNDB
curl -X POST http://localhost:8000/api/v1/bndbs \
  -H "Authorization: Bearer <key>" \
  -F "file=@firmware.bndb" \
  -F "name=firmware.bndb" \
  -F "description=Extracted from router firmware"

# list / search BNDBs
curl -X POST http://localhost:8000/api/v1/bndbs/query \
  -H "Authorization: Bearer <key>" \
  -H "Content-Type: application/json" \
  -d '{"name": "firmware", "limit": 20, "page": 1}'

# get metadata
curl -H "Authorization: Bearer <key>" \
  http://localhost:8000/api/v1/bndbs/<uuid>

# download
curl -H "Authorization: Bearer <key>" -o output.bndb \
  http://localhost:8000/api/v1/bndbs/<uuid>/download

# delete (owner or admin)
curl -X DELETE -H "Authorization: Bearer <key>" \
  http://localhost:8000/api/v1/bndbs/<uuid>
```

BNDBs can also be managed from the **BNDBs** tab in the web UI.

### Storage

BNDB files are stored as `<uuid>.bndb.gz` in the directory configured by
`WARP_BNDB_STORAGE_DIR` (default `./bndb_storage`). The directory is created
automatically on server startup. Compression is transparent — clients always
upload and download raw `.bndb` files.

## Configuration

The server is configured via environment variables, all prefixed with `WARP_`.

| Variable | Default | Description |
|----------|---------|-------------|
| `WARP_DEBUG` | `false` | Enable debug mode: exposes Swagger UI at `/docs`. |
| `WARP_DATABASE_URL` | `sqlite+aiosqlite:///./warp.db` | SQLAlchemy async database URL. |
| `WARP_HOST` | `127.0.0.1` | Bind address. |
| `WARP_PORT` | `8000` | Listen port. |
| `WARP_LOG_LEVEL` | `info` | Uvicorn log level (`debug`, `info`, `warning`, `error`). |
| `WARP_RELOAD` | `false` | Enable auto-reload on file changes (dev only). |
| `WARP_BNDB_STORAGE_DIR` | `./bndb_storage` | Directory for uploaded BNDB files (created automatically). |
| `WARP_CORS_ORIGINS` | `[]` | JSON list of allowed CORS origins, e.g. `'["https://app.example.com"]'`. |
| `WARP_TRUSTED_PROXIES` | `[]` | JSON list of trusted reverse-proxy IPs allowed to set `X-Forwarded-For`. |
| `WARP_MAX_LOGIN_ATTEMPTS` | `5` | Failed attempts before an IP or user account is locked. |
| `WARP_LOCKOUT_DURATION_MINUTES` | `30` | Minutes before a locked IP or account is automatically unlocked. |

> **Warning:** `WARP_DEBUG=true` exposes Swagger UI at `/docs` and ReDoc at `/redoc`. Never enable it in production.

## Docker

```bash
docker build -t warp-server .
docker run -p 8000:8000 -v warp-data:/data warp-server
```

Run `warp-ctl` commands against the same volume:

```bash
docker run -v warp-data:/data warp-server sh -c "warp-ctl bootstrap"
```

Environment variables (`WARP_DATABASE_URL`, `WARP_CORS_ORIGINS`, etc.) can be
passed with `-e`:

```bash
docker run -p 8000:8000 -v warp-data:/data \
  -e WARP_CORS_ORIGINS='["http://localhost:3000"]' \
  warp-server
```

## Migrations

A single `migrate` command runs all pending database migrations:

```bash
# dry-run — shows what would change
uv run warp-ctl migrate

# apply all pending migrations
uv run warp-ctl migrate --apply
```

Migrations are idempotent and safe to re-run. Current migrations:

- **hash-keys** — hashes any plaintext API keys (SHA-256). After migration, previously issued raw keys become invalid; create new ones via `warp-ctl key create` or the web UI.
- **lockout-columns** — adds `locked`, `failed_login_count`, and `locked_at` columns to the `users` table for account lockout support.
- **purge-auto-names** — deletes functions and symbols with auto-generated names (`sub_`, `nullsub`, `j_sub_`, `outlined_sub_`, `_OUTLINED_FUNCTION`).
