contexa-core Enterprise

승인 워크플로우

SOAR Tool 실행을 위한 Human-in-the-loop 승인 시스템입니다. 자동 승인, 단일 승인자, 다중 승인자, 만장일치, 긴급 승인 유형을 지원하며 요청 생성부터 해결까지 전체 승인 수명 주기를 관리합니다.

개요

@SoarTool 어노테이션 메서드가 실행 전 승인을 요구하면, SOAR Pipeline은 ApprovalService에 위임합니다. 서비스는 ApprovalRequest를 생성하고, SoarApprovalNotifier를 통해 지정된 승인자에게 알리며, 승인, 거절, 만료, 또는 취소될 때까지 요청의 수명 주기를 추적합니다.

승인 시스템은 SoarContext 세션 상태와 통합되어, 승인이 대기 중일 때 세션을 WAITING_APPROVAL로 전환합니다. 해결되면 Pipeline은 승인 결과에 따라 Tool 실행을 진행하거나 액션을 중단합니다.

@SoarTool (approval = REQUIRED)
ApprovalRequestDetails
ApprovalService.requestApproval()
ApprovalRequest (PENDING)
SoarApprovalNotifier
사람 검토
APPROVED / REJECTED

ApprovalService

승인 워크플로우를 관리하기 위한 핵심 서비스 인터페이스입니다. 구현체가 정의해야 하는 추상 메서드와 일반적인 작업을 위한 편의 기본 메서드를 모두 제공합니다.

public interface ApprovalService io.contexa.contexacore.soar.approval

추상 메서드

requestApproval String

SOAR Tool 실행을 위한 새로운 승인 요청을 생성합니다. 요청을 추적하고 해결하는 데 사용할 수 있는 생성된 승인 ID를 반환합니다.

soarContext SoarContext 인시던트 상세 및 세션 상태를 포함하는 현재 SOAR 세션 컨텍스트.
requestDetails ApprovalRequestDetails 액션 이름, 유형, 위험 수준, 파라미터를 포함한 승인 필요 액션의 상세.
getApprovalStatus ApprovalStatus

ID로 승인 요청의 현재 상태를 검색합니다.

approvalId String requestApproval()에서 반환된 승인 요청 식별자.
handleApprovalResponse void

사람 검토자의 승인 또는 거절 응답을 처리합니다.

approvalId String 승인 요청 식별자.
isApproved boolean 요청이 승인되었는지 (true) 또는 거절되었는지 (false).
comment String 검토자 코멘트 또는 거절 사유.
reviewer String 검토 사용자의 식별자.
getPendingApprovalIds Set<String>

현재 대기 중인 모든 승인 요청 ID의 집합을 반환합니다.

getPendingCount int

현재 대기 중인 승인 요청의 수를 반환합니다.

기본 편의 메서드

메서드반환 타입설명
requestApproval(ApprovalRequest) CompletableFuture<Boolean> ApprovalRequest 객체를 직접 사용하는 비동기 승인 요청.
processApprovalResponse(requestId, approved, reviewer, comment) void 편의를 위해 파라미터 순서를 변경하여 handleApprovalResponse()에 위임.
waitForApprovalSync(ApprovalRequest) boolean 승인 해결을 위한 블로킹 대기. SYNC 실행 모드에서 사용됩니다.
saveApprovalRequest(ApprovalRequest) ApprovalRequest 승인 요청을 백업 스토어에 영속화합니다.
sendApprovalNotification(ApprovalRequest) void 대기 중인 요청에 대해 지정된 승인자에게 알림을 전송합니다.
processApproval(approvalId, approved, reason) void 기본 검토자 "system"을 사용한 간소화된 승인 처리.
getPendingApprovals() List<ApprovalRequest> 모든 대기 중인 승인 요청을 전체 객체로 반환합니다.
submitApprovalRequest(ApprovalRequest) void 복합 작업: 요청을 저장한 후 알림을 전송합니다.
approve(approvalId) void 기본 코멘트 "Approved"와 검토자 "system"을 사용한 빠른 승인.
reject(approvalId) void 기본 코멘트 "Rejected"와 검토자 "system"을 사용한 빠른 거절.
getApprovalRequest(approvalId) ApprovalRequest ID로 전체 승인 요청 객체를 검색합니다. 기본적으로 null을 반환합니다.

ApprovalRequest

단일 승인 요청을 나타내는 도메인 객체입니다. 요청 Tool, 승인 유형, 검토자 정보, 타임아웃 설정을 포함하여 생성부터 해결까지 전체 수명 주기를 추적합니다. 빌더 패턴 생성과 편의 팩토리 메서드를 모두 지원합니다.

