ms-ai-architect/skills/ms-ai-engineering/references/agent-orchestration/multi-tenant-agent-isolation.md
Kjell Tore Guttormsen ddce43d8b2 feat(ms-ai-architect): Spor 1 — Port-1-substrat migrert på 4 ikke-advisor-skills (243 Source + 327 Type + 325 TOC + stale-verified poison fjernet) [skip-docs]
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.
2026-07-04 10:19:11 +02:00

15 KiB

Multi-Tenant Agent Isolation and Security

Last updated: 2026-02 Status: GA Category: Agent Orchestration & Automation Type: reference


Innhold

Introduksjon

Multi-tenant agentarkitektur er en fundamental utfordring for organisasjoner som tilbyr AI-agenter til flere kunder, avdelinger eller forretningsenheter. Korrekt isolasjon sikrer at data, konfigurasjoner og agentoppførsel ikke lekker mellom tenants, samtidig som man opprettholder kostnadseffektivitet og skalerbarhet.

Azure-plattformen tilbyr flere isolasjonsmodeller for AI-agenter -- fra logisk isolasjon med delt infrastruktur til fullstendig fysisk separasjon med dedikerte ressurser per tenant. Valget avhenger av regulatoriske krav, dataklassifisering, ytelsesgarantier og kostnadsbetraktninger. Microsoft Entra ID utgjør fundamentet for tenant-aware tilgangskontroll, mens Azure API Management, Azure OpenAI og Foundry Agent Service tilbyr tenant-isolasjon på ulike nivåer.

For norsk offentlig sektor med strenge krav til dataisolasjon (Schrems II, NSM, Sikkerhetsloven) er det kritisk å velge riktig isolasjonsmodell. Mange offentlige virksomheter opererer med skjermingsverdig informasjon som krever sterkere isolasjonsgarantier enn standard multi-tenant-løsninger tilbyr.

Kjernekomponenter

Komponent Formål Teknologi
Identity Isolation Tenant-bevisst autentisering og autorisasjon Microsoft Entra ID, Entra Agent ID
Data Isolation Separasjon av tenant-data i lagring og retrieval Cosmos DB partitions, Azure AI Search per-tenant indexes
Model Isolation Dedikerte eller delte modelldeployments Azure OpenAI deployment models
Network Isolation Nettverkssegmentering mellom tenants Azure VNet, Private Endpoints
Quota Isolation Ressurskvoter per tenant Azure APIM rate limiting, TPM-kvoter
Audit Segregation Separate revisjonslogger per tenant Log Analytics workspaces, tenant-tagged telemetry

Isolasjonsmodeller for Azure OpenAI

Oversikt

Modell Dataisolasjon Ytelsesisolasjon Kompleksitet Kostnad
Delt instans, delt deployment Lav Lav Lav Lavest
Delt instans, dedikert deployment per tenant Medium Høy Medium Medium
Dedikert instans per tenant (provider-sub) Høy Høy Lav-Medium Høy
Tenant-provided instans (tenant-sub) Høy Høy Lav for provider Høyest

Pattern 1: Logisk isolasjon med delt infrastruktur

// Tenant-bevisst agentorkestrering med Semantic Kernel
public class MultiTenantAgentOrchestrator
{
    private readonly IKernelFactory _kernelFactory;
    private readonly ITenantResolver _tenantResolver;

    public async Task<AgentResponse> ProcessRequest(
        string userId,
        string prompt)
    {
        // Resolve tenant fra brukerens identitet
        var tenant = await _tenantResolver.ResolveTenant(userId);

        // Opprett tenant-scoped Kernel
        var kernel = _kernelFactory.CreateForTenant(tenant.Id);

        // Sett tenant-kontekst for alle operasjoner
        kernel.Data["TenantId"] = tenant.Id;
        kernel.Data["DataBoundary"] = tenant.DataBoundary;

        // Agenten arver tenant-begrensninger
        var agent = new ChatCompletionAgent
        {
            Name = "TenantScopedAgent",
            Instructions = $"""
                Du er en assistent for {tenant.Name}.
                Du har KUN tilgang til data merket med tenant {tenant.Id}.
                Aldri referer til eller avslør data fra andre tenants.
                """,
            Kernel = kernel
        };

        return await agent.InvokeAsync(prompt);
    }
}

Pattern 2: Per-tenant Azure OpenAI deployments

// Dedikert modell-deployment per tenant for ytelsesisolasjon
public class TenantDeploymentManager
{
    private readonly Dictionary<string, string> _tenantDeployments;

    public AzureChatCompletion GetServiceForTenant(string tenantId)
    {
        var deploymentName = _tenantDeployments[tenantId];

        return new AzureChatCompletion(
            deploymentName: deploymentName,  // f.eks. "gpt-4o-tenant-ddt"
            endpoint: _endpoint,
            credentials: new DefaultAzureCredential()
        );
    }
}

