chore(tools): add secret scanning gate

This commit is contained in:
Danila Poyarkov 2026-07-01 15:24:06 +03:00
parent b709af1850
commit 2d2d7250bb
4 changed files with 82 additions and 1 deletions

47
.gitleaks.toml Normal file
View file

@ -0,0 +1,47 @@
title = "OpenPencil Gitleaks configuration"
[extend]
useDefault = true
[[allowlists]]
description = "Local and generated artifacts"
paths = [
'''(^|/)\.env$''',
'''(^|/)\.worktrees/''',
'''(^|/)dist/''',
'''(^|/)node_modules/''',
'''^desktop/target/''',
'''^packages/[^/]+/dist/''',
'''^test-results/''',
'''^scratch/'''
]
[[allowlists]]
description = "Public Google Fonts browser API key"
regexTarget = "line"
paths = ['''packages/core/src/constants\.ts''']
regexes = ['''GOOGLE_FONTS_API_KEY''']
[[allowlists]]
description = "Keyboard shortcut metadata is not a secret"
regexTarget = "line"
paths = ['''packages/vue/src/editor/commands/registry\.ts''']
regexes = ['''keybinding:\s*['\"][^'\"]+['\"]''']
[[allowlists]]
description = "Documented dummy OpenRouter test key"
regexTarget = "line"
paths = ['''tests/e2e/chat/panel\.spec\.ts''']
regexes = ['''sk-or-test-key-12345''']
[[allowlists]]
description = "Figma fixture identifiers are public test metadata"
regexTarget = "line"
paths = [
'''tests/engine/io/fig/heavy/component-metadata\.test\.ts''',
'''tests/fixtures/figma-oracles/.*\.json'''
]
regexes = [
'''componentKey''',
'''"fileKey"'''
]

View file

@ -26,9 +26,10 @@
"lint:structure": "oxlint -c oxlint.json vite.config.ts vite/ src/ packages/scene-graph/src/ packages/scene-graph/scripts/ packages/core/src/ packages/vue/src/ packages/cli/src/ packages/mcp/src/ packages/dom-css/src/ packages/dom-css/tests/ packages/dom-css/scripts/ packages/pen/src/ packages/pen/scripts/ packages/kiwi/src/ packages/kiwi/tests/ packages/kiwi/scripts/ packages/fig/src/ packages/fig/tests/ packages/fig/scripts/ tests/ scripts/ tools/",
"format": "oxfmt --write .oxfmtrc.json vite.config.ts vite/ src/ packages/scene-graph/src/ packages/scene-graph/scripts/ packages/core/src/ packages/cli/src/ packages/mcp/src/ packages/vue/src/ packages/dom-css/src/ packages/dom-css/tests/ packages/dom-css/scripts/ packages/pen/src/ packages/pen/scripts/ packages/kiwi/src/ packages/kiwi/tests/ packages/kiwi/scripts/ packages/fig/src/ packages/fig/tests/ packages/fig/scripts/ tests scripts/ tools/",
"format:check": "bun run format && status=$(git status --porcelain -uall) && test -z \"$status\" || (echo \"$status\" && exit 1)",
"check": "bun run build:packages && bun run lint && tsgo --noEmit && bun run check:vue && bun run check:i18n && bun run check:packages && bun run check:deps && bun run check:audit && bun run check:monorepo && bun run check:arch && bun run test:type-shapes && bun run test:tools && bun run test:dupes",
"check": "bun run build:packages && bun run lint && tsgo --noEmit && bun run check:vue && bun run check:i18n && bun run check:packages && bun run check:deps && bun run check:audit && bun run check:secrets && bun run check:monorepo && bun run check:arch && bun run test:type-shapes && bun run test:tools && bun run test:dupes",
"check:deps": "knip --include unlisted,unresolved,binaries",
"check:audit": "bun audit --audit-level=critical",
"check:secrets": "bun tools/secret-scan/src/index.ts",
"check:monorepo": "sherif --ignore-rule root-package-dependencies",
"check:i18n": "bun tools/i18n/src/check-locales.ts",
"check:packages": "bun tools/package-quality/src/check/metadata.ts && bun tools/package-quality/src/check/publint.ts && bun tools/package-quality/src/check/attw.ts",

View file

@ -0,0 +1,6 @@
{
"name": "@open-pencil/tools-secret-scan",
"version": "0.0.0",
"private": true,
"type": "module"
}

View file

@ -0,0 +1,27 @@
const GITLEAKS_VERSION = 'v8.30.1'
const GITLEAKS_MODULE = `github.com/zricethezav/gitleaks/v8@${GITLEAKS_VERSION}`
const gitleaksArgs = ['dir', '--config', '.gitleaks.toml', '--redact', '--no-banner', '.']
function run(command: string, args: string[]): Bun.SpawnSyncReturns<Buffer> | null {
try {
return Bun.spawnSync([command, ...args], {
stdout: 'inherit',
stderr: 'inherit'
})
} catch (error) {
if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
return null
}
throw error
}
}
const proc = run('gitleaks', gitleaksArgs) ?? run('go', ['run', GITLEAKS_MODULE, ...gitleaksArgs])
if (!proc?.success) {
console.error('Secret scan failed.')
process.exit(proc?.exitCode || 1)
}
console.log('Secret scan passed.')