New: AI Agent SDK is live — integrate Claude-powered wallet actions into your app. Read the docs
Threat Model

Threat Model

This document describes the threat boundary, attacker model, trust assumptions, and residual risks for Veil in STRIDE format. It is intended for security reviewers, auditors, and operators evaluating Veil for production use.

⚠️

Veil has not undergone a formal third-party security audit. The mitigations below represent the design intent and current implementation; some are marked planned and are not yet enforced on-chain.


Attacker Model

ActorCapabilityGoal
Remote attackerNetwork access, phishing sites, malicious JavaScriptSteal funds or authorise a transaction without the user’s biometric
Malicious anchor / serviceControl over anchor-issued assets, forged off-chain dataIssue fraudulent tokens or manipulate swap pricing
Compromised cloud / passkey syncRead access to iCloud Keychain or Google Password Manager backupRecover the passkey credential and sign on the user’s behalf
Malicious co-signerAn add_signer transaction the user was tricked into approvingExfiltrate funds after gaining on-chain signer status
Malicious smart contractInvoke Veil wallet via cross-contract callTrigger an authorised action without the user’s knowledge
Insider / supply-chainCompromise of an npm package or GitHub Actions runnerInject malicious SDK code or steal CI secrets
Quantum adversary (future)Break P-256 ECDSA offlineRecover signing key from on-chain public key

STRIDE Threat Table

Spoofing

#ThreatComponentMitigationStatus
S-1Attacker forges a WebAuthn assertion with an arbitrary P-256 key__check_authContract rejects keys not in has_signer() registry✅ Implemented
S-2Phishing site harvests a passkey assertion for the real originWebAuthn / browserWebAuthn origin binding — clientDataJSON.origin is set by the authenticator and cannot be spoofed by a relying party✅ By spec
S-3Cloud-passkey sync compromise — attacker restores credential on a new devicePasskey sync providerPasskey private key is stored in the secure enclave; cloud sync stores an encrypted blob that requires re-authentication on the new device⚠️ Trust in sync provider
S-4Malicious anchor impersonates a legitimate issuerAsset trust lineVeil does not auto-establish trust lines; user must approve change_trust via biometric✅ Implemented

Tampering

#ThreatComponentMitigationStatus
T-1Attacker modifies the transaction after the user signsXDR envelopeSoroban signature_payload is a deterministic hash of the auth entry; any modification changes the payload and breaks the challenge binding✅ Implemented
T-2Attacker tampers with clientDataJSON or authData in transitWebAuthn pipelineBoth fields are included in the ECDSA message hash (SHA256(authData ‖ SHA256(clientDataJSON))); tampering invalidates the signature✅ Implemented
T-3SDK is tampered in a supply-chain attacknpm packagepackage-lock.json pins exact versions; Dependabot keeps dependencies updated; GitGuardian scans for secret leaks⚠️ No sub-resource integrity yet
T-4Wraith indexer serves tampered transfer historyHorizon dataUI uses Horizon as a secondary source; discrepancies can be surfaced; full Horizon verification is planned⚠️ Partial

Repudiation

#ThreatComponentMitigationStatus
R-1User denies authorising a transactionSmart contractEvery authorised action requires a valid WebAuthn assertion; clientDataJSON contains the exact signature_payload hash, creating a non-repudiable audit trail on-chain✅ By design
R-2Operator denies a Lens price query was servedLens oraclex402 payment receipts provide a timestamped record of each API call✅ Implemented

Information Disclosure

#ThreatComponentMitigationStatus
I-1Private key exfiltration via JavaScriptSecure enclaveWebAuthn create() returns only the public key; the private key never leaves the hardware enclave✅ By spec
I-2localStorage credential ID exposure (same-origin XSS)SDKcredential_id in localStorage reveals which passkey is registered; does not expose the private key⚠️ Switch to IndexedDB + encryption in production
I-3Stellar public key linkage (address reuse)BlockchainStellar public keys are permanently visible on-chain; multi-account rotation is not yet supported⚠️ Residual risk
I-4Agent conversation history in memoryAgent serverChat history is held in-process memory only; no persistence layer for conversations✅ No DB persistence

