Security & Data Transparency
Last updated: September 27, 2026
IAG Journal is built local-first: your trades, fills, P&L, and balances live in a database on your computer. This page explains what that means in practice, what the cloud account is for, and how a technical user can independently verify the shipping macOS app — using free tools and observable evidence.
This is not a legal policy. For what we collect and how we use it, see our Privacy Policy.
The short version
- Your trading data stays in a local database on your machine. We never receive trades, fills, P&L, or balances.
- Broker credentials (when you use AutoSync) are stored in your OS keychain on that machine — not sent to IAG servers.
- The cloud account holds email, subscription/entitlement status, and device-link metadata so Leather Edition can sign you in and stay paid.
- Payments go through Stripe. We never see or store your full card number.
- TastyTrade AutoSync talks Mac → tastytrade directly (read-only OAuth). Brokerage data is not proxied through IAG.
- Brokers connected through SnapTrade talk your device → SnapTrade with a read-only OAuth grant you approve in your own SnapTrade account; the token stays in your device's secure store, and IAG servers never see it or the data fetched with it.
- No third-party advertising or analytics trackers on the website.
What leaves your machine vs. what never does
Stays on your device
- Imported and synced trades
- Positions, P&L, balances, charts
- CSV files you import
- Broker API credentials (OS keychain; if the OS store refuses, an owner-only file in the data folder — see the Privacy Policy)
- Journal notes (local)
Cloud / processors (limited)
- Email for login-code sign-in
- Subscription / entitlement status
- Per-device: install id, hostname label, app version, platform, last-seen
- Stripe billing metadata (not full card)
- Feedback / diagnostics you choose to send (previewed first)
- Watchlist: your custom tickers and add/hide events — unless you turn off Settings → Watchlist → “Share watchlist activity with IAG”, which stops all of it
Published service stack (see Privacy for detail): Supabase (auth & account DB), Stripe (payments), Vercel (site & API), Resend (transactional email), GitHub (installer hosting).
Independent verification checklist (macOS)
Below is a step-by-step protocol for verifying code identity, the local-first architecture, and the safety of TastyTrade AutoSync. No trust required — every claim gets tested.
Origin.Executed in full against the shipping build in July 2026 by a subscriber (iOS engineer / options trader) prior to connecting a live brokerage account. All checks passed. Reference results are included so you know what “pass” looks like.
Time. ~90 minutes, mostly passive monitoring. Tools. Terminal (built-in), LuLu (free, open-source firewall from Objective-See), and a web browser.
What has changed since that run.The run was executed against the 1.x desktop; the protocol and the claims under test still stand for Journal 2.0, but several observations read differently on current builds, so the reference results below have been updated where they moved. Sign-in no longer hands off to your web browser — you type a short emailed code into the app, so step 7 produces no browser callback at all (the app still never handles a password, and the code is stored server-side only as a hash). The Leather features added since the run — Market Awareness, Smart Watchlist, and IAG Read — periodically fetch a shared, non-personal dataset from the same account backend already listed below. Those fetches are requests for the shared brief or watchlist snapshot; your trades, positions, and P&L are not part of them. Three things do travel outbound from these features, and all are worth naming: a thumbs up / thumbs down you click on a market brief; the ticker symbols you add, hide, or unhide on the Watchlist (popularity signals for the shared list); and the custom tickers you follow, which the app asks the backend to compute scores for. The last two are on by default and are both switched off by Settings → Watchlist → “Share watchlist activity with IAG”, after which nothing about your watchlist leaves the device; none of it ever carries a position, size, or P&L. 2.0 also fetches market reference data directly from two named third parties — underlying prices from Yahoo Finance (the tickers in your journal or watchlist, with date ranges) and USD/CAD rates from the Bank of Canada — so idle observation shows more destinations than the two-row 2026 table did; the updated table below lists what each one is. Step 9, the CSV-import litmus test, is unaffected and remains the check that matters.
Prefer the original artifact? Download the checklist (PDF).
Phase A — Verify the binary (before granting anything)
Claim under test: the app you downloaded is the app the developer built, signed by a verified identity, and scanned by Apple.
- Install the app by dragging it to /Applications and eject the DMG. Always run from Applications — running from the mounted disk image triggers macOS app translocation and breaks updates.
- Verify the code signature (the 2.0 app's name contains spaces, so keep the quotes):
codesign -dv --verbose=4 "/Applications/Investing Against the Grain Journal.app"Pass: Authority=Developer ID Application: Daniel Lemmon (C86X522W2S) (Apple identity-verified developer certificate) and flags=0x10000 (runtime) (hardened runtime enabled).
- Verify Apple notarization:
spctl -a -vv "/Applications/Investing Against the Grain Journal.app"Pass: accepted + source=Notarized Developer ID— Apple's notarization service scanned this exact build for malware.
Fail conditions (stop and contact support): unsigned or ad-hoc signature, a different signer identity, or rejected from spctl. Re-run the notarization check after every fresh download — it takes five seconds and re-verifies the supply chain.
Phase B — Watch the network (the local-first claim)
Claim under test:“Your trades never leave your machine.”
- Quit IAG Journal completely. Install LuLu and approve its network extension (System Settings → General → Login Items & Extensions → Network Extensions → enable LuLu → allow the filter prompt).
- Configure LuLu (menu bar icon → Settings):
- Mode: Passive Mode OFF (you want alerts)
- Rules: uncheck“Allow Already Installed Programs” — critical; if left on, LuLu silently whitelists the app and the test observes nothing
- Rules: “Allow Apple Programs” ON; DNS + localhost allowed
- View Rules → delete any pre-existing rules for the app
- Launch IAG Journal and record every alert bearing its name. For each alert, expand Details & Options and use the process-ancestry icon to confirm the connection truly originates from the app.
Reference result (2.0):the app's account/entitlement backend, port 443. Depending on your journal you may also see Yahoo Finance (underlying prices for your tickers) and the Bank of Canada (USD/CAD rates, only when the journal holds non-USD trades) — both read-only reference-data fetches from the table below. - Sign in when prompted: request a login code, read it from your email, and type it into the app.
Reference result (2.0): no browser hand-off and no localhost callback — the app never handles a password, and the only traffic is to the backend that verifies the code. No new destinations. - Let the app idle 15+ minutes.
Reference result (2.0): not silence, but nothing new — a lightweight update check to the same backend roughly every 30 minutes, and (only once a broker is connected) AutoSync polls the broker on the interval you chose, hourly by default. Every idle connection should map to the table below; anything else deserves a question. - The litmus test — CSV import. Import a transaction CSV while watching LuLu.
Pass: zero new outbound connections at the moment trade data enters the app. Trade data renders from the local database with no network involvement — observable proof of the local-first claim. - Identify every destination you allowed. LuLu often shows a bare IP (many cloud hosts publish no reverse DNS — normal). Look up ownership at ARIN: search.arin.net/rdap.
| Destination (2.0) | Registrant / owner | Purpose · when |
|---|---|---|
| iagjournal.com | Vercel, Inc. | Account / entitlement backend, update check (~30 min), shared watchlist & market briefs · launch + idle |
| api.tastyworks.com | tastyworks, Inc. | TastyTrade AutoSync — direct to broker · on the sync interval, after Phase D |
| query1.finance.yahoo.com | Yahoo | Underlying prices for your tickers · when charts / replay / 0DTE need them |
| bankofcanada.ca | Bank of Canada | USD/CAD rate series · only when the journal holds non-USD trades |
| github.com | GitHub, Inc. (Microsoft) | Downloading app updates · when an update is staged |
| (your other brokers) | IBKR · Schwab · SnapTrade | AutoSync — direct from your device, only for brokers you connect |
Any destination that doesn't map to this table (or to Supabase / Stripe per the Privacy Policy) deserves a question before allowing. In particular, brokerage sync traffic terminating anywhere other than the broker (or SnapTrade, for brokers connected through it) would contradict the direct-to-broker claim — that is exactly what this protocol exists to catch.
Tip: when creating allow rules, choose Endpoint scope rather than Process scope. Process-scope rules whitelist all future destinations for the app, which blinds later observations.
Phase C — Data at rest
- Confirm the database is local:
ls ~/Library/Application\ Support/ | grep -i iagReference result: iag-journal — your trades live in that folder, on your disk.
- Confirm full-disk encryption:
fdesetup statusPass: FileVault is On. If not, enable it before importing brokerage data — the local database is the asset the local-first model protects, and it flows into Time Machine backups too.
Phase D — TastyTrade AutoSync (the credential decision)
Claims under test: the app never sees your password, access is read-only, and brokerage data flows direct to tastytrade — not through IAG servers.
- Follow the in-app AutoSync instructions to create a personal OAuth client at tastytrade. At the scope screen: check read only. Leave trade unchecked. This is enforced server-side by tastytrade — a read-only token is architecturally incapable of placing orders, no matter who holds it.
- Store the client_secret and refresh_token in a password manager only (shown once; never in notes / files / screenshots).
- Paste into IAG Journal and connect. Per the app's guidance, set the backfill start date appropriately if you've already imported history via CSV.
- Post-connect verification (three checks):
- Traffic: the sync fires a new LuLu alert. Identify the IP via ARIN. Pass: registrant is tastyworks, Inc. — your brokerage data goes Mac → tastytrade, direct. Fail (revoke immediately):sync traffic terminating at the app vendor's own infrastructure would mean brokerage data proxying through their servers.
- Keychain:open Keychain Access, search “iag”. Reference result: iag-journal-tt entries in the login keychain (local, FileVault-protected, not iCloud-synced).
- Kill switch:tastytrade → Manage → My Profile → API → Manage OAuth Grants — confirm your grant is listed. That page revokes the app's access instantly and unilaterally. Know where it is.
Ongoing posture
- Leave LuLu resident. Any new destination from the app after an update gets identified (ancestry → ARIN) before allowing.
- After each app update: re-run the spctl check (step 3) and glance at LuLu.
- The read scope is permanent. Treat any future request to expand permissions as a fresh security review.
- Keep your own system of record. A journal is an analytics layer; your data discipline shouldn't depend on any one tool.
Verdict from the July 2026 run
Signed and notarized binary · two total network destinations across launch, login, hours of idle, CSV import, and live sync · zero traffic correlated with trade data entering the app · sync direct-to-broker (ARIN-confirmed) · passwordless OAuth with server-enforced read-only scope · credentials in the local keychain · unilateral revocation available at tastytrade.
Every published claim was observed, not just believed. The reviewer approved connecting to a live account. (That run tested the 1.x build; on Journal 2.0 the same protocol passes with the updated reference results above — more named destinations, each accounted for, and the same zero-traffic result on the step that matters, CSV import.)
Contact
Questions about security, data handling, or something you observed while running this checklist? Email support@iagjournal.com.
See also our Privacy Policy and Terms of Service. Download checklist (PDF).