fix(config): cover shipped bundle source ownership

This commit is contained in:
Tianyi Cui
2026-08-07 23:26:39 +08:00
parent 356453d6cb
commit 4ee93f7944
3 changed files with 59 additions and 23 deletions
-1
View File
@@ -368,7 +368,6 @@
name: '@deepseek-ai/dsh-web-search-deepseek'
config:
apiKeyEnv: DEEPSEEK_API_KEY
baseURL: !!js process.env.DEEPSEEK_SEARCH_BASE_URL
- id: tool-web
name: '@deepseek-ai/dsh-tool-web'
@@ -0,0 +1,30 @@
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, describe, expect, it } from 'vitest'
import { collectConfigSourceOwnershipViolations } from './verify-config-source-ownership.ts'
const roots: string[] = []
afterEach(() => {
for (const root of roots.splice(0)) rmSync(root, { recursive: true, force: true })
})
describe('configuration source ownership gate', () => {
it('rejects inline endpoints in shipped bundle patches', () => {
const root = mkdtempSync(join(tmpdir(), 'dsh-config-source-ownership-'))
roots.push(root)
const directory = join(root, 'packages/bundle/base')
mkdirSync(directory, { recursive: true })
writeFileSync(
join(directory, 'cordis.patch.yml'),
'config:\n baseURL: !!js process.env.DEEPSEEK_SEARCH_BASE_URL\n',
)
expect(collectConfigSourceOwnershipViolations(root)).toEqual([
'packages/bundle/base/cordis.patch.yml:2: inlines a credential or endpoint from the environment.'
+ ' The adapter resolves apiKeyEnv through ctx.credentials and the endpoint through the'
+ ' environment snapshot; inlining here bypasses both ladders.',
])
})
})
+16 -9
View File
@@ -16,6 +16,7 @@ const SHIPPED_CONFIG_GLOBS = [
'apps/*/config/*.yml',
'examples/*/*.cordis.yml',
'examples/*/cordis.yml',
'packages/bundle/*/cordis.patch.yml',
// The Python runtime ships its own default composition inside the wheel.
'python/*/src/**/cordis.yml',
]
@@ -29,12 +30,13 @@ const SHIPPED_CONFIG_GLOBS = [
*/
const INLINE_DENY = /^\s*(apiKey|baseURL|apiKeyEnv|authToken|headers)\s*:\s*!!js\b/
const failures: string[] = []
for (const glob of SHIPPED_CONFIG_GLOBS) {
for (const file of globSync(glob, { cwd: ROOT })) {
/** Return every forbidden inline environment form in shipped configuration. */
export function collectConfigSourceOwnershipViolations(root: string): string[] {
const failures: string[] = []
for (const glob of SHIPPED_CONFIG_GLOBS) {
for (const file of globSync(glob, { cwd: root })) {
const rel = file.split(sep).join('/')
readFileSync(resolve(ROOT, rel), 'utf8').split('\n').forEach((line, index) => {
readFileSync(resolve(root, rel), 'utf8').split('\n').forEach((line, index) => {
if (!INLINE_DENY.test(line)) return
failures.push(
`${rel}:${String(index + 1)}: inlines a credential or endpoint from the environment.`
@@ -43,15 +45,20 @@ for (const glob of SHIPPED_CONFIG_GLOBS) {
)
})
}
}
return failures
}
if (failures.length > 0) {
if (process.argv[1] && import.meta.filename === resolve(process.argv[1])) {
const failures = collectConfigSourceOwnershipViolations(ROOT)
if (failures.length > 0) {
process.stderr.write('verify-config-source-ownership: configuration source ownership violated:\n')
for (const failure of failures) process.stderr.write(` ${failure}\n`)
process.exit(1)
}
}
process.stdout.write(
process.stdout.write(
'verify-config-source-ownership: no credential or endpoint uses the ordinary inline environment form'
+ ' in shipped configuration.\n',
)
)
}