fix(ms-ai-architect): broken dpia KB reference, remove orphaned hook script
commands/dpia.md: fix gdpr-compliance-ai-systems.md path from: references/norwegian-public-sector-governance/ to: references/responsible-ai/ (where the file actually lives) hooks/scripts/pre-edit-secrets.mjs: remove orphaned script that was never registered in hooks.json. Secrets scanning handled by llm-security. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
5e5b3d0946
commit
724cc1f9c8
2 changed files with 1 additions and 94 deletions
|
|
@ -43,7 +43,7 @@ Gjennomfør en komplett DPIA for følgende AI-system:
|
|||
|
||||
Les kunnskapsbasene:
|
||||
- skills/ms-ai-governance/references/norwegian-public-sector-governance/dpia-norwegian-methodology-ai.md
|
||||
- skills/ms-ai-governance/references/norwegian-public-sector-governance/gdpr-compliance-ai-systems.md
|
||||
- skills/ms-ai-governance/references/responsible-ai/gdpr-compliance-ai-systems.md
|
||||
- skills/ms-ai-governance/references/responsible-ai/ai-impact-assessment-framework.md
|
||||
|
||||
Lever en komplett DPIA-rapport med alle 5 faser, risikomatrise og anbefaling."
|
||||
|
|
|
|||
|
|
@ -1,93 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
// pre-edit-secrets.mjs
|
||||
// Scans file edits for potential secrets before allowing save (cross-platform, no jq dependency)
|
||||
//
|
||||
// Exit codes:
|
||||
// 0 = Allow edit
|
||||
// 2 = Block edit (secrets detected)
|
||||
|
||||
import { appendFileSync, mkdirSync, readFileSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
|
||||
const input = readFileSync(0, 'utf-8');
|
||||
|
||||
const { tool_input } = JSON.parse(input);
|
||||
const content = tool_input?.content ?? tool_input?.new_string ?? '';
|
||||
const filePath = tool_input?.file_path ?? tool_input?.path ?? '';
|
||||
|
||||
if (!content) process.exit(0);
|
||||
|
||||
// Skip test files, mocks, example/template files
|
||||
if (/\.(test|spec|mock)\.(ts|js|tsx|jsx)$|__tests__|__mocks__/.test(filePath)) {
|
||||
process.exit(0);
|
||||
}
|
||||
if (/\.(example|template|sample)(\..*)?$|\.env\.example|\.env\.template|\.env\.sample/.test(filePath)) {
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// === SECRET PATTERNS ===
|
||||
const SECRETS = [
|
||||
// AWS Keys
|
||||
[/AKIA[0-9A-Z]{16}/, 'AWS Access Key detected in edit.', 'Use environment variables instead.'],
|
||||
|
||||
// Generic API Keys
|
||||
[/(api[_-]?key|apikey)\s*[:=]\s*["'][a-zA-Z0-9]{20,}["']/, 'Potential API key detected.', 'Use environment variables (process.env.API_KEY) instead.'],
|
||||
|
||||
// Private keys
|
||||
[/-----BEGIN (RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/, 'Private key detected in edit.', 'Never commit private keys. Use environment variables or secret managers.'],
|
||||
|
||||
// JWT secrets
|
||||
[/(jwt[_-]?secret|JWT_SECRET)\s*[:=]\s*["'][^"']{10,}["']/, 'JWT secret detected.', 'Use environment variables instead.'],
|
||||
|
||||
// Database connection strings with passwords
|
||||
[/(postgres|mysql|mongodb):\/\/[^:]+:[^@]+@/, 'Database connection string with credentials detected.', 'Use environment variables for database URLs.'],
|
||||
|
||||
// Azure Storage connection strings
|
||||
[/DefaultEndpointsProtocol=https;AccountName=[^;]+;AccountKey=[A-Za-z0-9+/=]{40,}/, 'Azure Storage connection string with AccountKey detected.', 'Use DefaultAzureCredential or environment variables instead.'],
|
||||
|
||||
// Azure AD / Entra client secrets
|
||||
[/(client[_-]?secret|ClientSecret)\s*[:=]\s*["'][A-Za-z0-9~._-]{34,}["']/, 'Azure AD client secret detected.', 'Use managed identity or environment variables instead.'],
|
||||
|
||||
// Azure Cognitive Services / AI Services keys
|
||||
[/(Ocp-Apim-Subscription-Key|cognitive[_-]?key|ai[_-]?key)\s*[:=]\s*["'][0-9a-f]{32}["']/, 'Azure AI Services key detected.', 'Use DefaultAzureCredential or environment variables instead.'],
|
||||
|
||||
// Slack/Discord webhooks
|
||||
[/https:\/\/hooks\.(slack|discord)\.com\/services\/[A-Za-z0-9/]+/, 'Webhook URL detected.', 'Webhook URLs are secrets. Use environment variables.'],
|
||||
|
||||
// GitHub tokens
|
||||
[/(ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{36,}/, 'GitHub token detected.', null],
|
||||
];
|
||||
|
||||
for (const [pattern, reason, advice] of SECRETS) {
|
||||
if (pattern.test(content)) {
|
||||
process.stderr.write(`BLOCKED: ${reason}\n`);
|
||||
if (filePath) process.stderr.write(`File: ${filePath}\n`);
|
||||
if (advice) process.stderr.write(`${advice}\n`);
|
||||
logBlock('secrets', filePath || 'unknown');
|
||||
process.exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
// Generic password assignment (warning only, don't block)
|
||||
if (/password\s*[:=]\s*["'][^"']{8,}["']/.test(content)) {
|
||||
if (!/example|placeholder|xxx|your.?password/.test(content)) {
|
||||
process.stderr.write(`WARNING: Possible hardcoded password detected.\n`);
|
||||
if (filePath) process.stderr.write(`File: ${filePath}\n`);
|
||||
process.stderr.write(`Consider using environment variables.\n`);
|
||||
}
|
||||
}
|
||||
|
||||
process.exit(0);
|
||||
|
||||
// --- Audit logging ---
|
||||
function logBlock(hook, target) {
|
||||
try {
|
||||
const home = process.env.HOME || process.env.USERPROFILE || '';
|
||||
const dir = join(home, '.claude', 'audit');
|
||||
mkdirSync(dir, { recursive: true });
|
||||
const ts = new Date().toISOString();
|
||||
appendFileSync(join(dir, 'blocked.log'), `[${ts}] [${hook}] ${target}\n`);
|
||||
} catch {
|
||||
// Audit logging is best-effort
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue