← cardwarden.app

Security White Paper

CardWarden Mobile App

Last Updated: July 2026

1. Introduction

Loyalty cards, payment cards, membership cards, and gift cards contain sensitive personal and financial information. Storing them digitally introduces risk that demands a security model where the user - and only the user - controls access to their data.

CardWarden is built on a zero-knowledge architecture. All encryption and decryption happens exclusively on the user's device. CardWarden's servers never have access to plaintext card data, master passwords, or encryption keys. Even in the event of a full server-side compromise, an attacker would obtain only encrypted blobs that cannot be decrypted without the user's master password.

This document provides a transparent overview of CardWarden's encryption design, key management, and data protection practices. It is intended for security-conscious users and auditors who want to understand how their data is safeguarded at every layer.

2. Security Principles

Zero-Knowledge Architecture

CardWarden's server infrastructure is designed so that it never has access to your plaintext data. All card details are encrypted on your device before they leave it. The server stores only encrypted ciphertext and wrapped key material. No one at CardWarden - not even system administrators with full database access - can read your cards.

End-to-End Encryption

Every piece of sensitive data is encrypted before it leaves your device and can only be decrypted on an authorized device where you have provided your master password. This applies to cloud backup, device sync, and family sharing. There is no point in the data's lifecycle where it exists in plaintext outside of your device.

Defense in Depth

CardWarden does not rely on a single layer of protection. Multiple independent security mechanisms work together:

  • Hardware-backed keystore for storing encryption keys in a secure hardware module on your device
  • Per-pocket encryption keys that limit the blast radius of any single key compromise
  • Authenticated encryption (AEAD) that detects any tampering with encrypted data
  • Calibrated key derivation with 600,000 PBKDF2 iterations to resist brute-force attacks
  • Purpose-specific subkeys derived via HKDF so that compromise of one subkey does not expose others

3. Account Security

Master Password

Your master password is the root of trust for all of your encrypted data. It serves two independent purposes:

  • Account authentication - When you sign in, your password is transmitted over TLS to the backend authentication service, where it is hashed using bcrypt and stored only in hashed form. The raw password is never stored on the server.
  • Encryption key derivation - Entirely on your device, PBKDF2-HMAC-SHA256 with 600,000 iterations and a random 128-bit salt derives a Key Encryption Key (KEK). This KEK unwraps your Master Key, which in turn derives all other encryption keys. The server never sees the KEK, the Master Key, or any derived subkey.

These two processes are completely independent. The authentication service has no access to the encryption key derivation path, and the encryption layer does not depend on the server's password hash.

Recovery Phrase

During account setup, CardWarden generates a 12-word recovery phrase from the BIP-39 English wordlist (2,048 words), providing approximately 132 bits of entropy. This phrase independently wraps the Master Key via a separate PBKDF2 derivation with its own salt and 600,000 iterations.

The recovery phrase is displayed once during setup and must be written down by the user. CardWarden does not store the recovery phrase in any recoverable form. If both the master password and the recovery phrase are lost, the encrypted data cannot be recovered by anyone, including CardWarden.

4. Encryption Architecture

Algorithms

Purpose Algorithm Key Size
Symmetric encryption ChaCha20-Poly1305 (AEAD) 256-bit
Password key derivation PBKDF2-HMAC-SHA256 256-bit output
Subkey derivation HKDF-SHA256 256-bit output
Key exchange (sharing) ECDH on NIST P-256 256-bit curve
Random key generation Platform CSPRNG 256-bit

Why ChaCha20-Poly1305?  It provides equivalent security to AES-256-GCM while delivering consistent performance on mobile devices that may lack dedicated AES hardware acceleration. It is an IETF standard (RFC 8439) used by WireGuard, TLS 1.3, and other modern security protocols. As an AEAD cipher, it provides both confidentiality and integrity in a single operation - any tampering with the ciphertext is detected during decryption.

Key Hierarchy

