Verdict — your project eliminates 5 of 7 risks from the cloud API threat model — 2 remain
The prior report found cloud API mode against bank accounts inadvisable across seven independent risk categories. Your project — a custom Python/Playwright/Ollama stack — was designed as the hybrid architecture those reports recommended. Here's how it maps.
Severity for each of the seven risks, comparing cloud API mode against this project. Green = eliminated. Amber = partially mitigated. Red = still present.
| Risk | Cloud API mode severity | Your project severity |
|---|---|---|
| Payload to cloud | High | Eliminated |
| API retention | Medium | Eliminated |
| Framework CVEs | High | Eliminated |
| Prompt injection | High | Largely eliminated |
| Session timeout | Medium | Eliminated |
| Credential handling | Medium | Partially mitigated |
| Bot detection | High | Partially mitigated |
_snapshot() also masks password values in the tree with a regex before the LLM ever sees them.~/Downloads/bank-agent/ — which is exactly the intended output.done. It never reads transaction data, balances, or memo fields. Downloads are pure Playwright — no LLM. The worst outcome from a successful injection is wrong navigation, not financial action._keepalive() moves the mouse during every LLM call — keeps the session warm. (2) LLM handles only 3–5 navigation steps, then Playwright takes over. (3) Playwright downloads have no LLM latency between them.sensitive_data opt-in has confirmed bugs where it silently fails. Credentials reach Anthropic/OpenAI servers..env, gitignored, and loaded locally. They're passed to the local LLM in the login task prompt — the LLM needs them to fill the form. Since Ollama is local, nothing reaches an external server. The snapshot masking (agent.py:420) adds defense-in-depth against accidental re-exposure in page-state feedback.Error object getter detectable server-side. TLS/JA4 fingerprinting is server-side and unbypassable by the browser. Detection leads to session termination or account lockout.channel="chrome" launches the real Chrome binary instead of Playwright's bundled Chromium — eliminates many Chromium-specific fingerprints, improves behavioral biometric signals. This is the most impactful available mitigation. The remaining risk: CDP protocol itself is still detectable via V8 serialization; TLS/JA4 fingerprinting cannot be addressed at the browser level.Bank Terms of Service violation. Chase's March 2026 ToS explicitly prohibit AI agents. Your project is an AI agent accessing Chase. Personal use for your own accounts reduces the CFAA risk substantially (the active Ninth Circuit case concerns commercial agents), but the ToS violation is unambiguous. The practical consequence isn't legal — it's account action: if Chase detects consistent automation, they can freeze, close, or flag the account. The probability is non-zero and rises with frequency of use.
CDP detection — real Chrome helps but doesn't close the gap. channel="chrome" is the right call and meaningfully better than Playwright's bundled Chromium. It removes Chromium-specific signals and produces more human-like rendering behavior. What it doesn't change: CDP itself leaks through V8's Error object serialization, which is a kernel-level signal read server-side without any DOM inspection. TLS/JA4 fingerprinting is also server-side. These are hard limits of the Playwright approach regardless of which Chrome binary is used.
| Design choice | Where | Why it matters |
|---|---|---|
| Local Ollama only | agent.py:68 | Eliminates all cloud payload, retention, and provider-side risks at once |
| LLM scope = navigation only | flows/ task prompts | LLM never reads financial data; prompt injection surface collapses to navigation UI labels |
| Playwright handles all downloads | agent.py:128–380 | Zero LLM latency between PDF downloads; solves session timeout for the long tail |
| Keepalive mouse movement | agent.py:516 | Prevents idle timeout during qwen3:32b generation; runs concurrent with LLM call |
| Model warmup on start | agent.py:82–121 | Loads qwen3:32b into VRAM while browser launches; first navigation step returns fast |
| Auto-discovery from sidebar | main_multi.py:137 | No hardcoded account list; works for any Chase user; found THIRD MG LLC that wasn't in the original list |
| channel="chrome" | agent.py:92 | Real Chrome binary reduces fingerprinting signals vs. Playwright's bundled Chromium |
| think=False | agent.py:551 | Suppresses qwen3 chain-of-thought; cuts token generation, fixes JSON parsing, reduces step latency |
| Snapshot capped at 4,000 chars | agent.py:424 | Prevents multi-minute generations on large account overview pages with many transactions |
| .env gitignored + wizard warning | .gitignore, main_multi.py:129 | Credential file excluded from version control; setup warns "do not share or commit" |
The risk assessment artifact's conclusion was "do not use cloud API mode against production bank accounts." Your project implements almost every mitigation that report identified as the viable alternative: local model, Playwright-direct downloads, narrow LLM scope, session keepalive, real Chrome binary, no third-party framework. Five of the seven risk categories from that report do not apply here.
What's left is the irreducible minimum for this type of tool: you're still running an automated session against a bank that has updated its ToS to prohibit AI agents. The CDP fingerprint is still present. These are hard limits of the Playwright-based approach — not things your architecture can fix. The honest framing is: this is as safe as a self-hosted Playwright bank agent can be, and that ceiling is below "fully compliant."
For personal use, occasional runs, on your own accounts: the practical risk is low. Chase's automated detection is tuned to commercial-scale access patterns, not an individual downloading their own statements monthly. The keepalive and real Chrome reduce the signal further. You've downloaded 133 statements across 14 accounts without incident — that's evidence the risk is manageable, not zero.
If you share this with your colleague, flag both the ToS and the CDP detection risk explicitly. Their account, their risk profile. The setup wizard should probably include a one-line note about Chase's automated-access policy — not to scare them off, but so they can make an informed call.