:allowedLocationTypes 的強(qiáng)制執(zhí)行機(jī)制)
開發(fā)者門戶后端前端【免費(fèi)下載鏈接】backstageBackstage is an open framework for building developer portals項(xiàng)目地址https://gitcode.com/GitHub_Trending/ba/backstage點(diǎn)擊查看免費(fèi)下載本篇技術(shù)指南圍繞 Backstage Catalog 后端在實(shí)體處理Processing階段對位置Location類型進(jìn)行統(tǒng)一校驗(yàn)的機(jī)制展開。該能力對應(yīng)插件補(bǔ)丁validate-location-types-in-processing已合并入主分支記錄于 plugins/catalog-backend/CHANGELOG.md 的e363ae2條目其核心變化是允許的位置類型allowedLocationTypes限制現(xiàn)在會(huì)在 Catalog 處理期間被一致地強(qiáng)制執(zhí)行。讀完本文你將掌握位置類型白名單的默認(rèn)行為、在何處配置、在哪個(gè)處理階段生效、其與繼承位置類型的交互規(guī)則以及如何通過倉庫內(nèi)的源碼與測試用例驗(yàn)證這套機(jī)制。一、背景Catalog 中的 Location 與位置類型在 Backstage 的軟件目錄Software Catalog中實(shí)體Entity并不是憑空出現(xiàn)的它們由**位置Location**引用外部資源如 YAML 文件、Git 倉庫而來。一個(gè)位置由type與target兩部分組成例如url:https://example.com/catalog-info.yaml、file:/path/to/catalog-info.yaml。位置類型location type決定了系統(tǒng)如何解釋和讀取該位置的target位置類型含義現(xiàn)狀url通過 URL 讀取遠(yuǎn)程資源默認(rèn)允許的唯一類型file讀取本地文件系統(tǒng)路徑受白名單控制github、github/api等 SCM 專用類型早期按平臺區(qū)分的類型早已被url取代并移除在 Backstage 的演進(jìn)過程中大量舊的 SCM 專用位置類型如github、github/api已被移除統(tǒng)一收斂為url類型見 plugins/catalog-backend/CHANGELOG.md 中6952行附近的說明。這就引出一個(gè)安全與一致性問題如果 Catalog 允許用戶注冊任意類型的位置就可能繞過管理員設(shè)定的讀取邊界。因此引入允許位置類型白名單機(jī)制而validate-location-types-in-processing這一補(bǔ)丁的價(jià)值在于把白名單校驗(yàn)下沉到處理階段并保持一致執(zhí)行堵住此前校驗(yàn)不一致的缺口。二、核心變更處理階段強(qiáng)制校驗(yàn)位置類型e363ae2變更的原始表述為Allowed location type restrictions are now applied consistently during catalog processing.其含義是以前對allowedLocationTypes的校驗(yàn)可能只在**注冊register環(huán)節(jié)生效而現(xiàn)在在實(shí)體處理processing**環(huán)節(jié)同樣嚴(yán)格執(zhí)行做到兩條鏈路行為一致。實(shí)現(xiàn)這一強(qiáng)制校驗(yàn)的核心函數(shù)位于 DefaultCatalogProcessingOrchestrator.ts 的runSpecialLocationStep第 342-373 行附近。該方法專門處理Location類型的實(shí)體LocationEntity是處理位置本身的入口。關(guān)鍵校驗(yàn)代碼如下const { type context.location.type, presence required } entity.spec; const { allowedLocationTypes } this.options; if ( allowedLocationTypes type ! context.location.type !allowedLocationTypes.includes(type) ) { context.collector.generic()( processingResult.inputError( context.location, Registered locations must be of an allowed type ${JSON.stringify( allowedLocationTypes, )}, ), ); return; }這段邏輯揭示了三個(gè)關(guān)鍵細(xì)節(jié)類型來源的優(yōu)先級type優(yōu)先取entity.spec.type若未顯式聲明則回退到context.location.type即注冊該位置時(shí)使用的類型這正是繼承位置類型的語義來源放行條件當(dāng)type與context.location.type相同時(shí)即使不在白名單中也直接放行——因?yàn)檫@屬于繼承而非新聲明不會(huì)引入新的讀取邊界拒絕方式當(dāng)type是新聲明且不在allowedLocationTypes白名單中時(shí)產(chǎn)出processingResult.inputError(...)并提前返回后續(xù)的readLocation處理器根本不會(huì)被執(zhí)行——這就是一致地強(qiáng)制的落地方式校驗(yàn)發(fā)生在任何實(shí)際讀取之前。被拒絕后產(chǎn)生的錯(cuò)誤信息形如Registered locations must be of an allowed type [url]該錯(cuò)誤會(huì)作為inputError寫入處理結(jié)果收集器ProcessorOutputCollector最終體現(xiàn)為 Catalog 中的處理失敗而非靜默忽略。三、白名單從哪來三個(gè)層次的配置入口allowedLocationTypes的傳遞鏈路是擴(kuò)展點(diǎn)/構(gòu)建器 → 處理編排器。在 CatalogBuilder.ts 中該值在build()時(shí)被注入編排器第 436-444 行const orchestrator new DefaultCatalogProcessingOrchestrator({ processors, integrations, rulesEnforcer, logger, parser, policy, allowedLocationTypes: this.allowedLocationType, });1. 默認(rèn)值僅允許urlCatalogBuilder.ts 第 191 行的構(gòu)造函數(shù)給出了默認(rèn)值this.allowedLocationType [url];也就是說在不做任何配置的情況下Catalog 只允許注冊url類型的位置file等其余類型一律在處理階段被拒絕。這既是安全默認(rèn)值也解釋了為什么舊文檔中file類型多用于本地開發(fā)調(diào)試場景。2. 傳統(tǒng)構(gòu)建方式CatalogBuilder.setAllowedLocationTypes對于使用傳統(tǒng)方式組裝 Catalog 的代碼可以直接調(diào)用構(gòu)建器方法第 365-373 行/** * Sets up the allowed location types from being registered via the location service. * * param allowedLocationTypes - the allowed location types */ setAllowedLocationTypes(allowedLocationTypes: string[]): CatalogBuilder { this.allowedLocationType allowedLocationTypes; return this; }該方法會(huì)整體覆蓋默認(rèn)值。例如希望同時(shí)允許url與fileconst builder await CatalogBuilder.create({ ... }); builder.setAllowedLocationTypes([url, file]);3. 新后端系統(tǒng)CatalogLocationsExtensionPoint在 Backstage 新后端系統(tǒng)New Backend System下推薦通過擴(kuò)展點(diǎn)方式配置。相關(guān)實(shí)現(xiàn)位于 CatalogPlugin.tsclass CatalogLocationsExtensionPointImpl implements CatalogLocationsExtensionPoint { #locationTypes: string[] | undefined; setAllowedLocationTypes(locationTypes: Arraystring) { this.#locationTypes locationTypes; } get allowedLocationTypes() { return this.#locationTypes; } }該擴(kuò)展點(diǎn)在插件初始化時(shí)被注冊第 175-179 行并在init階段按需傳遞給構(gòu)建器第 270-274 行if (locationTypeExtensions.allowedLocationTypes) { builder.setAllowedLocationTypes( locationTypeExtensions.allowedLocationTypes, ); }注意這里的判斷條件只有當(dāng)擴(kuò)展點(diǎn)確實(shí)被調(diào)用過值非undefined時(shí)才覆蓋默認(rèn)值否則保留默認(rèn)的[url]。這一設(shè)計(jì)保證未調(diào)用setAllowedLocationTypes()時(shí)保留默認(rèn)行為對應(yīng) CHANGELOG 中的51240ee條目。使用擴(kuò)展點(diǎn)的模塊示例import { catalogLocationsExtensionPoint } from backstage/plugin-catalog-node/alpha; const myModule createBackendModule({ pluginId: catalog, moduleId: my-locations-policy, register(env) { env.registerInit({ deps: { locations: catalogLocationsExtensionPoint, }, async init({ locations }) { locations.setAllowedLocationTypes([url, file]); }, }); }, });四、行為規(guī)則總結(jié)什么情況下會(huì)被拒絕綜合runSpecialLocationStep的判定邏輯可以整理出如下行為矩陣假設(shè)白名單為[url]場景entity.spec.typecontext.location.type結(jié)果繼承類型未顯式聲明未設(shè)置url放行type context.location.type聲明與來源一致urlurl放行聲明類型在白名單內(nèi)file白名單含fileurl放行聲明類型不在白名單fileurl拒絕拋出inputError不執(zhí)行readLocation一個(gè)容易被忽略的細(xì)節(jié)是繼承與聲明的區(qū)別。若一個(gè)Location實(shí)體未在spec.type中顯式聲明類型它會(huì)繼承注冊鏈路如url:https://...的類型這種情況下即使該類型不在白名單例如context.location.type為file也會(huì)因type ! context.location.type為false而直接通過校驗(yàn)。換句話說白名單限制的是新引入的讀取類型而非沿襲已有的讀取類型。五、測試驗(yàn)證強(qiáng)制校驗(yàn)的可執(zhí)行證據(jù)倉庫為這套機(jī)制提供了完整的單元測試見 DefaultCatalogProcessingOrchestrator.test.ts 第 349-397 行的describe(allowed location types)用例。測試構(gòu)造了一個(gè)allowedLocationTypes: [url]的編排器實(shí)例并驗(yàn)證兩條核心路徑用例 1拒絕未授權(quán)類型。位置實(shí)體來源為url:https://example.com/c.yaml但spec聲明type: filemakeEntity(url, file)。斷言結(jié)果const disallowed await orchestrator.process({ entity: makeEntity(url, file), state: {}, }); expect(disallowed.ok).toBe(false); expect(processor.readLocation).not.toHaveBeenCalled();即處理結(jié)果ok為false且readLocation處理器從未被調(diào)用——校驗(yàn)確實(shí)發(fā)生在任何讀取動(dòng)作之前。用例 2繼承類型放行。位置來源與spec均聲明為filemakeEntity(file, file)雖然file不在白名單中但因type context.location.type而放行const inherited await orchestrator.process({ entity: makeEntity(file, file), state: {}, }); expect(inherited.ok).toBe(true); expect(processor.readLocation).toHaveBeenCalled();這兩個(gè)用例從可執(zhí)行層面印證了前文總結(jié)的行為矩陣也是你升級plugin-catalog-backend后回歸驗(yàn)證該機(jī)制的最佳入口。六、升級影響與排查建議確認(rèn)你的位置注冊方式如果你此前依賴file類型位置且未顯式配置白名單升級到包含e363ae2的版本后這些位置會(huì)在處理階段被拒絕。請通過CatalogBuilder.setAllowedLocationTypes([url, file])或新后端系統(tǒng)的catalogLocationsExtensionPoint顯式放行。識別報(bào)錯(cuò)特征被拒絕的實(shí)體會(huì)在 Catalog 中留下類似Registered locations must be of an allowed type [url]的inputError可在 Catalog 實(shí)體的處理錯(cuò)誤信息中檢索該關(guān)鍵詞快速定位是哪種位置類型觸發(fā)了白名單。理解默認(rèn)安全邊界默認(rèn)僅允許url意味著未配置時(shí)任何 SCM 專用或本地文件類型的新位置注冊都會(huì)被攔截這是刻意為之的安全設(shè)計(jì)而非缺陷。七、進(jìn)一步閱讀變更記錄 plugins/catalog-backend/CHANGELOG.md檢索e363ae2與setAllowedLocationTypes校驗(yàn)實(shí)現(xiàn) DefaultCatalogProcessingOrchestrator.ts 的runSpecialLocationStep第 342-373 行白名單注入 CatalogBuilder.ts 第 191、370、443 行擴(kuò)展點(diǎn)實(shí)現(xiàn) CatalogPlugin.ts 第 52-64、175-179、270-274 行單元測試 DefaultCatalogProcessingOrchestrator.test.ts 第 349-397 行通過以上源碼與測試證據(jù)你可以完整掌握 Backstage Catalog 在位置類型白名單上的處理階段強(qiáng)制執(zhí)行機(jī)制并在實(shí)際部署中準(zhǔn)確配置與排障。贊分享開發(fā)者門戶后端前端【免費(fèi)下載鏈接】backstageBackstage is an open framework for building developer portals項(xiàng)目地址https://gitcode.com/GitHub_Trending/ba/backstage點(diǎn)擊查看免費(fèi)下載相關(guān)推薦Activepieces 連接-組件綁定強(qiáng)制校驗(yàn)引擎內(nèi)執(zhí)行的連接歸屬校驗(yàn)機(jī)制與配置實(shí)戰(zhàn)Activepieces 連接 組件綁定強(qiáng)制校驗(yàn)引擎內(nèi)執(zhí)行的連接歸屬校驗(yàn)機(jī)制與配置實(shí)戰(zhàn) 導(dǎo)讀 在 Activepieces 的自動(dòng)化流程中一個(gè)步驟Step工作流自動(dòng)化低代碼AI 應(yīng)用人工智能AI AgentMCP 服務(wù)后端前端Canopy 區(qū)塊鏈交易處理機(jī)制深度解析從校驗(yàn)、防重放到狀態(tài)執(zhí)行Canopy 區(qū)塊鏈交易處理機(jī)制深度解析從校驗(yàn)、防重放到狀態(tài)執(zhí)行 導(dǎo)讀 本文以 Canopy Network 官方 Go 實(shí)現(xiàn)的 state machine區(qū)塊鏈后端xberg 中空 MIME 類型的拒絕機(jī)制從 C FFI 調(diào)用到 Rust 內(nèi)核的完整校驗(yàn)鏈路xberg 中空 MIME 類型的拒絕機(jī)制從 C FFI 調(diào)用到 Rust 內(nèi)核的完整校驗(yàn)鏈路 本文以 xberg 的 error_empty_mime 錯(cuò)誤后端AI 應(yīng)用NLP創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考