feat(exporters): allowlist token-usage schema + assert metric export (CWE-212)
This commit is contained in:
parent
708ba04571
commit
a9c442c201
3 changed files with 81 additions and 0 deletions
|
|
@ -13,6 +13,7 @@ import {
|
|||
applyFieldAllowlist,
|
||||
POST_BASH_STATS_ALLOWED,
|
||||
EVENT_EMIT_PAYLOAD_ALLOWED,
|
||||
TOKEN_USAGE_ALLOWED,
|
||||
} from '../../lib/exporters/field-allowlist.mjs';
|
||||
|
||||
// ---- path-validator: CWE-22 mitigation -------------------------------------
|
||||
|
|
@ -241,6 +242,40 @@ test('field-allowlist: Object.freeze on allowlists (drift-pin)', () => {
|
|||
assert.equal(Object.isFrozen(POST_BASH_STATS_ALLOWED), true,
|
||||
'POST_BASH_STATS_ALLOWED must be frozen — runtime mutation prevention');
|
||||
assert.equal(Object.isFrozen(EVENT_EMIT_PAYLOAD_ALLOWED), true);
|
||||
assert.equal(Object.isFrozen(TOKEN_USAGE_ALLOWED), true,
|
||||
'TOKEN_USAGE_ALLOWED must be frozen — runtime mutation prevention');
|
||||
});
|
||||
|
||||
// ---- token-usage allowlist (SKAL-2, CWE-212) -------------------------------
|
||||
|
||||
test('field-allowlist: token-usage INCLUDES numeric/label fields, EXCLUDES session_id/transcript_path/cwd (two-sided)', () => {
|
||||
const record = {
|
||||
ts: '2026-06-26T12:00:00.000Z',
|
||||
session_id: 'uuid-secret',
|
||||
transcript_path: '/Users/ktg/.claude/projects/x/sesn.jsonl',
|
||||
cwd: '/Users/ktg/secret/project',
|
||||
scope: 'main-context',
|
||||
model: 'claude-opus-4-8',
|
||||
tokens_input: 12345,
|
||||
tokens_output: 6789,
|
||||
tokens_cache_creation: 400,
|
||||
tokens_cache_read: 5000,
|
||||
cost_usd: 0.42,
|
||||
is_estimate: false,
|
||||
price_table_version: '2026-06-26',
|
||||
};
|
||||
const out = applyFieldAllowlist(record, 'token-usage');
|
||||
// INCLUDED (numeric + low-cardinality labels)
|
||||
for (const k of ['tokens_input', 'tokens_output', 'tokens_cache_creation',
|
||||
'tokens_cache_read', 'cost_usd', 'is_estimate', 'price_table_version', 'scope', 'model']) {
|
||||
assert.equal(k in out, true, `${k} MUST be allowlisted`);
|
||||
}
|
||||
assert.equal(out.tokens_input, 12345);
|
||||
assert.equal(out._schema_id, 'token-usage');
|
||||
// EXCLUDED (CWE-212 boundary)
|
||||
assert.equal('session_id' in out, false, 'session_id MUST be stripped (CWE-212)');
|
||||
assert.equal('transcript_path' in out, false, 'transcript_path MUST be stripped (CWE-212)');
|
||||
assert.equal('cwd' in out, false, 'cwd MUST be stripped (CWE-212)');
|
||||
});
|
||||
|
||||
test('field-allowlist: null/undefined record handled safely', () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue