DocsSecurity & Encryption

Security & Encryption

Zero-knowledge by design

Your blueprint is encrypted in your browser before it ever leaves your device. Our servers only ever store ciphertext — we cannot read your identity, even if we wanted to.

AES-256-GCM
Web Crypto API

Architecture

Zero-knowledge overview

Zero-knowledge means the server cannot read the data it stores. Your blueprint is encrypted in your browser using a key that the server never possesses in full. When you retrieve your blueprint, the server decrypts it using a key shard and your Google Drive provides the other shard — neither alone is sufficient to decrypt.

Data flow

Your BrowserAES-256-GCM encrypt
Our ServerStores ciphertext only
Your DriveHolds key shard

Encrypted before transit

The AES-256-GCM encryption runs entirely in the browser using the Web Crypto API. The plaintext blueprint never travels over the network.

Only ciphertext stored

Our database contains only the encrypted blob, IV, and algorithm metadata. There is no decryption capability on the server without the Google Drive key shard.

Split key model

The master key is split: one shard on the server (tied to your account), one shard in your Google Drive appDataFolder. Both are required for decryption.

Encryption

Client-side AES-256-GCM

We use the browser-native window.crypto.subtle API — no third-party cryptography libraries. AES-GCM provides both confidentiality and integrity (authenticated encryption). Each encrypt operation generates a fresh 96-bit IV.

crypto.ts (browser, simplified)
// Client-side encryption (runs in your browser only)
async function encryptBlueprint(blueprint, key) {
  const encoded = new TextEncoder().encode(JSON.stringify(blueprint));
  const iv = crypto.getRandomValues(new Uint8Array(12)); // 96-bit IV

  const ciphertext = await crypto.subtle.encrypt(
    { name: 'AES-GCM', iv },
    key,          // CryptoKey — never leaves the browser
    encoded
  );

  return {
    ciphertext: bufferToBase64(ciphertext),
    iv: bufferToBase64(iv),
    algorithm: 'AES-256-GCM',
  };
}

// Decryption — same principle, reversed
async function decryptBlueprint(encrypted, key) {
  const ciphertext = base64ToBuffer(encrypted.ciphertext);
  const iv = base64ToBuffer(encrypted.iv);

  const plaintext = await crypto.subtle.decrypt(
    { name: 'AES-GCM', iv },
    key,
    ciphertext
  );

  return JSON.parse(new TextDecoder().decode(plaintext));
}
AlgorithmAES-256-GCM
Key length256 bits
IV size96 bits (12 bytes)
Auth tag128 bits (GHASH)
APIWeb Crypto (SubtleCrypto)
Key usageencrypt, decrypt

Key management

Google Drive key storage

The encryption key shard stored in your Google Drive lives in appDataFolder — a hidden, app-specific folder that only your Google account and Artificial ID can access. No other Google Drive app or user can see it.

1

Key generation

On first login, a 256-bit AES-GCM master key is generated using crypto.getRandomValues() in the browser. This key is split using HKDF into two 128-bit shards.

2

Shard storage

Shard A is encrypted with your account-derived secret and stored in our database. Shard B is uploaded to your Google Drive appDataFolder. Neither shard alone can decrypt your blueprint.

3

Key reconstruction

On authenticated API requests, the server fetches shard A from the database and shard B from Google Drive (via your OAuth token). HKDF combines them into the master key, which is used to decrypt your blueprint for the response and then discarded.

4

Key rotation

You can rotate your encryption key from the dashboard. A new master key is generated, your blueprint is re-encrypted, and new shards replace the old ones. Old shards are immediately deleted.

What if I revoke Google Drive access?

If you revoke the Google Drive OAuth scope, the server can no longer fetch shard B and your blueprint becomes unreadable — even to us. Re-granting the scope restores access. This is intentional: you hold the kill switch.

Watermarking

HMAC-SHA256 content signing

