EBA AI Guidelines Compliance¶
The European Banking Authority (EBA) has issued guidelines on the use of AI in credit institutions, focusing on model risk management, consumer protection, and fairness.
Executive Summary¶
Coverage Status¶
| Requirement Area | OxideShield Coverage | Status |
|---|---|---|
| Model Risk Management | 85% | ✅ Good |
| Consumer Protection | 90% | ✅ Good |
| Data Governance | 75% | ⚠️ Partial |
| Explainability | 60% | ⚠️ Partial |
| Fairness/Bias | 40% | ❌ Gap |
Key EBA Requirements¶
- Model Governance - AI models must be documented, validated, and monitored
- Consumer Protection - Customers must be protected from AI-driven harm
- Fairness - Credit decisions must not discriminate on protected characteristics
- Explainability - Customers must receive explanations for adverse decisions
- Human Oversight - Material decisions require human review
Requirement Mapping¶
1. Model Risk Management¶
| EBA Requirement | OxideShield Feature | Implementation |
|---|---|---|
| Model inventory | Policy-as-code | policy.yaml defines all guards |
| Validation testing | Red team scanner | oxideshield scan |
| Performance monitoring | Metrics collector | Telemetry integration |
| Change management | Git-based policy | Version control |
| Incident response | Alert system | Webhook alerts |
Implementation:
# Model inventory via policy-as-code
policy:
name: credit-decision-guards
version: "1.2.0"
owner: risk-management@bank.com
approval_date: "2025-01-15"
next_review: "2025-07-15"
guards:
- name: credit-fairness
type: PatternGuard
validation:
last_tested: "2025-01-10"
accuracy: 0.94
false_positive_rate: 0.02
2. Consumer Protection¶
| EBA Requirement | OxideShield Feature | Implementation |
|---|---|---|
| Vulnerability detection | PsychologicalSafetyGuard | Crisis indicators |
| Manipulation prevention | DarkPatternGuard | 6 manipulation categories |
| Data protection | PIIGuard | PII redaction |
| Fair treatment | AutonomyGuard | Agency protection |
Implementation:
from oxideshield import (
psychological_safety_guard,
dark_pattern_guard,
pii_guard,
)
class BankingCustomerProtection:
"""EBA-compliant customer protection pipeline."""
def __init__(self):
self.psych = psychological_safety_guard()
self.dark = dark_pattern_guard()
self.pii = pii_guard()
def check_customer_interaction(
self,
customer_message: str,
ai_response: str
) -> dict:
"""Validate interaction for EBA compliance."""
# Check customer for vulnerability indicators
vuln_result = self.psych.check_user_input(customer_message)
if vuln_result.concerns_detected:
return {
"action": "ESCALATE_TO_HUMAN",
"reason": "vulnerable_customer_detected",
"compliance": "EBA_CONSUMER_PROTECTION"
}
# Check AI response for manipulation
dark_result = self.dark.check(ai_response)
if dark_result.detected:
return {
"action": "BLOCK_RESPONSE",
"reason": "manipulation_detected",
"categories": dark_result.categories
}
# Redact any PII in logs
sanitized = self.pii.redact(ai_response)
return {"action": "ALLOW", "sanitized": sanitized}
3. Credit Decision Fairness¶
| EBA Requirement | OxideShield Feature | Status |
|---|---|---|
| Protected characteristic detection | PIIGuard | ✅ |
| Discriminatory language detection | PatternGuard | ✅ |
| Bias metrics | Under development | ❌ Gap |
| Disparate impact analysis | Planned | ❌ Gap |
Current Implementation:
from oxideshield import pattern_guard
# Detect discriminatory credit decision language
fairness_guard = pattern_guard(
name="credit-fairness",
patterns=[
# Direct discrimination
"denied due to race",
"rejected because of gender",
"not approved based on age",
"declined for disability",
"ineligible due to nationality",
# Indirect discrimination indicators
"neighborhood risk score",
"postal code exclusion",
"name-based assessment",
],
action="block",
severity="critical"
)
result = fairness_guard.check(ai_credit_response)
if not result.passed:
log_fairness_incident(result)
escalate_to_compliance(result)
4. Explainability¶
| EBA Requirement | OxideShield Feature | Status |
|---|---|---|
| Audit trail | Attestation layer | ✅ |
| Decision logging | GuardResult metadata | ✅ |
| Customer explanation | Not implemented | ❌ Gap |
| Reason codes | GuardResult.reason | ✅ |
Implementation:
from oxideshield import AttestationSigner, FileAuditStorage, AuditedGuard
# Create audited guard pipeline for credit decisions
signer = AttestationSigner.generate()
storage = FileAuditStorage("/var/log/bank/credit-audit")
# All credit decisions are cryptographically logged
audited_guard = AuditedGuard(
guard=credit_decision_guard,
signer=signer,
storage=storage,
metadata={
"application_id": application_id,
"decision_type": "credit",
"regulatory_framework": "EBA"
}
)
result = audited_guard.check(credit_application)
# Generate audit report for regulators
report = storage.generate_report(
start_date="2025-01-01",
end_date="2025-12-31",
format="eba"
)
5. Human Oversight¶
| EBA Requirement | OxideShield Feature | Implementation |
|---|---|---|
| Human review trigger | GuardAction::Review | Guard configuration |
| Override capability | Dashboard API | Manual override |
| Escalation | Alert system | Webhook integration |
| Kill switch | Emergency controller | Proxy gateway |
Implementation:
# Human oversight configuration
guards:
- name: credit-decision
type: MLClassifierGuard
config:
# Require human review for edge cases
actions:
- when: confidence < 0.8
action: review
escalate_to: credit_officers
- when: amount > 100000
action: review
escalate_to: senior_underwriters
- when: vulnerability_detected
action: review
escalate_to: vulnerable_customer_team
emergency:
enabled: true
admin_token: ${EMERGENCY_TOKEN}
# All credit decisions blocked when kill switch active
Audit Evidence Generation¶
Monthly Compliance Report¶
from oxideshield import ComplianceReporter
reporter = ComplianceReporter(framework="eba")
report = reporter.generate_monthly_report(
month="2025-01",
include_sections=[
"model_inventory",
"performance_metrics",
"incident_summary",
"fairness_metrics",
"customer_protection_stats",
]
)
# Export in EBA-expected format
report.export("eba-monthly-2025-01.pdf")
Regulatory Examination Preparation¶
from oxideshield import AuditExporter
exporter = AuditExporter(storage)
# Generate examination package
package = exporter.generate_examination_package(
period_start="2024-01-01",
period_end="2024-12-31",
include=[
"all_guard_decisions",
"human_overrides",
"incidents",
"policy_changes",
"validation_results",
],
format="eba_examination"
)
package.export_zip("eba-exam-2024.zip")
Gap Remediation¶
Current Gaps¶
| Gap | Impact | Remediation Plan |
|---|---|---|
| Bias metrics | High | Q2 2026 - FairnessGuard |
| Customer explanation | Medium | Q2 2026 - Explainability layer |
| Disparate impact | Medium | Q3 2026 - Analytics dashboard |
Workarounds¶
Bias Detection Workaround:
# Use PatternGuard for proxy detection until FairnessGuard available
proxy_bias_guard = pattern_guard(
patterns=[
# Proxy indicators
"based on postal code",
"neighborhood score",
"name similarity",
# Add institution-specific patterns
]
)
References¶
- EBA Guidelines on AI (2024)
- Model risk management requirements
- Consumer protection standards
-
https://www.eba.europa.eu/
-
EBA/GL/2020/06 - Loan Origination
- Credit decision requirements
-
Automation governance
-
CRD V/CRR II - Capital Requirements
- Model risk capital
- Operational risk for AI