Documentation
¶
Overview ¶
Package detect は行単位の PII 検出エンジンを提供する。
Index ¶
- Constants
- func IsCSVOrTSVPath(path string) bool
- func IsObjectScopePath(path string) bool
- type DetectReason
- type Detector
- func (d *Detector) CollectDropped(enabled bool)
- func (d *Detector) DroppedTruncated() bool
- func (d *Detector) MergeExternalFindings(file, content string, findings []Finding, candidates []external.Candidate) []Finding
- func (d *Detector) Rules() []rule.Rule
- func (d *Detector) ScanContent(file, content string) []Finding
- func (d *Detector) ScanDiffHunk(file string, lines []DiffLine) []Finding
- func (d *Detector) ScanDiffHunkOpts(file string, lines []DiffLine, opts DiffScanOptions) []Finding
- func (d *Detector) ScanDiffHunkWithCSVHeader(file string, lines []DiffLine, csvHeader string) []Finding
- func (d *Detector) ScanLine(file string, lineNo int, line string) []Finding
- func (d *Detector) SetScanMinConfidence(minConf rule.Confidence)
- func (d *Detector) TakeDropped() []DroppedCandidate
- type DiffLine
- type DiffScanOptions
- type DroppedCandidate
- type Finding
Constants ¶
const ( // DropReasonRequireContextMissing は RequireContext のパターンで、 // 近傍にコンテキストキーワードが無く破棄されたことを表す。 DropReasonRequireContextMissing = "require-context-missing" // DropReasonNegativeContext は同一行(source context 由来を含む)の // 負文脈で破棄されたことを表す。 DropReasonNegativeContext = "negative-context" // DropReasonCrossLineNegativeContext は論理隣接行の負文脈 // (hasCrossLineNegativeContext、ScanContent/ScanDiffHunk 経由)で // 破棄されたことを表す。 DropReasonCrossLineNegativeContext = "cross-line-negative-context" // DropReasonValidateFailed は Rule.Validate または Pattern.Validate が // false を返して破棄されたことを表す(チェックサム等)。 DropReasonValidateFailed = "validate-failed" // DropReasonValidateLineFailed は Pattern.ValidateLine が false を // 返して破棄されたことを表す。 DropReasonValidateLineFailed = "validate-line-failed" // DropReasonAllowlisted は allowlist(stopword / 正規表現)に一致して // 破棄されたことを表す。 DropReasonAllowlisted = "allowlisted" // DropReasonKindExcluded は Rule.Kind の下位種別が設定ファイルの // [rules] exclude_kinds に一致して破棄されたことを表す。 DropReasonKindExcluded = "kind-excluded" // DropReasonBelowMinConfidence は最終信頼度が min_confidence 未満で // 破棄されたことを表す。cooccurrence_boost で一旦保持に回った候補が // 結局昇格しなかった場合の最終的な破棄もここに含む // (保持に回った時点そのものは記録しない)。 DropReasonBelowMinConfidence = "below-min-confidence" // DropReasonOverlapLost は resolveOverlaps/resolveOverlapsPerLine の // 重複解決で他候補に敗れて破棄されたことを表す。 DropReasonOverlapLost = "overlap-lost" // DropReasonPathDemotionBelowMin はテスト経路の信頼度降格 // (path_profile.go)で Low に落ち、min_confidence 未満になって // 破棄されたことを表す。 DropReasonPathDemotionBelowMin = "path-demotion-below-min" // DropReasonUUIDToken は候補が UUID トークンの内部に完全に含まれる // ため破棄されたことを表す。 DropReasonUUIDToken = "uuid-token" )
棄却理由の語彙(この文字列で固定。--explain-dropped の text/json 出力に そのまま現れる安定した識別子のため、値を変更しないこと)。
const AllowMarker = "pii-allow"
AllowMarker は後方互換のために残している旧除外マーカー。
const IgnoreMarker = "jp-pii-detector:ignore"
IgnoreMarker を含む行は検出対象から除外される(意図的なダミー値向け)。
Variables ¶
This section is empty.
Functions ¶
func IsCSVOrTSVPath ¶
IsCSVOrTSVPath は path の拡張子が .csv/.tsv(大文字小文字を区別しない)かを 返す。internal/source/gitdiff.go が diff hunk 用の post-image ヘッダ行を `git show` で取得するかどうかの判定に使う(ヘッダ取得は CSV/TSV だけに 意味があり、それ以外の拡張子で無駄な git 呼び出しをしないため)。 sourceKindForPath と判定基準がずれないよう、拡張子リストを再定義せず sourceKindForPath に委譲する。
func IsObjectScopePath ¶
IsObjectScopePath は path がオブジェクトスコープ処理の対象(.json/.yaml/.yml) かを返す。internal/source/gitdiff.go が diff hunk 用の post-image 全文を `git show` で取得するかどうかの判定に使う(取得は対象拡張子だけに意味があり、 それ以外の拡張子で無駄な git 呼び出しをしないため)。csv_context.go の IsCSVOrTSVPath と対称で、拡張子リストを再定義せず objectScopeKindForPath に 委譲する。
Types ¶
type DetectReason ¶
type DetectReason struct {
BaseConfidence string `json:"base_confidence,omitempty"`
FinalConfidence string `json:"final_confidence,omitempty"`
ContextKeywords []string `json:"context_keywords,omitempty"`
ContextPromoted bool `json:"context_promoted,omitempty"`
RequireContext bool `json:"require_context,omitempty"`
ContextWindow int `json:"context_window,omitempty"`
Validated bool `json:"validated,omitempty"`
// CooccurrenceBoosted は、[rules] cooccurrence_boost 有効時に近傍の別カテゴリ
// 高信頼 PII との共起で信頼度が 1 段昇格したことを示す(調査・チューニング用)。
CooccurrenceBoosted bool `json:"cooccurrence_boosted,omitempty"`
// PathDemoted はテスト経路(testdata/ 等)の信頼度降格が適用されたかを表す
// (internal/detect/path_profile.go)。true の場合、Confidence は既に
// 降格後の値(Low)になっている。
PathDemoted bool `json:"path_demoted,omitempty"`
// Kind はルール固有の下位種別(Rule.Kind が設定されている場合のみ設定される。
// internal/rule/rule.go 参照)。現状は jp-phone-number の PhoneKind が返す
// service/ip/mobile/fixed/international のいずれか。設定ファイルの
// [rules] exclude_kinds(internal/config)でこの値ごとに検出を除外できる。
Kind string `json:"kind,omitempty"`
// External は組み込みルールではなく、[external_recognizer] で設定した外部コマンド
// 由来の検出であることを示す(--explain 表示用。internal/detect/external.go の
// MergeExternalFindings が設定する)。外部候補はチェックサム等の内部検証を
// 一切行わないため、Validated は常に false のままになる。
External bool `json:"external,omitempty"`
}
DetectReason は検出の根拠を表す。生の PII は含めない。
type Detector ¶
type Detector struct {
// contains filtered or unexported fields
}
Detector は設定を適用済みの検出エンジン。
func (*Detector) CollectDropped ¶
CollectDropped は棄却候補の記録(DroppedCandidate)を有効/無効にする (既定 false)。無効時は記録のコストが各記録箇所の bool 分岐 1 個のみで、 性能・挙動・出力は従来と完全に不変(golden 等への影響ゼロ)。 --explain-dropped 用。並列フルスキャン開始前(Detector 構築直後)に 呼ぶことを想定する。
func (*Detector) DroppedTruncated ¶
DroppedTruncated は直近の TakeDropped 以降、上限(maxDroppedCandidates)に 達して記録を打ち切ったことがあるかを返し、内部フラグをリセットする (TakeDropped と対で、1 回の走査ごとに呼ぶ想定)。
func (*Detector) MergeExternalFindings ¶
func (d *Detector) MergeExternalFindings(file, content string, findings []Finding, candidates []external.Candidate) []Finding
MergeExternalFindings は file の外部レコグナイザ候補(internal/external.Run が 返した Candidate のうち、この file 分。File が一致しないものは無視する)を検証・ 変換し、findings(通常の検出。呼び出し側が d.ScanContent(file, content) で 得たもの)と統合して返す。candidates が空なら findings をそのまま返す (呼び出し側のホットパス最適化用。外部レコグナイザ未設定時はこの関数自体が 呼ばれないため、無効時のコストはゼロ)。
ScanContent が内部で行う cooccurrence_boost(近傍の高信頼 PII との共起昇格)と path_demotion(testdata/ 等の信頼度降格)は、この関数を呼ぶ時点で ScanContent が 既に完了しているため、外部候補には適用されない(意図的な v1 のスコープ外。 外部候補に適用するのは下記の allowlist・ignore マーカー・min_confidence・ 重複解決のみ)。
各候補は次の順で検証し、いずれかで落ちれば「この候補だけ」を破棄する (internal/external.Run 自体が返す「この走査回の候補をすべて破棄」判定とは別の、 候補単位の意味検証):
- rule_id が externalRuleIDSuffix を持たない候補は破棄する。internal/external は JSON の構造検証のみを行い、この意味検証はしないため、ここが唯一の強制点になる。
- rule_id が [rules] disabled に含まれる候補は破棄する。通常ルールと同じ無効化 手段を外部ルールにも適用できるようにするため。
- line・column・length が content の範囲内に収まらない候補は破棄する (子の自己申告位置を信用しない)。
- 値そのものは content から親側で切り出す(プロトコルは値を運ばない)。値が乗る 行に ignore マーカー(jp-pii-detector:ignore / 旧 pii-allow)があれば破棄する。
- allowlist(stopword・正規表現)に一致すれば破棄する。
- confidence は受信値をパースし、不正・空なら Low として扱う(破棄はしない)。 パース後の値が min_confidence 未満なら破棄する。
生存した候補は findings と合わせて resolveOverlapsPerLine で重複解決する (同一箇所に通常の検出と外部候補が重なった場合、既存の信頼度・範囲優先の決着規則 がそのまま適用される。外部候補だから優先/劣後するという特別扱いはしない)。
func (*Detector) ScanContent ¶
ScanContent はファイル内容全体を行に分割して走査する。
func (*Detector) ScanDiffHunk ¶
ScanDiffHunk は差分 hunk(文脈行+追加行)を走査し、検出値が追加行に乗る finding だけを返す(行番号はウィンドウ内 1 始まり)。CSV/TSV の列コンテキスト・ JSON/YAML のオブジェクトスコープ親キー文脈のいずれも使わない後方互換の エントリポイントで、ScanDiffHunkOpts(file, lines, DiffScanOptions{}) に委譲する (既存呼び出し — internal/source/gitdiff.go の CSV/JSON/YAML 以外の経路、 internal/eval 等 — のシグネチャ・挙動を一切変えないため)。
func (*Detector) ScanDiffHunkOpts ¶
func (d *Detector) ScanDiffHunkOpts(file string, lines []DiffLine, opts DiffScanOptions) []Finding
ScanDiffHunkOpts は ScanDiffHunk/ScanDiffHunkWithCSVHeader の一般化版 (issue #134)。opts がゼロ値なら ScanDiffHunk と完全に同じ挙動になる。
API 拡張の形について: ScanDiffHunkWithCSVHeader 追加時と同じく、既存 シグネチャ・既存呼び出し(本パッケージ外では internal/source・internal/eval)を 一切変更せず、新規の関数を追加する形を選んだ。ただし今回は CSV ヘッダに加えて JSON/YAML の post-image 全文・hunk 開始行という、渡せるオプションが今後も 増えうる性質を踏まえ、専用関数を増やす代わりに汎用の DiffScanOptions 構造体を 導入した。ScanDiffHunk・ScanDiffHunkWithCSVHeader 側はそれぞれ薄い委譲に とどめている。
設計意図(ScanDiffHunk と共通): 文脈行(未変更行)は正のコンテキスト (ラベル等)の補完にのみ使い、抑制(ignore マーカー・負コンテキスト)の 駆動には使わない。これにより、追加した値の隣の既存行に「円」等の負コンテキストや 古い jp-pii-detector:ignore があっても、追加行の新規 PII を取りこぼさない (セキュリティ検出器として偽陰性を避ける)。同一行の抑制(値そのものの行)は 通常どおり適用される。一方、追加行同士が隣接する場合(両方 Added)は、 フルスキャン(ScanContent)と同じく隣接行の負コンテキストを適用する。 そうしないと、同じ 2 行の追加が CI のフルスキャンでは抑制され pre-commit --staged では報告されるという非対称が生まれるため。CSV 列コンテキストの PositiveText/NegativeText も、この「文脈行は正の補完のみ・抑制は値の行のみ」 という原則に従う(csvHeader 自体は外部から渡された固定情報であり、hunk 内の 文脈行/追加行の区別とは独立に、行ごとの列の割り当てにのみ使う)。オブジェクト スコープの親キー文脈(PostImage 由来)も同じ原則に従う: postImage 自体は 外部から渡された固定情報で、hunk 内の文脈行/追加行の区別とは独立に働くが、 親キー由来の finding が実際に報告されるかどうかは通常どおり「値が追加行に 乗っているか」で決まる。
この「抑制は検出値が乗る行に対してのみ適用し、隣接行のマーカーを巻き添えに しない」という原則は diff 経路専用ではなく、ScanContent 側の隣接行走査 (scanAdjacentLines)にも同様に適用される。
func (*Detector) ScanDiffHunkWithCSVHeader ¶
func (d *Detector) ScanDiffHunkWithCSVHeader(file string, lines []DiffLine, csvHeader string) []Finding
ScanDiffHunkWithCSVHeader は ScanDiffHunk に、走査対象が .csv/.tsv の場合の post-image ヘッダ行(1 行目のテキスト)を追加で渡せる版。hunk 自体は 変更箇所がファイル先頭付近でない限りヘッダ行を含まないため、呼び出し側 (internal/source/gitdiff.go)が `git show` で post-image のヘッダ行だけを 個別取得して渡す。csvHeader を空文字にすると ScanDiffHunk と完全に同じ 挙動になる(ヘッダ未取得・取得失敗・非 CSV ファイルはすべてこの経路)。 ScanDiffHunkOpts(file, lines, DiffScanOptions{CSVHeader: csvHeader}) に委譲する 後方互換のエントリポイント(既存呼び出しのシグネチャ・挙動を一切変えない)。
func (*Detector) SetScanMinConfidence ¶ added in v0.4.3
func (d *Detector) SetScanMinConfidence(minConf rule.Confidence)
SetScanMinConfidence は、報告用 min_confidence を変えずに ScanContent 等が 返す finding の下限だけを引き下げる。CLI の --fail-on が報告閾値より低い 場合の終了判定・baseline 登録に使う。走査開始前に 1 回だけ呼ぶこと。
func (*Detector) TakeDropped ¶
func (d *Detector) TakeDropped() []DroppedCandidate
TakeDropped は記録済みの DroppedCandidate を返し、内部の蓄積をクリアする (drain 方式)。ScanContent/ScanLine/ScanDiffHunk を必要な回数呼び出した 後にまとめて回収する想定(フルスキャンで複数ファイルを走査する場合も、 全走査完了後に 1 度だけ呼べばよい)。CollectDropped(false)(既定)の ままなら常に nil を返す。
type DiffScanOptions ¶
type DiffScanOptions struct {
// CSVHeader は .csv/.tsv の post-image ヘッダ行(1 行目のテキスト)。
// ScanDiffHunkWithCSVHeader の csvHeader 引数と同じ意味・同じフォールバック
// 規則(空文字列 = 列コンテキストなし)。
CSVHeader string
// PostImage は .json/.yaml/.yml の post-image 全文("\n" 区切り、hunk の
// 断片ではなくファイル全体)。呼び出し側(internal/source/gitdiff.go)が
// `git show` で取得する(サイズ上限・取得失敗・バイナリはすべて呼び出し側の
// 責任で空文字列にフォールバックする)。空文字列は「取得できなかった/
// 対象外」を表し、オブジェクトスコープの親キー文脈なしにフォールバックする
// (object_scope.go の applyObjectScopeContextForDiff 参照)。
PostImage string
// HunkStartLine は hunk の新ファイル側開始行(unified diff の
// `@@ -a,b +c,d @@` の c、1 始まり)。PostImage 中の対応行を lines[i]
// (0 始まり)↔ PostImage の行 HunkStartLine+i-1(0 始まり)で対応付けるために
// 使う。PostImage が空文字列の場合は参照されない。
HunkStartLine int
}
DiffScanOptions は ScanDiffHunkOpts への追加オプション(すべて省略可能で、 ゼロ値なら ScanDiffHunk と完全に同じ挙動になる)。
type DroppedCandidate ¶
type DroppedCandidate struct {
RuleID string
File string
Line int // 1 始まり
Column int // 1 始まり(ルーン単位)
// Reason は棄却理由。下記 DropReasonXxx 定数のいずれか(固定語彙)。
Reason string
// PatternBase はこの候補が仮に採用されていた場合の信頼度。パターン
// ループ内の棄却は Pattern.Base、below-min-confidence・overlap-lost・
// path-demotion-below-min・cross-line-negative-context は棄却時点で
// 解決済みの Finding.Confidence を使う。FN 分析での優先度付けに使う
// 補助情報であり、検出可否・出力には一切影響しない。
PatternBase rule.Confidence
}
DroppedCandidate は検出候補が確定に至らず棄却された記録(opt-in、FN 分析用。 issue #43 段階4)。生のマッチ値は絶対に保持しない(Finding.Match の json:"-" と同じ安全境界の思想。値はマスク済みですら持たない。位置と ルールで特定するには十分という判断)。
type Finding ¶
type Finding struct {
RuleID string `json:"rule_id"`
Description string `json:"description"`
File string `json:"file"`
Line int `json:"line"` // 1 始まり
Column int `json:"column"` // 1 始まり(ルーン単位)
Match string `json:"-"` // 元テキスト(生値。マスクは出力層で行う。直接 marshal では出さない)
Confidence rule.Confidence `json:"-"`
// ConfidenceScore は検証・文脈距離・構造証拠を加算した内部スコア(0-100)。
// JSON/SARIF 等の公開契約は既存の 3 値 Confidence を維持し、score は出力しない。
ConfidenceScore int `json:"-"`
// Reason は検出の根拠(調査・チューニング用。既定の出力には含めない)。
Reason DetectReason `json:"reason,omitempty"`
// Offset/EndOffset は走査対象テキスト全体の先頭からのルーン単位の半開区間
// [Offset, EndOffset)。ComputeOffsets を呼んだときのみ設定され、その場合
// HasOffset が true になる。行・列ベースの位置を文字オフセットへ変換したい
// 利用側(例: Microsoft Presidio の RecognizerResult)向けの情報で、
// 単一テキスト走査でのみ意味を持つ(ファイル/差分走査では付与されない)。
HasOffset bool `json:"-"`
Offset int `json:"-"`
EndOffset int `json:"-"`
// contains filtered or unexported fields
}
Finding は 1 件の検出結果。
注意: この型は出力スキーマではない。機械可読な出力(json/sarif 等)は internal/report の jsonFinding を経由し、値は既定でマスクされる。Finding を 直接 json.Marshal する経路は存在しないが、誤って marshal しても生の PII を 漏らさないよう、生値を保持する Match は json:"-" でシリアライズ対象から外す。
func ComputeOffsets ¶
ComputeOffsets は ScanContent に渡したのと同一の content を使い、各 finding に テキスト全体の先頭からのルーン単位オフセット(半開区間 [Offset, EndOffset))を 付与して返す。行・列ベースの検出位置を文字オフセットベースへ変換したい利用側 (例: Microsoft Presidio の RecognizerResult は文字オフセットを要求する)向けの ヘルパー。
content は ScanContent と同じく "\n" 区切りで行に分割されるため、ここで求める 行頭のルーン位置は ScanContent が見た行と一致する。正規化は 1 ルーン = 1 ルーンの 1:1 変換なので、列はそのまま行頭からのルーン数として使える。