contexa-iam

AI 보안 표현식

Spring Security의 SpEL 표현식 시스템을 AI 기반 위험 평가 함수로 확장합니다. Contexa의 AbstractAISecurityExpressionRoot는 URL 레벨 및 메서드 레벨 인가 결정에 실시간 Zero Trust 액션 평가를 제공합니다.

개요

Contexa는 Spring Security의 표현식 기반 접근 제어를 실시간으로 ZeroTrustAction 결과를 평가하는 AI 통합 함수로 확장합니다. 이 표현식은 URL 레벨 보안 구성과 메서드 레벨 어노테이션 모두에서 사용할 수 있습니다.

표현식 시스템은 두 개의 레벨로 구축됩니다:

  • URL 레벨 — URL 정책에서 HTTP 요청 매칭을 위한 CustomWebSecurityExpressionRoot
  • 메서드 레벨@Protectable을 사용한 어노테이션 기반 인가를 위한 CustomMethodSecurityExpressionRoot

두 클래스 모두 공유 #ai.* 표현식 API를 제공하는 AbstractAISecurityExpressionRoot를 확장합니다. URL 레벨에서는 현재 사용자 기준의 ZeroTrustActionRepository 조회를 사용하고, 메서드 레벨에서는 요청 속성(contexa.zeroTrustAction)을 먼저 확인한 뒤 짧은 수명의 Caffeine 캐시와 저장소 조회를 순서대로 사용합니다.

Expression API 참조

모든 표현식은 SpEL에서 #ai 접두사를 통해 접근합니다. 이들은 AbstractAISecurityExpressionRoot에 정의되어 있으며 URL과 메서드 레벨 모두에서 사용할 수 있습니다.

표현식 반환 타입 설명
#ai.isAllowed() boolean AI 평가 결과가 ALLOW이면 true를 반환
#ai.isBlocked() boolean AI 평가 결과가 BLOCK이면 true를 반환
#ai.needsChallenge() boolean AI 평가 결과가 CHALLENGE이면 true를 반환
#ai.needsEscalation() boolean AI 평가 결과가 ESCALATE이면 true를 반환
#ai.isPendingAnalysis() boolean AI 평가 결과가 PENDING_ANALYSIS이면 true를 반환
#ai.hasAction(String) boolean 현재 ZeroTrustAction이 특정 액션 문자열과 일치하는지 확인
#ai.hasActionIn(String...) boolean 현재 액션이 제공된 액션 문자열 중 하나와 일치하면 true를 반환
#ai.hasActionOrDefault(defaultAction, actions...) boolean 제공된 액션을 확인하며, ZeroTrustAction을 사용할 수 없는 경우 default boolean 값을 반환

URL 레벨 표현식

CustomWebSecurityExpressionRootAbstractAISecurityExpressionRoot를 확장하고 HTTP 요청 평가에 필요한 웹 컨텍스트를 제공합니다. 현재 OSS 클라이언트 화면에서는 이 표현식이 주로 Policy Center의 수동/빠른 생성 흐름과 저장된 URL 정책 평가에 연결됩니다.

추가 URL 레벨 메서드

메서드 반환 타입 설명
hasIpAddress(String ipAddress) boolean 요청이 주어진 IP 주소 또는 CIDR 범위에서 발생했는지 확인
getHttpMethod() String 현재 요청의 HTTP 메서드(GET, POST 등)를 반환

사용 예제

이 표현식은 관리자 콘솔의 Policy Center에서 작성되거나 저장된 URL 정책 조건에서 사용됩니다:

SpEL
// Allow only if AI approves AND user has USER role
#ai.isAllowed() and hasRole('USER')

// Allow if AI approves AND request is from internal network
#ai.isAllowed() and hasIpAddress('10.0.0.0/8')

