公開文件
AegisMeetings 零知識加密架構白皮書
本文件向任何讀者公開說明架構、威脅模型與保證邊界;設計以開放密碼學標準為基礎,歡迎獨立檢視。完整技術敘述見下方正文。
版本 1.18
發布日期 2026-05
公開版,不含實作細節
版本:1.18(2026-05 修訂:與現行實作對齊——檔案上傳與即時錄音分片皆於瀏覽器端加密後,透過 SAS 授權直連 Microsoft Azure Blob 寫入,不經 Web/API 應用程式 VM 承載或轉存明文音訊。轉錄與 AI 產出之 逐字稿、摘要、重點、待辦 以合併 密封 bundle 為主體;在 V5 管線下 優先以密文形式存放於 Azure Blob,受管資料庫之 meeting_assets 主要保存 storage_path、content_length、blob_sha256(及可選 ETag) 等指標,encrypted_content 不寫入整包大塊密文。歷史會議或過渡路徑若仍含舊欄位資料,以實際資料列為準。)
發布日期:2026-04(修訂 2026-05) 文件性質:公開版(不含實作細節)
🌐 本地化說明(Localization Note):
- 密碼學術語(AES、RSA、XChaCha20 等)不翻譯,全語言版本保留英文原名
- 「零知識」在各語系的法規對應術語:日文
ゼロ知識、韓文제로 지식、德文Zero-Knowledge、法文zéro connaissance- 「誠實窗口期」為 AegisMeetings 自創術語,原意為 Honest Processing Window。指音檔進入加密運算環境後至物理抹除前的唯一明碼作業時段。此期間數據僅於記憶體流動,確保處理過程透明且不留痕跡。
摘要(Executive Summary)
AegisMeetings 是為會議設計的零知識 SaaS 平台。「零知識」意味著:即便是 AegisMeetings 的工程師、系統管理員,或伺服器遭到入侵的攻擊者,都無法讀取您的會議音檔、逐字稿或 AI 摘要。
這不是一個行銷聲明,而是一個密碼學設計保證:系統架構從根本上阻止了服務提供者接觸使用者內容的可能性,而非依賴存取控制政策或員工操守。
本文件說明我們如何實現這項保證、以及這項保證的邊界在哪裡。
與 E2EE 的差異:AegisMeetings 採用「零知識加密儲存架構」,而非端對端加密(E2EE)。兩者的關鍵差異在於 AI 轉錄:我們的轉錄主機在處理期間需要短暫接觸明文音訊(我們稱為「誠實窗口期」)。我們不隱瞞這一點——若不如此,AI 功能便無從實現。除此窗口期外,所有儲存資料連我們自己也無法讀取。
一、核心設計原則
1-1. 金鑰不離開您的裝置
您的加密金鑰(RSA-4096 主私鑰)由您的瀏覽器在您的裝置記憶體中生成,從未傳送至我們的伺服器。
- WebAuthn PRF 路線(具備 Face ID / 指紋 / Windows Hello 等、且瀏覽器支援 PRF 擴充之裝置):金鑰的衍生材料綁定於裝置硬體(安全晶片 / TPM)。攻擊者即便取得您的電腦,也必須通過您的生物辨識或 PIN 驗證,才能衍生出解鎖私鑰所需的對稱金鑰——軟體層面的攻擊無法繞過這道硬體屏障
- Argon2 密碼路線(降級方案,適用於不支援或無法使用 WebAuthn PRF 硬體衍生之環境):除您設定的金庫密碼與伺服器下發之 Salt 外,瀏覽器會在本機 IndexedDB 內產生並保存一組僅存於該瀏覽器設定檔的裝置秘密(device secret);用於保護私鑰的對稱金鑰由 Argon2id(128MB 記憶體成本)衍生,且 Argon2 的鹽值會與上述裝置秘密經密碼學方式混合。因此僅有密碼、而沒有該瀏覽器上的裝置秘密,無法還原私鑰——可避免「攻擊者同時竊得伺服器密文與使用者密碼即可在任意電腦解密」的風險。此為刻意設計:在無硬體安全晶片路線可用時,將解密能力綁定至使用者已授權之瀏覽器儲存空間(較純密碼、可任意跨瀏覽器輸入即解密之模型,安全性顯著提高)
我們的伺服器只儲存「被您的金鑰鎖住的保險箱」,永遠拿不到鑰匙。
1-2. 伺服器只搬運密文(加密邊界摘要)
資料進入系統可粗分兩段:① 瀏覽器 → Azure Blob(密文上傳/即時分片) 與 ② 音檔轉錄主機群於誠實窗口期內處理 → 密封產出寫回 Blob 並回報指標(見 §1-3)。
- ① 上傳與即時錄音:不論整檔上傳或即時錄音之分片,音訊皆在您的裝置上以 libsodium crypto_secretstream(底層為 XChaCha20-Poly1305 之串流封裝,區塊式 AEAD)加密;瀏覽器持 SAS 將密文 直寫 Microsoft Azure Blob。網站與 API 主機(Web VM)不接觸明文音訊,僅處理上傳完成之中繼資訊,以及一把以轉錄主機公鑰鎖住、Web 身分無法解開的音檔金鑰包裹。
- ② 處理與入庫:僅隔離之音檔轉錄主機群在誠實窗口期內可解密並執行 AI;產出之逐字稿、摘要、重點與待辦等經 密封 bundle 後,由 Worker 寫入 Azure Blob(V5 主存)。隨後以 內部 HTTPS Webhook 通知 Web 層,payload 僅含 Blob 路徑、長度、完整性雜湊(及可選 ETag)等指標,由 Web 寫入受管資料庫(例如
meeting_assets.storage_path等),不夾帶整包密文大塊。對稱金鑰材料以您裝置之 RSA 公鑰包成wrapped_keys(通常仍存於資料庫)。逐字稿不在瀏覽器產生;明文僅在窗口期內存在於轉錄主機之處理記憶體與暫存檔生命週期內(見 §1-3、§1-4)。
完整元件如何串接、何者走內網,以讀者友善、去識別化之營運資料流圖統一說明於 §1-4(避免與下節密碼學演算法表重複敘述)。
系統最終儲存的密文(靜態面)
| 資料 | 存放位置 | 內容 | 誰能解讀 |
|---|---|---|---|
| 音檔(整檔或即時分片) | Azure Blob Storage | 加密密文(例如 original.enc、play/.../chunk_*.enc) |
只有持有您私鑰的裝置 |
| 逐字稿、摘要、重點、待辦(合併密封 bundle) | Azure Blob(主存);資料庫存指標 | V5:asset_role = sealed_transcript_bundle,密文於 Blob;DB 存 storage_path、content_length、blob_sha256 等 |
只有持有您私鑰的裝置 |
對稱金鑰材料(wrapped_keys) |
資料庫 | 以您的 RSA 公鑰鎖住;含音檔/串流/HLS/逐字稿等欄位 | 只有持有您私鑰的裝置 |
伺服器(含資料庫、Blob 儲存)所見的靜態內容,皆為「沒有對應私鑰即無法解讀之密文」(或僅為路徑/雜湊等不可還原之中繼指標)。
1-3. AI 處理的誠實窗口期(The Honest Processing Window)
我們對一個技術現實保持誠實:AI 轉錄需要聆聽明文音訊。以下措施旨在最小化文件開頭「本地化說明」所定義之誠實窗口期(Honest Processing Window)的暴露面與殘留風險:
- 轉錄主機與 Web 伺服器職責分離;轉錄主機專用解密密鑰僅能由轉錄主機執行身分經雲端金鑰保管服務(例如 Azure Key Vault)讀取,Web 應用身分在權限設計上不可讀取該等機密
- 解密後之音訊於轉錄主機上僅以暫存檔形式存在於處理期間(常見部署下
/tmp掛載於記憶體型檔案系統);處理完成即刪除暫存檔,不將明文音檔作為持久檔留存 - AI 處理完成後,敏感緩衝區依設計執行安全清零(例如 libsodium
sodium_memzero);送交 Web 層之 webhook 僅攜帶 Blob 指標與允許之中繼資料;密封 bundle 之本體已寫入 Blob(見 §1-2 表) - 轉錄主機停用 swap,降低記憶體內容被換出至磁碟之風險
依 Microsoft Azure 公開的資料隱私政策(Azure OpenAI Data Privacy),Azure OpenAI 服務不會將客戶提交的資料用於改善或訓練 Microsoft 的基礎模型。提交的資料可能依 Microsoft 標準政策於伺服器端保留最多 30 天,用於濫用偵測(Abuse Monitoring),期滿自動刪除,且僅受 Microsoft 內部人員存取管制。
1-4. 從上傳到轉錄:營運資料流(去識別化圖)
以下圖示不標示內部 IP、訂用帳戶 ID、資源實際名稱,方便一般讀者理解;與 §2 密碼學演算法表互補(本節重「誰與誰說話」與「何時為密文」,§2 重「用哪種演算法」)。
使用者瀏覽器
│ HTTPS(傳輸層加密)
▼
[網站與 API 主機(Web)] … 與網站頁面同一企業內部虛擬網路區段
│
├─① 音檔密文 … 以有時效之上傳授權(SAS)**直傳**雲端物件儲存(不經 Web 記憶體保存明文音檔)
│ ↑ 物件儲存經 **私人網路連線(Private Endpoint)** 接入內網
│
├─② 寫入受管資料庫:會議狀態、密文路徑、中繼欄位(**私人網路連線**)
│
├─③ **內網快取/協調服務(Redis,TLS)** … 例如避免同一會議被重複排程之協調(SETNX 等)
│
├─④ **容量與排程協調(應用程式元件)** … 當有新轉錄需求時,依政策喚起或擴充「**音檔轉錄主機群**」之台數(呼叫雲平台 **管理平面 API**,走加密骨幹網路,非使用者瀏覽器直連)
│
└─⑤ **雲端訊息佇列**(依方案分流:一般/優先/VIP)… 寫入轉錄任務;轉錄主機以 **Pull + 鎖定** 領取並續租,避免重複處理
[音檔轉錄主機群(自動擴充)] … 獨立內網區段,出站受網路安全群組白名單管制
│
├─⑥ 自訊息佇列 **PULL** 任務(連線與憑證由轉錄身分讀取,與 Web 身分分離)
│
├─⑦ 同上 **內網快取/協調(Redis)** … 例如叢集內最多同時幾台搶佇列之座位(seat)協調
│
├─⑧ 自物件儲存 **下載密文音檔** → 於主機上短暫解密為暫存檔 → **轉錄管線讀取暫存檔**(處理完 **刪除暫存檔**;不在磁碟留存可播放之明文音檔)
│
├─⑨ **FunASR 等語音模型**於轉錄主機記憶體內執行(模型檔於**映像打包階段**預裝;行程啟動時載入;**不在**每台 VM 開機時重跑大型 `conda clean` 類維護——該類清理應於**打包映像時**完成)
│
├─⑩ **受管大語言服務(HTTPS)** … 產生摘要等文字;傳輸層加密;**送出者為轉錄主機**,非一般使用者瀏覽器直連
│
└─⑪ **內部 HTTPS Webhook** → 回到 [網站與 API 主機(Web)] 之內部 API 路徑(攜帶一次性或內部驗證;**僅 Blob 路徑、長度、SHA-256/ETag 等指標**)。Web 更新資料庫內會議資產之 **Blob 指標**;**密封 bundle 密文已於步驟前置寫入 Azure Blob**
[網站與 API 主機(Web)收到 ⑪ 後]
└─ 寫入/更新 `meeting_assets` 等結構(指標與完整性欄位);**使用者裝置**仍須以自有私鑰於瀏覽器端解密閱讀(零知識邊界不因轉錄完成而改變)
圖中編號與加密邊界對照(摘要)
| 編號 | 大致內容 | 此階段音檔/逐字稿多為 |
|---|---|---|
| ①②⑤⑥⑧ | 上傳、排程、佇列、下載 | 密文為主;⑧ 於轉錄主機上短暫解密 |
| ③⑦ | 協調/鎖 | 不含音檔內容;控制面資料 |
| ④ | 擴縮轉錄叢集 | 無使用者音檔內容 |
| ⑨ | 語音轉文字 | 誠實窗口期內之明文處理(暫存檔 + 記憶體) |
| ⑩ | 摘要等 LLM | 以已轉出之文字為輸入;仍屬窗口期內之雲端運算 |
| ⑪ | 回寫 Web | Webhook payload 經內部 TLS;主存為 Blob,DB 入庫以 指標與完整性欄位 為主 |
與目前程式實作對齊(不含密鑰、不含內部位址)
- 瀏覽器端加密上傳與 libsodium secretstream(XChaCha20-Poly1305)、RSA-OAEP 包裹音檔金鑰:與前端金庫/上傳模組及 ADR 一致。
- Web 層佇列與 Redis 鎖、轉錄主機 Redis seat:與 Laravel 佇列/快取及 Python Worker 之 PULL + seat 設計一致。
- 「容量與排程協調」對應
AzureWorkerService(Laravel):在上傳或佇列有任務時向雲平台申請增加轉錄主機台數;閒置時依政策縮減,不處理音檔內容,只調整運算容量。 - 訊息佇列、Blob、受管 LLM:分別對應程式碼中的 Service Bus、Azure Storage SDK、Azure OpenAI HTTP 呼叫路徑。
- 轉錄主機 main.py:模組載入時即 預載 FunASR 四模型(映像內路徑);處理單筆音檔時使用 暫存檔 + 處理完刪除;摘要與進階文字處理於 Worker 記憶體內完成後經 webhook 回傳。
二、密碼學架構(演算法與金鑰;與 §1-4 營運流互補)
本節保留演算法選型與金鑰階層之技術定義,供稽核與同業驗證;各雲端元件如何串接請以 §1-4 為準,避免與上節文字重複。
2-1. 演算法選型
| 用途 | 演算法 | 選用理由 |
|---|---|---|
| 主金鑰對 | RSA-4096 OAEP | 業界標準,可在所有主流瀏覽器原生執行 |
| 私鑰靜態保護 | AES-256-GCM | 硬體加速,NIST 標準 |
| 音檔上傳密文(瀏覽器) | libsodium secretstream(XChaCha20-Poly1305) | 串流封裝、大 nonce 空間,適合大型音檔分塊加密 |
| 逐字稿等 Worker 產出密文 | XChaCha20-Poly1305(含 secretstream 等封裝) | 與上傳鏈路一致之 libsodium 管線;細節見內部 ADR |
| 金鑰衍生(密碼路線) | Argon2id | 2015 Password Hashing Competition 冠軍,抵抗 GPU 及 ASIC 暴力破解 |
| 裝置綁定(硬體路線) | WebAuthn PRF | W3C 標準,金鑰衍生材料由裝置安全晶片產生,無法在沒有物理驗證的情況下衍生 |
| 裝置綁定(密碼/降級路線) | Argon2id + 瀏覽器端裝置秘密 | 與伺服器 Salt 混合後衍生 AES 金鑰;密碼與經授權之瀏覽器 IndexedDB 內秘密缺一不可,伺服器不持有裝置秘密 |
| 訊息完整性 | HMAC-SHA256 | 確保系統內部傳遞的任務訊息未遭竄改 |
| 會議子金鑰分離(上傳端) | HKDF-SHA256 | 自單一 Master 衍生 K_main(secretstream)與 K_hls(AES-128-HLS),固定 info 區隔演算法脈絡 |
2-2. 金鑰階層
使用者主金鑰對(RSA-4096)
│ ← 由使用者裝置生成,私鑰從不傳送至伺服器
│
└── 每筆會議的 wrapped_keys(多組對稱材料,以您的 RSA 公鑰打包,存於資料庫)
│
├── 瀏覽器上傳路徑:32-byte Master Secret(高熵隨機)
│ → Web Crypto **HKDF-SHA256**(RFC 5869;空 salt、固定 **info** 字串區隔用途)
│ ├── **K_main**(32B)… 音檔 secretstream;`wrapped_keys` 之 **raw**/**stream** 皆為其 Base64
│ └── **K_hls**(16B)… 瀏覽器 HLS 與轉錄主機 ffmpeg AES-128 切片;`wrapped_keys` 之 **hls**
│ (與 K_main 分離,避免同一材料跨協定重用)
│
└── 逐字稿金鑰(Transcript_AES_Key)
← 轉錄主機於 AI 處理後產生,以您的 RSA 公鑰包入 wrapped_keys
轉錄主機收到之 RSA-OAEP 綁定 JSON 含 raw_aes_key(K_main)與 hls_aes_key(K_hls,16B);瀏覽器 wrapped_keys 含對應之 hls 欄位供 HLS 播放。
關鍵特性:每筆會議使用獨立的對稱金鑰材料;即便單一會議洩漏,也不影響其他會議。上述材料皆由您的 RSA 主公鑰保護,只有您的私鑰可以解開。
瀏覽器端串流加密上傳之步驟細節已併入 §1-2、§1-4;此處不再重複 ASCII 圖以避免與公開版維護成本脫節。
三、信任邊界
我們定義了四個安全區域,以及各區域能看到和看不到的內容:
| 組件 | 可見資料 | 不可見資料 |
|---|---|---|
| 瀏覽器(您控制) | 金鑰、解密後的明文內容 | 無限制——這是您的設備 |
| Web 伺服器(我們運營) | 加密密文、元資料(會議時間、參與者帳號) | 您的音檔、逐字稿、AI 摘要的任何明文 |
| 雲端儲存(Azure Blob) | 加密檔案(對其而言是毫無意義的亂碼) | 任何可讀內容 |
| 轉錄主機(我們運營,半信任) | 誠實窗口期內的明文音訊(處理完即清除) | 歷史會議的任何資料、Web 伺服器的任何憑證 |
即便有人同時取得 Web 伺服器、資料庫、以及雲端儲存的完整存取權,他們得到的只是一堆無法解密的密文。
四、多裝置與跨瀏覽器存取
4-1. 跨裝置/跨瀏覽器授權(Out-of-Band Transfer,配對碼)
若您要在新的瀏覽器設定檔、新瀏覽器或新裝置上使用已有金庫,系統透過安全的帶外傳輸協議授權該環境(使用者介面常稱為「配對」):
- 在已解鎖且已授權的瀏覽器/裝置 A 上,於安全設定產生一組限時六位數配對碼(效期短,以產品介面為準)
- 在新環境 B 的授權流程中輸入該六位數配對碼,向伺服器領取經加密的私鑰包裹(包裹內容對伺服器不可讀)
- 包裹被成功領取後即自伺服器刪除(防止重放攻擊)
- 裝置 B 在本地解開包裹後,以該環境支援之方式重新綁定金庫(WebAuthn PRF 或 Argon2 + 該瀏覽器新產生之裝置秘密;若為密碼路線,依畫面提示一併完成金庫密碼相關步驟)
此過程中,伺服器僅扮演短暫的「加密包裹中繼站」,無法讀取傳輸中的私鑰。金庫密碼本身從不傳送至伺服器。
配對碼的密碼學強度(與金庫主密碼區分):六位數配對碼僅約 10⁶ 種組合,無法像金庫密碼一樣以高記憶體成本 Argon2id 長期支撐離線暴力嘗試。實作上,瀏覽器以 刻意較輕量之 Argon2id 參數衍生用於包裹的對稱金鑰(僅供短效、一次性領取流程),仰賴極短時效、單次領取即刪除包裹、以及伺服器端 API 限速與濫用偵測來約束線上枚舉。若需長期離線暴力抵抗,請以 Aegis Recovery PDF 或 WebAuthn PRF/金庫密碼路線為準。
4-2. 跨瀏覽器 / 跨裝置存取與降級路線之綁定範圍
您的加密私鑰以密文形式存放於我們的伺服器(每台裝置可有一筆獨立的加密設定)。還原私鑰的運算完全在您的瀏覽器內執行。
-
WebAuthn PRF 使用者(硬體路線):PRF 憑證是否可跨裝置取決於驗證器類型。使用雲端同步之 Passkey 者,可在已同步之環境間使用;使用 Windows Hello、Touch ID 等強綁定驗證器時,新裝置/新瀏覽器無法僅憑帳密解鎖,須依 4-1 節完成帶外授權,或依第五節以 Aegis Recovery PDF 復原後重新綁定。
-
Argon2 密碼路線使用者(無硬體 PRF 時之降級方案):在同一台、同一瀏覽器設定檔內,解密需要 「金庫密碼 + 該瀏覽器 IndexedDB 內之裝置秘密」。換成另一瀏覽器、另一設定檔或新裝置時,無法只靠帳號登入與金庫密碼就完成綁定——還須由已授權端取得 4-1 節之限時六位數配對碼於新環境完成授權,或使用 Aegis Recovery PDF(第五節)於本機還原後再綁定。
-
清除瀏覽器網站資料(例如透過瀏覽器設定或快捷鍵清除 Cookie/網站資料,常一併清除 IndexedDB、localStorage 等):若導致裝置秘密與本地金鑰快取一併遺失,其效果等同失去該瀏覽器上的綁定——必須使用 PDF 復原,或透過另一台已授權的裝置/瀏覽器取得新的六位數配對碼(4-1),方可於該瀏覽器重新綁定金庫。
設計意旨:降級路線在無法使用硬體安全衍生時,以瀏覽器端秘密補齊信任錨,使「僅洩漏帳號密碼與伺服器密文」不足以在任意環境解密,與本產品之零知識安全承諾一致。
我們的伺服器永遠只持有「被您的密碼+裝置/瀏覽器端條件、或硬體驗證鎖住」的密文,無法代您暴力還原金庫密碼或裝置秘密。
五、災難復原
若您遺失所有授權設備,系統提供完整的離線恢復機制:
- 首次建立金庫時,系統自動下載 Aegis Recovery PDF——強烈建議妥善保存
- PDF 包含以下內容:
- 24 字助記詞(BIP-39 相容格式,同時印在頁面上供人工核對)
- QR Code(助記詞的視覺呈現,供紙本備查)
- 完整加密私鑰(嵌入 PDF 檔案元資料,以助記詞 + Argon2id 加密保護)
- 金庫密碼(若您使用密碼路線,記錄備用;復原後於新瀏覽器重新綁定時仍須輸入,並將產生新的瀏覽器端裝置秘密)
- 恢復方式:將 PDF 檔案上傳至復原頁面,系統在瀏覽器本地自動解析 PDF 元資料並還原私鑰——PDF 內容從不傳送至我們的伺服器。完成復原後,該瀏覽器須視同新授權環境,依產品流程重新綁定;若您僅想從「已清除資料」的同一瀏覽器恢復,亦同。
⚠️ 重要說明:復原機制依賴 PDF 檔案的完整電子版。若僅列印紙本,PDF 元資料(含加密私鑰 payload)會遺失,紙本無法用於數位復原。建議將 PDF 電子檔存放於 Google Drive 或信任的 USB 隨身碟,並建立至少兩份異地備份。
⚠️ 此 PDF 等同您加密金庫的最高存取憑證,持有者可還原您所有會議記錄。請妥善保管,不要分享給任何人。
六、安全保證
我們保證
- ✅ 服務端無法解密:即便 AegisMeetings 的全部伺服器遭到入侵,攻擊者取得的只有密文
- ✅ 儲存洩漏安全:若雲端儲存發生資料外洩,所有檔案均為加密狀態
- ✅ 最小歷史暴露:若轉錄主機遭到入侵,攻擊者頂多看到當下正在處理的單筆會議,無法存取歷史資料
- ✅ 部署時機密注入:所有執行期機密(資料庫連線密碼、佇列金鑰)僅在部署時透過 Azure Managed Identity 從 Key Vault 拉取一次,注入本地快取(檔案權限嚴格限制),運行時零外部機密查詢
- ✅ PHP 執行環境沙箱化:危險系統函數全數停用、檔案系統存取範圍嚴格限制,即便發現 RCE 漏洞也無法執行系統指令或讀取系統檔案
- ✅ 唯讀應用程式層:部署完成後程式碼目錄為 root 擁有、PHP 僅有讀取權限,無法植入 Web Shell 或修改程式碼
- ✅ 核心前端資源自託管:主要 字型、樣式與應用程式 JS/CSS bundle 由本站自行託管(Vite 編譯產物),不依賴一般意義下的「整站第三方 JS/CSS CDN」。內容安全政策(CSP)另以明確允許清單納入少數執行所需之第三方來源(例如 libsodium WASM 載入、Cloudflare Web Analytics/Insights 等),與完全零第三方指令碼之模型不同;細見 §8-1、§8-9。
- ✅ API 全域限速:所有 API 端點實施限速保護,防止暴力破解與自動化攻擊
- ✅ VM 磁碟全程加密:伺服器磁碟啟用 Encryption at Host,即便實體硬碟遭物理取走,資料仍為加密狀態
- ✅ 網路最小暴露面:虛擬網路子網套用網路安全群組(NSG);使用者流量經邊緣與雲端負載平衡轉發至應用伺服器,應用 VM 不綁定可直接從網際網路撥入的公網介面;系統管理通道不倚賴對外開放之 SSH 埠
- ✅ 每日自動備份:Web 伺服器每日自動備份至獨立的 Recovery Services Vault,確保系統可還原
- ✅ 供應鏈安全掃描:每次部署前自動執行
composer audit與npm audit,比對全球 CVE 漏洞資料庫;發現高風險漏洞時部署自動中止。同時啟用 GitHub Dependabot 持續監控依賴,發現新漏洞時自動發起修補 Pull Request - ✅ 依賴版本鎖定:正式環境僅使用經測試的精確版本(lock 檔),杜絕供應鏈投毒攻擊
已知限制(我們誠實告知)
- ⚠️ 使用者設備若遭入侵:攻擊者控制您的瀏覽器後,可以讀取記憶體中的私鑰。任何以用戶端金鑰為基礎的加密系統在此情境下都無法提供保護,這是用戶端加密架構的本質限制,而非 AegisMeetings 的缺陷。但我們會透過行為異常偵測(見 8-5 節)盡可能縮短此場景的損害窗口,但無法完全消除此風險。端點安全(裝置防毒、瀏覽器更新)屬使用者責任範圍
- ⚠️ AI 處理窗口期:如第一節所述,AI 轉錄期間明文短暫存在於轉錄主機記憶體中
- ⚠️ 無靜態主金鑰的前向保密性:若您的主私鑰遭洩漏,歷史會議理論上可被解密。此為靜態主金鑰架構的本質特性,與常見之「使用者持有主金鑰」雲端加密儲存模型之取捨類似。未來版本規劃引入每次會議的臨時金鑰(per-meeting ephemeral keys)以解決此限制
- ⚠️ 元資料不在加密範圍內:會議建立時間、時長、參與者帳號等元資料為明文儲存,用於系統運作。此為多數協作與儲存類產品之常見取捨
- ⚠️ 六位數配對碼熵有限:見 §4-1;其設計目標為短時帶外授權,不等同金庫主密碼之離線暴力抵抗能力
七、雲端與網路控管(營運面縱深防禦)
本節說明與密碼學保證互補之營運與雲端架構:不揭露內部資源名稱或 IP,僅描述對外可驗證之控管原則。
7-1. 邊緣與入口流量
- 誰有公網、誰沒有:對外提供網站時,可從網際網路連線的是負載平衡器(Load Balancer)上的公網 IP(以及/或者您若啟用 CDN 代理,則使用者先連到 CDN 的邊緣位址)。應用 VM 沒有自己另掛一顆「直連 VM」的公網 IP,流量是由 LB(或 CDN 回源)轉進私有網路內的 Web 伺服器——因此攻擊者無法略過 LB/CDN,改打「某台 VM 專屬的公網 IP」來直連應用(因為根本沒有那顆 IP)。
- 對外網站流量可經 CDN/邊緣供應商(例如 Cloudflare)進入;免費方案通常仍含基礎 DDoS 緩解與代理/快取,而 完整 WAF(受管規則集、進階 L7 規則)多為付費加值,是否啟用以實際帳戶方案為準。
- 雲端側以負載平衡器作為應用層入口之一,後端為私有網路內之 Web 伺服器。
7-2. 敏感資料平面與身分
- 機密與儲存:執行期機密由雲端受管身分(Managed Identity)向金鑰保管庫取得;金鑰保管庫與物件儲存之公網端點關閉,僅能經虛擬網路內之**私人連線(Private Link)**搭配 DNS 解析使用。即便連線字串外洩,自一般公網亦無法連上服務之公網端點。
- 權限最小化:Web 與轉錄主機使用不同受管身分;高敏感之轉錄主機專用機密僅授權予轉錄主機身分,避免單一元件遭入侵時權限過度擴張(細部對照見內部架構文件)。
7-3. 子網、服務端點與持續檢視
- 子網路套用 NSG,僅放行業務所需埠與來源;可搭配雲端供應商免費層級之**服務端點(Service Endpoints)**作為路由與政策輔助(與 Private Link 可並存)。
- 訂用帳戶啟用 Microsoft Defender for Cloud 之基礎雲端安全態勢管理(Foundational CSPM,免費層級),自動產生設定建議(例如儲存體匿名存取、NSG 疏漏等),與人工變更形成雙重檢查。進階伺服器防護等付費方案為獨立計價,須與免費建議區分,避免誤啟用。
7-4. 與本白皮書其他章節之關係
上述措施屬縱深防禦:可降低誤設定與入侵後橫向移動之風險,但不取代第一至五節之密碼學保證——使用者內容之機密性仍主要由客戶端金鑰與密文設計承擔。
八、傳輸層與執行環境安全
除密碼學設計外,AegisMeetings 亦在傳輸層與伺服器執行環境部署了多層防護,確保「攻破我們的代價極高,即便成功仍拿不到明文資料」。
8-1. Content Security Policy(CSP)
每個 HTML 回應均附帶 CSP Header,限制瀏覽器可執行的資源來源:
| 指令 | 設定(與程式 SecurityHeaders 中介層一致) |
說明 |
|---|---|---|
script-src |
'self'、unsafe-inline、unsafe-eval、wasm-unsafe-eval、https://cdn.jsdelivr.net、https://static.cloudflareinsights.com |
unsafe-inline/unsafe-eval 服務 Blade 內嵌腳本與 Alpine.js;wasm-unsafe-eval 供瀏覽器載入並編譯 libsodium WASM(音檔 secretstream);jsdelivr 為目前 WASM 取得路徑;Cloudflare Insights 為經 CDN 注入之分析 beacon(若網站經 Cloudflare 代理) |
style-src |
'self'、unsafe-inline |
樣式表由本站自行託管 |
font-src |
'self'、data: |
字型自託管;data: 供 pdfmake 內嵌字型 |
connect-src |
'self'、實際 Azure Storage 帳戶之 HTTPS 原點(與 SAS 上傳一致) |
使用者瀏覽器不直連 Azure OpenAI;受管 LLM 呼叫發生於 轉錄主機(Worker) 出站,不在此 CSP 表內。前端錯誤回報走同源 /api/client-log 進 Application Insights |
worker-src |
'self'、blob: |
供 Worker/WASM 執行緒 |
media-src |
'self'、Blob、Azure Storage 原點 |
加密音檔播放等 |
form-action |
'self' 與金流閘道網域(例如 Paddle) |
限制表單提交目的地 |
frame-ancestors |
none |
防止 Clickjacking |
object-src |
none |
禁用 Flash 等老舊外掛 |
base-uri |
'self' |
阻止 base tag 注入改寫相對路徑 |
upgrade-insecure-requests |
強制啟用 | 確保資源走 HTTPS |
unsafe-eval與wasm-unsafe-eval均為已知取捨:若發生 XSS,攻擊者執行任意 JS 或載入惡意 WASM 的防線會弱於嚴格 nonce 型 CSP。第三方script-src主機亦擴大供應鏈與帳戶遭濫用時的暴露面。我們以輸入驗證、CSRF 保護、HSTS、限速與監控等縱深防禦補強;即便 XSS 發生,攻擊者仍無法自伺服器讀取您的金庫私鑰或會議明文(該等資料不在伺服器端以明文存在)。
搭配其他 Headers:X-Frame-Options: DENY、X-Content-Type-Options: nosniff、Referrer-Policy: strict-origin-when-cross-origin、Permissions-Policy(關閉不必要感測器)、Strict-Transport-Security(HSTS,1 年)。
8-2. 機密管理(Deploy-Time Secret Injection)
所有執行期機密(資料庫連線密碼、Redis 存取金鑰、佇列 HMAC 金鑰)僅在部署時從 Azure Key Vault 拉取一次,注入本地加密快取。運行時零外部機密查詢:
部署流程(CI/CD Pipeline,僅在版本更新時執行)
│
├─ 透過 Azure Managed Identity(無帳密的機器身份)
│ ↓
│ Azure Key Vault(公網端點關閉,僅經私人連線與授權身分存取)
│ ↓
├─ 一次性拉取所有機密 → 寫入本地快取(檔案權限 0640,僅 root 和應用程式群組可讀)
└─ Laravel config:cache 凍結設定
運行時(每個 HTTP 請求)
│
└─ 從本地快取載入 → 零 Key Vault 網路呼叫 → 零延遲
防護措施:
.env檔案不存在於正式環境;機密值快取於 PHP 序列化檔案(keyvault-cache.php),由root:www-data擁有、權限0640,PHP-FPM 以www-data身份唯讀存取open_basedir限制 PHP 僅能存取應用程式目錄(見 8-7 節)- 程式碼目錄為唯讀(見 8-8 節),攻擊者無法覆寫快取檔案
- 機密變更時,需重新執行部署流程或手動刷新快取指令,即時生效
8-3. 「拿到 Session 也沒有金鑰」的設計保證
攻擊者即便拿到使用者的 Session 資料:
| 攻擊者取得的資料 | 能做什麼 | 不能做什麼 |
|---|---|---|
| Session Token | 模擬已登入狀態發 API 請求 | 無法取得私鑰(私鑰只在使用者瀏覽器記憶體) |
| 加密密文(資料庫) | — | 無法解密,私鑰不在伺服器端 |
| 包裹後的金鑰(資料庫) | — | 無法解包,需要使用者的私鑰 |
同時拿到 Session + 資料庫 + 雲端儲存 = 仍然拿不到明文,因為私鑰由使用者裝置之 WebAuthn/生物辨識,或 金庫密碼加上僅存於該瀏覽器 IndexedDB 的裝置秘密(密碼路線)保護,永遠不在伺服器上。
8-4. 裝置授權強制執行
所有涉及加密內容的操作(查看會議記錄、逐字稿、音檔、AI 摘要)均要求裝置已通過授權。未授權裝置僅能存取帳號基本資訊(會員等級、剩餘時數、訂閱狀態),無法存取任何加密內容。
未授權裝置嘗試存取加密內容
↓
系統攔截 → 導引至裝置授權流程(跨裝置授權,見第四節)
此設計確保即便攻擊者取得有效的 Session Token,若其裝置從未通過授權,仍無法存取任何加密資料。
8-5. 行為異常偵測
AegisMeetings 持續監控異常存取模式,當偵測到以下信號時,系統將自動啟動分級防護:
| 偵測信號 | 說明 |
|---|---|
| 短時間大量讀取 | 單一帳號在極短時間內批量存取大量會議記錄(異常行為模式,正常用戶不會如此操作) |
| 新授權裝置批量存取 | 剛完成授權的裝置立即大量讀取歷史會議(攻擊者竊得私鑰後的典型自動化腳本特徵) |
| 地理速度異常 | 短時間內從地理上不可能的位置連續存取(需疊加其他信號,避免 VPN 使用者誤觸發) |
| 非慣常時段大量操作 | 帳號在從未有過活動的時段出現大量操作 |
分級回應機制:
第一層:降速限制 → 攻擊腳本從「秒級批量」降為「分鐘級」
第二層:強制重驗 → 要求重新解鎖金庫(攻擊腳本無法自動完成)
第三層:暫停 + 通知 → 帳號功能暫停,同時發送 Email / SMS 通知帳號持有人
此機制的設計目標是「止血而非完全消除風險」:即便攻擊者成功取得私鑰,系統偵測到異常批量操作後可迅速介入,大幅縮小實際洩漏的資料範圍,哪怕只是加密資料。
8-6. API 限速保護(Rate Limiting)
所有 API 端點均實施全域限速(每分鐘 60 次),防止暴力破解與自動化攻擊腳本:
| 防護場景 | 機制 |
|---|---|
| 暴力密碼猜測 | 單一 IP 超過限額後回傳 HTTP 429,強制等待 |
| 自動化爬蟲 | 限速使批量資料蒐集在實務上不可行 |
| DDoS 減緩 | 若網域經 Cloudflare 代理,可使用其免費層級之邊緣 DDoS 緩解;應用層仍以本文件所述之 API 限速為主。**Cloudflare WAF(付費加值)**未啟用時,不將其列為現有防線。 |
8-7. PHP 執行環境沙箱化(Runtime Sandboxing)
Web 伺服器的 PHP-FPM 執行環境實施多層限制,即便攻擊者發現遠端程式碼執行(RCE)漏洞,也難以造成實質損害:
| 措施 | 效果 |
|---|---|
| 危險函數停用 | exec、shell_exec、system、passthru、proc_open 等系統命令函數全數停用,攻擊者無法執行作業系統指令 |
| 檔案系統隔離(open_basedir) | PHP 僅能存取應用程式目錄和 /tmp,無法讀取 /etc/passwd、/proc 或其他系統檔案 |
| 伺服器指紋隱藏 | HTTP 回應中不揭露 PHP 版本資訊,增加攻擊者的偵查成本 |
此設定僅影響處理 Web 請求的 PHP-FPM 程序。CLI 工具(部署腳本、佇列處理器)不受影響,確保系統維運不受限制。
8-8. 唯讀應用程式層(Immutable Application Layer)
部署完成後,應用程式碼目錄由 root 擁有,PHP-FPM(www-data)僅有讀取權限:
/var/www/aegismeetings/ ← root:www-data 755(PHP 可讀不可寫)
├── app/ ← 應用程式碼
├── vendor/ ← 第三方套件
├── storage/ ← www-data:www-data(唯一可寫目錄,用於日誌與快取)
└── bootstrap/cache/ ← www-data:www-data(框架啟動快取)
效果:即便攻擊者透過漏洞取得 PHP 程序的執行權限,也無法植入 Web Shell、修改程式碼、或覆寫設定檔。可寫目錄僅限 storage/(日誌與暫存)和 bootstrap/cache/(框架快取),且這些目錄不包含可執行的路由進入點。
8-9. 前端資產與 CSP 允許之第三方(Self-Hosted Core + Allowlisted Exceptions)
核心資產(字型、應用程式 CSS、Vite 編譯之 JS bundle)由應用程式伺服器自行託管,不依賴典型「整頁應用從公用 CDN 載入主要 bundle」之模型。
實務上仍經 CSP 明示允許的少數外部來源(與 §8-1 一致):
| 類別 | 說明 |
|---|---|
| WASM/執行時 | libsodium 以 WASM 於瀏覽器執行 secretstream;需 wasm-unsafe-eval,並依目前部署自 jsdelivr 等路徑取得 WASM 位元組 |
| 分析/邊緣 | 若網站經 Cloudflare 代理,可能載入 Cloudflare Web Analytics/Insights beacon |
安全效益(相對完全依賴第三方 CDN 載入主程式):
- 主要業務程式碼仍為 自建置產物,可重現建置與 lockfile 稽核
- 供應鏈面仍須監控 允許清單內 之第三方完整性與帳戶安全(與「絕對零第三方」敘述不同,已於 §6 誠實揭露)
8-10. Session 生命週期管理
- 使用者可自行設定閒置登出時間:1 小時 / 8 小時 / 1 天 / 7 天(預設 7 天)
- 計時方式為「閒置計時」:持續使用不會被中斷,停止活動超過設定時間才登出
- Session 過期時,瀏覽器端自動清除本地金鑰快取,確保「身份驗證過期」與「金鑰存取過期」同步,不留殘跡
- Session 以 Redis TLS(port 6380)加密傳輸,Session ID 為密碼學隨機字串,無法被猜測或暴力枚舉
- Session Payload 伺服器端加密:Session 內容在寫入 Redis 前經 Laravel 加密引擎加密(AES-256-CBC),即便 Redis 遭入侵,攻擊者看到的也是密文
- Session Cookie 安全旗標:
secure(僅 HTTPS)、httponly(JavaScript 無法讀取)、samesite=Lax(防止 CSRF 跨站請求偽造)全部強制啟用
8-11. 零信任出站管制(Zero-Trust Egress Filtering)
為了徹底阻斷資料外洩(Data Exfiltration)途徑,AegisMeetings 的 Web 伺服器與轉錄主機均實施嚴格的出站網路白名單限制。
伺服器僅被允許連線至內部資料庫、Azure 儲存體與特定的第三方 API(如郵件發送服務)。任何對外公網的未授權連線請求(例如駭客嘗試將資料傳送至自己的 C2 伺服器,或嘗試下載外部惡意工具)皆會在虛擬網路邊界被直接丟棄。即便系統出現未知的 RCE 漏洞,攻擊者也無法將打包的資料成功傳送出我們的安全網路環境。
8-12. 供應鏈安全防護(Supply Chain Security)
現代 Web 應用依賴大量開源套件,供應鏈攻擊(駭客污染上游套件、植入惡意程式碼)已成為主流攻擊向量。AegisMeetings 採用三層防線:
- 版本鎖定:正式環境部署時嚴格使用
composer.lock與package-lock.json鎖定的精確版本(composer install --no-dev+npm ci),絕不在正式環境執行版本更新,確保只安裝經開發環境驗證的套件版本 - CI 漏洞閘門:每次部署前,CI 流水線自動執行
composer audit(PHP)與npm audit(Node.js),比對全球 CVE 漏洞資料庫。發現高風險或嚴重漏洞時,部署自動中止,不允許帶有已知漏洞的程式碼進入正式環境 - 自動化持續監控:啟用 GitHub Dependabot,每日掃描所有依賴(含 PHP 套件、npm 套件、GitHub Actions),發現新漏洞時自動發起修補 Pull Request,維護團隊僅需審核並合併
8-13. 異常行為與安全防護相關紀錄
為維護整體服務與用戶之資訊安全、防範詐欺與惡意攻擊,在偵測到異常或疑似濫用行為時,我們可能產出僅供安全與風控用途之技術紀錄。此類紀錄與一般應用程式或營運日誌分開儲存與治理,設計上不包含會議內容(音檔、逐字稿、摘要等)。保留期間原則上為長期或無限期;對外揭露與法遵敘述以《隱私政策》《服務條款》為準。
九、名詞解釋
| 術語 | 說明 |
|---|---|
| 零知識加密(Zero-Knowledge Encryption) | 服務提供者在設計上無法讀取使用者儲存資料的加密架構。AegisMeetings 採用此模型:靜態資料全程加密,連服務提供者也無法讀取 |
| 端對端加密(E2EE) | 資料從發送者到接收者全程加密,任何中間節點(含服務提供者)都無法解讀。Signal、WhatsApp 屬此類。AegisMeetings 不屬於 E2EE:AI 轉錄需要在轉錄主機上短暫處理明文音訊(見「誠實窗口期」) |
| RSA-4096 | 業界標準非對稱加密演算法,使用 4096 位元金鑰 |
| AES-256-GCM | 美國國家標準局(NIST)認可的對稱加密演算法 |
| XChaCha20-Poly1305 | 現代 AEAD;音檔上傳實務上經 libsodium secretstream 串流封裝(底層仍為 XChaCha 家族) |
| Argon2id | 2015 密碼雜湊競賽冠軍演算法,用於從密碼安全衍生金鑰 |
| WebAuthn PRF | W3C 標準,允許硬體安全晶片(指紋/臉部辨識)產生金鑰衍生材料,無物理驗證則無法衍生 |
| 裝置秘密(device secret,密碼路線) | 僅存於瀏覽器 IndexedDB 的隨機秘密,與金庫密碼及伺服器 Salt 一併參與 Argon2 衍生;伺服器不持有,換瀏覽器或清除站內資料後需配對或 PDF 復原 |
| 配對/帶外授權 | 已授權瀏覽器產生限時六位數配對碼,供新環境領取加密私鑰包裹並重新綁定(見第四節) |
| HMAC-SHA256 | 雜湊訊息驗證碼,確保資料傳輸過程中未遭竄改 |
| 誠實窗口期 | 音檔進入加密運算環境後至物理抹除前,數據僅於記憶體流動之唯一明碼作業時段(原意:Honest Processing Window) |
| 前向保密性(Forward Secrecy) | 即便長期金鑰洩漏,過去的通訊仍受保護的特性 |
| SAS Token | 限時、限權的雲端儲存存取憑證,用於瀏覽器直傳音檔,過期後自動失效 |
| Managed Identity | Azure 雲端平台提供的無密碼機器身份,用於服務間的安全存取,無需在程式碼中儲存任何憑證 |
| open_basedir | PHP 執行環境的檔案系統隔離機制,限制 PHP 可存取的目錄範圍,防止讀取系統敏感檔案 |
| disable_functions | PHP 執行環境的函數停用機制,禁止呼叫危險的系統命令函數,阻止 RCE 漏洞的實際利用 |
| Rate Limiting(限速) | 限制單位時間內 API 請求次數的機制,防止暴力破解和自動化攻擊 |
| Immutable Infrastructure(唯讀部署) | 部署完成後應用程式碼為唯讀的架構,防止運行時被竄改或植入惡意程式碼 |
| Egress Filtering(出站過濾) | 限制伺服器對外連線目的地的網路安全機制,僅允許白名單中的服務,阻斷資料外洩途徑 |
| C2 伺服器 | Command & Control 伺服器,攻擊者用來遠端控制已入侵主機並接收竊取資料的外部伺服器 |
| 供應鏈攻擊(Supply Chain Attack) | 攻擊者入侵或污染上游開源套件,將惡意程式碼植入廣泛使用的軟體依賴中,藉此感染下游應用 |
| CVE | Common Vulnerabilities and Exposures,全球公認的資安漏洞編號系統,用於唯一識別已知漏洞 |
| SCA(Software Composition Analysis) | 軟體組成分析,自動掃描專案所有第三方依賴並比對已知漏洞資料庫的安全工具 |
十、聯絡資安團隊
若您在我們的系統中發現潛在安全性問題,請先私下聯繫我們,給我們機會在公開揭露前完成修復:
我們承諾第一時間親自回覆、驗證並修復問題。在修復完成前,懇請對漏洞細節保密,共同保護所有使用者的資料安全。
本文件為公開版本,不含系統實作細節。版本 1.16,2026 年 4 月發布。 技術設計基於開放的密碼學標準,任何具備密碼學知識的研究者均可獨立驗證本文件的設計合理性。