promptkaizen-agent 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -3
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +4 -1
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/install-systemd.d.ts +17 -0
- package/dist/cli/install-systemd.d.ts.map +1 -0
- package/dist/cli/install-systemd.js +96 -0
- package/dist/cli/install-systemd.js.map +1 -0
- package/dist/cli/start.d.ts.map +1 -1
- package/dist/cli/start.js +43 -2
- package/dist/cli/start.js.map +1 -1
- package/dist/cli/status.d.ts.map +1 -1
- package/dist/cli/status.js +24 -2
- package/dist/cli/status.js.map +1 -1
- package/dist/cli/uninstall-systemd.d.ts +8 -0
- package/dist/cli/uninstall-systemd.d.ts.map +1 -0
- package/dist/cli/uninstall-systemd.js +58 -0
- package/dist/cli/uninstall-systemd.js.map +1 -0
- package/dist/config.d.ts +61 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +31 -1
- package/dist/config.js.map +1 -1
- package/dist/detection-secret.d.ts +8 -0
- package/dist/detection-secret.d.ts.map +1 -0
- package/dist/detection-secret.js +37 -0
- package/dist/detection-secret.js.map +1 -0
- package/dist/index.js +13 -5
- package/dist/index.js.map +1 -1
- package/dist/mask-rules-fetcher.d.ts +15 -0
- package/dist/mask-rules-fetcher.d.ts.map +1 -0
- package/dist/mask-rules-fetcher.js +67 -0
- package/dist/mask-rules-fetcher.js.map +1 -0
- package/dist/pii-masker.d.ts +48 -1
- package/dist/pii-masker.d.ts.map +1 -1
- package/dist/pii-masker.js +144 -41
- package/dist/pii-masker.js.map +1 -1
- package/dist/secret-detector.d.ts +82 -0
- package/dist/secret-detector.d.ts.map +1 -0
- package/dist/secret-detector.js +400 -0
- package/dist/secret-detector.js.map +1 -0
- package/dist/types.d.ts +12 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export type DetectionCategory = 'secret' | 'pii' | 'pii_jp' | 'custom';
|
|
2
|
+
export type DetectionSeverity = 'low' | 'medium' | 'high';
|
|
3
|
+
/** 1 entry あたりの検知メタ上限。超過分は重大度順 (high>medium>low) で切り捨てる。 */
|
|
4
|
+
export declare const MAX_DETECTIONS_PER_ENTRY = 50;
|
|
5
|
+
/** 1 entry 内で同一 ruleId にまとめた検知メタ。生機密本文は含まない。 */
|
|
6
|
+
export interface DetectionMeta {
|
|
7
|
+
category: DetectionCategory;
|
|
8
|
+
ruleId: string;
|
|
9
|
+
severity: DetectionSeverity;
|
|
10
|
+
/** この entry 内での出現回数。 */
|
|
11
|
+
count: number;
|
|
12
|
+
/**
|
|
13
|
+
* 復元不能なマスク済みプレビュー。識別補助用。
|
|
14
|
+
* secret/custom は先頭4+末尾2 (例: `sk-a…yz`)、pii/pii_jp は末尾2のみ (例: `…18`)。
|
|
15
|
+
*/
|
|
16
|
+
maskedPreview: string;
|
|
17
|
+
/**
|
|
18
|
+
* マッチ値の一方向ハッシュ先頭 12 桁。重複排除/相関用 (本文は復元不能)。
|
|
19
|
+
* pii/pii_jp はローカル鍵による HMAC-SHA256 (低エントロピー値の総当たり復元対策)、
|
|
20
|
+
* secret/custom は sha256。鍵はクラウドへ送らない。
|
|
21
|
+
*/
|
|
22
|
+
matchHash: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function normalizeForDetection(text: string): string;
|
|
25
|
+
/** クレジットカード番号の Luhn チェック (13〜19 桁)。 */
|
|
26
|
+
export declare function luhnValid(value: string): boolean;
|
|
27
|
+
/** マイナンバー (個人番号, 12 桁) のチェックデジット検証。 */
|
|
28
|
+
export declare function isValidMyNumber(value: string): boolean;
|
|
29
|
+
/** 法人番号 (13 桁) のチェックデジット検証 (先頭 1 桁が検査数字)。 */
|
|
30
|
+
export declare function isValidCorporateNumber(value: string): boolean;
|
|
31
|
+
/** Shannon エントロピー (bits/char)。高エントロピー文字列の「シークレットらしさ」。 */
|
|
32
|
+
export declare function shannonEntropy(s: string): number;
|
|
33
|
+
/**
|
|
34
|
+
* 復元不能なマスク済みプレビュー。
|
|
35
|
+
* - pii / pii_jp: 末尾 2 文字のみ可視 (`…18`)。マイナンバー等の低エントロピー値は
|
|
36
|
+
* 先頭を見せると桁の大半が漏れるため、先頭は一切露出しない。
|
|
37
|
+
* - secret / custom: 先頭 4 + 末尾 2 文字のみ可視 (`sk-a…yz`)。prefix によるキー種別の
|
|
38
|
+
* 識別性を優先 (高エントロピー値のため 6 文字露出しても復元不能)。
|
|
39
|
+
*/
|
|
40
|
+
export declare function maskMatch(value: string, category?: DetectionCategory): string;
|
|
41
|
+
/** マッチ値の sha256 先頭 12 桁 (secret/custom 用の一方向変換)。 */
|
|
42
|
+
export declare function hashMatch(value: string): string;
|
|
43
|
+
/**
|
|
44
|
+
* マッチ値の HMAC-SHA256 先頭 12 桁 (pii/pii_jp 用)。
|
|
45
|
+
* マイナンバー (10^12 通り) のような低エントロピー値は無塩 sha256 だと総当たりで
|
|
46
|
+
* 復元できてしまうため、ローカル鍵 (クラウドへ送らない) で鍵付きハッシュにする。
|
|
47
|
+
*/
|
|
48
|
+
export declare function hmacHash(value: string, secret: string): string;
|
|
49
|
+
/**
|
|
50
|
+
* 任意のパース済み値 (entry.raw) から全 string を再帰収集して連結する。
|
|
51
|
+
* JSON.stringify だとエスケープ (\n, \") でパターンが壊れるため、生の string を集める。
|
|
52
|
+
* maxChars で総量を上限化 (巨大 entry でのメモリ/CPU 暴発を防止)。
|
|
53
|
+
*/
|
|
54
|
+
export declare function collectStrings(value: unknown, maxChars?: number): string;
|
|
55
|
+
export interface CustomDictionaryEntry {
|
|
56
|
+
ruleId: string;
|
|
57
|
+
/** 正規表現文字列 (global flag は自動付与)。 */
|
|
58
|
+
pattern: string;
|
|
59
|
+
severity?: DetectionSeverity;
|
|
60
|
+
}
|
|
61
|
+
export interface SecretDetectorOptions {
|
|
62
|
+
/** 組織/ユーザー登録のカスタム辞書 (#21 連携。category='custom')。 */
|
|
63
|
+
customDictionary?: CustomDictionaryEntry[];
|
|
64
|
+
/** 高エントロピー検出を有効にするか (既定 true)。 */
|
|
65
|
+
enableEntropy?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* pii/pii_jp の matchHash (HMAC-SHA256) に使うローカル鍵。クラウドへ送らないこと。
|
|
68
|
+
* 通常は loadOrCreateDetectionSecret() (agent 設定 or 初回起動時生成) を渡す。
|
|
69
|
+
* 未指定時はプロセス内ランダム鍵に fallback する (無塩 sha256 には決して戻さない。
|
|
70
|
+
* 相関がプロセス内に限定されるだけで、安全側に倒れる)。
|
|
71
|
+
*/
|
|
72
|
+
hmacSecret?: string;
|
|
73
|
+
}
|
|
74
|
+
export declare class SecretDetector {
|
|
75
|
+
private readonly rules;
|
|
76
|
+
private readonly enableEntropy;
|
|
77
|
+
private readonly hmacSecret;
|
|
78
|
+
constructor(opts?: SecretDetectorOptions);
|
|
79
|
+
/** テキストから検知メタを返す。生機密本文は保持しない。 */
|
|
80
|
+
detect(text: string): DetectionMeta[];
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=secret-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret-detector.d.ts","sourceRoot":"","sources":["../src/secret-detector.ts"],"names":[],"mappings":"AAgBA,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAA;AACtE,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEzD,4DAA4D;AAC5D,eAAO,MAAM,wBAAwB,KAAK,CAAA;AAE1C,gDAAgD;AAChD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,wBAAwB;IACxB,KAAK,EAAE,MAAM,CAAA;IACb;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAA;CAClB;AAqBD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI1D;AAMD,uCAAuC;AACvC,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAehD;AAED,uCAAuC;AACvC,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CActD;AAED,6CAA6C;AAC7C,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAc7D;AAED,yDAAyD;AACzD,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAUhD;AAMD;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAQ7E;AAED,oDAAoD;AACpD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,SAAU,GAAG,MAAM,CAgBzE;AA2ID,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAA;IACd,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,iBAAiB,CAAA;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACpC,mDAAmD;IACnD,gBAAgB,CAAC,EAAE,qBAAqB,EAAE,CAAA;IAC1C,kCAAkC;IAClC,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAID,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;gBAEvB,IAAI,GAAE,qBAA0B;IAqB5C,iCAAiC;IACjC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE;CA8FtC"}
|
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SecretDetector = exports.MAX_DETECTIONS_PER_ENTRY = void 0;
|
|
4
|
+
exports.normalizeForDetection = normalizeForDetection;
|
|
5
|
+
exports.luhnValid = luhnValid;
|
|
6
|
+
exports.isValidMyNumber = isValidMyNumber;
|
|
7
|
+
exports.isValidCorporateNumber = isValidCorporateNumber;
|
|
8
|
+
exports.shannonEntropy = shannonEntropy;
|
|
9
|
+
exports.maskMatch = maskMatch;
|
|
10
|
+
exports.hashMatch = hashMatch;
|
|
11
|
+
exports.hmacHash = hmacHash;
|
|
12
|
+
exports.collectStrings = collectStrings;
|
|
13
|
+
const crypto_1 = require("crypto");
|
|
14
|
+
/** 1 entry あたりの検知メタ上限。超過分は重大度順 (high>medium>low) で切り捨てる。 */
|
|
15
|
+
exports.MAX_DETECTIONS_PER_ENTRY = 50;
|
|
16
|
+
// ---------------------------------------------
|
|
17
|
+
// 正規化前処理 (全角→半角 / 単一桁の漢数字→算用数字)
|
|
18
|
+
// ---------------------------------------------
|
|
19
|
+
// NFKC で全角英数字・記号を半角化 (例: SK-… / 123 → SK-… / 123)。
|
|
20
|
+
// 漢数字は位取り (十/百/千) の誤変換を避け、単一桁文字のみ算用数字へ寄せる。
|
|
21
|
+
const KANJI_DIGITS = {
|
|
22
|
+
〇: '0',
|
|
23
|
+
零: '0',
|
|
24
|
+
一: '1',
|
|
25
|
+
二: '2',
|
|
26
|
+
三: '3',
|
|
27
|
+
四: '4',
|
|
28
|
+
五: '5',
|
|
29
|
+
六: '6',
|
|
30
|
+
七: '7',
|
|
31
|
+
八: '8',
|
|
32
|
+
九: '9',
|
|
33
|
+
};
|
|
34
|
+
function normalizeForDetection(text) {
|
|
35
|
+
let t = text.normalize('NFKC');
|
|
36
|
+
t = t.replace(/[〇零一二三四五六七八九]/g, (c) => KANJI_DIGITS[c] ?? c);
|
|
37
|
+
return t;
|
|
38
|
+
}
|
|
39
|
+
// ---------------------------------------------
|
|
40
|
+
// 検証ヘルパ (誤検知抑制)
|
|
41
|
+
// ---------------------------------------------
|
|
42
|
+
/** クレジットカード番号の Luhn チェック (13〜19 桁)。 */
|
|
43
|
+
function luhnValid(value) {
|
|
44
|
+
const digits = value.replace(/\D/g, '');
|
|
45
|
+
if (digits.length < 13 || digits.length > 19)
|
|
46
|
+
return false;
|
|
47
|
+
let sum = 0;
|
|
48
|
+
let alt = false;
|
|
49
|
+
for (let i = digits.length - 1; i >= 0; i--) {
|
|
50
|
+
let d = Number(digits[i]);
|
|
51
|
+
if (alt) {
|
|
52
|
+
d *= 2;
|
|
53
|
+
if (d > 9)
|
|
54
|
+
d -= 9;
|
|
55
|
+
}
|
|
56
|
+
sum += d;
|
|
57
|
+
alt = !alt;
|
|
58
|
+
}
|
|
59
|
+
return sum % 10 === 0;
|
|
60
|
+
}
|
|
61
|
+
/** マイナンバー (個人番号, 12 桁) のチェックデジット検証。 */
|
|
62
|
+
function isValidMyNumber(value) {
|
|
63
|
+
const d = value.replace(/\D/g, '');
|
|
64
|
+
if (!/^\d{12}$/.test(d))
|
|
65
|
+
return false;
|
|
66
|
+
const body = d.slice(0, 11);
|
|
67
|
+
const check = Number(d[11]);
|
|
68
|
+
let sum = 0;
|
|
69
|
+
for (let n = 1; n <= 11; n++) {
|
|
70
|
+
const pn = Number(body[11 - n]); // body 最下位を 1 桁目
|
|
71
|
+
const qn = n <= 6 ? n + 1 : n - 5;
|
|
72
|
+
sum += pn * qn;
|
|
73
|
+
}
|
|
74
|
+
const r = sum % 11;
|
|
75
|
+
const expected = r <= 1 ? 0 : 11 - r;
|
|
76
|
+
return expected === check;
|
|
77
|
+
}
|
|
78
|
+
/** 法人番号 (13 桁) のチェックデジット検証 (先頭 1 桁が検査数字)。 */
|
|
79
|
+
function isValidCorporateNumber(value) {
|
|
80
|
+
const d = value.replace(/\D/g, '');
|
|
81
|
+
if (!/^\d{13}$/.test(d))
|
|
82
|
+
return false;
|
|
83
|
+
const check = Number(d[0]);
|
|
84
|
+
const body = d.slice(1); // 12 桁
|
|
85
|
+
let sum = 0;
|
|
86
|
+
for (let n = 1; n <= 12; n++) {
|
|
87
|
+
const pn = Number(body[12 - n]);
|
|
88
|
+
const qn = n % 2 === 1 ? 1 : 2;
|
|
89
|
+
sum += pn * qn;
|
|
90
|
+
}
|
|
91
|
+
const r = sum % 9;
|
|
92
|
+
const expected = 9 - r;
|
|
93
|
+
return expected === check;
|
|
94
|
+
}
|
|
95
|
+
/** Shannon エントロピー (bits/char)。高エントロピー文字列の「シークレットらしさ」。 */
|
|
96
|
+
function shannonEntropy(s) {
|
|
97
|
+
if (s.length === 0)
|
|
98
|
+
return 0;
|
|
99
|
+
const freq = {};
|
|
100
|
+
for (const ch of s)
|
|
101
|
+
freq[ch] = (freq[ch] ?? 0) + 1;
|
|
102
|
+
let e = 0;
|
|
103
|
+
for (const k of Object.keys(freq)) {
|
|
104
|
+
const p = freq[k] / s.length;
|
|
105
|
+
e -= p * Math.log2(p);
|
|
106
|
+
}
|
|
107
|
+
return e;
|
|
108
|
+
}
|
|
109
|
+
// エントロピー検出の閾値 (誤検知抑制のため正規表現と併用)。詳細は docs 参照。
|
|
110
|
+
const ENTROPY_MIN_LENGTH = 20;
|
|
111
|
+
const ENTROPY_THRESHOLD = 4.0; // bits/char
|
|
112
|
+
/**
|
|
113
|
+
* 復元不能なマスク済みプレビュー。
|
|
114
|
+
* - pii / pii_jp: 末尾 2 文字のみ可視 (`…18`)。マイナンバー等の低エントロピー値は
|
|
115
|
+
* 先頭を見せると桁の大半が漏れるため、先頭は一切露出しない。
|
|
116
|
+
* - secret / custom: 先頭 4 + 末尾 2 文字のみ可視 (`sk-a…yz`)。prefix によるキー種別の
|
|
117
|
+
* 識別性を優先 (高エントロピー値のため 6 文字露出しても復元不能)。
|
|
118
|
+
*/
|
|
119
|
+
function maskMatch(value, category) {
|
|
120
|
+
const v = value.trim();
|
|
121
|
+
if (category === 'pii' || category === 'pii_jp') {
|
|
122
|
+
if (v.length <= 2)
|
|
123
|
+
return '*'.repeat(Math.max(1, v.length));
|
|
124
|
+
return `…${v.slice(-2)}`;
|
|
125
|
+
}
|
|
126
|
+
if (v.length <= 8)
|
|
127
|
+
return v[0] + '*'.repeat(Math.max(1, v.length - 1));
|
|
128
|
+
return `${v.slice(0, 4)}…${v.slice(-2)}`;
|
|
129
|
+
}
|
|
130
|
+
/** マッチ値の sha256 先頭 12 桁 (secret/custom 用の一方向変換)。 */
|
|
131
|
+
function hashMatch(value) {
|
|
132
|
+
return (0, crypto_1.createHash)('sha256').update(value).digest('hex').slice(0, 12);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* マッチ値の HMAC-SHA256 先頭 12 桁 (pii/pii_jp 用)。
|
|
136
|
+
* マイナンバー (10^12 通り) のような低エントロピー値は無塩 sha256 だと総当たりで
|
|
137
|
+
* 復元できてしまうため、ローカル鍵 (クラウドへ送らない) で鍵付きハッシュにする。
|
|
138
|
+
*/
|
|
139
|
+
function hmacHash(value, secret) {
|
|
140
|
+
return (0, crypto_1.createHmac)('sha256', secret).update(value).digest('hex').slice(0, 12);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* 任意のパース済み値 (entry.raw) から全 string を再帰収集して連結する。
|
|
144
|
+
* JSON.stringify だとエスケープ (\n, \") でパターンが壊れるため、生の string を集める。
|
|
145
|
+
* maxChars で総量を上限化 (巨大 entry でのメモリ/CPU 暴発を防止)。
|
|
146
|
+
*/
|
|
147
|
+
function collectStrings(value, maxChars = 200_000) {
|
|
148
|
+
const parts = [];
|
|
149
|
+
let total = 0;
|
|
150
|
+
const walk = (v) => {
|
|
151
|
+
if (total >= maxChars)
|
|
152
|
+
return;
|
|
153
|
+
if (typeof v === 'string') {
|
|
154
|
+
parts.push(v);
|
|
155
|
+
total += v.length;
|
|
156
|
+
}
|
|
157
|
+
else if (Array.isArray(v)) {
|
|
158
|
+
for (const x of v)
|
|
159
|
+
walk(x);
|
|
160
|
+
}
|
|
161
|
+
else if (v !== null && typeof v === 'object') {
|
|
162
|
+
for (const x of Object.values(v))
|
|
163
|
+
walk(x);
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
walk(value);
|
|
167
|
+
return parts.join('\n');
|
|
168
|
+
}
|
|
169
|
+
// 都道府県 (住所検出用)。
|
|
170
|
+
const PREFECTURES = '北海道|青森県|岩手県|宮城県|秋田県|山形県|福島県|茨城県|栃木県|群馬県|埼玉県|千葉県|東京都|神奈川県|新潟県|富山県|石川県|福井県|山梨県|長野県|岐阜県|静岡県|愛知県|三重県|滋賀県|京都府|大阪府|兵庫県|奈良県|和歌山県|鳥取県|島根県|岡山県|広島県|山口県|徳島県|香川県|愛媛県|高知県|福岡県|佐賀県|長崎県|熊本県|大分県|宮崎県|鹿児島県|沖縄県';
|
|
171
|
+
// 全ルールは正規化済みテキスト (NFKC + 漢数字寄せ) に対して実行する。
|
|
172
|
+
const BUILTIN_RULES = [
|
|
173
|
+
// --- シークレット ---
|
|
174
|
+
// Anthropic を OpenAR より先に: OpenAI 側は sk-ant- を negative lookahead で除外。
|
|
175
|
+
{
|
|
176
|
+
ruleId: 'anthropic_key',
|
|
177
|
+
category: 'secret',
|
|
178
|
+
severity: 'high',
|
|
179
|
+
regex: /sk-ant-(?:api|oat|ort)\d+-[A-Za-z0-9_-]{40,}/g,
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
ruleId: 'openai_key',
|
|
183
|
+
category: 'secret',
|
|
184
|
+
severity: 'high',
|
|
185
|
+
regex: /sk-(?!ant-)(?:proj-)?[A-Za-z0-9]{40,}/g,
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
ruleId: 'github_token',
|
|
189
|
+
category: 'secret',
|
|
190
|
+
severity: 'high',
|
|
191
|
+
regex: /gh[pousr]_[A-Za-z0-9]{36}/g,
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
ruleId: 'slack_token',
|
|
195
|
+
category: 'secret',
|
|
196
|
+
severity: 'high',
|
|
197
|
+
regex: /xox[baprs]-[A-Za-z0-9-]{10,}/g,
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
ruleId: 'aws_access_key',
|
|
201
|
+
category: 'secret',
|
|
202
|
+
severity: 'high',
|
|
203
|
+
regex: /\bAKIA[0-9A-Z]{16}\b/g,
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
ruleId: 'gcp_api_key',
|
|
207
|
+
category: 'secret',
|
|
208
|
+
severity: 'high',
|
|
209
|
+
regex: /\bAIza[0-9A-Za-z_-]{35}\b/g,
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
ruleId: 'private_key_block',
|
|
213
|
+
category: 'secret',
|
|
214
|
+
severity: 'high',
|
|
215
|
+
regex: /-----BEGIN (?:RSA |EC |OPENSSH |DSA |PGP )?PRIVATE KEY-----/g,
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
ruleId: 'jwt',
|
|
219
|
+
category: 'secret',
|
|
220
|
+
severity: 'medium',
|
|
221
|
+
regex: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g,
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
ruleId: 'bearer_token',
|
|
225
|
+
category: 'secret',
|
|
226
|
+
severity: 'medium',
|
|
227
|
+
regex: /Bearer\s+[A-Za-z0-9._-]{20,}/g,
|
|
228
|
+
},
|
|
229
|
+
// --- PII (汎用) ---
|
|
230
|
+
{
|
|
231
|
+
ruleId: 'email',
|
|
232
|
+
category: 'pii',
|
|
233
|
+
severity: 'low',
|
|
234
|
+
regex: /[a-zA-Z0-9._%+-]{2,}@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
ruleId: 'credit_card',
|
|
238
|
+
category: 'pii',
|
|
239
|
+
severity: 'high',
|
|
240
|
+
// 13〜19 桁を区切り (空白/ハイフン) 込みで候補化し Luhn 検証。
|
|
241
|
+
regex: /\b(?:\d[ -]?){12,18}\d\b/g,
|
|
242
|
+
validate: luhnValid,
|
|
243
|
+
},
|
|
244
|
+
// --- 日本語 PII (APPI の個人情報・個人識別符号) ---
|
|
245
|
+
{
|
|
246
|
+
ruleId: 'jp_mynumber',
|
|
247
|
+
category: 'pii_jp',
|
|
248
|
+
severity: 'high',
|
|
249
|
+
regex: /\b\d{4}[\s-]?\d{4}[\s-]?\d{4}\b/g,
|
|
250
|
+
validate: isValidMyNumber,
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
ruleId: 'jp_corporate_number',
|
|
254
|
+
category: 'pii_jp',
|
|
255
|
+
severity: 'medium',
|
|
256
|
+
regex: /\b\d{13}\b/g,
|
|
257
|
+
validate: isValidCorporateNumber,
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
ruleId: 'jp_phone',
|
|
261
|
+
category: 'pii_jp',
|
|
262
|
+
severity: 'medium',
|
|
263
|
+
// 携帯 (070/080/090) / フリーダイヤル (0120,0800) / 固定 (区切り必須)。
|
|
264
|
+
regex: /\b0[789]0-\d{4}-\d{4}\b|\b0120-\d{3}-\d{3}\b|\b0800-\d{3}-\d{4}\b|\b0\d{1,3}-\d{2,4}-\d{4}\b/g,
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
ruleId: 'jp_postal',
|
|
268
|
+
category: 'pii_jp',
|
|
269
|
+
severity: 'low',
|
|
270
|
+
// 電話番号の一部 (前後に数字/ハイフン) を除外。〒 付きは可視性が高い。
|
|
271
|
+
regex: /(?<![\d-])(?:〒\s?)?\d{3}-\d{4}(?![\d-])/g,
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
ruleId: 'jp_address',
|
|
275
|
+
category: 'pii_jp',
|
|
276
|
+
severity: 'medium',
|
|
277
|
+
regex: new RegExp(`(?:${PREFECTURES})[^\\s「」、。]{0,18}?[市区町村郡][^\\s「」、。]{0,20}?(?:\\d+|[十百千]+)(?:丁目|番地|番|-|−)`, 'g'),
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
ruleId: 'jp_wareki_date',
|
|
281
|
+
category: 'pii_jp',
|
|
282
|
+
severity: 'low',
|
|
283
|
+
regex: /(?:令和|平成|昭和|大正|明治)\s?(?:元|\d{1,2})\s?年(?:\s?\d{1,2}\s?月(?:\s?\d{1,2}\s?日)?)?/g,
|
|
284
|
+
},
|
|
285
|
+
];
|
|
286
|
+
const SEVERITY_RANK = { high: 0, medium: 1, low: 2 };
|
|
287
|
+
class SecretDetector {
|
|
288
|
+
rules;
|
|
289
|
+
enableEntropy;
|
|
290
|
+
hmacSecret;
|
|
291
|
+
constructor(opts = {}) {
|
|
292
|
+
const custom = (opts.customDictionary ?? [])
|
|
293
|
+
.map((e) => {
|
|
294
|
+
try {
|
|
295
|
+
return {
|
|
296
|
+
ruleId: e.ruleId,
|
|
297
|
+
category: 'custom',
|
|
298
|
+
severity: e.severity ?? 'medium',
|
|
299
|
+
regex: new RegExp(e.pattern, 'g'),
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
catch {
|
|
303
|
+
// 不正な正規表現は無視 (辞書のせいで検知全体を落とさない)。
|
|
304
|
+
return null;
|
|
305
|
+
}
|
|
306
|
+
})
|
|
307
|
+
.filter((r) => r !== null);
|
|
308
|
+
this.rules = [...BUILTIN_RULES, ...custom];
|
|
309
|
+
this.enableEntropy = opts.enableEntropy ?? true;
|
|
310
|
+
this.hmacSecret = opts.hmacSecret ?? (0, crypto_1.randomBytes)(32).toString('hex');
|
|
311
|
+
}
|
|
312
|
+
/** テキストから検知メタを返す。生機密本文は保持しない。 */
|
|
313
|
+
detect(text) {
|
|
314
|
+
if (!text)
|
|
315
|
+
return [];
|
|
316
|
+
const norm = normalizeForDetection(text);
|
|
317
|
+
const rawHits = [];
|
|
318
|
+
for (const rule of this.rules) {
|
|
319
|
+
rule.regex.lastIndex = 0;
|
|
320
|
+
let m;
|
|
321
|
+
while ((m = rule.regex.exec(norm)) !== null) {
|
|
322
|
+
const matched = m[0];
|
|
323
|
+
// ゼロ幅マッチの無限ループ回避。
|
|
324
|
+
if (m.index === rule.regex.lastIndex)
|
|
325
|
+
rule.regex.lastIndex++;
|
|
326
|
+
if (rule.validate && !rule.validate(matched))
|
|
327
|
+
continue;
|
|
328
|
+
rawHits.push({
|
|
329
|
+
ruleId: rule.ruleId,
|
|
330
|
+
category: rule.category,
|
|
331
|
+
severity: rule.severity,
|
|
332
|
+
value: matched,
|
|
333
|
+
start: m.index,
|
|
334
|
+
end: m.index + matched.length,
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
// スパン重複除外 (secret カテゴリのみ): 同一箇所を複数ルールが拾う二重計上を防ぐ。
|
|
339
|
+
// 例: `Bearer eyJ…` は jwt と bearer_token の両方にマッチする。ルール定義順
|
|
340
|
+
// (特異的なルールが先) を優先し、重複した後段ルールのヒットは破棄する。
|
|
341
|
+
// pii/pii_jp は別個の値が隣接し得る (住所+郵便番号等) ため対象外。
|
|
342
|
+
const hits = [];
|
|
343
|
+
for (const h of rawHits) {
|
|
344
|
+
const dup = h.category === 'secret' &&
|
|
345
|
+
hits.some((a) => a.category === 'secret' && a.ruleId !== h.ruleId && h.start < a.end && a.start < h.end);
|
|
346
|
+
if (!dup)
|
|
347
|
+
hits.push(h);
|
|
348
|
+
}
|
|
349
|
+
const matchedValues = hits.map((h) => h.value);
|
|
350
|
+
if (this.enableEntropy) {
|
|
351
|
+
for (const token of norm.split(/[^A-Za-z0-9+/=_-]+/)) {
|
|
352
|
+
if (token.length < ENTROPY_MIN_LENGTH)
|
|
353
|
+
continue;
|
|
354
|
+
// 英字と数字が混在する文字列のみ (英文/数字列の誤検出を抑制)。
|
|
355
|
+
if (!(/[A-Za-z]/.test(token) && /\d/.test(token)))
|
|
356
|
+
continue;
|
|
357
|
+
if (shannonEntropy(token) < ENTROPY_THRESHOLD)
|
|
358
|
+
continue;
|
|
359
|
+
// 既存の正規表現ヒットと重複するトークンは二重計上しない。
|
|
360
|
+
if (matchedValues.some((v) => v.includes(token) || token.includes(v)))
|
|
361
|
+
continue;
|
|
362
|
+
// start/end は重複除外 (上で完了済み) では使わないため -1 で埋める。
|
|
363
|
+
hits.push({
|
|
364
|
+
ruleId: 'high_entropy',
|
|
365
|
+
category: 'secret',
|
|
366
|
+
severity: 'medium',
|
|
367
|
+
value: token,
|
|
368
|
+
start: -1,
|
|
369
|
+
end: -1,
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
// (category, ruleId) ごとに集約。生 value はここで preview/hash に変換して破棄。
|
|
374
|
+
const groups = new Map();
|
|
375
|
+
for (const h of hits) {
|
|
376
|
+
const key = `${h.category}:${h.ruleId}`;
|
|
377
|
+
const cur = groups.get(key);
|
|
378
|
+
if (cur)
|
|
379
|
+
cur.values.push(h.value);
|
|
380
|
+
else
|
|
381
|
+
groups.set(key, { hit: h, values: [h.value] });
|
|
382
|
+
}
|
|
383
|
+
const metas = [...groups.values()].map(({ hit, values }) => ({
|
|
384
|
+
category: hit.category,
|
|
385
|
+
ruleId: hit.ruleId,
|
|
386
|
+
severity: hit.severity,
|
|
387
|
+
count: values.length,
|
|
388
|
+
maskedPreview: maskMatch(values[0], hit.category),
|
|
389
|
+
matchHash: hit.category === 'pii' || hit.category === 'pii_jp'
|
|
390
|
+
? hmacHash(values[0], this.hmacSecret)
|
|
391
|
+
: hashMatch(values[0]),
|
|
392
|
+
}));
|
|
393
|
+
// 重大度順 (high>medium>low、同重大度はルール定義順) に整列し、1 entry あたり
|
|
394
|
+
// MAX_DETECTIONS_PER_ENTRY 件へキャップ (cloud 側で batch ごと棄却されないため)。
|
|
395
|
+
metas.sort((a, b) => SEVERITY_RANK[a.severity] - SEVERITY_RANK[b.severity]);
|
|
396
|
+
return metas.slice(0, exports.MAX_DETECTIONS_PER_ENTRY);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
exports.SecretDetector = SecretDetector;
|
|
400
|
+
//# sourceMappingURL=secret-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret-detector.js","sourceRoot":"","sources":["../src/secret-detector.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { MaskStat } from './pii-masker';
|
|
2
|
+
import type { DetectionMeta } from './secret-detector';
|
|
1
3
|
/** 観測対象の AI コーディングツール種別。filepath から判定する。 */
|
|
2
4
|
export type ObservationSource = 'claude_code' | 'codex';
|
|
3
5
|
export interface ParsedEntry {
|
|
@@ -7,6 +9,16 @@ export interface ParsedEntry {
|
|
|
7
9
|
parsedAt: string;
|
|
8
10
|
/** entry の発生元ツール。Claude Code / OpenAI Codex CLI を区別する。 */
|
|
9
11
|
source: ObservationSource;
|
|
12
|
+
/**
|
|
13
|
+
* 流出検知メタ (Issue #42)。検知が 1 件以上あった entry にのみ付与。
|
|
14
|
+
* 生機密本文は含まず category/severity/件数/マスク済みプレビュー/ハッシュのみ。
|
|
15
|
+
*/
|
|
16
|
+
detections?: DetectionMeta[];
|
|
17
|
+
/**
|
|
18
|
+
* マスク実績 (Issue #43)。マスキングが 1 件以上あった entry にのみ付与。
|
|
19
|
+
* ruleId と件数のみで、マスク前の生値は含まない。cloud 側で日次集計される。
|
|
20
|
+
*/
|
|
21
|
+
masks?: MaskStat[];
|
|
10
22
|
}
|
|
11
23
|
export interface ObservationBatch {
|
|
12
24
|
apiKey: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,OAAO,CAAA;AAEvD,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,GAAG,EAAE,OAAO,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,0DAA0D;IAC1D,MAAM,EAAE,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEtD,4CAA4C;AAC5C,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,OAAO,CAAA;AAEvD,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,GAAG,EAAE,OAAO,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,0DAA0D;IAC1D,MAAM,EAAE,iBAAiB,CAAA;IACzB;;;OAGG;IACH,UAAU,CAAC,EAAE,aAAa,EAAE,CAAA;IAC5B;;;OAGG;IACH,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAA;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,WAAW,EAAE,CAAA;CAC5B;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;CAClB"}
|