Pattern 3: Hybrid multi-tenant med Deployment Stamps

┌──────────────────────────────────────────────┐
│              Shared Infrastructure            │
│  ┌─────────────────────────────────────────┐  │
│  │  Azure API Management (AI Gateway)      │  │
│  │  - Tenant routing                       │  │
│  │  - Rate limiting per tenant             │  │
│  │  - Token quota enforcement              │  │
│  └───────────┬────────────┬────────────────┘  │
│              │            │                   │
│  ┌───────────▼──┐  ┌─────▼──────────┐       │
│  │ Standard     │  │  Premium        │       │
│  │ Tenants      │  │  Tenants        │       │
│  │              │  │                 │       │
│  │ Shared AOAI  │  │ Dedicated AOAI  │       │
│  │ Shared Index │  │ Per-tenant Index│       │
│  │ Shared CosmosDB│ │ Dedicated DB   │       │
│  └──────────────┘  └────────────────┘       │
└──────────────────────────────────────────────┘

Tenant Data Isolation

RAG med tenant-isolasjon

# Azure AI Search med tenant-scoped retrieval
from azure.search.documents import SearchClient
from azure.identity import DefaultAzureCredential

class TenantScopedRetriever:
    def __init__(self, search_endpoint: str, index_name: str):
        self.client = SearchClient(
            endpoint=search_endpoint,
            index_name=index_name,
            credential=DefaultAzureCredential()
        )

    def search(self, query: str, tenant_id: str) -> list:
        """Søk med obligatorisk tenant-filter"""
        results = self.client.search(
            search_text=query,
            filter=f"tenant_id eq '{tenant_id}'",
            # OData-filter sikrer at BARE tenant-data returneres
            select=["content", "title", "source"],
            top=5
        )
        return [r for r in results]

Cosmos DB partisjonering

// Tenant-ID som partition key i Cosmos DB
public class AgentConversationStore
{
    private readonly Container _container;

    public async Task<ConversationThread> GetThread(
        string tenantId, string threadId)
    {
        // Partition key = tenant_id sikrer fysisk isolasjon
        var response = await _container.ReadItemAsync<ConversationThread>(
            id: threadId,
            partitionKey: new PartitionKey(tenantId)
        );
        return response.Resource;
    }

    // Cross-tenant access er umulig uten riktig partition key
}

Permission Enforcement

Microsoft Entra Agent ID

Microsoft Entra Agent ID gir agenter dedikerte identiteter med kontrollerte tilganger:

// Opprett agent-identitet med tenant-scoped tilganger
public class AgentIdentityManager
{
    public async Task<AgentIdentity> CreateTenantAgent(
        string tenantId,
        string agentPurpose)
    {
        // Hver tenant-agent får en unik managed identity
        var identity = await _entraClient.CreateAgentIdentity(new
        {
            DisplayName = $"Agent-{agentPurpose}-{tenantId}",
            // Scoped til kun denne tenantens ressurser
            Permissions = new[]
            {
                $"data.read.tenant.{tenantId}",
                $"tools.invoke.tenant.{tenantId}"
            },
            // Kort-levd tokens for minste privilegium
            TokenLifetime = TimeSpan.FromMinutes(15)
        });

        return identity;
    }
}

RBAC-modell for multi-tenant agenter

Rolle Tilgang Scope
Agent.Reader Les tenant-data via RAG Spesifikk tenant
Agent.Writer Opprett/oppdater agentressurser Spesifikk tenant
Agent.Admin Full kontroll over agenter Spesifikk tenant
Platform.Admin Konfigurer tverrtenants infrastruktur Plattform-nivå
Audit.Reader Les revisjonslogger Per tenant eller global

Audit Segregation

# Tenant-segregert logging til Application Insights
from opentelemetry import trace

tracer = trace.get_tracer("multi-tenant-agent")

def process_agent_request(tenant_id: str, user_id: str, prompt: str):
    with tracer.start_as_current_span("agent_invocation") as span:
        # Tenant-kontekst på alle spans
        span.set_attribute("tenant.id", tenant_id)
        span.set_attribute("user.id", user_id)
        span.set_attribute("agent.name", "customer-support")

        # Tenant-spesifikk logging
        # KQL kan filtrere: traces | where customDimensions.tenant_id == "xxx"

        result = invoke_agent(prompt, tenant_id)

        span.set_attribute("response.token_count", result.token_count)
        span.set_attribute("response.evaluation.relevance", result.relevance)

        return result

KQL for tenant-isolert rapportering

// Kostnads- og bruksrapport per tenant
traces
| where timestamp > ago(30d)
| where customDimensions.tenant_id != ""
| summarize
    total_requests = count(),
    total_tokens = sum(todouble(customDimensions["response.token_count"])),
    avg_latency = avg(duration),
    avg_relevance = avg(todouble(customDimensions["response.evaluation.relevance"]))
    by tostring(customDimensions["tenant_id"])