public class ApprovalRequest implements Serializable io.contexa.contexacore.domain

주요 필드

필드타입설명
requestIdString고유 식별자 (예: APR-1709942400000).
sessionIdString요청을 시작한 SOAR 세션.
incidentIdString연관된 보안 인시던트 식별자.
toolNameString승인이 필요한 @SoarTool의 이름.
actionTypeString액션 분류 (예: "BLOCK_IP", "ISOLATE_HOST").
parametersMap<String, Object>검토자 검사를 위한 Tool 호출 파라미터.
reasonString액션에 대한 정당화 근거.
approvalTypeApprovalType따를 승인 워크플로우 유형.
statusApprovalStatus현재 수명 주기 상태.
requestedAtLocalDateTime요청 생성 타임스탬프.
requestedByString요청을 시작한 사용자 또는 시스템.
approvedByString요청을 해결한 검토자.
approvedAtLocalDateTime승인 또는 거절 타임스탬프.
rejectionReasonString요청이 거절될 때 제공되는 사유.
requiredRolesSet<String>이 요청을 승인하는 데 필요한 역할.
requiredApproversIntegerMULTI 또는 UNANIMOUS 유형에 필요한 승인자 수.
approvalTimeoutInteger요청이 만료되기 전 타임아웃 (분).
potentialImpactString액션의 잠재적 영향 설명.
organizationIdString멀티 테넌트 배포를 위한 조직 컨텍스트.

수명 주기 메서드

메서드설명상태 전환
approve(approver)요청을 승인으로 표시하고 승인자와 타임스탬프를 기록합니다.* → APPROVED
reject(approver, reason)사유와 함께 요청을 거절로 표시합니다.* → REJECTED
expire()요청을 만료로 표시합니다 (타임아웃 도달).PENDING → EXPIRED
cancel()요청을 취소합니다 (예: 승인 전 인시던트 해결).PENDING → CANCELLED
addApproval(approver, name, role, comments)다중 승인자 워크플로우에서 개별 승인을 기록합니다.* → APPROVED

팩토리 메서드

Java
// Quick creation with auto-generated APR- prefixed ID
ApprovalRequest request = ApprovalRequest.create(
    "session-abc-123",       // sessionId
    "block_ip_address",      // toolName
    Map.of("ip", "10.0.0.1", "duration", 24),  // parameters
    "Suspicious traffic detected from this IP"   // reason
);
// request.status = PENDING, request.requestedAt = now()

빌더 패턴

Java
ApprovalRequest request = ApprovalRequest.builder()
    .requestId("APR-custom-001")
    .sessionId("session-abc-123")
    .incidentId("INC-2024-001")
    .toolName("isolate_host")
    .actionDescription("Isolate compromised host from network")
    .toolParameters(Map.of("hostname", "web-server-03", "incidentId", "INC-2024-001"))
    .approvalType(ApprovalType.MULTI)
    .requestedBy("soar-pipeline")
    .requestReason("Host shows signs of lateral movement")
    .potentialImpact("Service disruption for web-server-03")
    .riskAssessment("HIGH - production server with active traffic")
    .timeoutMinutes(30)
    .organizationId("org-456")
    .build();

ApprovalType

요청의 승인 워크플로우 변형을 정의합니다. 필요한 승인자 수와 승인 프로세스 관리 방법을 결정합니다.

public enum ApprovalType (ApprovalRequest 내부에 중첩)
설명사용 사례
AUTO 자동 승인. 정책에 따라 요청이 자동으로 승인됩니다. ToolApprovalPolicyManager가 사람의 검토가 불필요하다고 판단하는 저위험 Tool.
MANUAL 수동 승인 필요. 사람이 검토하고 결정해야 합니다. 사람의 감독이 필요한 중위험 액션의 표준 승인.
SINGLE 단일 승인. 한 명의 지정된 승인자가 승인해야 합니다. 특정 역할 보유자의 인가가 필요한 액션 (예: IP 차단을 위한 SOC 분석가).
MULTI 다중 승인 필요. 설정 가능한 수의 승인자가 독립적으로 승인해야 합니다. 합의가 필요한 고위험 액션 (예: 호스트 격리, 방화벽 변경).
UNANIMOUS 만장일치. 지정된 모든 승인자가 승인해야 합니다. 단일 이의라도 실행을 차단해야 하는 핵심 인프라 변경.
EMERGENCY 긴급 승인. 축소된 요구 사항으로 신속한 승인. 표준 승인 일정이 너무 느린 시간에 민감한 인시던트.

ApprovalStatus

승인 요청의 수명 주기에서 현재 상태를 나타냅니다.

