Squirrel Stash 隱私權政策

最後更新 / Last updated: 2026-06-28 · App 版本 / version: 1.0.0+

本文件以繁體中文為主,English follows below。兩個版本內容等價,若有衝突 以英文版為準(App Store / Play Store 審查依據)。

繁體中文版

1. 我們是誰

「Squirrel Stash(松鼠票夾)」是一款獨立開發的票券管理 App。我們 沒有帳號系統、不需登入,您的票券、優惠券、設定預設 只儲存在您的裝置上。為了控管免費版 AI 辨識額度、防止濫用, 我們有一個最小化的 Firebase 後端服務(Cloud Functions + Firebase 匿名驗證 + Firestore):Cloud Functions 代理 AI 請求與獎勵式廣告 / 預算檢查,並只記錄一個匿名 Firebase Auth UID與 AI 使用量/ 廣告獎勵/預算計數——不含您的票券內容, 也不含姓名、email 等個人資料。詳見下方說明。

2. 我們收集哪些資料

類別 內容 儲存位置 是否離開您的裝置
票券 / 優惠券資料 標題、條碼、到期日、備註、自訂分類 本機 Hive 資料庫(AES-256 加密)
票券截圖 您拍照或從相簿匯入的票券圖片 本機檔案系統(App 私有目錄) 僅在使用 AI 辨識時上傳;上傳前會自動遮罩條碼(見第 3 節)
eSIM LPA 字串 電信商提供的 eSIM 啟用字串 本機 Hive(AES-256 加密) 否(安裝時透過 OS 系統 URL 啟動)
付費 / 訂閱資料 Squirrel Pro 權益狀態:方案、到期日、產品 ID;訂閱驗證所需的最小平台資料 本機 SharedPreferences;Apple / Google IAP;Firebase Functions / Firebase custom claims 購買由 Apple / Google IAP 處理;為驗證或還原 Pro 權益,App 可能將必要訂閱驗證資料送到 Squirrel 控制的 Firebase Function,並以匿名 Firebase Auth UID 更新 custom claim / 權益中繼資料
App 使用記錄 v1.0 上架版本不啟動 telemetry SDK,不收集使用事件
崩潰報告 v1.0 上架版本不啟動 telemetry SDK,不收集遠端崩潰報告
帳號識別 我們不要求註冊帳號,不會收集 email、電話、姓名
匿名 Firebase UID Firebase 匿名驗證建立的 UID,用於驗證 Cloud Function 呼叫、AI 使用量 / 廣告獎勵 / 預算計數與訂閱權益中繼資料 Firebase Auth / Firestore / Firebase custom claims 是;這是 App 功能與防濫用用途,不是廣告追蹤,也不是 Squirrel Stash 自建的裝置識別碼
廣告 ID / 裝置 ID Free 使用者啟動 AI 辨識並選擇廣告支援解鎖時,獎勵式廣告供應商可能依其 SDK 與平台政策處理廣告或裝置識別資訊(例如 ATT 同意後的 IDFA)。Squirrel Stash 不建立自己的裝置識別碼。 第三方廣告供應商;Squirrel Stash 自身不儲存自建裝置 ID 僅限您主動選擇廣告支援解鎖時;我們不把票券內容、圖片、分類名稱、條碼或 AI 辨識結果提供給廣告供應商做投放
位置資訊 不收集

3. 圖片辨識(AI VLM)— 關鍵說明

當您使用「拍照新增票券」或「AI 辨識」功能時,App 會將圖片送到第三方 AI 模型供應商以辨識票券資訊(標題、到期日、商家名稱等)。

3.1 條碼遮罩

我們在上傳前會用本機程式自動偵測並用黑色方塊覆蓋圖片中的所有 條碼 / QR Code 區域。這個動作完全在您的裝置上發生,不需要您 手動操作。

遮罩流程(概念虛擬碼,僅作說明用):

function maskBarcodes(image):
    barcodes ← detectBarcodes(image)        # 本機 ML 模型,不上雲端
    if barcodes is empty:
        return image (no masking needed)
    canvas ← decode(image)
    for each barcode in barcodes:
        bbox ← barcode.bounds + 8px padding  # 涵蓋條碼 quiet zone
        canvas.fillRect(bbox, color=BLACK)   # 純黑覆蓋
    return encodeJpeg(canvas, quality=90)

偵測失敗或像素填充失敗時,App 會中止上傳而非送出未遮罩 的原圖(強制中止,不降級)。