The watermarking system lets you prove that a piece of AI-generated content was produced using your blueprint. An HMAC-SHA256 signature is computed over the content plus metadata (blueprint ID, persona, timestamp). Anyone with your public verification key can confirm authenticity.

watermark.ts (signing)
// HMAC-SHA256 watermark generation
async function signContent(content, secretKey) {
  const key = await crypto.subtle.importKey(
    'raw',
    new TextEncoder().encode(secretKey),
    { name: 'HMAC', hash: 'SHA-256' },
    false,
    ['sign']
  );

  const payload = JSON.stringify({
    content,
    blueprint_id: getBlueprintId(),
    persona_id: getActivePersona(),
    timestamp: Date.now(),
  });

  const signature = await crypto.subtle.sign(
    'HMAC',
    key,
    new TextEncoder().encode(payload)
  );

  return `hmac-sha256:${bufferToHex(signature)}`;
}

HMAC-SHA256

Keyed-hash MAC using SHA-256. The signing key is derived from your blueprint secret and never exposed through the API.

Verification endpoint

Anyone can call POST /v1/watermark/verify with content + signature. No API key required for verification — it is intentionally public.

90-day TTL

Signatures carry a timestamp and a 90-day TTL by default. Expired signatures return a valid: false response with an expiry reason.

Authentication

Three authentication tiers

Choose the authentication method that fits your security posture. Google OAuth is recommended for most users; passkeys offer phishing-resistant hardware-backed auth.

Recommended

Google OAuth 2.0

Sign in with your existing Google account. Tokens are short-lived and refresh automatically. No password stored anywhere.

PKCE flow
ID token verified server-side
Refresh token stored httpOnly cookie

WebAuthn Passkeys

Use a biometric authenticator (Face ID, Touch ID, Windows Hello) or a hardware security key. Phishing-resistant by design.

FIDO2 / WebAuthn L2
Resident key stored on your device
No shared secret with the server

Email + Password

Classic email and password authentication. Passwords are hashed with Argon2id (memory-hard) before storage — never in plaintext.

Argon2id — 64MB / 3 iterations
Per-user salt
HIBP breach check on registration

Session security

Token architecture

Short-lived access tokens and rotated refresh tokens minimize the impact of a compromised token. Both token types are cryptographically signed and validated on every request.

Access token

Short-lived token used for all API requests. Signed with an RS256 key pair — the server never shares the private key.

FormatJWT (RS256)
Lifetime15 minutes
StorageMemory only (never localStorage)

Refresh token

Used only to issue new access tokens. Rotated on every use (refresh token rotation). Old tokens are invalidated immediately.

FormatOpaque token (256-bit)
Lifetime7 days (rotated on use)
StoragehttpOnly Secure SameSite=Strict cookie

Data sovereignty

You own your data

Your blueprint is stored in your Google Drive and in our database as encrypted ciphertext. You can delete either copy independently. Deleting your account removes all server-side records permanently and irreversibly within 30 days.

Export anytime

Download your full decrypted blueprint as JSON from the dashboard at any time. No lock-in, no approval process.

Delete anytime

Account deletion purges all server-side data within 30 days (regulatory minimum). Your Google Drive data can be deleted independently at any time.

Data residency

Server-side ciphertext is stored in the EU (Frankfurt, AWS eu-central-1). No data is processed in regions with mandatory decryption orders.

No AI training

Your blueprint is never used to train models, fine-tune LLMs, or shared with third parties for any purpose. The architecture makes this impossible anyway — we can't read it.

Audit status

Security reviews

Internal cryptographic reviews have been completed. A full external penetration test is scheduled for Q3 2026.

AES-256-GCM implementationVerified
HMAC-SHA256 watermarkingVerified
Key derivation (PBKDF2 / HKDF)Verified
WebAuthn registration flowVerified
JWT signing / verificationVerified
Full penetration test (ext)Q3 2026

Next steps

Related documentation