> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aropay.aro.media/llms.txt
> Use this file to discover all available pages before exploring further.

# Security model

> How AroPay protects credentials, keys, and funds: a summary of the platform's security architecture.

A condensed view of the controls behind the sandbox. The theme throughout:
**credentials can't escalate, and key material doesn't travel**.

## Credentials

<AccordionGroup>
  <Accordion title="Passwords" icon="lock" iconType="duotone">
    Hashed with **scrypt** (N=32768, r=8, p=1) and a per-user salt. Policy: at
    least 10 characters with upper, lower, and digit. Five consecutive failures
    lock the account for 15 minutes; login errors are generic so nothing leaks
    about which part was wrong. Provisioned and admin-reset accounts are forced
    to rotate on first login.
  </Accordion>

  <Accordion title="Sessions" icon="cookie-bite" iconType="duotone">
    HMAC-SHA256-signed cookie (httpOnly, `secure`, `SameSite=Lax`, 24-hour
    TTL). Sessions embed the account's **token version**: a password change
    bumps it and instantly invalidates every other session.
  </Accordion>

  <Accordion title="API keys" icon="key" iconType="duotone">
    256-bit secrets, stored as **SHA-256 hashes**, unrecoverable after
    creation. Prefix-only display, optional expiry, immediate revocation, and
    <a href="/security/authentication#session-only-endpoints">session-only management</a>:
    a key cannot create keys, change the password, manage 2FA/passkeys, or
    export wallets.
  </Accordion>

  <Accordion title="TOTP & passkeys" icon="fingerprint" iconType="duotone">
    TOTP secrets AES-256-GCM encrypted at rest, codes single-use per time
    step, disable requires password **and** a live code. Passkeys are
    origin-bound WebAuthn credentials with signed, single-use, fast-expiring
    challenges.
  </Accordion>
</AccordionGroup>

## Custodial key custody

* Generated server-side; **never** returned, logged, or shown in any UI.
* Encrypted at rest with **AES-256-GCM** (per-wallet IV + auth tag) under a
  platform master key held in the deployment environment.
* Decrypted only transiently, in memory, to sign.
* The single egress path is the deliberate, session-only
  [export](/guides/export-and-backup), re-encrypted under **your**
  passphrase (PBKDF2-SHA256, 310k iterations + AES-256-GCM) before it leaves.

## Request hardening

* **Input validation everywhere**: every body, query, and path param is
  schema-validated; failures return structured `validation_error` details.
* **Amounts bounded** to uint64 in base units; addresses EIP-55 checksummed.
* **Ownership enforced on every access**: wallets, transactions, keys, and
  passkeys resolve only within the authenticated account; cross-tenant IDs
  read as `404 not_found`.
* **Content-type as CSRF defense**: writes require `application/json`,
  which cross-origin HTML forms cannot produce without a preflight the API
  never allows. Combined with `SameSite=Lax` cookies, classic CSRF has no
  path.
* **Rate limits** on login, reads, and writes; see
  [Rate limits](/security/rate-limits).

## Platform isolation

The sandbox resolves only on its dedicated hosts; admin-portal routes 404
there, and sandbox routes 404 on the portal, enforced at the proxy layer, not
by convention.

## Confidentiality boundary

What FHE does and doesn't hide, in one line: **amounts are encrypted; the
sandbox can decrypt balances of custodial wallets it manages** (that's how the
dashboard shows figures), external wallets stay opaque, and redeem settlement
publicly decrypts exactly one value: the burned amount. Details in
[Confidential transfers](/concepts/confidential-transfers).

<Note>
  The current MVP sandbox runs on Sepolia, so funds are testnet-denominated; the
  same platform orchestrates real value once deployed to Mainnet. Accounts are
  provisioned by admins, who can also deactivate them, killing sessions and keys
  immediately. The controls above are the production security model; integrate
  against them now and it carries over.
</Note>