// Deny only if AI explicitly blocks (permissive mode)
!(#ai.isBlocked())

// Allow or challenge actions only
#ai.hasActionIn('ALLOW', 'CHALLENGE')

메서드 레벨 표현식

CustomMethodSecurityExpressionRootAbstractAISecurityExpressionRoot를 확장하고 소유권 검증 및 전체 hasPermission() 지원을 포함한 메서드 레벨 인가 기능을 추가합니다.

추가 메서드 레벨 메서드

메서드 반환 타입 설명
hasPermission(Object, Object) boolean CompositePermissionEvaluator를 통한 소유권 검사를 포함한 전체 권한 평가
hasPermission(Object, String, Object) boolean 도메인별 라우팅이 포함된 대상 타입 기반 권한 평가

캐싱

메서드 레벨 표현식은 ZeroTrustAction 조회를 위해 2단계 캐시를 사용합니다:

  • Caffeine 로컬 캐시 — 5초 TTL, 최대 10,000개 항목
  • Redis — 기본 분산 저장소, 세션 범위

@Protectable과 함께 사용

메서드 레벨 AI 표현식은 일반적으로 @Protectable 어노테이션 및 @PreAuthorize와 함께 사용됩니다:

Java
@PreAuthorize("#ai.isAllowed() and hasPermission(#id, 'USER', 'READ')")
@Protectable(ownerField = "userId")
public User getUser(Long id) { ... }

@PreAuthorize("#ai.isAllowed() and hasPermission(#orderId, 'ORDER', 'UPDATE')")
@Protectable(ownerField = "customerId", sync = true)
public void updateOrder(Long orderId, OrderDto dto) { ... }

@PreAuthorize("!(#ai.isBlocked()) and hasRole('ADMIN')")
@Protectable
public List<AuditLog> getAuditLogs() { ... }

URL vs 메서드 비교

두 표현식 루트는 서로 다른 인가 레이어를 담당하며 고유한 기능을 가집니다:

기능 URL 레벨 메서드 레벨
Expression Root CustomWebSecurityExpressionRoot CustomMethodSecurityExpressionRoot
캐시 요청 속성 + 저장소 조회 요청 속성 + Caffeine (5초 TTL) + 저장소 조회
소유권 검사 아니오 예 (ownerField 사용)
hasPermission() 제거됨 (URL 레벨 전용) 전체 지원
hasIpAddress() 아니오
트리거 HTTP 요청 매칭 @Protectable 어노테이션
일반적 사용 Policy Center 기반 URL 정책 서비스 메서드 어노테이션

ZeroTrustAction 흐름

AI 보안 표현식은 AI 분석 파이프라인에서 생성된 ZeroTrustAction을 평가합니다. 다음 다이어그램은 초기 분석에서 인가 결정까지의 요청 흐름을 보여줍니다:

ZeroTrustAction 평가 흐름
HTTP 요청 수신 요청이 필터 체인에 진입
AI 분석 파이프라인 위험 점수 계산, 행동 분석, 위협 감지
ZeroTrustAction 생성 ALLOW | BLOCK | CHALLENGE | ESCALATE | PENDING_ANALYSIS
공유 Zero Trust 액션 저장소 현재 OSS 기본 구현은 Redis-backed ZeroTrustActionRepository
표현식 평가 #ai.isAllowed(), #ai.isBlocked() 등
인가 결정 표현식 결과에 따라 접근 허용 또는 거부

액션 타입

액션 의미 일반적 응답
ALLOW AI 평가가 낮은 위험을 나타냄 정상적으로 접근 허용
BLOCK AI 평가가 높은 위험 또는 위협을 나타냄 접근 거부, 인시던트 기록
CHALLENGE AI 평가가 중간 위험을 나타냄 추가 검증 필요 (MFA, CAPTCHA)
ESCALATE AI 평가가 사람의 검토를 필요로 함 수동 승인을 위해 보안 팀에 라우팅
PENDING_ANALYSIS AI 분석이 아직 진행 중 기본 정책 적용 또는 완료 대기

액션 해석 모델

공개 #ai API는 숫자형 위험 점수를 노출하지 않습니다. 현재 런타임은 Zero Trust 액션을 계산하고, 표현식은 그 액션을 기준으로 평가됩니다:

Text
Resolved Zero Trust actions:
  ALLOW             -> #ai.isAllowed()
  BLOCK             -> #ai.isBlocked()
  CHALLENGE         -> #ai.needsChallenge()
  ESCALATE          -> #ai.needsEscalation()
  PENDING_ANALYSIS  -> #ai.isPendingAnalysis()

Fallback pattern:
  #ai.hasActionOrDefault(''BLOCK'', ''ALLOW'')

실전 시나리오

시나리오 1: 위험 기반 접근 제어

AI 표현식을 사용하여 위험 수준에 따른 계층적 접근 제어를 구현합니다:

  • 낮은 위험 — AI가 ALLOW를 반환, 접근 허용
  • 중간 위험 — AI가 CHALLENGE를 반환, 추가 인증(MFA) 필요
  • 높은 위험 — AI가 BLOCK을 반환, 접근 거부
SpEL
// Strict mode: only allow if AI explicitly approves
#ai.isAllowed()

// Permissive mode: allow unless AI explicitly blocks
!(#ai.isBlocked())

// Challenge-aware: allow if permitted or after challenge completion
#ai.hasActionIn('ALLOW', 'CHALLENGE')

시나리오 2: AI + 역할 기반 하이브리드

심층 방어를 위해 AI 위험 평가와 전통적인 역할 기반 접근 제어를 결합합니다:

SpEL
// Require both AI approval and appropriate role
#ai.isAllowed() and hasAnyAuthority('ROLE_USER', 'ROLE_ADMIN')

// Admin bypass with AI monitoring (AI can still block suspicious admin activity)
hasRole('ADMIN') and !(#ai.isBlocked())

// Elevated access requires both AI approval and specific authority
#ai.isAllowed() and hasAuthority('PERMISSION_SENSITIVE_DATA_READ')

시나리오 3: 소유권 + AI 검증

세밀한 접근 제어를 위해 AI 표현식을 @Protectable 소유권 검사 및 권한 평가와 결합합니다:

Java
// AI + ownership + permission: triple-layered authorization
@Protectable(ownerField = "createdBy", sync = true)
@PreAuthorize("#ai.isAllowed() and hasPermission(#id, 'DOCUMENT', 'UPDATE')")
public void updateDocument(Long id, DocumentDto dto) { ... }

// AI + ownership for read operations
@Protectable(ownerField = "patientId")
@PreAuthorize("#ai.isAllowed() and hasPermission(#id, 'MEDICAL_RECORD', 'READ')")
public MedicalRecord getRecord(Long id) { ... }

// Fallback when AI is unavailable: default to deny
@Protectable(ownerField = "accountId")
@PreAuthorize("#ai.hasActionOrDefault('BLOCK', 'ALLOW') and hasPermission(#id, 'ACCOUNT', 'UPDATE')")
public void updateAccount(Long id, AccountDto dto) { ... }

Admin에서 AI 인식 정책 생성

AI 보안 표현식은 관리자 콘솔의 Policy Center에서 작성되는 정책 조건에 사용할 수 있습니다. 이를 통해 관리자는 코드 작성 없이 현재 Zero Trust 액션 결과를 정책 조건에 반영할 수 있습니다.

1단계: Policy Center 열기

관리자 콘솔에서 Policy Center를 연 뒤 Create 탭 또는 빠른 생성 흐름을 엽니다. 여기서 정책 대상 리소스와 HTTP 메서드 패턴을 선택합니다.

2단계: AI 조건 템플릿 선택

조건 편집기에서 사전 정의된 AI 표현식 템플릿 중 선택하거나 사용자 정의 SpEL 표현식을 작성합니다. 사용 가능한 템플릿:

  • AI Approved#ai.isAllowed()
  • AI Not Blocked!(#ai.isBlocked())
  • AI Approved + Role#ai.isAllowed() and hasRole('...')
  • Custom AI Expression#ai.* 함수를 사용한 유효한 SpEL 작성

3단계: 승인 워크플로 구성

AI 생성 정책의 경우 승인 워크플로를 사용할 수 있습니다. AI 표현식이 포함된 정책은 다음과 같이 설정할 수 있습니다:

  • 자동 승인 — 낮은 위험의 정책 변경에 즉시 적용
  • 검토 필요 — 활성화 전 보안 팀 검토를 위해 대기열에 추가
  • Shadow 모드 — 평가하되 적용하지 않음, AI 정책 효과 테스트용

4단계: 정책 효과 모니터링

활성화 후 관리자 콘솔에서 AI 정책 결과를 모니터링합니다:

  • 정책별 허용/거부/챌린지 비율 확인
  • 오탐(False Positive) 및 미탐(False Negative) 비율 추적
  • 보호 리소스의 위험 점수 분포 분석
  • 에스컬레이션 패턴 및 응답 시간 검토

캐시 아키텍처

AI 보안 표현식은 모든 표현식 평가마다 AI 분석을 다시 실행하지 않도록 캐시된 ZeroTrustAction 객체에 의존합니다. 캐싱 전략은 URL 레벨과 메서드 레벨 표현식 간에 다릅니다.

캐시 레이어

ZeroTrustAction 캐시 조회 순서
Request Attribute 가장 먼저 확인 — 현재 HTTP 요청의 인-리퀘스트 캐시
Caffeine 로컬 캐시 메서드 레벨 전용 — 5초 TTL, 최대 10K 항목
Redis 기본 분산 저장소 — 세션 범위 TTL
캐시 레이어 범위 TTL 최대 항목 사용 대상
Request Attribute 단일 HTTP 요청 요청 생명주기 요청당 1개 URL 및 메서드 레벨 모두
Caffeine JVM 로컬 5초 10,000 메서드 레벨 전용
Redis 분산 (세션 범위) 세션 TTL 무제한 URL 및 메서드 레벨 모두

Request Attribute 캐시는 단일 HTTP 요청 내에서 참조하는 표현식 수에 관계없이 ZeroTrustAction이 한 번만 해석되도록 보장합니다. 메서드 레벨의 Caffeine 캐시는 짧은 시간 내 반복 평가에 대해 저지연 접근을 제공합니다.