The message bridge is a dumb, environment and client agnostic relay of arbitrary messages. It lets two parties share an arbitrary message where parties can gossip a symmetric key off-band.
The bridge is made so that it cannot eavesdrop on any messages. The bridge expects only ciphertext. All clients MUST encrypt all payloads before submitting to the bridge..
- Importantly this bridge is completely agnostic to any client or environment, it simply relays messages, hence it implements no logic or opinions related to client handling.
- All messages received by this bridge are temporarily held for delivery, but are automatically purged after a period of time. This service has and SHOULD NOT have persisting storage.
The bridge is currently used in the World ID Protocol. The most used path is for RPs to request proofs from users (to their Authenticators) and for Authenticators to send back proofs.
sequenceDiagram
IDKit ->> Bridge: POST /request
Bridge ->> IDKit: <id>
IDKit ->> Bridge: Poll for updates GET /response/:id
Authenticator ->> Bridge: GET /request/:id
Bridge ->> Authenticator: <request>
Authenticator ->> Bridge: PUT /response/:id
IDKit ->> Bridge: Poll for updates GET /response/:id
Bridge ->> IDKit: <response>
POST /request: Called by IDKit. Initializes a proof verification request.GET /request/:id: Called by Authenticator. Used to fetch the proof verification request. One time use.HEAD /request/:id: Existence check for a request.200if present,404otherwise.PUT /response/:id: Called by Authenticator. Used to send the proof back to the application.GET /response/:id: Called by IDKit. Continuous pulling to fetch the status of the request and the response if available. Response can only be retrieved once.HEAD /response/:id: Existence check for a request's status.200if present,404otherwise.POST /response: Called by a client to create a standalone response without a prior request (see Standalone Response Flow).PUT /request/:id: Staging only (ENVIRONMENT == "staging"). Idempotent request upsert.
This flow allows a client to send a /response without first generating a /request first.
sequenceDiagram
participant ClientA
participant Bridge
participant ClientB
ClientA->>Bridge: POST /response (payload)
Bridge->>ClientA: 201 CREATED {request_id}
ClientB->>Bridge: GET /response/:request_id
Bridge->>ClientB: 200 OK {response}
An easy way to run is using a Dockerized Redis:
docker run -d -p 6379:6379 redis
When building the Dockerfile locally remember to specify the --platform=linux/amd64 flag.
Integration tests build the bridge in-process and drive it directly, so the only external dependency is Redis (override its location with REDIS_URL):
docker-compose -f docker-compose.test.yml up -d
cargo test