ms-ai-architect/skills/ms-ai-engineering/references/agent-orchestration/agent-compliance-and-audit-trails.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

18 KiB

Agent Compliance and Audit Trail Management

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


Innhold

Introduksjon

Compliance og revisjonsspor for AI-agenter er ikke lenger en "nice-to-have" -- det er et regulatorisk krav under EU AI Act, GDPR, og nasjonale regelverk som den norske Forvaltningsloven. Organisasjoner må dokumentere hva agenter gjør, hvilke data de aksesserer, hvilke beslutninger de tar, og hvordan disse beslutningene kan etterprøves. Uten strukturerte revisjonsspor risikerer virksomheter regulatoriske sanksjoner og tap av tillit.

Microsoft tilbyr en governance-stack for agentcompliance gjennom Microsoft Foundry Control Plane for unified agentsynlighet, Microsoft Purview Compliance Manager for regulatorisk mapping, Microsoft Entra Agent ID for identitets- og tilgangsstyring, Azure Monitor og Log Analytics for sentralisert logging, og Microsoft Agent 365 for enterprise-grade agentovervåking. Disse verktøyene til sammen sikrer at enhver agenthandling kan spores tilbake til en spesifikk brukerforespørsel, gjennom agentens resonnering, til det endelige resultatet.

For norsk offentlig sektor er kravene spesielt strenge: Forvaltningsloven krever dokumentasjon av saksbehandling, Arkivloven krever journalføring, Offentlighetsloven gir innsynsrett, og EU AI Act stiller krav til risikostyring og logging av høyrisiko AI-systemer.

Kjernekomponenter

Komponent Formål Teknologi
Action Audit Logging Logg alle agenthandlinger Azure Monitor, Log Analytics
Decision Trail Dokumentér beslutningskjeden OpenTelemetry traces, custom attributes
Retention Policies Bevar data iht. regelverk Azure Storage lifecycle, Purview
Regulatory Alignment Map kontroller til regelverk Microsoft Purview Compliance Manager
Compliance Reporting Generer compliance-rapporter Azure Monitor Workbooks, Power BI
Agent Identity Spor hvem/hva som handlet Microsoft Entra Agent ID

Action Audit Logging

Comprehensive agent audit log

from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
import json

class AgentActionType(Enum):
    QUERY_RECEIVED = "query_received"
    INTENT_CLASSIFIED = "intent_classified"
    AGENT_ROUTED = "agent_routed"
    RAG_RETRIEVAL = "rag_retrieval"
    TOOL_INVOKED = "tool_invoked"
    LLM_CALLED = "llm_called"
    RESPONSE_GENERATED = "response_generated"
    RESPONSE_FILTERED = "response_filtered"
    ERROR_OCCURRED = "error_occurred"
    HUMAN_ESCALATED = "human_escalated"

@dataclass
class AgentAuditEntry:
    timestamp: str = field(
        default_factory=lambda: datetime.utcnow().isoformat()
    )
    trace_id: str = ""
    span_id: str = ""
    session_id: str = ""
    user_id: str = ""
    agent_id: str = ""
    agent_name: str = ""
    action_type: str = ""
    action_details: dict = field(default_factory=dict)
    input_summary: str = ""  # Redacted/summarized
    output_summary: str = ""  # Redacted/summarized
    data_accessed: list = field(default_factory=list)
    tools_used: list = field(default_factory=list)
    model_used: str = ""
    tokens_consumed: int = 0
    duration_ms: float = 0
    success: bool = True
    error_message: str = ""
    compliance_flags: list = field(default_factory=list)

class AgentAuditLogger:
    def __init__(self, log_analytics_client):
        self.client = log_analytics_client

    async def log(self, entry: AgentAuditEntry):
        """Logg audit entry til Azure Log Analytics"""
        await self.client.upload(
            rule_id=os.environ["DCR_IMMUTABLE_ID"],
            stream_name="Custom-AgentAuditLog_CL",
            logs=[{
                "TimeGenerated": entry.timestamp,
                "TraceId": entry.trace_id,
                "SpanId": entry.span_id,
                "SessionId": entry.session_id,
                "UserId": entry.user_id,
                "AgentId": entry.agent_id,
                "AgentName": entry.agent_name,
                "ActionType": entry.action_type,
                "ActionDetails": json.dumps(entry.action_details),
                "InputSummary": entry.input_summary,
                "OutputSummary": entry.output_summary,
                "DataAccessed": json.dumps(entry.data_accessed),
                "ToolsUsed": json.dumps(entry.tools_used),
                "ModelUsed": entry.model_used,
                "TokensConsumed": entry.tokens_consumed,
                "DurationMs": entry.duration_ms,
                "Success": entry.success,
                "ErrorMessage": entry.error_message,
                "ComplianceFlags": json.dumps(entry.compliance_flags)
            }]
        )

