# 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](#introduksjon) - [Kjernekomponenter](#kjernekomponenter) - [Arkitekturmønstre](#arkitekturmønstre) - [Beslutningsveiledning](#beslutningsveiledning) - [Integrasjon med Microsoft-stakken](#integrasjon-med-microsoft-stakken) - [Offentlig sektor (Norge)](#offentlig-sektor-norge) - [Kostnad og lisensiering](#kostnad-og-lisensiering) - [For arkitekten (Cosmo)](#for-arkitekten-cosmo) - [Kilder og verifisering](#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 er **`2026-05-15-preview`**. Redaction-policies, `confidenceScoreThreshold`, `disableEntityValidation`, `entitySynonyms` og `valueExclusionPolicy` er preview-funksjoner (først introdusert i `2025-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: ```json { "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](https://ai.azure.com/): 1. Naviger til Language → PII Detection 2. Velg **Extract PII from text** 3. Velg språk: `Norwegian` 4. Lim inn tekst med fødselsnummer 5. 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:** ```yaml # 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:** 1. Trigger: When a new form is submitted (Forms) 2. Action: **Azure AI Language - Detect PII** - Text: `{form_response}` - Language: `no` 3. Condition: If `@{body('Detect_PII')?['entities']}` is not empty 4. 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:** ```python # 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:** ```xml https://{endpoint}/language/:analyze-text POST @{ return JsonConvert.SerializeObject(new { kind = "PiiEntityRecognition", parameters = new { language = "no" }, analysisInput = new { documents = new[] { new { id = "1", text = context.Request.Body.As() } } } }); } @(((IResponse)context.Variables["pii-response"]).Body.As()["results"]["documents"][0]["redactedText"].ToString()) ``` ## 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 1. **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) 2. **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) 3. **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) 4. **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) 5. **Testing og kvalitetssikring:** - Hvordan testes false negatives? (PII som ikke detekteres) - Hvordan håndteres edge cases? (D-nummer, navn med spesialtegn) ### Vanlige fallgruver 1. **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 2. **Mangel på språkstøtte:** - Problem: Bruker `language: "en"` (engelsk) for norsk tekst → norske navn ikke detekteres - Løsning: Alltid spesifiser `language: "no"` 3. **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 4. **Ikke håndtere multi-tenant scenarier:** - Problem: Maskeringsregler varierer per tenant (f.eks. kommune vs. statlig etat) - Løsning: Parameteriser `piiCategories` basert på tenant-konfigurasjon 5. **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](https://learn.microsoft.com/en-us/azure/ai-services/language-service/personally-identifiable-information/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](https://learn.microsoft.com/en-us/azure/ai-services/language-service/personally-identifiable-information/concepts/entity-categories) — bekrefter dedikert kategori **NOIdentityNumber** («Norway Identity Number») - [How to: Redact Text PII](https://learn.microsoft.com/en-us/azure/ai-services/language-service/personally-identifiable-information/how-to/redact-text-pii) — Text PII GA-API **`2026-05-01`**, preview **`2026-05-15-preview`**; redactionPolicies (4 typer), confidenceScoreThreshold-overrides, DisableEntityValidation, EntitySynonyms, ValueExclusionPolicy - [Quickstart: Detect PII](https://learn.microsoft.com/en-us/azure/ai-services/language-service/personally-identifiable-information/quickstart) — Quickstart er nå for native document PII; link til text/conversation how-to-guides for tekst-PII - [Transparency Note for PII](https://learn.microsoft.com/en-us/azure/foundry/responsible-ai/language-service/transparency-note-personally-identifiable-information) (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)