目的:條碼是您的票券價值載體(兌換碼、eSIM LPA、會員號碼、付款 QR), 遮罩後即使 AI 供應商保留圖片,也無法用來盜用您的票券。

3.2 我們會把圖片送到哪裡

供應商 模型 用途 隱私政策 資料保留
OpenAI gpt-5.4-mini Free 票券 / 優惠券 / eSIM 圖片辨識 + 圖片種類判定;Pro fallback openai.com policy API 預設 30 天保留、不訓練
OpenAI gpt-5.4 Pro 票券 / 優惠券 / eSIM 圖片辨識主模型 同上 同上

我們不使用 OpenRouter / Google AI Studio / Groq 等其他第三方 推論供應商。所有 AI 影像辨識皆透過 Squirrel 控制的 Firebase Cloud Function 代理到 OpenAI API;App 用戶端不內嵌 OpenAI API key。Cloud Function 會用匿名 Firebase Auth UID 進行額度 / 獎勵式廣告 / 成本控管,但不儲存您的票券內容。

我們無法控制 OpenAI 的政策變更。Squirrel Stash 提供 的條碼遮罩是一道防線,但您仍應評估自身敏感資料的風險。如果您不希望 任何圖片離開裝置,請不要使用 AI 辨識功能,改用手動 輸入或條碼掃描(這兩個功能完全在本機運作)。

3.3 隨同圖片傳輸的內容

為了讓 AI 模型給出更準確的分類結果,圖片之外 我們會在 prompt 中夾帶

我們不會傳輸

4. 本機資料安全

5. 您的權利(GDPR / 台灣個資法)

5.1 存取 / 匯出

您隨時可以透過「設定 → 備份」匯出所有資料(加密 ZIP 檔)。

5.2 修改

所有資料皆可在 App 內直接編輯。

5.3 刪除

「設定 → 清除所有資料」會永久刪除所有本機票券、優惠券、截圖、設定, 並 cancel 所有通知排程。

操作流程:

  1. 點擊「設定 → 清除所有資料」紅色按鈕
  2. 在彈出對話框中輸入「刪除」二字啟用確認鈕
  3. 點擊「清除所有資料」立即執行

明確會清除:本機 Hive boxes、所有截圖目錄、多數 SharedPreferences 設定、所有已排程的通知。

明確保留(白名單機制):

注意 1:刪除本機資料不會回溯刪除過去送給 AI 供應商的圖片副本。如需向各供應商請求刪除,請參考其隱私政策。

注意 2:「設定 → 清除所有資料」是本機票券 / 優惠券 / 截圖 / 設定的刪除入口。若您也要要求刪除伺服器端以匿名 Firebase Auth UID 保存的 AI 使用量、獎勵式廣告 / 預算計數或訂閱權益中繼資料,請透過 support@squirrelwallet.app 聯絡我們;因為本 App 沒有帳號系統,若無法對應到特定匿名 UID,我們可能無法辨識您的伺服器端紀錄。

5.4 付費 / 訂閱

Squirrel Pro 透過 Apple App Store / Google Play 的 In-App Purchase 流程購買與還原。Squirrel Stash 不營運自己的付款處理系統,也不接收信用卡號或商店帳號密碼。為了驗證 / 還原 Pro 權益,App 可能將必要的 Apple 訂閱 claim / 平台驗證資料送到 Squirrel 控制的 Firebase Function,並以匿名 Firebase Auth UID 更新 Firebase custom claim / 權益中繼資料;App 也會在本機保存必要的訂閱狀態(方案、到期日、產品 ID)以顯示權益與離線判斷。

6. 兒童隱私

本 App 不刻意收集 13 歲以下兒童的資料。若我們發現意外收集,將立即刪除。

7. 政策變更

本政策若有重大變更,會在 App 內顯示提示,並更新本頁的 "Last updated" 日期。

8. 聯絡我們


English

1. Who we are

Squirrel Stash is an indie ticket / coupon management app. We have no account system and no login — your ticket / coupon data is stored on your device by default. To enforce the free-tier AI-recognition quota and prevent abuse, we do run a minimal Firebase backend (Cloud Functions + anonymous Firebase Auth + Firestore): Cloud Functions proxy AI requests and reward / budget checks, and record only an anonymous Firebase Auth UID plus AI-usage, ad-reward, budget counters, and subscription entitlement metadata — never your ticket contents, and never personal data such as your name or email. See below for details.

2. What data we touch

CategoryContentStorageLeaves device?
Tickets / CouponsTitles, barcodes, expiry, notes, custom categoriesLocal Hive DB (AES-256 encrypted)No
Ticket screenshotsPhotos you take or importLocal app-private dirOnly when AI recognition is invoked; barcodes are masked first (§3)
eSIM LPACarrier-provided activation stringLocal Hive (AES-256 encrypted)No (OS handles installation)
Paid purchases / subscriptionsSquirrel Pro entitlement status: plan, expiry, product ID; minimal platform data needed for subscription validationLocal SharedPreferences; Apple / Google IAP; Firebase Functions / Firebase custom claimsPurchase is processed by Apple / Google IAP. To validate or restore Pro access, the app may send necessary subscription validation data to a Squirrel-controlled Firebase Function and update custom claims / entitlement metadata keyed by the anonymous Firebase Auth UID.
Usage analyticsNot collected in the v1.0 launch build; telemetry SDKs are not initialisedNo
Crash reportsNot collected in the v1.0 launch build; telemetry SDKs are not initialisedNo
Account IDsWe do not require sign-up
Anonymous Firebase UIDA UID created by Firebase anonymous auth to key AI-usage, ad-reward, budget counters, and subscription entitlement metadataFirebase Auth / Firestore / Firebase custom claimsYes; this is for App Functionality and abuse prevention, not ad tracking, and it is not a Squirrel-created device identifier
Ad IDs / Device IDsWhen a Free user starts AI recognition and chooses the ad-supported unlock, the rewarded-ad provider may process advertising or device identifiers under its SDK and platform policies (for example IDFA after ATT consent). Squirrel Stash does not create its own device identifier.Third-party ad provider; Squirrel Stash does not store its own device IDOnly when you choose the ad-supported unlock; we do not share wallet contents, images, category names, barcodes, or AI recognition results with ad providers for ad targeting
LocationNot collected

3. AI Recognition (VLM) — Important Disclosure

When you use the "scan ticket via AI" feature, the app sends an image to OpenAI to extract ticket metadata (title, expiry, merchant).

3.1 Barcode masking

Before any upload, the app automatically detects and blacks out every barcode / QR code in the image on-device. This happens entirely on your device — no manual action required.

Masking flow (conceptual pseudocode, illustrative only):

function maskBarcodes(image):
    barcodes ← detectBarcodes(image)        # local ML model, never leaves device
    if barcodes is empty:
        return image (no masking needed)
    canvas ← decode(image)
    for each barcode in barcodes:
        bbox ← barcode.bounds + 8px padding  # cover the barcode quiet zone
        canvas.fillRect(bbox, color=BLACK)   # solid black fill
    return encodeJpeg(canvas, quality=90)

If detection or pixel-fill fails, the app aborts the upload rather than degrading to the unmasked original. There is no fallback path that sends the original image when masking partially fails.

Rationale: barcodes carry the value of the ticket (redemption codes, eSIM LPA, membership numbers, payment QRs). Masking ensures that even if the provider retains the image, it cannot be used to redeem your tickets.

3.2 Where the masked image goes

ProviderModelUsePrivacy policyRetention
OpenAI gpt-5.4-mini Free ticket / coupon / eSIM image extraction + image-kind classifier; Pro fallback openai.com policy API default 30-day retention, no training
OpenAI gpt-5.4 Pro ticket / coupon / eSIM primary extraction model same as above same as above

We do not use OpenRouter / Google AI Studio / Groq or any other third-party inference provider. All AI image recognition is proxied to the OpenAI API through a Squirrel-controlled Firebase Cloud Function; the app client does not embed an OpenAI API key. The Cloud Function uses the anonymous Firebase Auth UID for quota, rewarded-ad, and cost controls, but does not store your ticket contents.

We do not control OpenAI's policy changes. Barcode masking is one line of defence — you should still assess the sensitivity of your data. If you prefer no image ever leaves your device, do not use AI recognition; use manual entry or barcode scanning instead (both run entirely on-device).

3.3 What travels with the image (and what doesn't)

To help the model classify accurately, the prompt does include:

The prompt does NOT send:

4. Local data security

5. Your rights (GDPR / TW PDPA)

This does not retroactively delete image copies that AI providers may retain per their own policies. Contact each provider for their deletion process. Settings → Reset all data is the deletion entry point for local data; contact support@squirrelwallet.app for deletion requests covering identifiable server-side anonymous Firebase records.

6. Children's privacy

This app does not knowingly collect data from children under 13. If we discover such collection, we will delete it.

7. Changes to this policy

Material changes will be announced in-app and the "Last updated" date above will be revised.

8. Contact