Denial of Service

#ThreatComponentMitigationStatus
D-1Flood Soroban RPC with junk transactionsSoroban RPCProtocol-level fee market; attackers pay per operation✅ By protocol
D-2Drain fee-payer G… account (HKDF-derived)Fee-payer accountFee-payer is only used for fee bump; wallet funds are held separately in the C… contract account✅ By design
D-3Remove the last signer, locking the walletremove_signerPhase 5 guardian recovery allows a pre-registered guardian to restore access; UI warns when removing the last signer✅ Guardian recovery
D-4DoS Lens price oracleLens servicex402 micropayment gate rate-limits free callers; Render horizontal scaling available⚠️ Basic rate limiting only

Elevation of Privilege

#ThreatComponentMitigationStatus
E-1Rogue signer added without user consentadd_signeradd_signer requires a valid WebAuthn signature from an existing registered signer✅ Implemented
E-2Cross-contract re-entrancy (malicious contract calls Veil)__check_authSoroban’s require_auth model prevents re-entrancy; each auth entry is bound to a specific invocation✅ By Soroban design
E-3Replay of an old valid WebAuthn assertion__check_authsignature_payload is derived from the Soroban auth entry hash, which is unique per ledger sequence; Soroban ledger sequences prevent replay at the network level✅ Implemented
E-4CI runner compromise exposes NEXT_PUBLIC_* env varsGitHub ActionsNEXT_PUBLIC_* values are public testnet addresses (browser-exposed by design); no mainnet secrets in CI✅ Testnet only
E-5Guardians recover to a key they controlGuardian recovery3-day timelock on complete_recovery; user can cancel during the window; guardian’s own key must authorise⚠️ Timelock relies on user monitoring

Trust Assumptions

AssumptionJustificationRisk if violated
Stellar consensus is BFT-honestStellar SCP tolerates up to ⅓ Byzantine validators in the quorum sliceDouble-spend or transaction censorship
WebAuthn implementation is correctBrowser/OS vendor (Apple, Google, Microsoft) implements the FIDO2 spec faithfullyPasskey bypass
Hardware secure enclave is tamper-resistantCertified by FIDO Alliance; assumed not to have hardware backdoorsPrivate key exfiltration
Cloud passkey sync provider (iCloud/Google) is honestOperator trusts Apple / Google with the encrypted passkey blobCredential recovery by a compromised cloud provider
p256 and sha2 Rust crates are correctWidely used, audited crates; Rust memory safety eliminates most implementation bugsSignature forgery or hash collision
Soroban VM is deterministic and isolatedSoroban design guarantee; each contract execution is sandboxedArbitrary code execution inside the VM
Vercel and Render supply-chain integrityBuild artefacts served from Vercel CDN; Render container imagesMalicious injection at deploy time

Residual Risks

RiskLikelihoodImpactAccepted Until
No formal security auditMediumHighPre-mainnet audit scheduled
localStorage credential ID (same-origin XSS readable)LowLowProduction SDK hardening
No RP ID / origin verification in contract (Phase 4 planned)LowHighPhase 4 — store rpIdHash at init()
No per-signer nonce (sequence replay across forks)Very LowMediumPhase 5 — on-chain nonce
Quantum adversary breaking P-256Very Low (10+ yr)CriticalPost-quantum: replace P-256 with ML-DSA when Soroban supports it
Passkey sync provider compromiseVery LowHighHardware key option (FIDO2 security key) as alternative authenticator
Malicious anchor issuing fraudulent assetsLowMediumUI shows asset issuer; user must approve trust lines explicitly

Scope

This threat model covers:

  • In scope: Soroban smart contract (invisible_wallet, factory), browser SDK (invisible-wallet-sdk), wallet PWA (frontend/wallet), AI agent (packages/agent), Lens price oracle, Wraith transfer indexer, docs site (frontend/docs), CI/CD pipeline.
  • Out of scope: Stellar network consensus layer, browser/OS vendor implementations of WebAuthn, Render/Vercel hosting infrastructure internals.

References