Files
arbiter/ARCHITECTURE.md
2026-02-13 17:24:20 +01:00

6.3 KiB
Raw Permalink Blame History

Arbiter

Arbiter is a permissioned signing service for cryptocurrency wallets. It runs as a background service on the user's machine with an optional client application for vault management.

Core principle: The vault NEVER exposes key material. It only produces signatures when a request satisfies the configured policies.


1. Peer Types

Arbiter distinguishes two kinds of peers:

  • User Agent — A client application used by the owner to manage the vault (create wallets, approve SDK clients, configure policies).
  • SDK Client — A consumer of signing capabilities, typically an automation tool. In the future, this could include a browser-based wallet.

2. Authentication

2.1 Challenge-Response

All peers authenticate via public-key cryptography using a challenge-response protocol:

  1. The peer sends its public key and requests a challenge.
  2. The server looks up the key in its database. If found, it increments the nonce and returns a challenge (replay-attack protection).
  3. The peer signs the challenge with its private key and sends the signature back.
  4. The server verifies the signature:
    • Pass: The connection is considered authenticated.
    • Fail: The server closes the connection.

2.2 User Agent Bootstrap

On first run — when no User Agents are registered — the server generates a one-time bootstrap token. It is made available in two ways:

  • Local setup: Written to ~/.arbiter/bootstrap_token for automatic discovery by a co-located User Agent.
  • Remote setup: Printed to the server's console output.

The first User Agent must present this token alongside the standard challenge-response to complete registration.

2.3 SDK Client Registration

There is no bootstrap mechanism for SDK clients. They must be explicitly approved by an already-registered User Agent.


3. Server Identity

The server proves its identity using TLS with a self-signed certificate. The TLS private key is generated on first run and is long-term; no rotation mechanism exists yet due to the complexity of multi-peer coordination.

Peers verify the server by its public key fingerprint:

  • User Agent (local): Receives the fingerprint automatically through the bootstrap token.
  • User Agent (remote) / SDK Client: Must receive the fingerprint out-of-band.

A streamlined setup mechanism using a single connection string is planned but not yet implemented.


4. Key Management

4.1 Key Hierarchy

There are three layers of keys:

Key Encrypts Encrypted by
User key (password) Root key — (derived from user input)
Root key Wallet keys User key
Wallet keys — (used for signing) Root key

This layered design enables:

  • Password rotation without re-encrypting every wallet key (only the root key is re-encrypted).
  • Root key rotation without requiring the user to change their password.

4.2 Encryption at Rest

The database stores everything in encrypted form using symmetric AEAD. The encryption scheme is versioned to support transparent migration — when the vault unseals, Arbiter automatically re-encrypts any entries that are behind the current scheme version. See IMPLEMENTATION.md for the specific scheme and versioning mechanism.


5. Vault Lifecycle

5.1 Sealed State

On boot, the root key is encrypted and the server cannot perform any signing operations. This state is called Sealed.

5.2 Unseal Flow

To transition to the Unsealed state, a User Agent must provide the password:

  1. The User Agent initiates an unseal request.
  2. The server generates a one-time key pair and returns the public key.
  3. The User Agent encrypts the user's password with this one-time public key and sends the ciphertext to the server.
  4. The server decrypts and verifies the password:
    • Success: The root key is decrypted and placed into a hardened memory cell. The server transitions to Unsealed. Any entries pending encryption scheme migration are re-encrypted.
    • Failure: The server returns an error indicating the password is incorrect.

5.3 Memory Protection

Once unsealed, the root key must be protected in memory against:

  • Memory dumps
  • Page swaps to disk
  • Hibernation files

See IMPLEMENTATION.md for the current and planned memory protection approaches.


6. Permission Engine

6.1 Fundamental Rules

  • SDK clients have no access by default.
  • Access is granted explicitly by a User Agent.
  • Grants are scoped to specific wallets and governed by policies.

Each blockchain requires its own policy system due to differences in static transaction analysis. Currently, only EVM is supported; Solana support is planned.

Arbiter is also responsible for ensuring that transaction nonces are never reused.

6.2 EVM Policies

Every EVM grant is scoped to a specific wallet and chain ID.

6.2.1 Transaction Sub-Grants

Arbiter maintains an ever-expanding database of known contracts and their ABIs. Based on contract knowledge, transaction requests fall into three categories:

1. Known contract (ABI available)

The transaction can be decoded and presented with semantic meaning. For example: "Client X wants to transfer Y USDT to address Z."

Available restrictions:

  • Volume limits (e.g., "no more than 10,000 tokens ever")
  • Rate limits (e.g., "no more than 100 tokens per hour")

2. Unknown contract (no ABI)

The transaction cannot be decoded, so its effects are opaque — it could do anything, including draining all tokens. The user is warned, and if approved, access is granted to all interactions with the contract (matched by the to field).

Available restrictions:

  • Transaction count limits (e.g., "no more than 100 transactions ever")
  • Rate limits (e.g., "no more than 5 transactions per hour")

3. Plain ether transfer (no calldata)

These transactions have no calldata and therefore cannot interact with contracts. They can be subject to the same volume and rate restrictions as above.

6.2.2 Global Limits

In addition to sub-grant-specific restrictions, the following limits can be applied across all grant types:

  • Gas limit — Maximum gas per transaction.
  • Time-window restrictions — e.g., signing allowed only 08:0020:00 on Mondays and Thursdays.