Immutable audit log med Azure Storage

# Immutable storage for regulatorisk krav
from azure.storage.blob import BlobServiceClient

class ImmutableAuditStore:
    def __init__(self, connection_string: str, container: str):
        self.client = BlobServiceClient.from_connection_string(
            connection_string
        )
        self.container = self.client.get_container_client(container)
        # Container konfigurert med immutability policy

    async def store_audit_record(self, record: AgentAuditEntry):
        """Lagre audit record i immutable blob storage"""
        blob_name = (
            f"audit/{record.timestamp[:10]}/"
            f"{record.agent_name}/{record.trace_id}.json"
        )
        blob_client = self.container.get_blob_client(blob_name)
        await blob_client.upload_blob(
            json.dumps(record.__dict__),
            overwrite=False  # Immutable -- kan ikke overskrives
        )

Decision Trail Documentation

Komplett beslutningskjede

from opentelemetry import trace

tracer = trace.get_tracer("agent-decision-trail")

async def process_with_full_trail(query: str, user_id: str):
    """Dokumentér komplett beslutningskjede for etterprøvbarhet"""

    with tracer.start_as_current_span("decision_trail") as root:
        root.set_attribute("user.id", user_id)
        root.set_attribute("query.hash", hash(query))  # Ikke full tekst

        # Steg 1: Intent classification
        with tracer.start_as_current_span("classify_intent") as span:
            intent = await classify(query)
            span.set_attribute("decision.type", "intent_classification")
            span.set_attribute("decision.result", intent.label)
            span.set_attribute("decision.confidence", intent.confidence)
            span.set_attribute("decision.reasoning",
                f"Klassifisert som '{intent.label}' basert på "
                f"nøkkelord-matching og semantisk likhet"
            )

        # Steg 2: Agent selection
        with tracer.start_as_current_span("select_agent") as span:
            agent = select_best_agent(intent)
            span.set_attribute("decision.type", "agent_selection")
            span.set_attribute("decision.result", agent.name)
            span.set_attribute("decision.reasoning",
                f"Valgt '{agent.name}' basert på intent '{intent.label}' "
                f"og agent capability score {agent.score}"
            )

        # Steg 3: Data retrieval
        with tracer.start_as_current_span("retrieve_data") as span:
            docs = await retrieve(query, agent)
            span.set_attribute("decision.type", "data_retrieval")
            span.set_attribute("data.sources",
                [d.source for d in docs])
            span.set_attribute("data.doc_count", len(docs))
            span.set_attribute("decision.reasoning",
                f"Hentet {len(docs)} dokumenter fra "
                f"{set(d.source for d in docs)}"
            )

        # Steg 4: Response generation
        with tracer.start_as_current_span("generate_response") as span:
            response = await agent.invoke(query, docs)
            span.set_attribute("decision.type", "response_generation")
            span.set_attribute("model.used", response.model)
            span.set_attribute("tokens.total", response.total_tokens)
            span.set_attribute("decision.reasoning",
                f"Generert svar med {response.model}, "
                f"{response.total_tokens} tokens"
            )

        return response

Retention Policies

Data lifecycle management

Datatype Retensjon Begrunnelse Implementering
Audit logs (sammendrag) 7 år Arkivloven, bokføringsloven Immutable Blob Storage
Full traces med innhold 12 måneder Debugging og forbedring Log Analytics, TTL
Samtalehistorikk 6 måneder Brukeropplevelse Cosmos DB TTL
Evaluerings-data 24 måneder Kvalitetssikring Log Analytics
PII-holdige logger 3 måneder GDPR dataminimering Automatisk sletting
Aggregerte metrikker Ubegrenset Trendanalyse Azure Monitor Metrics

Automatisert retensjon

