EU AI Act Article 12 — Exactly What Your Code Must Log
What Article 12 actually says
Article 12 of Regulation (EU) 2024/1689 states that high-risk AI systems must be designed to automatically record events — logs — that are relevant throughout their operational lifetime.
The key phrase is "automatically record." Logging cannot be optional, manual, or retroactive. It must happen automatically every time the system operates.
Who Article 12 applies to
Article 12 applies to providers of high-risk AI systems — companies that build and place AI systems on the market. If you have built an AI system that falls under Annex III (employment decisions, credit scoring, education, law enforcement, etc.), Article 12 applies to your code.
If you are a deployer using an AI system built by someone else (OpenAI, Anthropic, Google), you have separate obligations under Article 26 but Article 12 may still apply to how you integrate and use those systems.
What must be logged
The regulation requires logging sufficient to ensure traceability. In practice this means:
Required for every AI operation:
- Start and end timestamp
- Input data reference or hash (not necessarily the raw data)
- Model or system version used
- User or session identifier
- Output or decision made
- Confidence score where applicable
Required at system level:
- System version and configuration
- Training data version (for providers)
- Deployment environment
Retention period: The general principle is logs must be retained for at least 6 months. For high-risk systems in regulated sectors (finance, healthcare) longer retention may be required under sector-specific law.
What a compliant logging system looks like
// lib/ai-logger.ts
interface AICallLog {
callId: string
timestamp: string
userId: string
sessionId: string
model: string
modelVersion: string
inputHash: string
outputHash: string
decisionType: string
confidence: number
durationMs: number
environment: string
}
export async function logAICall(log: AICallLog): Promise<void> {
await db.aiLogs.create({
...log,
retainUntil: addMonths(new Date(), 6)
})
logger.info({ event: 'ai_call', ...log })
}
Common Article 12 violations found in real codebases
Pattern 1: No logging at all
# 73% of violations we find
response = openai.chat.completions.create(
model="gpt-4",
messages=messages
)
return response.choices[0].message.content
# No log. Nothing.
Pattern 2: Logging the wrong things
console.log('AI call made')
const result = await openai.chat(params)
// No model, no user, no duration
Pattern 3: Logging disabled in production
if os.getenv('DEBUG'):
logger.info(f"AI call: {input}")
# Logs nothing in production
Pattern 4: Logs not retained
// Console logs are ephemeral
console.log('AI decision:', decision)
// Not written to any persistent store
How to fix Article 12 violations
The fastest fix is to create a wrapper around your AI API calls that handles logging automatically:
// lib/ai-client.ts — Article 12 compliant
export async function callAI(params: AICallParams): Promise<AIResponse> {
const callId = crypto.randomUUID()
const start = Date.now()
await logAICall({
callId,
timestamp: new Date().toISOString(),
userId: params.userId,
model: params.model,
inputHash: await hash(params.input),
event: 'start'
})
try {
const response = await openai.chat.completions.create(params)
await logAICall({
callId,
durationMs: Date.now() - start,
outputHash: await hash(response.choices[0].message.content),
event: 'complete'
})
return response
} catch (error) {
await logAICall({ callId, event: 'error', error: error.message })
throw error
}
}
Every AI call in your codebase then calls callAI() instead of calling the OpenAI SDK directly.
Automatically detect Article 12 violations in your repo
EU ACT Guard scans your repository for these exact patterns and returns:
- Every file with direct AI calls that lack logging
- Every log statement missing required fields
- Whether logs are written to persistent storage
Find violations like these in your own codebase
EU ACT Guard scans your GitHub repository, website, and privacy policy in 5 minutes. Free first scan.
Run free scan →