Obscura Server
Obscura Server is a minimalist, secure relay server for the Signal Protocol. It facilitates end-to-end encrypted asynchronous messaging while knowing nothing about the content of the messages.
Features
- Zero-Knowledge Architecture: The server stores opaque encrypted blobs. It cannot read message content.
- Signal Protocol Support: Uses PreKeys (Identity, Signed, One-Time) to enable X3DH key exchanges.
- Asynchronous Delivery: Stores encrypted messages until the recipient comes online to fetch them.
- Strict Privacy Limits: Automatic garbage collection of old messages and global inbox limits to prevent metadata buildup.
- Container Native: Built with Docker in mind for easy deployment.
- Configurable: Fully configurable via command-line flags or environment variables.
Configuration
Obscura Server can be configured using either command-line options or by setting corresponding environment variables. Command-line options take precedence over environment variables.
| Option | Description | Environment Variable | Default | Required |
|---|---|---|---|---|
--database-url |
PostgreSQL connection string | DATABASE_URL |
- | Yes |
--jwt-secret |
Secret key for signing JWTs | JWT_SECRET |
- | Yes |
--server-host |
Interface to bind the server to | SERVER_HOST |
0.0.0.0 |
No |
--port |
Port to bind the server to | PORT |
3000 |
No |
--access-token-ttl-secs |
Access Token lifetime in seconds | ACCESS_TOKEN_TTL_SECS |
900 |
No |
--refresh-token-ttl-days |
Refresh Token lifetime in days | REFRESH_TOKEN_TTL_DAYS |
30 |
No |
--message-ttl-days |
Days before a message is auto-deleted | MESSAGE_TTL_DAYS |
30 |
No |
--max-inbox-size |
Max pending messages per user | MAX_INBOX_SIZE |
1000 |
No |
--message-batch-limit |
Max messages sent per DB fetch loop | MESSAGE_BATCH_LIMIT |
50 |
No |
--rate-limit-per-second |
API requests allowed per second | RATE_LIMIT_PER_SECOND |
10 |
No |
--rate-limit-burst |
Max API burst allowance per IP | RATE_LIMIT_BURST |
20 |
No |
--auth-rate-limit-per-second |
Auth requests allowed per second | AUTH_RATE_LIMIT_PER_SECOND |
1 |
No |
--auth-rate-limit-burst |
Auth API burst allowance per IP | AUTH_RATE_LIMIT_BURST |
3 |
No |
--trusted-proxies |
CIDR ranges of trusted proxies | TRUSTED_PROXIES |
10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.1/32 |
No |
--ws-outbound-buffer-size |
WS outbound channel capacity | WS_OUTBOUND_BUFFER_SIZE |
32 |
No |
--ws-ack-buffer-size |
WS ACK channel capacity | WS_ACK_BUFFER_SIZE |
100 |
No |
--ws-ack-batch-size |
WS ACK DB batch size | WS_ACK_BATCH_SIZE |
50 |
No |
--ws-ack-flush-interval-ms |
WS ACK DB flush interval | WS_ACK_FLUSH_INTERVAL_MS |
500 |
No |
Example
# Using Flags
# Using Environment Variables
Docker
A Dockerfile is included for easy deployment.
Build and Run
-
Build the image:
-
Run with Docker:
Docker Compose
A docker-compose.yml is provided for a complete local stack (Postgres + Server):
Development
Prerequisites
- Rust 1.83+
- PostgreSQL 16+
protoc(Protocol Buffers compiler)
Running Locally
-
Start Postgres:
-
Run the server:
Migrations are applied automatically on startup.
Testing
API Documentation
- REST API: Defined in
specs/001-signal-server/contracts/openapi.yaml. - WebSocket: Available at
/v1/gateway. Expects Protobuf messages defined inproto/obscura.proto.
License
Copyright (c) 2026 Nolan Cooper
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.