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.
420 lines
16 KiB
Markdown
420 lines
16 KiB
Markdown
# APIM Authentication: OAuth, Azure AD & Managed Identity
|
|
|
|
**Last updated:** 2026-06-24
|
|
**Status:** GA
|
|
**Category:** API Management & AI Gateway
|
|
**Type:** reference
|
|
**Source:** https://learn.microsoft.com/azure/api-management/backends
|
|
|
|
---
|
|
|
|
## Innhold
|
|
|
|
- [Introduksjon](#introduksjon)
|
|
- [Azure AD Integration](#azure-ad-integration)
|
|
- [OAuth 2.0 Flows](#oauth-20-flows)
|
|
- [Managed Identity](#managed-identity)
|
|
- [Client Certificate Authentication](#client-certificate-authentication)
|
|
- [API Key Rotation](#api-key-rotation)
|
|
- [Defense-in-Depth Mønster](#defense-in-depth-mønster)
|
|
- [Referanser](#referanser)
|
|
- [For Cosmo](#for-cosmo)
|
|
|
|
## Introduksjon
|
|
|
|
Autentisering og autorisering er grunnleggende for å sikre AI-tjenester som eksponeres gjennom Azure API Management. Når organisasjoner bygger ut sin AI-plattform med Azure OpenAI, er det kritisk at kun autoriserte applikasjoner og brukere får tilgang, at API-nøkler ikke lekker, og at tilgang kan spores og revideres. APIM tilbyr flere autentiseringsmekanismer som kan kombineres for defense-in-depth.
|
|
|
|
For norsk offentlig sektor er sikker autentisering spesielt viktig gitt krav fra NSM, Datatilsynet og interne sikkerhetspolicyer. Managed identity eliminerer behovet for å håndtere API-nøkler, OAuth 2.0 gir finkornet tilgangskontroll, og sertifikatbasert autentisering tilfredsstiller strenge krav til mutual TLS. Denne referansen dekker alle APIM-autentiseringsmønstre relevant for AI-konsumenter.
|
|
|
|
APIM fungerer som et sentralt autentiseringspunkt mellom AI-konsumenter og backend-tjenester. Klienter autentiserer seg mot APIM (via subscription keys, OAuth tokens, eller sertifikater), og APIM autentiserer seg mot Azure OpenAI-backend (via managed identity eller API keys). Dette separerer klient-identitet fra backend-tilgang og gir full kontroll over hvem som bruker hvilke AI-modeller.
|
|
|
|
---
|
|
|
|
## Azure AD Integration
|
|
|
|
### Microsoft Entra ID som Identity Provider
|
|
|
|
Microsoft Entra ID (tidligere Azure AD) er den primære identitetsleverandøren for Azure-tjenester og integrerer sømløst med APIM:
|
|
|
|
| Integrasjonspunkt | Beskrivelse |
|
|
|-------------------|-------------|
|
|
| APIM Developer Portal | Brukerinnlogging via Entra ID |
|
|
| API-autorisering | JWT-validering av access tokens |
|
|
| Backend-autentisering | Managed identity mot Azure OpenAI |
|
|
| RBAC | Rollebasert tilgang til APIM-administrasjon |
|
|
|
|
### Registrere App i Microsoft Entra ID
|
|
|
|
For å sette opp OAuth 2.0-basert tilgang til AI-APIer:
|
|
|
|
```
|
|
1. Azure Portal → Microsoft Entra ID → App registrations
|
|
2. "+ New registration"
|
|
- Name: "AI Gateway API"
|
|
- Supported account types: "Accounts in this organizational directory only"
|
|
3. Kopier Application (client) ID og Directory (tenant) ID
|
|
4. Under "Expose an API":
|
|
- Set Application ID URI: api://ai-gateway-api
|
|
- Add scope: "AI.Chat", "AI.Completion", "AI.Embedding"
|
|
5. Under "App roles":
|
|
- Add role: "AI.User" (for standard tilgang)
|
|
- Add role: "AI.Admin" (for admin-operasjoner)
|
|
```
|
|
|
|
### APIM Policy for Azure AD Token-validering
|
|
|
|
```xml
|
|
<inbound>
|
|
<base />
|
|
<!-- Valider Azure AD token -->
|
|
<validate-azure-ad-token tenant-id="{{TENANT_ID}}"
|
|
header-name="Authorization"
|
|
failed-validation-httpcode="401"
|
|
failed-validation-error-message="Unauthorized. Access token is missing or invalid.">
|
|
<client-application-ids>
|
|
<application-id>{{CLIENT_APP_ID}}</application-id>
|
|
</client-application-ids>
|
|
<audiences>
|
|
<audience>api://ai-gateway-api</audience>
|
|
</audiences>
|
|
<required-claims>
|
|
<claim name="roles" match="any">
|
|
<value>AI.User</value>
|
|
<value>AI.Admin</value>
|
|
</claim>
|
|
</required-claims>
|
|
</validate-azure-ad-token>
|
|
</inbound>
|
|
```
|
|
|
|
### RBAC-roller for Azure OpenAI
|
|
|
|
| Rolle | Rettigheter | Bruksområde |
|
|
|-------|------------|------------|
|
|
| Cognitive Services OpenAI User | Bruke deployments (chat, completion, embedding) | Applikasjoner og managed identities |
|
|
| Cognitive Services OpenAI Contributor | Opprette og administrere deployments | CI/CD pipelines |
|
|
| Cognitive Services Contributor | Full tilgang til ressursen | Administratorer |
|
|
| Reader | Lese-tilgang | Monitorering og audit |
|
|
|
|
---
|
|
|
|
## OAuth 2.0 Flows
|
|
|
|
### Støttede OAuth 2.0 Flows for AI-APIer
|
|
|
|
| Flow | Bruksområde | Anbefalt for |
|
|
|------|------------|-------------|
|
|
| Client Credentials | Server-til-server (ingen brukerinteraksjon) | Backend-tjenester, automatiserte pipelines |
|
|
| Authorization Code + PKCE | Web-applikasjoner med brukerinnlogging | Chat-applikasjoner, brukergrensesnitt |
|
|
| On-Behalf-Of | Delegert tilgang gjennom mellomtjenester | Orchestratorer, middleware |
|
|
| Device Code | CLI-verktøy og IoT-enheter | Utviklerverktøy, testing |
|
|
|
|
### Client Credentials Flow (Server-til-Server)
|
|
|
|
Mest brukt for automatiserte AI-tjenester:
|
|
|
|
```bash
|
|
# Hent token via client credentials
|
|
curl -X POST "https://login.microsoftonline.com/${TENANT_ID}/oauth2/v2.0/token" \
|
|
-H "Content-Type: application/x-www-form-urlencoded" \
|
|
-d "grant_type=client_credentials" \
|
|
-d "client_id=${CLIENT_ID}" \
|
|
-d "client_secret=${CLIENT_SECRET}" \
|
|
-d "scope=api://ai-gateway-api/.default"
|
|
```
|
|
|
|
### APIM Policy for OAuth 2.0 Validering
|
|
|
|
```xml
|
|
<inbound>
|
|
<base />
|
|
<!-- Valider OAuth 2.0 JWT fra ekstern identity provider -->
|
|
<validate-jwt header-name="Authorization"
|
|
failed-validation-httpcode="401"
|
|
failed-validation-error-message="Unauthorized">
|
|
<openid-config url="https://login.microsoftonline.com/{{TENANT_ID}}/v2.0/.well-known/openid-configuration" />
|
|
<issuers>
|
|
<issuer>https://login.microsoftonline.com/{{TENANT_ID}}/v2.0</issuer>
|
|
</issuers>
|
|
<audiences>
|
|
<audience>api://ai-gateway-api</audience>
|
|
</audiences>
|
|
<required-claims>
|
|
<claim name="scp" match="any">
|
|
<value>AI.Chat</value>
|
|
<value>AI.Completion</value>
|
|
</claim>
|
|
</required-claims>
|
|
</validate-jwt>
|
|
|
|
<!-- Logg bruker-identitet for audit -->
|
|
<set-header name="X-User-Id" exists-action="override">
|
|
<value>@(context.Request.Headers.GetValueOrDefault("Authorization","")
|
|
.AsJwt()?.Claims.GetValueOrDefault("oid", "unknown"))</value>
|
|
</set-header>
|
|
</inbound>
|
|
```
|
|
|
|
### Scopes og Granulær Tilgangskontroll
|
|
|
|
Definer scopes som mapper til AI-kapabiliteter:
|
|
|
|
| Scope | Rettighet | Eksempel |
|
|
|-------|-----------|---------|
|
|
| `AI.Chat` | Chat completion-tilgang | Standard chatbot-bruk |
|
|
| `AI.Completion` | Text completion | Automatisk tekstgenerering |
|
|
| `AI.Embedding` | Embedding-generering | RAG-pipelines, søk |
|
|
| `AI.ImageGeneration` | DALL-E bildegenererring | Kreativ innholdsproduksjon |
|
|
| `AI.Admin` | Full tilgang + admin-operasjoner | Modell-administrasjon |
|
|
|
|
---
|
|
|
|
## Managed Identity
|
|
|
|
### System-Assigned vs User-Assigned Managed Identity
|
|
|
|
| Type | Livssyklus | Bruksområde |
|
|
|------|-----------|------------|
|
|
| System-assigned | Knyttet til APIM-instansen | Enkel oppsett, én identitet per instans |
|
|
| User-assigned | Uavhengig Azure-ressurs | Delt identitet, multi-region, forhåndskonfigurasjon |
|
|
|
|
### Konfigurere Managed Identity for Azure OpenAI
|
|
|
|
**Steg 1: Aktiver managed identity på APIM**
|
|
|
|
```bash
|
|
# Aktiver system-assigned managed identity
|
|
az apim update \
|
|
--name ai-gateway-apim \
|
|
--resource-group rg-apim \
|
|
--enable-managed-identity true
|
|
```
|
|
|
|
**Steg 2: Tildel Cognitive Services OpenAI User-rolle**
|
|
|
|
```bash
|
|
# Hent APIM identity object ID
|
|
APIM_IDENTITY=$(az apim show --name ai-gateway-apim --resource-group rg-apim \
|
|
--query identity.principalId -o tsv)
|
|
|
|
# Tildel rolle på Azure OpenAI-ressurs
|
|
az role assignment create \
|
|
--role "Cognitive Services OpenAI User" \
|
|
--assignee-object-id $APIM_IDENTITY \
|
|
--scope /subscriptions/{sub-id}/resourceGroups/{rg}/providers/Microsoft.CognitiveServices/accounts/{aoai-name}
|
|
```
|
|
|
|
**Steg 3: Konfigurer APIM-policy for managed identity autentisering**
|
|
|
|
```xml
|
|
<inbound>
|
|
<base />
|
|
<!-- Hent access token via managed identity -->
|
|
<authentication-managed-identity
|
|
resource="https://cognitiveservices.azure.com"
|
|
output-token-variable-name="managed-id-access-token"
|
|
ignore-error="false" />
|
|
|
|
<!-- Sett Authorization-header med bearer token -->
|
|
<set-header name="Authorization" exists-action="override">
|
|
<value>@("Bearer " + (string)context.Variables["managed-id-access-token"])</value>
|
|
</set-header>
|
|
|
|
<!-- Fjern eventuell api-key header for sikkerhet -->
|
|
<set-header name="api-key" exists-action="delete" />
|
|
</inbound>
|
|
```
|
|
|
|
### Backend-konfigurasjon med Managed Identity
|
|
|
|
Alternativ tilnærming via backend-entitet (anbefalt):
|
|
|
|
```bicep
|
|
resource aoaiBackend 'Microsoft.ApiManagement/service/backends@2023-09-01-preview' = {
|
|
name: 'ai-gateway-apim/aoai-backend'
|
|
properties: {
|
|
url: 'https://my-aoai.openai.azure.com'
|
|
protocol: 'http'
|
|
credentials: {
|
|
authorization: {
|
|
scheme: 'Bearer'
|
|
parameter: 'managed-identity'
|
|
}
|
|
}
|
|
tls: {
|
|
validateCertificateChain: true
|
|
validateCertificateName: true
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**Merk:** Når du importerer en API direkte fra Microsoft Foundry, konfigurerer APIM automatisk managed identity-autentisering mot backend.
|
|
|
|
---
|
|
|
|
## Client Certificate Authentication
|
|
|
|
### Mutual TLS (mTLS)
|
|
|
|
For scenarier der klienter må autentisere seg med sertifikater:
|
|
|
|
```xml
|
|
<inbound>
|
|
<base />
|
|
<!-- Valider klientsertifikat -->
|
|
<choose>
|
|
<when condition="@(context.Request.Certificate == null)">
|
|
<return-response>
|
|
<set-status code="403" reason="Forbidden" />
|
|
<set-body>Client certificate required</set-body>
|
|
</return-response>
|
|
</when>
|
|
<when condition="@(!context.Request.Certificate.Verify())">
|
|
<return-response>
|
|
<set-status code="403" reason="Forbidden" />
|
|
<set-body>Invalid client certificate</set-body>
|
|
</return-response>
|
|
</when>
|
|
<!-- Valider spesifikt thumbprint -->
|
|
<when condition="@(context.Request.Certificate.Thumbprint != "{{TRUSTED_CERT_THUMBPRINT}}")">
|
|
<return-response>
|
|
<set-status code="403" reason="Forbidden" />
|
|
<set-body>Untrusted client certificate</set-body>
|
|
</return-response>
|
|
</when>
|
|
</choose>
|
|
|
|
<!-- Logg sertifikatinformasjon for audit -->
|
|
<set-header name="X-Client-Cert-Subject" exists-action="override">
|
|
<value>@(context.Request.Certificate.Subject)</value>
|
|
</set-header>
|
|
</inbound>
|
|
```
|
|
|
|
### CA-sertifikat Validering (v2 Tiers)
|
|
|
|
I APIM v2-tiers kan du konfigurere custom CA-sertifikater direkte på backend-entiteten:
|
|
|
|
| Valideringsmetode | Bruksområde |
|
|
|-------------------|------------|
|
|
| Certificate thumbprint | Eksakt sertifikatmatch |
|
|
| Subject name + Issuer thumbprint | CA-basert validering |
|
|
| Certificate chain validation | Full kjede-validering |
|
|
|
|
---
|
|
|
|
## API Key Rotation
|
|
|
|
### Sikker API-nøkkelhåndtering via Named Values
|
|
|
|
```xml
|
|
<!-- Bruk named value (eventuelt Key Vault-referanse) for API-nøkler -->
|
|
<set-header name="api-key" exists-action="override">
|
|
<value>{{azure-openai-api-key}}</value>
|
|
</set-header>
|
|
```
|
|
|
|
### Key Vault-integrasjon for Automatisk Rotasjon
|
|
|
|
```
|
|
1. Opprett Key Vault secret med API-nøkkel
|
|
2. Konfigurer rotasjonspolicy i Key Vault
|
|
3. Opprett named value i APIM med Key Vault-referanse
|
|
4. APIM henter automatisk oppdatert nøkkel
|
|
```
|
|
|
|
```bash
|
|
# Opprett Key Vault secret
|
|
az keyvault secret set \
|
|
--vault-name kv-ai-gateway \
|
|
--name aoai-api-key \
|
|
--value "your-api-key-here"
|
|
|
|
# Opprett APIM named value med Key Vault-referanse
|
|
az apim nv create \
|
|
--resource-group rg-apim \
|
|
--service-name ai-gateway-apim \
|
|
--named-value-id aoai-api-key \
|
|
--display-name "Azure OpenAI API Key" \
|
|
--secret true \
|
|
--value "your-api-key-here"
|
|
```
|
|
|
|
### Anbefalt Autentiseringshierarki
|
|
|
|
| Prioritet | Metode | Sikkerhetsnivå | Anbefalt for |
|
|
|-----------|--------|---------------|-------------|
|
|
| 1 | Managed Identity + OAuth 2.0 | Høyest | Produksjonsmiljøer |
|
|
| 2 | Managed Identity alene | Høy | Enklere oppsett |
|
|
| 3 | API Key via Key Vault | Moderat | Legacy-integrasjoner |
|
|
| 4 | API Key direkte | Lavest | Kun dev/test |
|
|
|
|
---
|
|
|
|
## Defense-in-Depth Mønster
|
|
|
|
### Kombinert Autentiseringspolicy
|
|
|
|
Kombiner klient-autentisering (OAuth) med backend-autentisering (managed identity):
|
|
|
|
```xml
|
|
<inbound>
|
|
<base />
|
|
|
|
<!-- Lag 1: Valider klient-token (OAuth 2.0) -->
|
|
<validate-azure-ad-token tenant-id="{{TENANT_ID}}"
|
|
header-name="Authorization"
|
|
failed-validation-httpcode="401">
|
|
<client-application-ids>
|
|
<application-id>{{CLIENT_APP_ID}}</application-id>
|
|
</client-application-ids>
|
|
<audiences>
|
|
<audience>api://ai-gateway-api</audience>
|
|
</audiences>
|
|
</validate-azure-ad-token>
|
|
|
|
<!-- Lag 2: Ekstraher brukerinfo for audit og rate limiting -->
|
|
<set-variable name="caller-id"
|
|
value="@(context.Request.Headers.GetValueOrDefault("Authorization","")
|
|
.AsJwt()?.Claims.GetValueOrDefault("oid", "anonymous"))" />
|
|
|
|
<!-- Lag 3: Rate limiting per bruker -->
|
|
<llm-token-limit counter-key="@((string)context.Variables["caller-id"])"
|
|
tokens-per-minute="10000"
|
|
estimate-prompt-tokens="true" />
|
|
|
|
<!-- Lag 4: Autentiser mot backend via managed identity -->
|
|
<authentication-managed-identity
|
|
resource="https://cognitiveservices.azure.com"
|
|
output-token-variable-name="mi-token" />
|
|
<set-header name="Authorization" exists-action="override">
|
|
<value>@("Bearer " + (string)context.Variables["mi-token"])</value>
|
|
</set-header>
|
|
|
|
<!-- Fjern klient-nøkler som ikke skal videresendes -->
|
|
<set-header name="api-key" exists-action="delete" />
|
|
</inbound>
|
|
```
|
|
|
|
---
|
|
|
|
## Referanser
|
|
|
|
- [Authenticate and authorize access to LLM APIs](https://learn.microsoft.com/en-us/azure/api-management/api-management-authenticate-authorize-ai-apis) — Offisiell autentiseringsguide for AI-APIer i APIM
|
|
- [Provide custom authentication to Azure OpenAI through a gateway](https://learn.microsoft.com/en-us/azure/architecture/ai-ml/guide/azure-openai-gateway-custom-authentication) — Arkitekturmønstre for autentisering
|
|
- [Backends in API Management](https://learn.microsoft.com/en-us/azure/api-management/backends) — Backend-konfigurasjon med managed identity
|
|
- [Import an Azure OpenAI API](https://learn.microsoft.com/en-us/azure/api-management/azure-openai-api-from-specification) — Automatisk autentiseringsoppsett ved import
|
|
- [validate-azure-ad-token policy](https://learn.microsoft.com/en-us/azure/api-management/validate-azure-ad-token-policy) — Policy-referanse for Azure AD-tokenvalidering
|
|
- [authentication-managed-identity policy](https://learn.microsoft.com/en-us/azure/api-management/authentication-managed-identity-policy) — Policy-referanse for managed identity
|
|
- [How to use managed identities in API Management](https://learn.microsoft.com/en-us/azure/api-management/api-management-howto-use-managed-service-identity) — Oppsettguide for managed identity
|
|
|
|
---
|
|
|
|
## For Cosmo
|
|
|
|
- **Bruk denne referansen** når kunder trenger veiledning om autentisering og autorisering av AI-APIer gjennom APIM, spesielt ved overgang fra API-nøkler til managed identity.
|
|
- Anbefal alltid managed identity som primær autentiseringsmetode mot Azure OpenAI — det eliminerer nøkkelhåndtering og reduserer angrepsflaten.
|
|
- For offentlig sektor: Kombiner OAuth 2.0 (klient-autentisering) med managed identity (backend-autentisering) for defense-in-depth. Managed identity alene sikrer kun gateway-til-backend, ikke klient-til-gateway.
|
|
- Husk at APIM automatisk konfigurerer managed identity-autentisering ved import fra Microsoft Foundry — dette er enkleste oppsett.
|
|
- Ved multi-region deployment: Sørg for at managed identity har riktige RBAC-roller på alle Azure OpenAI-instanser i alle regioner.
|