Skip to main content

warp-server

FastAPI implementation of the WARP signature server API.

Development

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:

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:

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)

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

# 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

# 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

# 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:

# 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

# 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. The API returns can_delete for the authenticated user; the server enforces the same rule on deletion, including for uploads in progress. Uploading another BNDB with the same name as one owned by the same user updates that record while keeping its UUID stable.

BNDB action User Admin
List and download All BNDBs All BNDBs
Upload and resume Own uploads Own uploads
Delete a BNDB Own BNDBs Any BNDB
Cancel an upload Own uploads Any upload

API

# 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>

For larger files, clients use POST /api/v1/bndbs/upload/init with name, total_chunks, size_bytes, chunk_size, and optionally the full-file sha256. Each PUT /api/v1/bndbs/upload/<upload_id>/<index> includes a multipart file and an X-Chunk-SHA256 header. GET /api/v1/bndbs/upload/<upload_id> returns received indices so interrupted uploads can resume. POST .../complete validates the chunks and publishes the BNDB. Sessions survive server restarts and expire after WARP_UPLOAD_TTL_MINUTES without activity. Clients can cancel a session with DELETE /api/v1/bndbs/upload/<upload_id>. The server also sweeps expired sessions and old orphan files hourly.

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

Storage

BNDB files are stored as <uuid>.<sha256>.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. Existing <uuid>.bndb.gz files remain readable and are replaced on the next upload with the same name.

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_MAX_BNDB_BYTES 8589934592 Maximum raw size of one BNDB.
WARP_MAX_BNDB_CHUNK_BYTES 8388608 Maximum raw size of an upload chunk.
WARP_MAX_BNDB_USER_BYTES 21474836480 Maximum total raw BNDB size per user.
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.
WARP_SESSION_TOKEN_TTL_HOURS 168 Lifetime of the token issued by POST /api/v1/auth/login.
WARP_MAX_REQUEST_BODY_BYTES 536870912 Reject requests whose Content-Length exceeds this. 0 disables.
WARP_MAX_DECOMPRESSED_BYTES 536870912 Cap on a gzip-decompressed request body.
WARP_MAX_WARP_CHUNK_BYTES 268435456 Cap on a single decompressed WARP chunk.
WARP_MAX_UPLOAD_CHUNKS 100000 Most chunks a single chunked upload may declare.
WARP_MAX_ACTIVE_UPLOADS 1000 Most concurrent in-flight chunked uploads, server-wide.
WARP_UPLOAD_TTL_MINUTES 60 Abandoned chunked uploads are deleted after this long.
WARP_MAX_EXPORT_ROWS 50000 Cap on rows loaded by bulk queries with no page size (e.g. format=flatbuffer).
WARP_MAX_PAGE_SIZE 200 Largest page size a paginated query may request.

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

Note: The IP lockout applies only to unrecognized API keys. A locked IP can still authenticate with a valid key, so bad tokens cannot lock out other clients sharing that address. Set WARP_TRUSTED_PROXIES when running behind a reverse proxy, otherwise every client is accounted for under the proxy's address.

Docker

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

The Docker image stores both SQLite and BNDB files under /data. When upgrading an older container, copy its /app/bndb_storage directory into the mounted volume at /data/bndb_storage before removing that container. Older images kept BNDB files outside the volume.

Run warp-ctl commands against the same volume:

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:

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:

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

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

For the shared-types upgrade, stop the server and back up the database before applying the migration, then restart with the new code. The migration rebuilds the types table atomically while preserving type GUIDs and blobs. It recovers upload memberships from the original owner and surviving function references. Old duplicate uploads containing only types cannot be recovered as separate memberships because earlier versions did not store that provenance.

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, their comments/constraints, and symbols with auto-generated names (sub_, nullsub, outlined_sub_, _OUTLINED_FUNCTION), including any number of leading j_ prefixes such as j_j_sub_1fc07f124. Uses the same filter as ingestion and can be re-run to clean these names even if an older version already ran. Named thunks such as j_j_memcpy are retained. Preview with warp-ctl migrate, then apply with warp-ctl migrate --apply.
  • add-indexes — creates the query indexes declared on the models but missing from older databases (function GUID/source/commit/symbol, symbol name, and the cascade targets). New databases get them automatically; existing ones need this migration. Expect it to take a while and to grow the database file on a large deployment.
  • shared-types — separates globally deduplicated type content from commit/source membership. Deleting an upload preserves types used by other uploads; deleting the final membership removes unreferenced content. Type metadata reports the earliest surviving upload, and source-filtered search finds types shared with that source.

Metadata

Release files for warp-server 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for warp-server 0.4.0
File Size Uploaded
warp_server-0.4.0.tar.gz 61.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for warp-server 0.4.0
File Interpreter ABI Platform
warp_server-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 168.1 kB

Release files / warp_server-0.4.0.tar.gz

Download URL warp_server-0.4.0.tar.gz
Size 61.3 kB
Tags Source
SHA-256 checksum
How to use checksums
4838b1f9b31e6bd2c7cf75c5f2a382288c2e95dd162042ff6a55d6efe108795b
BLAKE2b-256 checksum
How to use checksums
dab1b32226e1b140e5f6bb3b54bd1f75ebe1b773dd3b6f1b39d4bd885b51e82f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / warp_server-0.4.0-py3-none-any.whl

Download URL warp_server-0.4.0-py3-none-any.whl
Size 106.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f473e27767bd58ebe9b2d02db6a8814412aef99dc2d4811b24b3a0c84be1809f
BLAKE2b-256 checksum
How to use checksums
6adfc3630534b8d08ebbceaa35b188699ac003931fed3b9ecd6ccbdcc45f5091
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files

0.3.5

2 release files

0.3.4

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page