| order by total_tokens desc

Cross-Tenant Attack Prevention

Trusselmodell

Trussel Angrepsvei Mitigering
Prompt injection for data-lekkasje Bruker crafter prompt som ber om annen tenants data Mandatory tenant-filter i alle data-queries
Token-sharing mellom tenants Delt autentiseringstoken Per-tenant managed identities
Side-channel via shared model Informasjon lekker gjennom modellens kontekst Separate deployments for sensitive tenants
Indirekte prompt injection Malicious data i en tenants kunnskapsbase påvirker en annen Strikt input-validering + Content Safety
Privilege escalation Agent eskalerer tilgang utover tenant-scope RBAC med kort-levde tokens + audit logging

Defence-in-depth for tenant-isolasjon

// Multi-layer isolasjonsvalidering
public class TenantIsolationMiddleware
{
    public async Task ValidateRequest(AgentRequest request)
    {
        // Layer 1: Identity verification
        var tenantFromToken = ExtractTenantFromToken(request.AuthToken);

        // Layer 2: Request parameter validation
        if (request.TenantId != tenantFromToken)
            throw new SecurityException("Tenant mismatch");

        // Layer 3: Data access filter injection
        request.DataFilters.Add(new TenantFilter(tenantFromToken));

        // Layer 4: Response validation
        // Verifiser at responsen ikke inneholder data fra andre tenants
        request.OnResponseGenerated += async (response) =>
        {
            await ValidateResponseDoesNotLeakCrossTenantData(
                response, tenantFromToken);
        };
    }
}

Resource Quotas

APIM-basert quota enforcement

<!-- Azure API Management policy for per-tenant kvoter -->
<policies>
    <inbound>
        <set-variable name="tenantId"
            value="@(context.Request.Headers
                .GetValueOrDefault("X-Tenant-Id","unknown"))" />

        <!-- Token rate limiting per tenant -->
        <azure-openai-token-limit
            counter-key="@((string)context.Variables["tenantId"])"
            tokens-per-minute="50000"
            estimate-prompt-tokens="true" />

        <!-- Request rate limiting per tenant -->
        <rate-limit-by-key
            calls="100"
            renewal-period="60"
            counter-key="@((string)context.Variables["tenantId"])" />
    </inbound>
</policies>

Norsk offentlig sektor

Spesielle krav

Krav Regulering Implementering
Data-suverenitet Schrems II Azure Norway East/West, eller Azure Local
Sikkerhetsgradert info Sikkerhetsloven Fysisk isolasjon, dedikert infrastruktur
Personvern GDPR Art. 28 Databehandleravtale per tenant, DPA
Logging Arkivloven Retensjonspolicies per tenant, minimum 5 år
Tilgangskontroll eInnsyn, offentlighetsloven Transparent tilgangslogg per tenant

Anbefalt isolasjonsmodell for offentlig sektor

For de fleste offentlige virksomheter i Norge anbefales hybrid modell:

  • Logisk isolasjon for standard tjenester (Cosmos DB partitioning, tenant-filter i AI Search)
  • Fysisk isolasjon for sensitiv informasjon (dedikert Azure OpenAI, VNet-isolert)
  • Azure Local for skjermingsverdig informasjon som ikke kan forlate norsk territorium

Beslutningsrammeverk

Scenario Anbefaling Begrunnelse
SaaS med mange småkunder Logisk isolasjon, delt AOAI Kostnadseffektivt, skalerer
Enterprise med compliance-krav Hybrid: delt infra + dedikerte AOAI Balanse mellom kostnad og isolasjon
Offentlig sektor standard Hybrid + Azure Norway region Datalokalitet + kostnadseffektivitet
Skjermingsverdig informasjon Full fysisk isolasjon Regulatorisk krav, ingen kompromisser
Multi-region med data residency Deployment stamps per region Datasuverenitet per jurisdiksjon

For Cosmo

  • Velg isolasjonsmodell basert på dataklassifisering -- ikke overengineer for åpne data, men underestimer aldri kravene for sensitiv informasjon. Hybrid er vanligvis riktig svar.
  • Tenant-filter i RAG er obligatorisk -- aldri stol på at agentens instruksjoner alene hindrer datalekkasje. Implementer tekniske kontroller (OData-filter, partition keys) som ikke kan omgås.
  • Microsoft Entra Agent ID er den anbefalte måten å gi agenter identitet med tenant-scoped tilganger -- bruk kort-levde tokens og minste privilegium.
  • APIM som AI Gateway er essensielt for multi-tenant -- det gir token rate limiting, kostnadsfordeling og audit logging per tenant uten kodeendringer i agentene.
  • For norsk offentlig sektor: Start med Azure Norway East, vurder Azure Local for høysikkerhet, og sørg for at databehandleravtaler er på plass per tenant.