143 lines
5.6 KiB
Go
143 lines
5.6 KiB
Go
package lib
|
||
|
||
import "strings"
|
||
|
||
// L2Labels contains substrings that mark a field as L2 (client-side encrypted
|
||
// only) during import. Matching is case-insensitive: if any substring appears
|
||
// in a field label, that field is flagged L2.
|
||
//
|
||
// L2 = things an AI agent should NEVER need. Personal identity, payment cards,
|
||
// government IDs. NOT API keys, SSH keys, TOTP — those are L1 (agent-readable).
|
||
//
|
||
// Contributing: add new terms anywhere in the list. Group by language or
|
||
// category, keep entries lowercase, and include a comment for the language.
|
||
var L2Labels = []string{
|
||
// Card / payment
|
||
"cvv", "cvc", "csv", "security code", "card number", "card no",
|
||
"pin code", "pin-code",
|
||
|
||
// Banking
|
||
"routing number", "account number", "iban", "swift", "sort code",
|
||
|
||
// Government ID — English
|
||
"ssn", "social security", "passport", "driver license", "driver's license",
|
||
"driving license", "driving licence", "national id", "id card", "id number",
|
||
"tax id", "identification number",
|
||
|
||
// Dutch — BSN = burgerservicenummer
|
||
"bsn", "burgerservicenummer", "rijbewijs", "paspoort", "identiteitskaart", "identiteitsbewijs",
|
||
|
||
// German — SVN = Sozialversicherungsnummer, StID = Steuer-ID
|
||
"sozialversicherungsnummer", "steuer-id", "steuernummer",
|
||
"führerschein", "fuhrerschein", "sozialversicherung", "reisepass", "personalausweis",
|
||
|
||
// French — NIR = numéro d'inscription au répertoire, CNI = carte nationale d'identité
|
||
"nir", "cni", "numéro de sécurité", "numero de securite",
|
||
"permis de conduire", "carte d'identit", "carte d identit", "passeport",
|
||
|
||
// Spanish — DNI, NIE, NIF, CURP (Mexico)
|
||
"dni", "nie", "nif", "curp",
|
||
"licencia de conducir", "seguro social", "pasaporte", "tarjeta de identidad", "cédula", "cedula",
|
||
|
||
// Portuguese — CPF, CNH = carteira nacional de habilitação, RNE = registro nacional de estrangeiros
|
||
"cpf", "cnh", "rne",
|
||
"carteira de motorista", "carteira de identidade", "passaporte",
|
||
|
||
// Italian — CF = codice fiscale, tessera sanitaria
|
||
"codice fiscale", "tessera sanitaria",
|
||
"patente di guida", "passaporto", "carta d'identit", "carta d identit",
|
||
|
||
// Chinese — 身份证号 = ID number, 社会保障号 = social security number
|
||
"身份证", "护照", "驾照", "驾驶证", "社保", "社会保障号", "居民身份",
|
||
|
||
// Japanese — マイナンバー = My Number, 運転免許証 = driver's license
|
||
"パスポート", "免許", "マイナンバー", "運転免許証", "住民票",
|
||
|
||
// Korean — 주민등록번호 = resident registration number
|
||
"여권", "운전면허", "주민등록", "주민등록번호", "외국인등록",
|
||
|
||
// Russian — ИНН = tax ID, СНИЛС = social insurance, ВУ = driver's license
|
||
"паспорт", "водительск", "снилс", "инн",
|
||
|
||
// Arabic — رقم الهوية = ID number, جواز سفر = passport
|
||
"جواز سفر", "رخصة قيادة", "بطاقة هوية", "رقم الهوية",
|
||
|
||
// Hindi — PAN = permanent account number, Aadhaar
|
||
"पासपोर्ट", "आधार", "लाइसेंस", "pan card",
|
||
|
||
// Turkish — TC Kimlik = national ID number
|
||
"pasaport", "ehliyet", "kimlik numar", "tc kimlik", "nüfus",
|
||
|
||
// Polish — PESEL = national ID, NIP = tax ID, dowód = ID card
|
||
"pesel", "nip",
|
||
"paszport", "prawo jazdy", "dowód osobisty", "dowod osobisty",
|
||
|
||
// Swedish — pass = passport, samordningsnummer = coordination number
|
||
"körkort", "personnummer", "samordningsnummer",
|
||
|
||
// Thai — บัตรประชาชน = ID card, หนังสือเดินทาง = passport, ใบขับขี่ = driver's license
|
||
"บัตรประชาชน", "หนังสือเดินทาง", "ใบขับขี่",
|
||
|
||
// Vietnamese — CMND/CCCD = citizen ID, hộ chiếu = passport, GPLX = driver's license
|
||
"cmnd", "cccd", "hộ chiếu", "ho chieu",
|
||
}
|
||
|
||
// L2Titles contains substrings matched against entry titles. If an entry's
|
||
// title matches, ALL fields in that entry are flagged L2.
|
||
// These are things a human needs but an agent never would.
|
||
var L2Titles = []string{
|
||
// Recovery / backup codes — human-only fallback
|
||
"backup code", "recovery code", "recovery key", "backup key",
|
||
"restore code", "restore key", "reset code",
|
||
|
||
// Crypto wallet seeds — human-only
|
||
"seed phrase", "mnemonic", "recovery phrase", "wallet seed",
|
||
|
||
// Pairing codes — one-time human setup
|
||
"pairing code", "pairing key",
|
||
|
||
// Crypto exchanges & wallets — entire record is sensitive
|
||
"coinbase", "binance", "kraken", "gemini", "bitstamp", "bitfinex",
|
||
"crypto.com", "kucoin", "bybit", "okx", "gate.io", "huobi", "htx",
|
||
"bitget", "mexc", "upbit", "bithumb",
|
||
"aa.com",
|
||
"metamask", "phantom", "ledger", "trezor", "exodus", "trust wallet",
|
||
"electrum", "myetherwallet", "blockchain.com",
|
||
}
|
||
|
||
// AutoL2Fields scans all fields in each VaultData and sets L2=true if the
|
||
// field label or entry title matches a sensitive pattern. Called after import.
|
||
func AutoL2Fields(entries []VaultData) {
|
||
for i := range entries {
|
||
// Check title — if it matches, mark ALL fields L2
|
||
titleLower := strings.ToLower(entries[i].Title)
|
||
titleMatch := false
|
||
for _, pat := range L2Titles {
|
||
if strings.Contains(titleLower, pat) {
|
||
titleMatch = true
|
||
break
|
||
}
|
||
}
|
||
if titleMatch {
|
||
for j := range entries[i].Fields {
|
||
entries[i].Fields[j].L2 = true
|
||
}
|
||
continue
|
||
}
|
||
|
||
// Check individual field labels
|
||
for j := range entries[i].Fields {
|
||
if entries[i].Fields[j].L2 {
|
||
continue
|
||
}
|
||
lower := strings.ToLower(entries[i].Fields[j].Label)
|
||
for _, pat := range L2Labels {
|
||
if strings.Contains(lower, pat) {
|
||
entries[i].Fields[j].L2 = true
|
||
break
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|