# Azure Storage lifecycle policy for audit data
lifecycle_policy = {
    "rules": [
        {
            "name": "audit-tier-to-cool",
            "type": "Lifecycle",
            "definition": {
                "actions": {
                    "baseBlob": {
                        "tierToCool": {"daysAfterModificationGreaterThan": 90},
                        "tierToArchive": {"daysAfterModificationGreaterThan": 365},
                        "delete": {"daysAfterModificationGreaterThan": 2555}
                        # 7 år
                    }
                },
                "filters": {
                    "blobTypes": ["blockBlob"],
                    "prefixMatch": ["audit/"]
                }
            }
        },
        {
            "name": "pii-cleanup",
            "type": "Lifecycle",
            "definition": {
                "actions": {
                    "baseBlob": {
                        "delete": {"daysAfterModificationGreaterThan": 90}
                    }
                },
                "filters": {
                    "blobTypes": ["blockBlob"],
                    "prefixMatch": ["pii-logs/"]
                }
            }
        }
    ]
}

Regulatory Alignment

EU AI Act mapping

EU AI Act krav Artikkel Agent-implementering
Risikostyringssystem Art. 9 Trusselmodellering + continuous monitoring
Datakvalitet Art. 10 RAG data quality checks + lineage
Teknisk dokumentasjon Art. 11 Agent manifest + arkitekturdokumentasjon
Journalføring Art. 12 Audit logs med full beslutningskjede
Transparens Art. 13 AI-disclosure i brukergrensesnitt
Menneskelig tilsyn Art. 14 Human-in-the-loop for høyrisiko-beslutninger
Nøyaktighet og robusthet Art. 15 Continuous evaluation + red teaming

Microsoft Purview Compliance Manager

# Integrer agent-compliance med Purview
# Purview Compliance Manager gir:
# 1. Pre-definerte assessment-maler for EU AI Act
# 2. Compliance score tracking over tid
# 3. Improvement actions med prioritering
# 4. Evidence collection og documentation

# Bruk Purview APIs for automatisert compliance-sjekk
from azure.purview.compliance import PurviewComplianceClient

client = PurviewComplianceClient(
    endpoint=os.environ["PURVIEW_ENDPOINT"],
    credential=DefaultAzureCredential()
)

# Sjekk compliance-status for agent-kontroller
assessment = await client.get_assessment(
    template_id="eu-ai-act-high-risk",
    group_id="ai-agents"
)

# Rapportér compliance-gap
for action in assessment.improvement_actions:
    if action.status != "Completed":
        print(f"GAP: {action.title} - {action.category}")

Compliance Reporting

KQL-basert compliance rapport

// Compliance rapport: Alle agenthandlinger siste 30 dager
let audit_summary = AgentAuditLog_CL
| where TimeGenerated > ago(30d)
| summarize
    total_actions = count(),
    unique_users = dcount(UserId),
    unique_agents = dcount(AgentName),
    errors = countif(Success == false),
    human_escalations = countif(ActionType == "human_escalated"),
    pii_access = countif(array_length(
        parse_json(ComplianceFlags)) > 0),
    total_tokens = sum(TokensConsumed),
    avg_response_time = avg(DurationMs)
    by AgentName;

// Detaljerte compliance-flagg
let compliance_flags = AgentAuditLog_CL
| where TimeGenerated > ago(30d)
| where ComplianceFlags != "[]"
| extend flags = parse_json(ComplianceFlags)
| mv-expand flag = flags
| summarize flag_count = count() by tostring(flag), AgentName
| order by flag_count desc;

audit_summary
| join kind=leftouter compliance_flags on AgentName

Power BI compliance dashboard

// Data for Power BI compliance dashboard
AgentAuditLog_CL
| where TimeGenerated > ago(90d)
| extend
    Week = startofweek(TimeGenerated),
    Agent = AgentName,
    Action = ActionType,
    HasPII = array_length(parse_json(ComplianceFlags)) > 0,
    ResponseTime = DurationMs
| summarize
    Actions = count(),
    Errors = countif(Success == false),
    PIIAccess = countif(HasPII),
    AvgResponseMs = avg(ResponseTime),
    P95ResponseMs = percentile(ResponseTime, 95),
    TokensUsed = sum(TokensConsumed)
    by Week, Agent, Action