CardWarden uses a layered key model. The Master Key sits at the top; purpose-specific subkeys are derived from it using HKDF with unique context labels; per-pocket Data Encryption Keys (DEKs) encrypt your actual card data. This design ensures that compromise of one key does not cascade to other parts of the system.

Key Hierarchy
Master Key
256-bit, generated by CSPRNG, stored in hardware keystore
HKDF-SHA256
DEK Wrap Subkey
wraps
Pocket DEK
Cards
Pocket DEK
Cards
Pocket DEK
Cards
EC Key Wrap Subkey
wraps
EC Private Key
for family sharing
Fingerprint Subkey
derives
Keyed Hashes
duplicate detection

Each pocket (a group of related cards) has its own 256-bit Data Encryption Key generated from the platform's cryptographically secure random number generator. Pocket DEKs are wrapped by the DEK Wrap Subkey before being stored in the cloud. Individual cards are encrypted using their pocket's DEK with ChaCha20-Poly1305, and each encryption operation uses a unique random 96-bit nonce.

5. Key Derivation

The Master Key is never derived from the master password directly. Instead, the password is used to derive a Key Encryption Key (KEK) that unwraps the Master Key. This separation allows the master password to be changed without re-encrypting all data - only the KEK wrap needs to be updated.

Key Derivation Flow
Master Password
user-memorized
PBKDF2-HMAC-SHA256
600,000 iterations + salt
Password KEK
256-bit
Recovery Phrase
12 BIP-39 words
PBKDF2-HMAC-SHA256
600,000 iterations + salt
Recovery KEK
256-bit
unwraps (ChaCha20-Poly1305)
Master Key
256-bit, stored in hardware keystore

Two independent paths can unwrap the same Master Key.
Either the master password or the recovery phrase is sufficient.

Why 600,000 Iterations?

The OWASP 2023 guidelines recommend a minimum of 600,000 iterations for PBKDF2-HMAC-SHA256. At this calibration, a modern GPU can test approximately 5,000 password guesses per second, making brute-force attacks against even moderate-strength passwords computationally impractical. Combined with the random 128-bit salt (unique per user), precomputed attacks (rainbow tables) are rendered ineffective.

6. Cloud Backup Security

When cloud backup is enabled, your card data is encrypted on your device before upload. The server receives and stores only encrypted ciphertext and wrapped key material. At no point does the server have access to your plaintext card data, your Master Key, or any derived subkeys.

Zero-Knowledge Cloud Sync

Your Device

Card Data (plaintext)
Pocket DEK + ChaCha20
Encrypted Blob
Master Key wraps DEK
Wrapped DEK

Server

Encrypted Blob
Wrapped DEK
Wrapped Master Key
KDF Parameters
🚫
Cannot decrypt anything

New Device

Master Password
PBKDF2 → KEK
Unwrap Master Key
Unwrap Pocket DEKs
Card Data (plaintext)

What the Server Stores

Stored (encrypted)

  • Encrypted card data (ciphertext)
  • Wrapped Pocket DEKs
  • Wrapped Master Key
  • KDF parameters (algorithm, iteration count, salt)
  • Your email address (for authentication)

Never accessible

  • Plaintext card details
  • Your master password
  • Your recovery phrase
  • The Master Key
  • Any derived subkeys or Pocket DEKs

Row-Level Security

The database enforces row-level security (RLS) policies at the database engine level. Each authenticated user can only query their own data and data from pockets they are members of. Even in a scenario where application-level access controls were bypassed, the database layer independently enforces data isolation.

7. Family Sharing Security

CardWarden allows you to share a pocket of cards with family members. The shared data remains end-to-end encrypted - the server facilitates the key exchange but never has access to the shared content or the keys that protect it.

Key Exchange Protocol

Each CardWarden user has an Elliptic Curve (EC) keypair on the NIST P-256 curve. The public key is stored in plaintext on the server; the private key is wrapped (encrypted) with a subkey derived from the user's Master Key, so it is inaccessible to the server.