public enum ApprovalStatus (ApprovalRequest 내부에 중첩)
설명종료 상태
PENDING 요청이 생성되었으며 검토자 액션을 대기 중. 아니오
APPROVED 요청이 승인됨. Tool 실행을 진행할 수 있습니다.
REJECTED 요청이 거절됨. Tool 실행이 차단됩니다.
EXPIRED 응답을 받기 전 요청이 타임아웃됨.
CANCELLED 요청이 취소됨 (예: 인시던트 해결, 세션 종료).

ApprovalRequestDetails

승인이 필요한 액션의 상세를 캡처하는 불변 레코드입니다. SoarContext와 함께 ApprovalService.requestApproval()에 전달되어 새로운 승인 요청을 생성합니다.

public record ApprovalRequestDetails implements Serializable io.contexa.contexacore.soar.approval
필드타입설명
actionName String 승인이 필요한 @SoarTool 이름 (예: "block_ip_address").
actionType String 액션 분류 (예: "CONTAINMENT", "ERADICATION").
riskLevel String 액션의 평가된 위험 수준 (예: "HIGH", "CRITICAL").
description String 액션이 수행할 작업에 대한 사람이 읽을 수 있는 설명.
arguments String Tool이 호출될 직렬화된 인수.
parameters Map<String, Object> Tool 호출을 위한 구조화된 파라미터.
Java
ApprovalRequestDetails details = new ApprovalRequestDetails(
    "block_ip_address",                          // actionName
    "CONTAINMENT",                               // actionType
    "HIGH",                                      // riskLevel
    "Block IP 10.0.0.1 at the firewall level",   // description
    "{ip: 10.0.0.1, duration: 24}",              // arguments
    Map.of("ip", "10.0.0.1", "durationHours", 24) // parameters
);

String approvalId = approvalService.requestApproval(soarContext, details);

SoarApprovalNotifier

승인 시스템을 위한 알림 인터페이스입니다. 구현체는 설정된 채널 (예: Slack, 이메일, PagerDuty)을 통해 사람 검토자에게 승인 알림을 전달하고 미해결 대기 요청에 대한 리마인더를 전송합니다.

public interface SoarApprovalNotifier io.contexa.contexacore.autonomous.notification
receiveApprovalNotification void

수신 승인 알림 메시지를 받아 처리합니다. 새로운 승인 요청이 생성되거나 외부 시스템이 승인 결정을 보낼 때 호출됩니다.

message String 알림 메시지 콘텐츠.
sendApprovalReminder void

예상 기간 내에 해결되지 않은 대기 중인 승인 요청에 대한 리마인더 알림을 전송합니다.

approvalId String 리마인더를 보낼 승인 요청 ID.

엔드투엔드 워크플로우 예제

Java
// 1. SOAR pipeline determines a tool requires approval
ApprovalRequestDetails details = new ApprovalRequestDetails(
    "isolate_host", "CONTAINMENT", "CRITICAL",
    "Isolate web-server-03 due to lateral movement detection",
    "{hostname: web-server-03}", Map.of("hostname", "web-server-03")
);

// 2. Request approval through the service
String approvalId = approvalService.requestApproval(soarContext, details);
// SoarContext transitions to WAITING_APPROVAL

// 3. Check status (polling or event-driven)
ApprovalStatus status = approvalService.getApprovalStatus(approvalId);

// 4a. Human approves via dashboard or notification channel
approvalService.handleApprovalResponse(
    approvalId, true, "Confirmed lateral movement in logs", "analyst-jane"
);

// 4b. Or use convenience methods
approvalService.approve(approvalId);   // Quick system approval
approvalService.reject(approvalId);    // Quick system rejection

// 5. Pipeline checks status and proceeds with tool execution
if (approvalService.getApprovalStatus(approvalId) == ApprovalStatus.APPROVED) {
    // Execute the @SoarTool method
}
Java
// Using the builder for full control over the approval request
ApprovalRequest request = ApprovalRequest.builder()
    .sessionId(soarContext.getSessionId())
    .incidentId(soarContext.getIncidentId())
    .toolName("isolate_host")
    .approvalType(ApprovalType.MULTI)
    .requestedBy("soar-pipeline")
    .requestReason("Lateral movement detected from web-server-03")
    .potentialImpact("Web traffic disruption for 200+ active sessions")
    .riskAssessment("CRITICAL - production server under active attack")
    .timeoutMinutes(15)
    .organizationId(soarContext.getOrganizationId())
    .build();

// Submit: saves and notifies in one call
approvalService.submitApprovalRequest(request);

// Or use async API
CompletableFuture<Boolean> future = approvalService.requestApproval(request);
future.thenAccept(approved -> {
    if (approved) {
        // Proceed with tool execution
    }
});

관련 문서