Norsk offentlig sektor

Spesifikke krav

Regelverk Krav Agent-implementering
Forvaltningsloven §11a Dokumentasjonsplikt for vedtak Komplett beslutningskjede for agenter som bidrar til vedtak
Arkivloven Journalføring av korrespondanse Agent-interaksjoner med borgere journalføres
Offentlighetsloven Innsynsrett i dokumenter Agent-logger tilgjengelig for innsynsbegjæring
GDPR Art. 22 Rett til ikke å bli utsatt for automatiserte beslutninger Human-in-the-loop for agenter som gjør enkeltvedtak
EU AI Act Logging av høyrisiko AI Full audit trail for agenter i saksbehandling
Sikkerhetsloven Beskyttelse av gradert info Isolerte audit logs for sikkerhetsgraderte agenter
Digdir prinsipper Etterprøvbarhet Transparent dokumentasjon av AI-bruk

Implementering for norsk offentlig sektor

# Journalføring av agent-interaksjoner i henhold til arkivloven
class NorwegianPublicSectorCompliance:
    def __init__(self, noark_client, audit_logger):
        self.noark = noark_client  # NOARK 5-kompatibelt system
        self.audit = audit_logger

    async def log_citizen_interaction(
        self,
        interaction: AgentAuditEntry,
        case_number: str = None
    ):
        """Journalfør borgerinteraksjon med agent"""

        # 1. Standard audit logging
        await self.audit.log(interaction)

        # 2. NOARK-journalpost for interaksjoner som
        #    berører saksbehandling
        if interaction.action_type in [
            "response_generated", "tool_invoked"
        ]:
            await self.noark.create_journal_entry(
                title=f"AI-agent interaksjon: {interaction.agent_name}",
                case_number=case_number,
                document_type="U",  # Utgående
                classification="Offentlig",  # Eller gradert
                content_reference=interaction.trace_id,
                metadata={
                    "ai_agent": interaction.agent_name,
                    "model": interaction.model_used,
                    "trace_id": interaction.trace_id,
                    "user_id": interaction.user_id
                }
            )

    async def handle_innsyn_request(
        self, request_period: tuple, agent_name: str = None
    ) -> list:
        """Håndter innsynsbegjæring for agent-logger"""
        query = f"""
        AgentAuditLog_CL
        | where TimeGenerated between (
            datetime('{request_period[0]}') ..
            datetime('{request_period[1]}'))
        """
        if agent_name:
            query += f"| where AgentName == '{agent_name}'"

        # Rediger PII før utlevering
        results = await self.query_logs(query)
        return [self.redact_pii(r) for r in results]

Beslutningsrammeverk

Scenario Anbefaling Begrunnelse
Informasjonsagent (lav risiko) Standard audit logging + 12 mnd retensjon Tilstrekkelig for debugging og kvalitet
Saksbehandlingsagent Full beslutningskjede + NOARK-integrasjon + 7 år Regulatorisk krav
Borgerrettet agent Audit + GDPR-compliance + innsynsstøtte Offentlighetsloven + GDPR
Sensitiv data-agent Immutable storage + strengere access control Personvern og sikkerhet
Multi-agent system Distribuert tracing + sentralisert audit Etterprøvbarhet på tvers av agenter

For Cosmo

  • Audit logging er ikke valgfritt -- det er et regulatorisk krav under EU AI Act Art. 12 og norsk forvaltningsrett. Implementer fra dag 1, ikke som etterpåklok.
  • Beslutningskjeden er det viktigste -- logg ikke bare hva agenten svarte, men HVORFOR: hvilken intent ble klassifisert, hvilken agent ble valgt, hvilke data ble hentet, hvilken modell ble brukt.
  • Retensjonspolicies må differensieres -- PII-holdige logger slettes etter 3 måneder (GDPR), men audit-sammendrag bevares i 7 år (Arkivloven). Automatisér med Azure Storage lifecycle policies.
  • For norsk offentlig sektor: Integrer agent-logging med NOARK 5 for journalføring, implementer innsynsstøtte for Offentlighetsloven, og sørg for human-in-the-loop for GDPR Art. 22.
  • Microsoft Purview Compliance Manager er verktøyet for å spore EU AI Act-compliance -- bruk pre-definerte assessment-maler og automatisér evidence collection.