Family Sharing Key Exchange
Owner's Device
Owner Private Key
Owner Public Key
Invitee's Device
Invitee Private Key
Invitee Public Key
ECDH Key Agreement (P-256)
Shared Secret
HKDF-SHA256 + random salt
Wrapping Key
ChaCha20-Poly1305
Wrapped Pocket DEK
stored on server for invitee

Both sides independently derive the same shared secret.
The server never sees the unwrapped Pocket DEK or the shared secret.

How Sharing Works

  1. The owner's device retrieves the invitee's public key from the server.
  2. ECDH key agreement is performed between the owner's private key and the invitee's public key, producing a shared secret that both parties can independently derive.
  3. HKDF-SHA256 derives a wrapping key from the shared secret using a fresh random salt (unique per share operation).
  4. The pocket's DEK is encrypted with this wrapping key using ChaCha20-Poly1305 and stored on the server for the invitee.
  5. The invitee's device performs the reverse ECDH (invitee private key × owner public key) to arrive at the same shared secret, derives the same wrapping key, and unwraps the Pocket DEK.

Each share operation uses a fresh random HKDF salt, providing per-operation key diversity even when the same owner shares multiple pockets with the same invitee.

Family Change Notifications

When a card in a shared pocket is added, modified, or deleted, CardWarden sends a push notification to the other family members so they can stay informed of changes. To deliver a useful notification, a small amount of non-sensitive metadata is included in the notification payload in unencrypted form. This is a deliberate, limited exception to the zero-knowledge model.

What Is Included

  • The card's display name (e.g. "Starbucks")
  • The card type (e.g. "Gift Card", "Loyalty Card")
  • The event type (e.g. "card added", "balance spent")
  • For balance changes: the amount and currency code (e.g. "$5.00")
  • The user's locale, used solely for number and currency formatting

What Is NOT Included

  • Card numbers, barcodes, or QR codes
  • PINs, CVVs, or security codes
  • Expiry dates
  • Notes or custom fields
  • Any data that could be used to impersonate, clone, or transact with the card

Why Plain Text Is Necessary

On both iOS and Android, the app cannot reliably perform decryption when running in the background. On iOS, the system terminates background apps aggressively, making it impossible to run custom decryption logic when a push notification arrives. On Android, the hardware-backed keystore that protects encryption keys is inaccessible while the device is locked. Since most notifications are received when the app is not in the foreground and/or the device is locked, encrypted payloads would result in generic, uninformative notifications in the majority of real-world scenarios.

Ephemeral Server-Side Storage

The notification metadata is written to a transient field on the server. A database trigger reads the metadata, enqueues the push notification for delivery, and immediately clears the field in the same operation. The metadata is not persisted, logged, or included in database backups. Its lifetime on the server is measured in milliseconds.

Transport Security

Although the notification content is not end-to-end encrypted, it is always encrypted in transit. The payload is transmitted over TLS 1.2+ to the platform push service (Firebase Cloud Messaging for Android, Apple Push Notification service for iOS), both of which use encrypted channels for delivery to the device.

Risk Scope

Even in a worst-case interception scenario, an attacker would learn only the card's display name, its type category, the most recent balance change amount, and the currency. This information alone is not sufficient to use, clone, or impersonate the card. No card numbers, authentication credentials, or transaction-enabling data are ever included in the notification payload.

8. Card Sharing

Card sharing is designed for one-off sharing with people outside your family - for example, sending a loyalty card to a friend over instant messaging. For family members, the more convenient approach is to grant them access to an entire pocket (see Family Sharing), which automatically gives them access to all cards within it. Card sharing, by contrast, shares a single card as a standalone, encrypted snapshot.

Share Links

