Files
CurrenciCombo/docs/Compliance_Integration_Spec.md

601 lines
14 KiB
Markdown
Raw Normal View History

# Compliance Integration Specification
## Overview
This document specifies compliance integration requirements for the ISO-20022 Combo Flow system, including LEI/DID/KYC/AML injection into ISO messages, compliance engine API contract, real-time status checks, identity assertion format, and audit trail requirements for hybrid workflows.
---
## 1. Compliance Requirements
### Required Compliance Attributes
| Attribute | Required For | Description | Format |
|-----------|-------------|-------------|--------|
| **LEI** | All workflows | Legal Entity Identifier | 20-character alphanumeric (e.g., `5493000IBP32UQZ0KL24`) |
| **DID** | Notarized workflows | Decentralized Identifier | W3C DID format (e.g., `did:web:example.com:user:123`) |
| **KYC** | Fiat/DTL steps | Know Your Customer verification | Level 1-3 (Level 2+ for fiat) |
| **AML** | Payments > threshold | Anti-Money Laundering check | Pass/Fail with risk level |
### Compliance Levels by Workflow Type
#### DeFi-Only Workflows
- **LEI**: Optional (recommended)
- **DID**: Optional
- **KYC**: Not required
- **AML**: Not required
#### Hybrid Workflows (DeFi + Fiat/DTL)
- **LEI**: Required
- **DID**: Required for notarization
- **KYC**: Level 2+ required
- **AML**: Required for payments > 10,000 EUR
#### Fiat-Only Workflows
- **LEI**: Required
- **DID**: Required
- **KYC**: Level 2+ required
- **AML**: Required for all payments
---
## 2. Compliance Engine API Contract
### Interface: `IComplianceEngine`
```typescript
interface IComplianceEngine {
/**
* Check compliance status for a user
*/
getComplianceStatus(userId: string): Promise<ComplianceStatus>;
/**
* Validate compliance for a workflow
*/
validateWorkflowCompliance(workflow: Workflow): Promise<ComplianceCheckResult>;
/**
* Run KYC verification
*/
verifyKYC(userId: string, level: number): Promise<KYCResult>;
/**
* Run AML screening
*/
screenAML(userId: string, amount: number, currency: string): Promise<AMLResult>;
/**
* Register LEI for user
*/
registerLEI(userId: string, lei: string): Promise<boolean>;
/**
* Register DID for user
*/
registerDID(userId: string, did: string): Promise<boolean>;
}
```
### Compliance Status Response
```typescript
interface ComplianceStatus {
userId: string;
lei: string | null;
did: string | null;
kyc: {
level: number;
provider: string;
verified: boolean;
expiresAt: string | null;
};
aml: {
passed: boolean;
provider: string;
lastCheck: string;
riskLevel: 'LOW' | 'MEDIUM' | 'HIGH';
};
valid: boolean;
}
```
### Workflow Compliance Check
```typescript
interface ComplianceCheckResult {
valid: boolean;
required: string[]; // ['LEI', 'DID', 'KYC', 'AML']
missing: string[];
warnings: string[];
}
```
---
## 3. LEI/DID/KYC/AML Injection into ISO Messages
### ISO-20022 Message Structure with Compliance
#### pacs.008 (Payment Instruction) Example
```xml
<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.10">
<FIToFICstmrCdtTrf>
<GrpHdr>
<MsgId>MSG-2025-01-15-001</MsgId>
<CreDtTm>2025-01-15T10:30:00Z</CreDtTm>
<NbOfTxs>1</NbOfTxs>
<CtrlSum>78000.00</CtrlSum>
<InitgPty>
<Nm>Example Corp Ltd.</Nm>
<Id>
<OrgId>
<Othr>
<Id>5493000IBP32UQZ0KL24</Id>
<SchmeNm>
<Cd>LEI</Cd>
</SchmeNm>
</Othr>
</OrgId>
</Id>
</InitgPty>
</GrpHdr>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>PLAN-12345678-ABCD-EFGH</EndToEndId>
<TxId>TX-2025-01-15-001</TxId>
</PmtId>
<PmtTpInf>
<SvcLvl>
<Cd>SEPA</Cd>
</SvcLvl>
<LclInstrm>
<Cd>INST</Cd>
</LclInstrm>
</PmtTpInf>
<IntrBkSttlmAmt Ccy="EUR">78000.00</IntrBkSttlmAmt>
<InstgAgt>
<FinInstnId>
<BICFI>BANKDEFFXXX</BICFI>
</FinInstnId>
</InstgAgt>
<InstdAgt>
<FinInstnId>
<BICFI>BENEFRPPXXX</BICFI>
</FinInstnId>
</InstdAgt>
<Dbtr>
<Nm>Example Corp Ltd.</Nm>
<Id>
<OrgId>
<Othr>
<Id>5493000IBP32UQZ0KL24</Id>
<SchmeNm>
<Cd>LEI</Cd>
</SchmeNm>
</Othr>
</OrgId>
</Id>
<CtctDtls>
<Email>compliance@example.com</Email>
</CtctDtls>
</Dbtr>
<DbtrAcct>
<Id>
<IBAN>DE89370400440532013000</IBAN>
</Id>
</DbtrAcct>
<Cdtr>
<Nm>Beneficiary Corp</Nm>
<PstlAdr>
<StrtNm>Main Street</StrtNm>
<BldgNb>123</BldgNb>
<PstCd>12345</PstCd>
<TwnNm>Berlin</TwnNm>
<Ctry>DE</Ctry>
</PstlAdr>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>DE89370400440532013001</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>Plan ID: PLAN-12345678-ABCD-EFGH</Ustrd>
<Strd>
<RfrdDocInf>
<Tp>
<CdOrPrtry>
<Cd>CINV</Cd>
</CdOrPrtry>
</Tp>
<Nb>PLAN-12345678-ABCD-EFGH</Nb>
<RltdDt>2025-01-15</RltdDt>
</RfrdDocInf>
<RfrdDocAmt>
<DuePyblAmt Ccy="EUR">78000.00</DuePyblAmt>
</RfrdDocAmt>
</Strd>
</RmtInf>
<SplmtryData>
<PlcAndNm>ComplianceData</PlcAndNm>
<Envlp>
<ComplianceData xmlns="urn:example:compliance:xsd:1.0">
<PlanId>PLAN-12345678-ABCD-EFGH</PlanId>
<LEI>5493000IBP32UQZ0KL24</LEI>
<DID>did:web:example.com:user:123</DID>
<KYC>
<Level>2</Level>
<Provider>Onfido</Provider>
<Verified>true</Verified>
<ExpiresAt>2026-12-31T23:59:59Z</ExpiresAt>
</KYC>
<AML>
<Passed>true</Passed>
<Provider>Chainalysis</Provider>
<LastCheck>2025-01-15T09:00:00Z</LastCheck>
<RiskLevel>LOW</RiskLevel>
</AML>
<DigitalSignature>
<Algorithm>ECDSA</Algorithm>
<Value>0x1234567890abcdef...</Value>
</DigitalSignature>
</ComplianceData>
</Envlp>
</SplmtryData>
</CdtTrfTxInf>
</FIToFICstmrCdtTrf>
</Document>
```
### Key Compliance Injection Points
1. **Header (`GrpHdr.InitgPty`)**: LEI in `Id.OrgId.Othr.Id` with `SchmeNm.Cd = "LEI"`
2. **Debtor (`Dbtr`)**: LEI in `Id.OrgId.Othr.Id`
3. **Supplementary Data (`SplmtryData`)**: Full compliance data (LEI, DID, KYC, AML, signature)
---
## 4. Real-Time Status Checks
### API Endpoint: `GET /api/compliance/status`
```typescript
// Request
GET /api/compliance/status?userId=user123
// Response
{
"userId": "user123",
"lei": "5493000IBP32UQZ0KL24",
"did": "did:web:example.com:user:123",
"kyc": {
"level": 2,
"provider": "Onfido",
"verified": true,
"expiresAt": "2026-12-31T23:59:59Z"
},
"aml": {
"passed": true,
"provider": "Chainalysis",
"lastCheck": "2025-01-15T09:00:00Z",
"riskLevel": "LOW"
},
"valid": true
}
```
### Workflow Compliance Check: `POST /api/compliance/check`
```typescript
// Request
POST /api/compliance/check
{
"steps": [
{ "type": "borrow", "asset": "CBDC_USD", "amount": 100000 },
{ "type": "swap", "from": "CBDC_USD", "to": "CBDC_EUR", "amount": 100000 },
{ "type": "pay", "asset": "EUR", "amount": 78000, "beneficiary": { "IBAN": "DE89..." } }
]
}
// Response
{
"valid": true,
"required": ["LEI", "DID", "KYC", "AML"],
"missing": [],
"warnings": []
}
```
### Frontend Integration
```typescript
// Real-time compliance badge in UI
const ComplianceBadge = () => {
const { data: compliance } = useQuery(['compliance'], () =>
api.getComplianceStatus()
);
return (
<div className="flex gap-2">
{compliance?.lei && <Badge>✓ LEI</Badge>}
{compliance?.did && <Badge>✓ DID</Badge>}
{compliance?.kyc?.verified && <Badge>✓ KYC</Badge>}
{compliance?.aml?.passed && <Badge>✓ AML</Badge>}
</div>
);
};
```
---
## 5. Identity Assertion Format
### W3C Verifiable Credential Format
```json
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://www.w3.org/2018/credentials/examples/v1"
],
"id": "https://example.com/credentials/123",
"type": ["VerifiableCredential", "ComplianceCredential"],
"issuer": {
"id": "did:web:example.com:issuer",
"name": "Compliance Authority"
},
"issuanceDate": "2025-01-15T10:00:00Z",
"credentialSubject": {
"id": "did:web:example.com:user:123",
"lei": "5493000IBP32UQZ0KL24",
"kyc": {
"level": 2,
"provider": "Onfido",
"verified": true,
"expiresAt": "2026-12-31T23:59:59Z"
},
"aml": {
"passed": true,
"provider": "Chainalysis",
"lastCheck": "2025-01-15T09:00:00Z",
"riskLevel": "LOW"
}
},
"proof": {
"type": "Ed25519Signature2020",
"created": "2025-01-15T10:00:00Z",
"verificationMethod": "did:web:example.com:issuer#key-1",
"proofPurpose": "assertionMethod",
"proofValue": "z5Vz5Vz5Vz5Vz5Vz5Vz5Vz5Vz5Vz5Vz5Vz5Vz5Vz5Vz5Vz5Vz5Vz5Vz5Vz5Vz5V"
}
}
```
### Entra Verified ID Integration
```typescript
// Request verified credential from Entra
const requestCredential = async (userId: string) => {
const response = await fetch('https://verifiedid.did.msidentity.com/v1.0/verifiableCredentials/request', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
credentialType: 'ComplianceCredential',
claims: {
lei: user.lei,
kycLevel: user.kyc.level
}
})
});
return response.json();
};
```
---
## 6. Audit Trail Requirements
### Audit Log Structure
```typescript
interface AuditLog {
planId: string;
timestamp: string;
event: 'PLAN_CREATED' | 'COMPLIANCE_CHECKED' | 'EXECUTION_STARTED' | 'EXECUTION_COMPLETED' | 'EXECUTION_FAILED';
userId: string;
compliance: {
lei: string;
did: string;
kyc: KYCStatus;
aml: AMLStatus;
};
metadata: {
steps: PlanStep[];
dltTxHash?: string;
isoMessageId?: string;
notaryProof?: string;
};
}
```
### Audit Trail Storage
1. **On-Chain (NotaryRegistry)**: Immutable proof hashes
2. **Off-Chain (Database)**: Full audit logs with compliance data
3. **ISO Messages**: Compliance data embedded in messages
### Compliance Audit Report
```typescript
interface ComplianceAuditReport {
planId: string;
executionDate: string;
user: {
userId: string;
lei: string;
did: string;
};
compliance: {
kyc: {
level: number;
provider: string;
verified: boolean;
expiresAt: string;
};
aml: {
passed: boolean;
provider: string;
lastCheck: string;
riskLevel: string;
};
};
workflow: {
steps: PlanStep[];
totalAmount: number;
currency: string;
};
receipts: {
dltTxHash: string;
isoMessageId: string;
notaryProof: string;
};
}
```
---
## 7. Compliance Workflow Integration
### Step 1: User Registration
```typescript
// User registers LEI and DID
await complianceEngine.registerLEI(userId, lei);
await complianceEngine.registerDID(userId, did);
```
### Step 2: KYC Verification
```typescript
// Run KYC verification (Level 2+ for fiat workflows)
const kycResult = await complianceEngine.verifyKYC(userId, 2);
if (!kycResult.verified) {
throw new Error('KYC verification failed');
}
```
### Step 3: AML Screening
```typescript
// Run AML screening for payments > threshold
const amlResult = await complianceEngine.screenAML(userId, amount, 'EUR');
if (!amlResult.passed) {
throw new Error('AML screening failed');
}
```
### Step 4: Workflow Compliance Check
```typescript
// Validate compliance before execution
const complianceCheck = await complianceEngine.validateWorkflowCompliance(workflow);
if (!complianceCheck.valid) {
throw new Error(`Missing compliance: ${complianceCheck.missing.join(', ')}`);
}
```
### Step 5: ISO Message Generation
```typescript
// Generate ISO message with compliance data
const isoMessage = generateISO20022Message(plan, {
lei: complianceStatus.lei,
did: complianceStatus.did,
kyc: complianceStatus.kyc,
aml: complianceStatus.aml,
signature: planSignature
});
```
---
## 8. Error Handling
### Compliance Validation Failures
```typescript
// Compliance check fails
if (!complianceCheck.valid) {
return {
error: 'COMPLIANCE_REQUIRED',
message: `Missing compliance attributes: ${complianceCheck.missing.join(', ')}`,
missing: complianceCheck.missing,
required: complianceCheck.required
};
}
```
### KYC Expiration Warning
```typescript
// Check if KYC is expiring soon
if (complianceStatus.kyc.expiresAt) {
const expiresAt = new Date(complianceStatus.kyc.expiresAt);
const daysUntilExpiry = (expiresAt.getTime() - Date.now()) / (1000 * 60 * 60 * 24);
if (daysUntilExpiry < 30) {
return {
warning: 'KYC_EXPIRING_SOON',
message: `KYC expires in ${daysUntilExpiry} days`,
expiresAt: complianceStatus.kyc.expiresAt
};
}
}
```
---
## 9. Testing Requirements
### Unit Tests
```typescript
describe('ComplianceEngine', () => {
it('should validate LEI format', () => {
expect(validateLEI('5493000IBP32UQZ0KL24')).toBe(true);
expect(validateLEI('invalid')).toBe(false);
});
it('should check workflow compliance', async () => {
const result = await complianceEngine.validateWorkflowCompliance(workflow);
expect(result.valid).toBe(true);
expect(result.missing).toEqual([]);
});
});
```
### Integration Tests
```typescript
describe('ISO Message Generation', () => {
it('should inject compliance data into pacs.008', () => {
const message = generateISO20022Message(plan, complianceData);
expect(message).toContain('<LEI>5493000IBP32UQZ0KL24</LEI>');
expect(message).toContain('<DID>did:web:example.com:user:123</DID>');
});
});
```
---
**Document Version**: 1.0
**Last Updated**: 2025-01-15
**Author**: Compliance Team