Payment Methods
Add a credit or debit card to your vault. Encrypted end-to-end on your device — BoxOwl servers store only ciphertext.
Payment methods are encrypted on your device with AES-256-GCM before upload. BoxOwl infrastructure cannot read them.
How it works in one paragraph
When you save a payment method, the card number and full metadata are encrypted on your phone with a key derived from your vault passphrase (or a registered passkey). The encrypted blob is what gets uploaded. BoxOwl servers can read a small set of display hints — the card network logo, the last 4 digits, the expiry, the cardholder name — so the card list renders without decryption. Everything else is opaque to us. CVV is never stored; the extension prompts for it at the moment of checkout and discards it after.
1. Add a card on Android
- Open Vault > Payment Methods.
- Tap the floating + button.
- Fill in the card number, expiry, cardholder name, and billing address (you can pick an existing address from your vault).
- Tap Save. If this is your first encrypted entry, the app walks you through vault setup: pick a passphrase (12+ chars) and write down the 12-word BIP-39 recovery phrase. The recovery phrase is shown once — BoxOwl servers never see it.
- After confirmation, the card appears in the list with its network icon and last-4. Tap to view masked PAN; re-authentication (biometric or passphrase) is required to reveal the full number.
The same passphrase works across the Android app and the browser extension. Set it up once; both clients derive the same key.
2. Add a card from the extension
- Open the BoxOwl popup and tap Save Password → Payment Method (or use Fill Payment on a checkout page and choose Save new card).
- Enter the card number (Luhn-validated), expiry MM/YY, cardholder name, and pick a billing address.
- Unlock your vault if it isn't already. The popup encrypts the PAN + metadata using AES-256-GCM with a per-entry data key, then wraps that key with your vault key (Argon2id-derived).
- The opaque ciphertext is POSTed to BoxOwl. Display hints (last-4, network, expiry, cardholder name) are sent in clear so the card list works without a re-decrypt.
3. Checkout autofill
On a checkout page:
- The extension detects payment fields (
cc-number,cc-exp,cc-csc, plus regex fallbacks for sites that don't use the standards). - You pick a card from the popup. If the vault is locked, the extension prompts for biometric (passkey) or passphrase unlock first.
- The background service-worker fetches the ciphertext, decrypts it locally, and injects the PAN, expiry, and cardholder name into the form. CVV is shown as a transient prompt — you type it in, the extension auto-fills, and the value is discarded immediately.
The unlock prompt UX is one round-trip: once the vault is unlocked in this browser session, subsequent card fills don't re-prompt for 15 minutes of activity (the timer resets on each use).
What BoxOwl can and can't see
| Field | Visible to BoxOwl? | Where it lives |
|---|---|---|
| Full card number (PAN) | No | Inside the encrypted ciphertext blob |
| CVV / CVC | No | Never stored anywhere — transient at checkout |
| Cardholder name | Yes (display hint) | Plain column |
| Last 4 digits | Yes (display hint) | Plain column |
| Expiry month/year | Yes (display hint) | Plain column |
| Card network (Visa, MC, etc.) | Yes (display hint) | Plain column — derived client-side from BIN |
| Billing address | Yes — same as your other vault addresses | Linked by ID; the address itself follows your visibility settings |
The display hints are deliberate: they let the card-list UI render with a network logo and "•••• 1234" line without decrypting. Showing the full number requires unlock + decrypt.
Crypto details
- Cipher: AES-256-GCM with a 12-byte random nonce and a 16-byte authentication tag. Additional Authenticated Data binds each ciphertext to
{userId, paymentMethodId, "pay", cryptoVersion}, so a blob from one user/entry can't be successfully decrypted into another. - Per-entry DEK: each card gets its own random 256-bit data key. The DEK is wrapped (AES-256-GCM, same AAD shape) with your vault KEK. The wrapped DEK travels with the ciphertext.
- Vault KEK: derived from your passphrase via Argon2id (m=64MiB, t=3, p=4) using a per-user 16-byte random salt provisioned at vault setup. The KEK can also be unwrapped from a registered passkey using the WebAuthn PRF extension.
- Recovery: a 12-word BIP-39 phrase, shown once at vault setup. The phrase derives a recovery key that re-wraps your KEK on the server, so you can decrypt your vault on a fresh device. The phrase itself never reaches BoxOwl.
The same primitives back passwords and secure notes — they share shared/e2ee-constants.ts between the extension, Android app, and backend so all three agree on byte layout. See the trust page for the broader picture.
PCI scope
BoxOwl's posture is that we are out of PCI-DSS scope for the card-storage feature because BoxOwl never receives, processes, or stores raw cardholder data — only opaque ciphertext we cannot decrypt. The user's device is the cardholder-data environment.
This is the same legal argument that applies to fully end-to-end encrypted password managers: the operator demonstrably cannot read the protected data, so they're not a CDE participant. We are not a payment processor and do not charge cards on your behalf — that role is handled by Stripe for subscription payments (separate from the vault).
If your organization needs a PCI attestation specifically for BoxOwl-stored cards, contact us via trust.html — we can provide the design doc, threat model, and crypto artifacts that support the out-of-scope argument.
Rotating your vault passphrase
From the Android password list, open the overflow menu and choose Change passphrase. The flow:
- Enter your current passphrase to derive the current KEK.
- Enter a new passphrase. The app derives a new KEK with the same Argon2id params and per-user salt.
- Locally, the app fetches every encrypted DEK (passwords, payment methods, secure notes, TOTP), unwraps with the old KEK, re-wraps with the new KEK, and POSTs the batch atomically to
/vault/passphrase/rotate. - You're shown a new BIP-39 recovery phrase. Write it down — the old one is invalidated.
- Biometric/passkey enrolment is cleared. You'll re-enrol on the unlock screen so the device-bound key wraps the new KEK.
Card data itself is never re-encrypted during rotation — only the wrapping DEK changes. That keeps rotation fast and avoids re-uploading large ciphertext blobs.
Limitations & what's next
- Android-first. Card add/edit/list/detail is fully functional on Android. The extension currently supports card add and checkout autofill; card management (rename, delete from extension UI) is being filled in.
- One card network per entry. BIN detection runs client-side at entry time; if your card's BIN changes (rare), the network icon may need a manual update via edit.
- No automatic CVV recall. By design. If a merchant requires CVV every time, that's the merchant's policy and BoxOwl can't bypass it.
- No automatic billing-address linking on update. If you change the linked billing address, do it from the card-edit screen — the link is set at save time.
Related
- Trust & Security — the full encryption story
- Security Best Practices — vault unlock UX, passkeys, recovery phrase
- Vault Management — how the rest of the vault works
- Browser Extension Setup — checkout autofill walkthrough