여는 글

FIU가 의심계좌 거래 제한을 추진한다는 기사를 봤다. 디지털자산기본법 정부안이 곧 나온다는 소식도 들렸다. 기사 자체는 정책 이야기지만, 엔지니어의 시선으로 읽다 보니 자연스럽게 “그럼 우리 시스템 아키텍처는 어떻게 바뀌어야 하지?”라는 고민으로 이어졌다.

단순히 법을 지키는 차원이 아니라, 기술적 부채를 해결하고 시스템을 고도화할 기회로 삼아야 하지 않을까.

1. FIU 의심거래 차단: 동기(Sync)와 비동기(Async)의 딜레마

FIU가 의심계좌 거래 제한을 추진한다는 건, 거래소 입장에서 보면 강력한 실시간 모니터링 및 차단(Blocking) 메커니즘이 필요하다는 뜻이다.

기존의 레거시 시스템은 아마도 잔액 확인을 포함하여 승인까지 동기로 나아가는 구조였을 것이다.

하지만 규제가 적용되면, 이 트랜잭션 경로(Critical Path) 상에 로직이 덧붙여지게 될텐데…

public class TransactionService {
    // ... Dependency Injection

    public TransactionResult process(Transaction tx) {
        // [TO-BE] 위험도 평가가 메인 로직에 개입
        // 이슈: 외부 API 호출이나 복잡한 연산으로 인한 Latency 발생 가능성
        try {
             RiskScore risk = riskService.evaluate(tx);

             if (risk.isBlocked()) return TransactionResult.BLOCKED_BY_RISK;
             if (risk.needsReview()) return TransactionResult.PENDING_REVIEW;

        } catch (TimeoutException e) {
             // 서킷 브레이커(Circuit Breaker) 발동: 장애 전파 방지 및 Fallback 처리
             log.error("Risk service timeout", e);
             return TransactionResult.SYSTEM_CHECK;
        }
        return executeTransaction(tx);
    }
}

아키텍처 고려사항

단순한 if문 추가가 아니다. riskService.evaluate()가 1초라도 지연되면 전체 결제/송금 시스템이 멈춘다.

  • Circuit Breaker: FDS(이상거래탐지) 서버가 죽더라도 메인 거래 시스템은 살아야 한다. Resilience4j 등을 도입해 장애 격리 전략을 짜야 한다.
  • Async Processing: 만약 즉시 차단이 아니라 ‘사후 탐지’도 허용된다면, Kafka 등을 활용해 비동기로 처리하여 사용자 경험(UX) 저하를 막아야 한다.

2. 룰 엔진(Rule Engine)

하드코딩과의 이별의심거래 판단 기준(규제)은 매달, 아니 매주 바뀔 수도 있다. “캄보디아 송금 차단” 같은 로직을 코드에 박아넣으면(Hard-coding), 운영팀 요청이 올 때마다 배포를 해야 하는 악순환에 빠진다.

// [Bad] 규제가 바뀔 때마다 배포해야 함
if (amount > 10000000 && country.equals("Cambodia")) {
    blockTransaction();
}

결국 비즈니스 로직과 코드를 분리하는 룰 엔진 도입이 필수가 된다.

public class RiskRuleEngine {
    private List<RiskRule> rules;

    public RiskScore evaluate(Transaction tx) {
        // 룰들이 체인 형태로 실행되거나 병렬로 실행됨
        return rules.stream()
            .map(rule -> rule.apply(tx))
            .reduce(RiskScore.ZERO, RiskScore::combine);
    }

    // 핵심: 배포 없이(No-deploy) 런타임에 룰 변경사항 반영
    public void reloadRules() {
        this.rules = ruleRepository.findAllActive();
    }
}

Drools 같은 엔터프라이즈급 엔진은 러닝커브가 높고 무겁다. 최근에는 Easy Rules 같은 경량 엔진을 쓰거나, JSON 기반의 독자적인 룰 스크립트를 파싱하는 방식으로 유연성을 확보하는 추세다.

3. 디지털자산기본법: MSA와 분산 트랜잭션의 악몽

김재섭 의원이 발의한 법안의 핵심 중 하나는 “거래·보관·평가 기능의 분리”다. 이는 기술적으로 거대한 모놀리식(Monolithic) 시스템을 마이크로서비스(MSA)로 쪼개라는 명령과 같다. 하지만 법안대로 기능이 물리적으로 분리되면, 데이터베이스도 쪼개지고 트랜잭션도 쪼개진다. 이제 우리는 분산 트랜잭션(Distributed Transaction)이라는 복잡한 문제를 풀어야 한다.

  • Saga Pattern: 보상 트랜잭션(Compensating Transaction)을 설계하여, 2번 단계 실패 시 1번 결제를 취소하는 로직을 직접 구현해야 한다.
  • Event Driven: “거래 완료” 이벤트를 발행하고, 보관 서비스가 이를 구독하여 최종적 일관성(Eventual Consistency)을 맞추는 구조로 가야 한다.

4. AI 기본법: 설명 가능한 AI (XAI)

AI 기본법 시행과 함께 금융권 AI 가이드라인이 강화되면, “왜 대출이 거절되었나요?”라는 질문에 시스템이 대답할 수 있어야 한다. 단순히 정확도(Accuracy)만 높은 블랙박스 모델은 더 이상 설 자리가 없다.

모델의 버전을 관리하고(MLOps), 판단의 근거를 남기는 것(Audit)이 모델 성능 자체만큼이나 중요해진다.

이런 변화들을 보면서 느낀 점

규제 뉴스를 보면 “또 규제야”라고 생각하기 쉽다. 나도 처음엔 그랬다.

근데 좀 더 생각해보니, 규제는 결국 새로운 시스템 요구사항이다.

  • FIU 의심거래 시스템 → 실시간 이벤트 처리 아키텍처 필요
  • 디지털자산기본법 기능 분리 → 마이크로서비스 전환 필요
  • AI 기본법 → 설명 가능한 AI, 감사 추적 필요

이렇게 보면 규제가 오히려 시스템을 더 견고하게 만드는 계기가 될 수도 있겠다는 생각이 든다.

물론 당장 구현해야 하는 입장에서는 부담이지만, 어차피 해야 할 거라면 미리 준비하는 게 낫지 않을까.

요즘 감사 로그 시스템이 규제 요건을 충족하는지, 비즈니스 로직이 하드코딩되어 있진 않은지 한번 점검해봐야겠다는 생각이 든다.

맺는글

규제를 제약이 아닌 설계 요구사항으로 받아들이면, 관점이 좀 달라지는 것 같다.

“이거 왜 해야 해?”가 아니라 “이걸 어떻게 구현하지?”로 바뀌니까.

그리고 이런 변화에 빠르게 대응할 수 있는 시스템을 만들어둔 회사가 결국 시장에서 유리한 위치를 차지하게 될 거다. 규제는 모든 플레이어에게 동시에 적용되니까, 준비된 곳과 안 된 곳의 차이가 명확하게 드러날 수밖에 없다.


참고 기사