Back to catalogue
WorkflowConfigChangeConfigChangeWhen configuration changes· non-blocking
Configuration change audit log
Records every change to a Claude Code configuration file (settings.json, skills, etc.) into a timestamped audit log for traceability and compliance.
Use cases
- Track who changed the Claude Code configuration and when
- Compliance audit on settings.json changes
- Detect unauthorized configuration changes
Providers & tags
Claude Code
#audit#config#compliance#logging
settings.json fragment
{
"hooks": {
"ConfigChange": [
{
"hooks": [
{
"command": "node $CLAUDE_PROJECT_DIR/.claude/hooks/config-audit-log.mjs",
"type": "command"
}
],
"matcher": ""
}
]
}
}Script · .claude/hooks/config-audit-log.mjs
#!/usr/bin/env node
// Journalise les changements de configuration Claude Code (ConfigChange)
import { readFileSync, appendFileSync, mkdirSync } from 'fs';
import { join } from 'path';
import { homedir } from 'os';
import { fileURLToPath } from 'url';
export function run(
input,
{
append = appendFileSync,
mkdir = mkdirSync,
home = homedir(),
projectDir = process.env.CLAUDE_PROJECT_DIR,
now = () => new Date().toISOString(),
} = {},
) {
const logDir = join(home, '.claude');
mkdir(logDir, { recursive: true });
const entry = {
ts: now(),
project: projectDir?.split('/').pop() ?? 'unknown',
change: input.change ?? input,
};
append(join(logDir, 'config-changes.jsonl'), JSON.stringify(entry) + '\n');
return { entry, message: '[config-audit] Changement journalise.\n' };
}
/* v8 ignore next 5 */
if (process.argv[1] === fileURLToPath(import.meta.url)) {
const input = JSON.parse(readFileSync(0, 'utf8'));
const result = run(input);
process.stderr.write(result.message);
}