기존 Spring Boot 애플리케이션에 Contexa 통합하기

Contexa의 실행 범위는 설치 여부가 아니라 활성화 모드로 결정됩니다. Starter 의존성만 추가한 상태, 호스트 인증을 유지하는 SANDBOX, Contexa가 인증을 소유하는 FULL을 구분해 적용해야 합니다.

현재 검증 기준 — 이 릴리스는 Java 17과 Spring Boot 3.5.4를 기준으로 검증합니다. Spring Boot 3.x가 대상이며 4.x는 지원하지 않습니다. 4.x 환경에서 @EnableAISecurity를 선언하면 구동을 차단합니다.

세 가지 실행 상태

  • Starter만 추가: @EnableAISecurity가 없으면 Contexa AI 보안, 필터, 인증 Provider, IAM 스키마를 활성화하지 않습니다.
  • SANDBOX (기본): HOST_OWNED 계약입니다. 호스트가 인증과 SecurityContext를 소유하고, Contexa는 브리지로 인증 주체를 받아 선택된 리소스의 정책만 독립적으로 평가합니다.
  • FULL: CONTEXA_OWNED 계약입니다. Contexa를 전역 인증·인가 플랫폼으로 사용할 신규 애플리케이션에서만 명시적으로 선택합니다.

내부에서 일어나는 일

@EnableAISecurity를 추가하면 선택한 모드가 먼저 소유권 경계를 결정합니다. 아래 인증 DSL과 필터 체인 생성 과정은 FULL / CONTEXA_OWNED 구성에 해당합니다.

1

Import & Detect

@EnableAISecurityAiSecurityImportSelector를 임포트하고, AiSecurityConfiguration을 로드합니다. 커스텀 PlatformConfig 빈이 없으면(@ConditionalOnMissingBean), 기본값이 자동 생성됩니다.

2

Create Flows

FlowContextFactoryPlatformConfig를 읽고 각 인증 흐름(Form, REST, MFA, OTT, Passkey)마다 독립적인 HttpSecurity 인스턴스를 생성합니다.

3

Apply Adapters

SecurityConfigurerOrchestrator가 어댑터 체인을 실행하여 Spring Security 메서드를 호출합니다: http.formLogin(), http.webAuthn()(DSL의 passkey()가 호출), http.oneTimeTokenLogin(). Zero Trust 필터도 이 단계에서 추가됩니다.

4

Register Chains

SecurityFilterChainRegistrar가 각 HttpSecurityOrderedSecurityFilterChain으로 감싸고 BeanDefinitionRegistry를 통해 Spring 빈으로 등록합니다 — 기존 필터 체인과 나란히, 절대 대체하지 않습니다.

FULL 모드의 기본 PlatformConfig는 Form Login, OTT MFA, 세션 관리와 AISessionSecurityContextRepository를 구성합니다. SANDBOX에서는 이 구성을 호스트 인증 소유권을 넘기는 근거로 사용하면 안 됩니다.

FULL 모드 내부 동작 — Contexa는 표준 Spring Security DSL을 구성합니다. 이 동작은 명시적으로 FULL을 선택한 경우에만 호스트 인증 구성을 소유합니다.

SANDBOX에서는 호스트 보안 소유권을 유지합니다

SANDBOX의 기준은 단순한 빈 공존이 아니라 HOST_OWNED 경계입니다. 호스트가 로그인, 세션, 인증 Provider와 SecurityContext를 계속 소유합니다.

Contexa 추가 전
기존 SecurityFilterChain
기존 UserDetailsService
기존 AuthenticationProvider
spring.security.* 속성
SANDBOX 활성화 후
기존 SecurityFilterChain (변경 없음)
기존 UserDetailsService (변경 없음)
기존 AuthenticationProvider (변경 없음)
spring.security.* 속성 (변경 없음)
+ 선택된 Contexa 리소스 평가 (독립 실행)
+ 호스트 인증 주체 브리지 (읽기 전용)
+ DB 정책 결정 (호스트 IAM과 분리)

깨지지 않는 이유

기존 빈 Contexa 추가 후 메커니즘
SecurityFilterChain SANDBOX에서 대체하거나 소유하지 않음 HOST_OWNED 소유권 경계
UserDetailsService 변경 없음 — 호스트 구현을 사용 브리지는 인증 주체를 전달받아 읽기만 함
AuthenticationProvider 변경 없음 — SANDBOX가 호스트 인증 Provider를 대체하지 않음 HOST_OWNED 인증 경계
CSRF / CORS 설정 변경 없음 — 호스트 설정 유지 Contexa 리소스 평가와 분리
spring.security.* 변경 없음 — 네임스페이스 충돌 없음 Contexa는 contexa.*contexa.security.zerotrust.* 사용

Shadow Mode로 안전하게 시작

Shadow Mode는 전체 Zero Trust 파이프라인 — 행동 분석, 위험도 산출, AI 결정 — 을 실행하지만 결정을 절대 강제하지 않습니다.

Shadow Mode

여기서 시작하세요. 기존 동작에 위험 없음.

  • AI가 선택된 Contexa 리소스 요청을 분석
  • 결정은 로그에만 기록
  • 사용자 차단이나 MFA 요구 없음
  • 실제 트래픽으로 행동 기준선 구축
  • 요청 오버헤드 최소 — 분석이 기본적으로 비동기로 수행됨

