# End-to-end encrypted storage for a web app

Seige lets a web app store end-to-end encrypted records and files without
implementing cryptography, key exchange or key recovery. The SDK encrypts each
change in the browser before it is sent. Seige's servers store ciphertext
without the keys to read it, and the data lives in the user's own Seige
account.

```js
import { createSeige } from "@seige_sdk/sdk";

const seige = createSeige({ appName: "Journal" });

await seige.from("entries").insert({ body: "A quiet day by the coast." });
await seige.files.put("photos/coast.jpg", photo);
```

Encryption is part of every call. There is no separate encryption API to use
and no key for your app to store.

## How the keys work

- Each browser that runs your app is a separate installation. On first use the
  SDK generates the installation's keys in that browser and sends Seige only the
  public keys, with proofs that bind them to your app's website.
- The user approves the app in a Seige window. Their account signs a grant
  that gives the installation the key for the app's folder.
- Keys are composite post-quantum OpenPGP keys: ML-KEM-768 with X25519 for
  encryption, and ML-DSA-65 with Ed25519 for signatures.
- Private keys stay in the browser, stored as AES-256-GCM ciphertext under a
  non-extractable WebCrypto key. Seige never generates or stores an app's
  private keys.
- When the user disconnects the app, Seige retires that installation's keys and
  replaces the folder's keys, so retired keys cannot read anything written
  afterwards.

## What Seige's servers can see

Seige's servers can see account and routing metadata, the number of
installations an app has, their public keys, and the sizes and timing of
requests. They cannot read file contents, file names, database contents or the
app's private keys.

## What encryption does not cover

- Your app's own code reads the data in plaintext while it works with it. Script
  running on your website, including injected script, can use the app's keys.
- An app can keep copies of data it has read. Disconnecting stops future access
  but cannot erase copies.
- Input sent to `seige.ai.generate()` is processed in readable form by Seige and
  the model host.

## Related guides

- [How Seige protects account data](/security/)
- [A database for a frontend-only app](/guides/database-for-frontend-only-apps/)
- [Key and revocation reference](/developers/)