Users can share individual cards via a link protected by a passphrase. The card data is encrypted using ChaCha20-Poly1305 with a key derived from the passphrase via PBKDF2-HMAC-SHA256 (200,000 iterations). The encrypted payload is embedded directly in the link. The recipient must know the passphrase to decrypt the card - the passphrase itself is never included in the link.

QR Code Sharing

For in-person sharing, CardWarden can generate a QR code containing the encrypted card data. A random 256-bit encryption key is embedded alongside the ciphertext within the QR code. Because QR sharing requires the recipient to physically scan the code, the security boundary is physical proximity rather than a passphrase. The QR code is intended for ephemeral, in-person use.

Duplicate Detection

To detect duplicate cards without exposing card numbers, CardWarden uses a keyed SHA-256 hash. The HMAC key is derived from the Master Key via HKDF, so the fingerprint cannot be reversed without access to the Master Key. The server sees only the hash - never the card number.

9. Data Export & Restore

CardWarden is designed so that your data is never locked in. You can export all of your cards at any time in a standard spreadsheet format compatible with Excel, Google Sheets, and other spreadsheet applications. This allows you to keep a personal backup, migrate to another card manager, or simply review your data outside the app.

Encrypted Export

When exporting, you can choose to protect the file with a passphrase. The export data is encrypted using ChaCha20-Poly1305 with a key derived from your passphrase via PBKDF2-HMAC-SHA256. The resulting file can only be opened by providing the same passphrase during import - whether back into CardWarden or on a different device.

Plain Text Export

If encryption is not needed - for example, when exporting for immediate use in a spreadsheet - you can export your data as plain text. The exported file contains all card details in a standard tabular format that can be opened directly in any spreadsheet application. Because this file is unencrypted, it should be handled with the same care as any document containing sensitive information.

Restore

Exported files can be imported back into CardWarden. If the export was encrypted, you will be prompted for the passphrase used during export. CardWarden validates the data integrity during import and restores your cards into the selected pocket, where they are immediately protected by the app's standard encryption.

10. Data Protection

At Rest

On your device, the Master Key and all Pocket DEKs are stored in the platform's hardware-backed keystore - a secure hardware module that prevents key extraction even if the device is rooted or jailbroken. Keys stored in the hardware keystore can only be used through the platform's cryptographic APIs; they never exist in application memory in exportable form.

Card data stored in the local database is encrypted with the pocket's DEK using ChaCha20-Poly1305. In the cloud, all card data is stored as authenticated ciphertext, and all key material is wrapped (encrypted) before storage.

In Transit

All communication between the CardWarden app and backend services uses TLS 1.2 or higher, ensuring that data is encrypted during transmission. Modern cipher suites are enforced, and connections to servers using outdated or weak cryptographic configurations are rejected.

Screen Capture Protection

Sensitive screens - including the recovery phrase display, QR code sharing, and card detail views showing private fields - are protected from screen capture and screen recording at the operating system level.

11. Infrastructure Security

CardWarden's backend infrastructure is hosted on a managed cloud platform with enterprise-grade security controls.

  • Database isolation - Row-level security (RLS) is enforced at the database engine level, ensuring that each user can only access their own data regardless of application-layer logic.
  • Isolated compute - Server-side functions execute in isolated environments with no persistent state, reducing the attack surface.
  • No plaintext access by design - No CardWarden employee or system administrator has access to decrypted user data. This is enforced by the zero-knowledge architecture, not by access control policies that could be circumvented.
  • Authentication - User authentication is handled by a dedicated authentication service that supports email/password and federated identity providers. Passwords are hashed using bcrypt with a cost factor that meets current security standards.

12. Our Commitment

CardWarden is built on the principle that your data belongs to you. The zero-knowledge architecture means that trust is enforced by mathematics and cryptographic design, not by promises or policies. Your data is never locked in - you can export everything at any time in a standard format.

We are committed to transparency about our security practices. This document will be updated as our architecture evolves. If you have security questions or would like to report a vulnerability, please contact us at thesimplestnet@gmail.com.