ms-ai-architect/skills/ms-ai-security/references/ai-security-engineering/pii-detection-norwegian-context.md
Kjell Tore Guttormsen 03d596e4ec docs(ms-ai-architect): KB-refresh tema-b — Foundry-navnesveip «Azure AI Foundry»→«Microsoft Foundry» (233 filer)
Verifisert mot offisiell MS-doc (juni 2026): «Microsoft Foundry» er det
gjeldende produkt-/portalnavnet; «Foundry (classic)» = gamle «Azure AI Foundry»
(/azure/foundry/ vs /azure/foundry-classic/). Premiss bekreftet før sveip.

Multi-regel, IKKE naiv s/Azure AI Foundry/Microsoft Foundry/ — MS dropper
«Azure AI» (legger IKKE til «Microsoft») for to produktvarianter:
- «Azure AI Foundry Agent[ Service|s]» → «Foundry Agent Service/Agents» (MS-form)
- «Azure AI Foundry Models» → «Foundry Models» (i «Azure OpenAI in Foundry Models»)
- «Azure AI Foundry SDK» → «Microsoft Foundry SDK» (operatør-valg)
- «Azure AI Foundry portal/project» + generisk → «Microsoft Foundry»
- Pre-eksisterende «Microsoft Foundry Models» (4) normalisert → «Foundry Models»

Bevart: «Azure OpenAI», «Azure AI Inference SDK», «Azure AI Search»,
«Azure AI Services», kode-IDer. Historisk ref «(tidligere Azure AI Foundry)»
i model-catalog-2026.md beskyttet via lookbehind. URL /azure/ai-foundry/→
/azure/foundry/ kun i owasp-llm-top10 (KB-ref); docs/-filer deferred.

Scope: skills (inkl. 3 SKILL.md) + commands + agents + README + CLAUDE.
Ekskludert: docs/ (interne), playground/+tests/ fixtures (testdata),
CHANGELOG.md (historisk logg), STATE.md (gitignored).

3 SKILL.md endret (advisor/engineering/security) → judge-cache teknisk
invalidert for disse, men scorer uendret: advisor 91, eng/gov/infra/sec 96
(alle ≥90). validate 239/0. 0 «Azure AI Foundry» igjen (utenom bevart ref).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 21:00:27 +02:00

432 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# PII Detection and Masking in Norwegian Text
**Last updated:** 2026-06-19
**Status:** GA
**Category:** AI Security Engineering
---
## 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
<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
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)