深度解析:RLS 行級(jí)安全與雙權(quán)限 API 密鑰體系)
Feedbase 安全架構(gòu)深度解析RLS 行級(jí)安全與雙權(quán)限 API 密鑰體系【免費(fèi)下載鏈接】feedbaseThe open-source solution for collecting feedback communicating updates.項(xiàng)目地址: https://gitcode.com/gh_mirrors/fe/feedbaseFeedbase 是一款開(kāi)源的產(chǎn)品反饋收集與更新溝通解決方案它把用戶反饋和更新日志兩大高頻場(chǎng)景做成了開(kāi)箱即用的 SaaS 形態(tài)。很多開(kāi)發(fā)者關(guān)心的是這樣一個(gè)直接面向公網(wǎng)、允許匿名用戶提交反饋的系統(tǒng)安全架構(gòu)到底靠什么撐起來(lái)答案就藏在兩層設(shè)計(jì)里——數(shù)據(jù)庫(kù)底層的RLS 行級(jí)安全以及應(yīng)用層的雙權(quán)限 API 密鑰體系。這篇文章將用最通俗的方式帶你拆解 Feedbase 的安全縱深設(shè)計(jì)理解它如何做到公開(kāi)可讀、嚴(yán)格可控。一、先認(rèn)識(shí) Feedbase 的數(shù)據(jù)地基Feedbase 基于 SupabasePostgreSQL構(gòu)建幾乎所有業(yè)務(wù)數(shù)據(jù)——反饋、評(píng)論、更新日志、項(xiàng)目配置、成員關(guān)系——都存放在一張張數(shù)據(jù)庫(kù)表中。它的數(shù)據(jù)庫(kù)結(jié)構(gòu)定義在 supabase/migrations/20231126133700_db_auth_schema.sql 中包括changelogs、feedback、feedback_comments、profiles、projects、project_members等核心表。對(duì)于一個(gè)允許任何人瀏覽反饋、匿名提交想法的產(chǎn)品來(lái)說(shuō)最大的安全悖論是數(shù)據(jù)既要對(duì)外公開(kāi)又不能被隨意篡改。Feedbase 的解法是讓 PostgreSQL 的 RLSRow Level Security行級(jí)安全成為第一道、也是最硬的一道防線。二、RLS 行級(jí)安全數(shù)據(jù)庫(kù)層面的隱形門衛(wèi)什么是 RLS為什么要用它傳統(tǒng) Web 應(yīng)用往往在應(yīng)用層做權(quán)限判斷數(shù)據(jù)庫(kù)本身來(lái)者不拒。RLS 的思路完全不同在數(shù)據(jù)庫(kù)內(nèi)部對(duì)每一行數(shù)據(jù)設(shè)置訪問(wèn)規(guī)則。即使你的應(yīng)用代碼出了 bug、密鑰泄露甚至遭遇 SQL 注入數(shù)據(jù)庫(kù)也會(huì)在返回?cái)?shù)據(jù)前強(qiáng)制校驗(yàn)越權(quán)查詢直接返回空結(jié)果。Feedbase 在遷移腳本中為每一張業(yè)務(wù)表都執(zhí)行了ALTER TABLE ... ENABLE ROW LEVEL SECURITY這意味著沒(méi)有一條數(shù)據(jù)能繞過(guò)規(guī)則被讀取。Feedbase 的 RLS 策略組合拳Feedbase 的權(quán)限策略遵循一套清晰的讀公開(kāi)、寫(xiě)認(rèn)證原則操作類型默認(rèn)策略典型對(duì)象SELECT讀取對(duì)所有人開(kāi)放反饋、更新日志、標(biāo)簽等INSERT寫(xiě)入僅登錄用戶反饋、評(píng)論、項(xiàng)目等UPDATE / DELETE僅登錄用戶項(xiàng)目、配置、邀請(qǐng)等特別值得一提的是profiles用戶資料表它的策略更加嚴(yán)格用戶可以讀取所有人的資料但只能更新自己的那一行通過(guò)auth.uid() id校驗(yàn)。這就是 RLS 最優(yōu)雅的地方——用數(shù)據(jù)庫(kù)原生能力把最小權(quán)限落實(shí)到每一行數(shù)據(jù)。雙重認(rèn)證API 密鑰也能過(guò) RLS 關(guān)卡在 supabase/migrations/20231130182016_api_key_system.sql 中Feedbase 定義了一個(gè)SECURITY DEFINER函數(shù)is_allowed_api_token()它會(huì)從請(qǐng)求頭中讀取lumkey字段與project_api_keys表中的 token 比對(duì)。所有核心表如changelogs、projects、project_configs的 RLS 策略都會(huì)調(diào)用這個(gè)函數(shù)來(lái)放行合法的 API 請(qǐng)求。換句話說(shuō)API 密鑰認(rèn)證不是應(yīng)用層的錦上添花而是直接嵌入數(shù)據(jù)庫(kù)策略的剛性約束。即使攻擊者偽造請(qǐng)求只要沒(méi)有合法 token數(shù)據(jù)庫(kù)這一關(guān)就過(guò)不去。三、雙權(quán)限 API 密鑰體系一把鑰匙開(kāi)一扇門如果說(shuō) RLS 是地基那么 API 密鑰體系就是門鎖系統(tǒng)。Feedbase 用一枚簡(jiǎn)單的枚舉實(shí)現(xiàn)了非常實(shí)用的權(quán)限分級(jí)。Full Access 與 Public Access兩種權(quán)限怎么選API 密鑰的權(quán)限類型定義在遷移腳本開(kāi)頭的token_type枚舉中只有兩種取值full_access完全訪問(wèn)管理員級(jí)別可以讀寫(xiě)項(xiàng)目下的所有資源——更新日志、項(xiàng)目配置、成員、邀請(qǐng)、API 密鑰本身幾乎等同于項(xiàng)目主人的操作權(quán)限。public_access公共訪問(wèn)受限權(quán)限主要用于提交反饋等面向公網(wǎng)的操作例如向feedback表插入新反饋。選擇建議很簡(jiǎn)單給后端服務(wù)、CI/CD、自動(dòng)化腳本用 Full Access給前端頁(yè)面、公開(kāi)提交反饋的小程序用 Public Access。這樣即使前端密鑰被扒走攻擊者也無(wú)法篡改你的更新日志或項(xiàng)目配置。密鑰的一生生成、展示與閱后即焚Feedbase 對(duì)密鑰的生命周期管理相當(dāng)考究相關(guān)邏輯在 apps/web/lib/utils.ts 和 apps/web/lib/api/projects.ts 中生成調(diào)用generateApiToken(fb, 20)生成以fb_開(kāi)頭、后接 20 位隨機(jī)字符的 token格式清晰且熵值足夠高。展示一次創(chuàng)建密鑰的彈窗見(jiàn) apps/web/components/dashboard/modals/add-api-key-modal.tsx會(huì)明確提示 Keep this key safe. You will not be able to view it again!——完整 token 僅在創(chuàng)建瞬間展示關(guān)閉后無(wú)法再次查看。脫敏存儲(chǔ)查詢密鑰列表時(shí)后端只返回short_token完整 token 的前 12 位用于 UI 展示和身份識(shí)別完整 token 永遠(yuǎn)不回傳前端。數(shù)量限制每個(gè)項(xiàng)目最多創(chuàng)建 3 個(gè) API 密鑰且名稱不可重復(fù)避免密鑰泛濫失控。四、一次請(qǐng)求的通關(guān)之旅認(rèn)證鏈路全流程Feedbase 的雙權(quán)限密鑰是如何從請(qǐng)求頭一路驗(yàn)證到數(shù)據(jù)庫(kù)的完整鏈路清晰而嚴(yán)密客戶端在 HTTP 請(qǐng)求的Authorization頭中以Bearer token形式攜帶密鑰后端在 apps/web/lib/auth.ts 的createClient()中截取 token并將其注入到發(fā)往 Supabase 請(qǐng)求的lumkey頭中Supabase 側(cè)執(zhí)行 SQL 時(shí)RLS 策略調(diào)用is_allowed_api_token()校驗(yàn)lumkey是否匹配、權(quán)限類型是否符合應(yīng)用層還會(huì)二次核對(duì)該密鑰是否屬于當(dāng)前項(xiàng)目防止跨項(xiàng)目盜用并判斷public_access密鑰是否越權(quán)訪問(wèn)了僅限 Full Access 的資源全部通過(guò)后數(shù)據(jù)才被放行返回。這套應(yīng)用層前置校驗(yàn) 數(shù)據(jù)庫(kù) RLS 兜底的雙保險(xiǎn)正是 Feedbase 安全架構(gòu)的精髓。公開(kāi)的 API 路由如 apps/web/app/api/v1/[slug]/changelogs/route.ts讀取更新日志時(shí)走allowAnonAccess通道而寫(xiě)入類操作則必須持有合法密鑰完美兼顧了公開(kāi)與安全。五、給開(kāi)發(fā)者的三條安全實(shí)踐建議看完 Feedbase 的安全設(shè)計(jì)你可以直接把這套思路遷移到自己的項(xiàng)目中善用 RLS 做兜底哪怕應(yīng)用層權(quán)限寫(xiě)得再嚴(yán)也一定要在數(shù)據(jù)庫(kù)層開(kāi)啟 RLS把最后一道門焊死。權(quán)限分級(jí)而非一刀切參考 Full Access / Public Access 的二元模型讓不同場(chǎng)景使用不同密鑰縮小攻擊面。密鑰脫敏與限流完整密鑰只展示一次、列表只返回短標(biāo)識(shí)、限制密鑰數(shù)量——這些看似微小的細(xì)節(jié)能極大降低泄露風(fēng)險(xiǎn)。結(jié)語(yǔ)Feedbase 用 RLS 行級(jí)安全筑牢數(shù)據(jù)底座用雙權(quán)限 API 密鑰體系實(shí)現(xiàn)精細(xì)管控再通過(guò)密鑰閱后即焚短標(biāo)識(shí)脫敏項(xiàng)目級(jí)隔離等設(shè)計(jì)補(bǔ)全細(xì)節(jié)。對(duì)于想自建反饋收集系統(tǒng)的團(tuán)隊(duì)來(lái)說(shuō)這套開(kāi)源的安全架構(gòu)不僅可靠更是一份值得逐行研讀的安全教科書(shū)。如果你也正在構(gòu)建類似的多租戶 SaaS不妨直接閱讀上文提到的遷移腳本與認(rèn)證源碼把這份成熟經(jīng)驗(yàn)抄進(jìn)自己的項(xiàng)目里?!久赓M(fèi)下載鏈接】feedbaseThe open-source solution for collecting feedback communicating updates.項(xiàng)目地址: https://gitcode.com/gh_mirrors/fe/feedbase創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考