Enforce Mode

기준선이 확립되면 전환.

  • AI가 선택된 Contexa 리소스 요청을 분석
  • 결정이 실시간으로 강제됨
  • ALLOW 정상 통과
  • CHALLENGE MFA 요구
  • BLOCK 접근 차단
YAML
contexa:
  security:
    zerotrust:
      mode: SHADOW   # 선택된 리소스를 분석하되, 결정을 강제하지 않음

contexa.security.zerotrust.mode 속성은 SecurityZeroTrustProperties에 바인딩됩니다(값: SHADOW, ENFORCE; 기본값 ENFORCE). SecurityZeroTrustProperties.isEnforcementEnabled()mode == ENFORCE일 때만 true를 반환합니다. SHADOW 모드에서는 SecurityDecisionEnforcementHandler가 결정 영속화와 차단 부수 효과를 건너뛰고, AuthorizationManagerMethodInterceptor@Protectable(sync = true)의 BLOCK/CHALLENGE/ESCALATE 결정을 관찰 전용으로 처리합니다(ZeroTrustAccessDeniedException을 던지지 않고 메서드가 정상 진행). 이 속성은 @ConfigurationProperties로 바인딩되므로 YAML 값 변경 후에는 애플리케이션 재시작이 필요합니다.

적용 전 확인 — Shadow Mode는 결정을 강제하지 않지만 실제 분석 경로는 실행됩니다. 운영 전 대상 리소스 범위, 로그, 지연 시간과 외부 AI 호출 여부를 자신의 환경에서 확인하세요. Shadow Mode 가이드 →

실전 적용 — Shadow에서 Enforce로

행동 기준선이 확립되면, 속성 하나를 변경하여 Enforce 모드로 전환합니다:

YAML
contexa:
  security:
    zerotrust:
      mode: ENFORCE   # AI 결정이 실제로 강제됨

Enforce 모드에서 AI의 결정이 실제로 적용됩니다:

ALLOW
요청이 정상 처리됨
!
CHALLENGE
MFA 재인증 요구
×
BLOCK
접근 즉시 차단
ESCALATE
관리자 검토 대기

롤백하려면 ENFORCESHADOW로 변경하세요. 해당 속성은 @ConfigurationProperties로 바인딩되므로 변경 사항이 적용되려면 애플리케이션 재시작이 필요합니다.

AI가 결정을 내리는 방식 →  |  마이그레이션 전략 →

FULL 모드에서 커스텀 인증 구성이 필요할 때

다음 인증 DSL 예제는 FULL / CONTEXA_OWNED 전용입니다. 레거시 호스트의 SANDBOX 통합에 복사하지 마세요. FULL에서 다른 인증 구성이 필요할 때만 PlatformConfig 빈을 정의합니다.

시나리오 A: REST API 전용

애플리케이션이 REST API만 제공하고 Form Login이 필요 없는 경우.

Java
@Bean
public PlatformConfig platformConfig(IdentityDslRegistry<HttpSecurity> registry) throws Exception {
    return registry
        .global(globalHttpCustomizer)
        .rest(rest -> rest.order(10))
        .session(Customizer.withDefaults())
        .build();
}

시나리오 B: FULL 모드의 Form Login + Zero Trust

Contexa가 인증을 소유하는 FULL 모드에서 Form Login과 AI 기반 보안을 함께 구성하는 경우입니다. AISessionSecurityContextRepository도 FULL 소유권 안에서 등록합니다.

Java
@Bean
public PlatformConfig platformConfig(IdentityDslRegistry<HttpSecurity> registry) throws Exception {
    return registry
        .global(http -> http
            .authorizeHttpRequests(authReq -> authReq
                .requestMatchers("/css/**", "/js/**", "/images/**").permitAll()
                .anyRequest().access(customDynamicAuthorizationManager))
            .securityContext(sc -> sc
                .securityContextRepository(aiSessionSecurityContextRepository)))
        .form(form -> form.defaultSuccessUrl("/dashboard"))
        .session(Customizer.withDefaults())
        .build();
}

시나리오 C: 복잡한 기존 설정 — rawHttp() 탈출구

DSL이 충분하지 않을 때 — 커스텀 필터, 커스텀 AuthenticationEntryPoint, 고급 설정 — Spring Security의 HttpSecurity에 직접 접근합니다:

Java
.form(form -> form
    .rawFormLogin(formLogin -> formLogin
        .authenticationDetailsSource(customDetailsSource)
        .successHandler(customSuccessHandler))
)

Spring Security의 FormLoginConfigurer에 완전히 접근하면서도 Contexa의 Zero Trust 파이프라인은 그대로 유지됩니다.

FULL 모드 조건 — 커스텀 PlatformConfig를 정의할 때는 AISessionSecurityContextRepository를 FULL 소유권 안에서 등록해야 합니다. SANDBOX에서 호스트 SecurityContext를 이 저장소로 교체하지 마세요.

Identity DSL 레퍼런스 →  |  인증 흐름 →  |  적응형 MFA →