Steg 9 (R4): unified migrate-corpus.mjs --write over engineering/governance/ infrastructure/security. 327 filer mutert, verified=null, prosa byte-identisk (fra første ## seksjon), advisor urørt (0 endringer). To applier-fixes oppdaget under kjøring (TDD, RED→GREEN): - insertHeaderFields: anker faller nå tilbake når en meta-linje selv passerer 500B (2 filer pakket et avsnitt i **Status:** → Type/Source landet utenfor scan-vinduet, applierens post-write-assertion fanget + restaurerte). - normalizeStaleVerified: fjerner nå ALLE stale non-date **Verified:** i 500B-vinduet, inkl. stray body-dup rett under --- (9 mlops-genaiops-filer var ellers falskt "verified"/fresh, droppet fra worklist). Operatør-godkjent utvidelse av carve-out; kun stray metadata-linjer, aldri prosa. test-transform-criterion: precondition oppdatert til post-migrasjons-sannhet (fila bærer nå Source). Suite 728/728 grønn.
20 KiB
PII Detection and Masking in Norwegian Text
Last updated: 2026-06-19 Status: GA Category: AI Security Engineering Type: reference Source: https://learn.microsoft.com/azure/ai-services/language-service/personally-identifiable-information/overview
Innhold
- Introduksjon
- Kjernekomponenter
- Arkitekturmønstre
- Beslutningsveiledning
- Integrasjon med Microsoft-stakken
- Offentlig sektor (Norge)
- Kostnad og lisensiering
- For arkitekten (Cosmo)
- Kilder og verifisering
Introduksjon
Beskyttelse av personopplysninger er ikke bare en teknisk nødvendighet, men en juridisk plikt i Norge. Azure AI Language tilbyr PII-deteksjon som kan identifisere og maskere sensitive opplysninger som fødselsnummer, D-nummer, adresser og telefonnummer i norsk tekst.
I norsk kontekst er PII-deteksjon spesielt viktig fordi:
- Fødselsnummer (11 siffer) er den viktigste personidentifikatoren i Norge, brukt av NAV, Skatteetaten og alle offentlige systemer
- D-nummer brukes for personer uten fødselsnummer (utlendinger, asylsøkere)
- Organisasjonsnummer (9 siffer) må skilles fra personopplysninger
- Adresser inneholder ofte gate, postnummer og poststed
- NAV-nummer og andre fagsystem-identifikatorer
Azure AI Language støtter norsk språk (language: "no") og kan detektere både generelle PII-kategorier (navn, e-post, telefon) og nordiske ID-numre (NOIdentityNumber). Tjenesten bruker maskinlæring kombinert med regex-basert validering for høy presisjon.
Kjernekomponenter
Azure AI Language PII Detection
Azure AI Language grupperer PII i tre feature-typer (etter input-format og prosesseringsmodell):
| Feature-type | Bruksområde | Format |
|---|---|---|
| Text PII | Ustrukturert tekst (e-post, chat, notater, prompts, logger) | Synkron, string-basert JSON payload |
| Conversation PII | Transkribert tale fra møter og kundesenter | Asynkron, tur-/transkriptbasert format |
| Document-based PII (tidl. «Native Document PII») | .pdf, .docx, .txt-filer |
Asynkron, lagringsbasert; bevarer dokumentstruktur + JSON-metadata |
Støttede entitetstyper (norsk kontekst)
| Entitetstype | Azure kategori | Eksempel | Validering |
|---|---|---|---|
| Fødselsnummer | NOIdentityNumber |
01019912345 | 11 siffer, kontrollsiffer |
| D-nummer | NOIdentityNumber |
41019912345 | 11 siffer, dag +40 |
| Person | Person |
Ola Nordmann | ML-basert |
| E-post | Email |
ola@example.no | Format-validering |
| Telefon | PhoneNumber |
+47 123 45 678 | Regex |
| Adresse | Address |
Storgata 1, 0123 Oslo | ML-basert |
| Organisasjon | Organization |
NAV, Skatteetaten | ML-basert |
| EU Passport | EUPassportNumber |
Norsk pass | Format-validering |
| EU Drivers License | EUDriversLicenseNumber |
Norsk saksbehandling | Format-validering |
| Bank Account | InternationalBankingAccountNumber |
IBAN | Format-validering |
Viktig: Azure detekterer norske fødselsnummer under kategorien NOIdentityNumber. Du må spesifisere language: "no" for optimal deteksjon.
Maskeringsstrategier (Verified MCP 2026-06)
API-versjoner (Text PII): GA er
2026-05-01; nyeste preview er2026-05-15-preview. Redaction-policies,confidenceScoreThreshold,disableEntityValidation,entitySynonymsogvalueExclusionPolicyer preview-funksjoner (først introdusert i2025-11-15-preview, nå dokumentert under gjeldende preview). Bruk GA-versjonen for produksjon.
Azure AI Language tilbyr fire redaction policies (redactionPolicies):
| Policy | Output | Bruksområde |
|---|---|---|
| CharacterMask (default) | Min SSN er *********** |
Standard masking; støtter valgfri redactionCharacter (f.eks. -) |
| EntityMask | Min SSN er [NOIdentityNumber_1] |
Logging, debugging |
| SyntheticReplacement | Min SSN er 12345678901 |
Syntetiske testdata (tilfeldig valgte erstatningsverdier fra forhåndsdefinert sett) |
| NoMask | Min SSN er 01019912345 |
Kun entitetsdeteksjon, ingen redactedText i respons |
Anbefalt: CharacterMask for produksjon, EntityMask for logging (spesifiserer entitetstype), NoMask når du kun trenger deteksjon uten redaction.
Per-entity policy overrides: Du kan spesifisere ulike policies per entitetstype i samme request, med én defaultRedactionPolicy og entitetsspesifikke overrides. (Verified MCP 2026-06)
DisableEntityValidation: Mulighet til å deaktivere streng entitetsvalidering (default false) for å øke hastighet i scenarioer der validering ikke er nødvendig. (Verified MCP 2026-06)
EntitySynonyms og ValueExclusionPolicy: Tilpass PII-tjenesten til organisasjonens vokabular — definer egne synonymer for entitetstyper, og ekskluder spesifikke termer fra deteksjon (f.eks. "politimann", "vitne"). (Verified MCP 2026-06)
Confidence Threshold (Verified MCP 2026-06)
Med preview-API-et kan du konfigurere confidenceScoreThreshold med global default og per-entitet, per-språk overrides:
{
"parameters": {
"confidenceScoreThreshold": {
"default": 0.9,
"overrides": [
{ "value": 0.8, "entity": "NOIdentityNumber" },
{ "value": 0.6, "entity": "Person", "language": "no" }
]
}
}
}
Råd: Bruk 0.8+ global default for produksjon (minimerer false positives), 0.6+ for utviklingsmiljø. Per-entitet overrides gir finkornet kontroll. (Verified MCP 2026-04)
Arkitekturmønstre
Mønster 1: Pre-Processing Pipeline (anbefalt)
Bruksområde: Skjemaer, søknader, kundehenvendelser
Innkommende data → Azure AI Language PII → Maskert tekst → Lagring → Prosessering
Fordeler:
- PII fjernes før lagring (comply-by-design)
- Ingen PII i database eller logging
- Enkel compliance-revidering
Ulemper:
- Irreversibel masking (kan ikke gjenopprette originaltekst)
- Latency på inbound-request
Implementasjon:
- Azure Function med PII detection før Cosmos DB/SQL
- Power Automate cloud flow med Azure AI Language connector
Mønster 2: Dynamic Masking (on-demand)
Bruksområde: Saksbehandlerportaler, kundesenterløsninger
Database (original) → Azure AI Language PII (on-demand) → Visning (maskert)
Fordeler:
- Originaldata bevares (kan gjenopprettes ved autorisasjon)
- Rollbasert tilgang (saksbehandler ser kun delvis masking)
Ulemper:
- PII i database (krever kryptering, TDE)
- Latency per visning
Implementasjon:
- Azure SQL Dynamic Data Masking + Azure AI Language
- Custom middleware i API-lag
Mønster 3: Pseudonymization (GDPR-compliant)
Bruksområde: Dataanalyse, maskinlæring
Original data → Azure AI Language PII → Pseudonymisering → Sekundær database → Analyse
Fordeler:
- Analytikere kan jobbe med data uten PII-eksponering
- Mulighet for re-identifikasjon ved autorisasjon (reverserbar mapping)
Ulemper:
- Kompleks key management (mapping-tabell må sikres)
- Risk for re-identifikasjon ved kobling med eksterne data
Implementasjon:
- Azure Synapse Analytics + PII detection i ELT-pipeline
- Mapping-tabell i Azure Key Vault managed secrets
Beslutningsveiledning
Når bruke Azure AI Language PII vs. andre løsninger?
| Scenario | Azure AI Language PII | Alternativ | Hvorfor |
|---|---|---|---|
| Norsk ustrukturert tekst | ✅ Ja | Azure SQL Dynamic Data Masking | Azure AI Language forstår kontekst (ikke bare regex) |
| Real-time chat/kundesenter | ✅ Ja | Regex-basert filtrering | Håndterer transkribert tale, dialekt-varianter |
| PDF/Word-dokumenter | ✅ Ja (Native Document PII) | Manuell ekstraksjon + regex | Støtter native formater, bevarer layout |
| Strukturert database-data | ❌ Nei | Azure SQL Dynamic Data Masking | Mer effektivt for kolonnebasert masking |
| Faste felt (f.eks. kun fødselsnummer) | ❌ Nei | Regex + checksumvalidering | Billigere, raskere |
Vanlige feil
| Feil | Konsekvens | Løsning |
|---|---|---|
Ikke spesifisere language: "no" |
Fødselsnummer ikke detektert | Bruk language: "no", ikke "en" |
| Bruke default PII-kategorier | Mangler norske identifikatorer | Eksplisitt inkluder NOIdentityNumber |
| Ikke validere confidence score | False positives i produksjon | Bruk confidenceScoreThreshold: 0.8 |
| Maskere all tekst (inkl. kontekst) | Ikke-semantisk output | Bruk selective masking (kun PII-entiteter) |
| Ikke teste med D-nummer | D-nummer lekker | Test med både fødselsnummer og D-nummer |
Røde flagg
- ⚠️ Fødselsnummer i URL-parametere → Bruk POST body, aldri GET query string
- ⚠️ PII i logmeldinger → Masker før logging (Azure Monitor støtter custom processing)
- ⚠️ Masking etter lagring → For sent! Bruk pre-processing pipeline
- ⚠️ Ikke kryptere maskert data → Masked data er fortsatt sensitive metadata (entity types)
- ⚠️ Gjenbruk maskerte datasett → Synthetic replacement er nødvendig for ML-training
Integrasjon med Microsoft-stakken
Microsoft Foundry (Verified MCP 2026-04)
Playground: Test PII-deteksjon i Microsoft Foundry portal:
- Naviger til Language → PII Detection
- Velg Extract PII from text
- Velg språk:
Norwegian - Lim inn tekst med fødselsnummer
- Se detekterte entiteter med confidence scores
Model deployment: Bruk modelVersion: "latest" for nyeste modell; velg GA-API 2026-05-01 for produksjon og 2026-05-15-preview for nye preview-features.
Merk: Microsoft Foundry (new) — ny portal med Foundry-prosjekter — og Foundry (classic) er begge tilgjengelige via https://ai.azure.com/. For opprettelse av Language-ressurs, bruk Azure Language in Foundry Tools. (Verified MCP 2026-06)
Copilot Studio
Custom PII masking i Copilot:
# I Copilot Studio, bruk Azure Function skill
- skill: "mask-pii"
trigger: "before_store_message"
action:
- call: azure_function_url
- parameters:
text: "{user_message}"
language: "no"
Beste praksis: Masker brukerinndata før de sendes til conversation history (unngå PII i Dataverse).
Power Automate
PII masking i cloud flow:
- Trigger: When a new form is submitted (Forms)
- Action: Azure AI Language - Detect PII
- Text:
{form_response} - Language:
no
- Text:
- Condition: If
@{body('Detect_PII')?['entities']}is not empty - Action: Store masked text:
@{body('Detect_PII')?['redactedText']}
Tips: Bruk confidenceScoreThreshold: 0.8 i custom connector for høy presisjon.
Azure Synapse Analytics / Databricks
PII masking i ELT pipeline:
# PySpark UDF med Azure AI Language
from pyspark.sql.functions import udf
from azure.ai.textanalytics import TextAnalyticsClient
def mask_pii(text):
client = TextAnalyticsClient(endpoint, credential)
result = client.recognize_pii_entities([text], language="no")[0]
return result.redacted_text
mask_pii_udf = udf(mask_pii)
df_masked = df.withColumn("text_masked", mask_pii_udf(df.text))
Optimalisering: Bruk batch processing (opptil 5000 dokumenter per request) for bedre throughput.
Azure API Management
PII masking i API gateway:
<policies>
<inbound>
<send-request mode="new" response-variable-name="pii-response">
<set-url>https://{endpoint}/language/:analyze-text</set-url>
<set-method>POST</set-method>
<set-body>@{
return JsonConvert.SerializeObject(new {
kind = "PiiEntityRecognition",
parameters = new { language = "no" },
analysisInput = new { documents = new[] { new { id = "1", text = context.Request.Body.As<string>() } } }
});
}</set-body>
</send-request>
<set-body>@(((IResponse)context.Variables["pii-response"]).Body.As<JObject>()["results"]["documents"][0]["redactedText"].ToString())</set-body>
</inbound>
</policies>
Offentlig sektor (Norge)
GDPR og Personopplysningsloven
Artikkel 32 - Sikkerhet ved behandling:
Behandlingsansvarlig og databehandler skal [...] iverksette egnede tekniske og organisatoriske tiltak for å sikre et sikkerhetsnivå som passer med risikoen.
PII-deteksjon oppfyller:
- Pseudonymisering (Art. 25, 32)
- Data minimization (Art. 5)
- Privacy by design (Art. 25)
Dokumentasjon:
- Logg alle PII-deteksjoner med tidsstempel, bruker, confidence score
- ROS-analyse: Identifiser risiko for false negatives (PII ikke detektert)
- DPIA: Dokumenter hvordan PII-masking reduserer risiko
Forvaltningsloven og Offentleglova
Innsyn i saksdokumenter (§ 13):
- Masker PII i dokumenter før offentliggjøring
- Bevar original i intern saksbehandling
Eksempel: Innsynskrav i NAV-sak → Masker andre personers fødselsnummer, behold søkerens.
Datatilsynets veiledning
Anbefalinger:
- Bruk
confidenceScoreThreshold: 0.8+for å minimere false negatives - Test med norske edge cases: D-nummer, korte navn (Ola, Per), dialektuttrykk
- Dokumenter hvilke PII-kategorier som detekteres (gi brukerne transparens)
Veiledning om automatiserte avgjørelser:
- PII-masking er ikke en "automatisert individuell avgjørelse" (GDPR Art. 22), men påvirker datakvalitet
- Sikre at maskerte data ikke forårsaker bias i AI-modeller
Digdir-prinsipper
Prinsipp 2: Sikkerhet og personvern:
- PII-deteksjon skal integreres i alle digitale tjenester som håndterer personopplysninger
- Bruk Azure AI Language som standardkomponent i sikker-by-design-arkitekturer
Prinsipp 4: Brukervennlighet:
- Masker kun nødvendig data (unngå overmasking som ødelegger lesbarhet)
- Gi brukere mulighet til å se originaltekst ved autorisasjon
Kostnad og lisensiering
Prismodell (Azure AI Language - Text Analytics)
| Tier | Pris (per 1000 text records) | Inkluderer |
|---|---|---|
| Free (F0) | 5000 records/måned gratis | PII detection, NER, sentiment |
| Standard (S) | $2 per 1000 records | All features, SLA 99.9% |
Norsk kontekst:
- 1 text record = opptil 5120 tegn
- Gjennomsnittlig norsk tekst (e-post, chat): 500-1000 tegn → 5-10 records per 1000 meldinger
Kostnadsestimering (NAV-eksempel):
- 10 000 søknader/måned, 2000 tegn per søknad
- (10 000 søknader × 2000 tegn) / 5120 tegn = ~4000 records
- Kostnad: 4 × $2 = $8/måned (~80 NOK)
Optimaliseringstips
| Teknikk | Besparelse | Trade-off |
|---|---|---|
| Batch processing (5000 docs/call) | 40% lavere latency | Kompleksitet i request-handling |
| Pre-filter med regex | 50% færre API-kall | Risk for false negatives |
| Selective field masking | 30% færre records | Må identifisere PII-felt på forhånd |
| Caching av resultater | 60% besparelse ved re-prosessering | Krever cache invalidation-strategi |
| Use Free tier for dev/test | 100% besparelse (opptil 5K/måned) | Ikke for produksjon |
Beste praksis: Kombiner regex-filtrering (fødselsnummer-pattern) med Azure AI Language for edge cases (navn, adresser).
For arkitekten (Cosmo)
Spørsmål å stille kunden
-
Datakilde og kontekst:
- Hvilke typer dokumenter/meldinger inneholder PII? (e-post, PDF, strukturert skjema)
- Hvor mange meldinger/dokumenter prosesseres per måned?
- Hvilke PII-typer er kritiske? (fødselsnummer, D-nummer, helseopplysninger)
-
Compliance og juridiske krav:
- Er dette et offentlig eller privat system? (Forvaltningsloven gjelder ikke private)
- Hvilke GDPR-artikler er relevante? (Pseudonymisering, data minimization)
- Kreves det innsyn i originaldokumenter? (bevar original i sikker lagring)
-
Teknisk arkitektur:
- Skal PII maskeres før lagring (pre-processing) eller ved visning (on-demand)?
- Brukes det eksisterende Azure-tjenester? (Synapse, Databricks, APIM)
- Kreves det reversering av masking? (pseudonymisering med key management)
-
Performance og skalerbarhet:
- Hva er akseptabel latency? (<100ms = pre-filter med regex, <1s = batch API)
- Støtter arkitekturen asynkron prosessering? (Native Document PII for batch)
-
Testing og kvalitetssikring:
- Hvordan testes false negatives? (PII som ikke detekteres)
- Hvordan håndteres edge cases? (D-nummer, navn med spesialtegn)
Vanlige fallgruver
-
Overforenklet regex-tilnærming:
- Problem: Detekterer kun fødselsnummer-format, ikke kontekst (f.eks. organisasjonsnummer)
- Løsning: Kombiner regex med Azure AI Language for kontekstuell validering
-
Mangel på språkstøtte:
- Problem: Bruker
language: "en"(engelsk) for norsk tekst → norske navn ikke detekteres - Løsning: Alltid spesifiser
language: "no"
- Problem: Bruker
-
Ikke teste med D-nummer:
- Problem: D-nummer har samme format som fødselsnummer, men dag +40 (f.eks. 41019912345)
- Løsning: Test med D-nummer i alle testcases
-
Ikke håndtere multi-tenant scenarier:
- Problem: Maskeringsregler varierer per tenant (f.eks. kommune vs. statlig etat)
- Løsning: Parameteriser
piiCategoriesbasert på tenant-konfigurasjon
-
Ikke dokumentere confidence threshold-valg:
- Problem: Uklar hvorfor 0.8 ble valgt (compliance-revidering)
- Løsning: Dokumenter valg i ADR (Architecture Decision Record)
Cosmos anbefalinger
For offentlig sektor (NAV, Skatteetaten, kommuner):
- ✅ Bruk Pre-Processing Pipeline (mønster 1) for å sikre PII aldri lagres
- ✅ Kombiner Azure AI Language med Azure SQL TDE (Transparent Data Encryption)
- ✅ Implementer audit logging for alle PII-deteksjoner (Azure Monitor)
- ✅ Integrer med Microsoft Purview for data classification
For private bedrifter (bank, helse, forsikring):
- ✅ Bruk Dynamic Masking (mønster 2) for kundesenterløsninger (rollbasert tilgang)
- ✅ Implementer pseudonymisering (mønster 3) for dataanalyse/ML
- ✅ Vurder Synthetic Replacement policy for syntetiske testdata
Red flags å unngå:
- ❌ IKKE lagre PII i Application Insights eller andre loggingssystemer
- ❌ IKKE bruk CharacterMask for ML-training (bruk SyntheticReplacement)
- ❌ IKKE anta at Azure AI Language detekterer 100% av PII (test manuelt)
- ❌ IKKE ignorer false positives (ødelegger brukeropplevelse)
Kilder og verifisering
Verified (fra Microsoft Learn MCP, re-verifisert 2026-06): (Verified MCP 2026-06)
- Azure AI Language PII Detection Overview — Oppdatert: tre feature-typer (Text PII / Conversation PII / Document-based PII); bruker «Azure Language in Foundry Tools»-terminologi; Foundry (new) + (classic)
- Recognized PII and PHI Entities — bekrefter dedikert kategori NOIdentityNumber («Norway Identity Number»)
- How to: Redact Text PII — Text PII GA-API
2026-05-01, preview2026-05-15-preview; redactionPolicies (4 typer), confidenceScoreThreshold-overrides, DisableEntityValidation, EntitySynonyms, ValueExclusionPolicy - Quickstart: Detect PII — Quickstart er nå for native document PII; link til text/conversation how-to-guides for tekst-PII
- Transparency Note for PII (GDPR compliance, nå under Microsoft Foundry responsible AI)
Baseline (modellkunnskap):
- Norsk fødselsnummer-format (11 siffer, mod11-checksumvalidering)
- D-nummer (dag +40 i fødselsnummer)
- Personopplysningsloven (norsk GDPR-implementering)
- Datatilsynets veiledning om pseudonymisering
Konfidensnivå: 95% (Verified via Microsoft Learn MCP 2026-06, Baseline fra kjente standarder)