프롬프트 엔지니어링
Contexa 는 사람과 Agent 의 HTTP 요청을 구조화된 프롬프트(Prompt)로 변환해 LLM 이 일관된 보안 결정을 내리도록 설계되었습니다. 요청 하나가 프롬프트가 되기까지는 수집 → 가공 → 정제 → 표준화 → 조립 → 보정 여섯 단계를 거칩니다. 이 문서는 그 흐름을 처음부터 끝까지 한 줄로 이어 보여 드립니다.
여섯 단계 파이프라인
프롬프트는 즉석에서 만들어지지 않습니다. 여섯 단계를 거치며 요청 주변의 모든 사실을 수집·정리·검증한 뒤에야 LLM 에 전달됩니다. 각 단계는 독립된 패키지로 구현되어 있고, 이전 단계의 출력이 다음 단계의 입력이 됩니다.
Stage 1 · 수집
요청이 Spring Security 필터 체인(Filter Chain)에 들어오면 AuthBridge 구현체가 헤더·세션·속성 등 다양한 출처에서 주체를 추출합니다. 추출된 정보는 세 종류의 증거 도장(Stamp) 으로 포장됩니다. 이 세 도장이 이후 모든 단계의 원천 입력입니다.
- principalType · 주체 유형
- authenticationType
- authenticationAssurance
- mfaCompleted
- authenticationSource
- sessionId · authenticationTime
- effect (ALLOW · DENY · UNKNOWN)
- privileged · 특권 동작
- policyId · policyVersion
- decisionSource
- effectiveRoles · effectiveAuthorities
- subjectId · 위임자 (사람)
- agentId · 대리 주체
- objectiveId · objectiveFamily
- allowedOperations
- allowedResources
- containmentOnly · expiresAt
증거 품질 다섯 등급
모든 증거가 같은 신뢰도를 가지지는 않습니다. 고객이 명시적으로 보낸 신호가 가장 강하고, 플랫폼이 구조적으로 관찰한 신호가 그 다음, 런타임 연속성으로 추정한 신호는 약합니다. BridgeSemanticBoundaryPolicy 는 모든 수집 시점에 다음 다섯 등급 중 하나를 붙입니다.
Stage 2 · 가공
수집된 증거만으로는 LLM 이 이 사람이 평소와 다르게 행동하는지 판단할 수 없습니다. 2 단계는 세 종류의 구성요소가 원시 증거를 관찰 가능한 패턴으로 확장합니다.
- SessionNarrativeCollector — 세션 내 행동 시퀀스
- ProtectableWorkProfileCollector — 평소 업무 프로필
- RoleScopeCollector — 역할 범위 스냅샷
- AuthenticationContextProvider — 인증 강도
- DelegationContextProvider — 위임 범위 확장
- PeerCohortContextProvider — 동료 그룹 이상치
- FrictionContextProvider — 마찰·승인 이력
- OrganizationContextProvider — 조직 계층
- ReasoningMemoryContextProvider — 과거 강화 사례
- ObjectiveDriftEvaluator — Agent 목표 이탈
- ObservedScopeInferenceService — 관찰 범위
- ContextCoverageEvaluator — 완성도 평가
ObjectiveDriftEvaluator 는 현재 요청의 리소스·액션이 DelegationStamp 의 allowedOperations·allowedResources 범위를 벗어나는지 실시간으로 판정합니다.
Stage 3 · 정제
프롬프트 주입(Prompt Injection) · 필드 스푸핑 · 신호 위조는 LLM 기반 보안 시스템이 가장 경계해야 할 위협입니다. CanonicalSecurityContextHardener 는 모든 필드를 LLM 에 넘기기 전에 필드별 정규화 절차를 거칩니다.
- Null 필드 기본값 치환
- 문자열 트림 · 길이 제한
- 열거형 값 정규화
- 시간 · 좌표 범위 검증
- 언어 · 국가 코드 ISO 정규화
- 페이로드 디코딩 후 출력 가능 문자 80% 이상 필터
- 세션 이야기 버스트 플래그 유지
- 업무 프로필 음수 값 제거
- 역할 범위 중복 제거 · 순서 보존
- 마찰 프로필 승인 이력 순서 고정
- 추론 메모리 가드레일 정제
- 신뢰 프로필 결정 상태 정규화
Stage 4 · 표준화
3 단계를 거친 모든 정보는 CanonicalSecurityContext 라는 단일 표준 컨텍스트 모델로 집약됩니다. 현재 구현은 Lombok 기반의 클래스이며, hardener가 필드 정규화와 기본값 보정을 수행한 뒤 프롬프트 조립 단계에 전달합니다. 22 개 필드와 7 개 프로필이 정해진 자리에 담기므로, 이후 프롬프트 조립 단계는 어떤 필드가 어디 있는지 예측 가능합니다.
주체
- userId
- organizationId
- tenantId
- principalType
- roleSet
- authoritySet
세션
- sessionId
- clientIp
- userAgent
- authenticationType
- mfaVerified
- concurrentSessions
위임
- delegated
- agentId
- objectiveId
- allowedOperations
- allowedResources
- objectiveDrift
인가
- effectiveRoles
- effectivePermissions
- scopeTags
- authorizationEffect
- policyId
- policyVersion
의도
- botUserAgent
- impossibleTravel
- intentMissingReferer
위치 · IP
- country · city
- latitude · longitude
- IP band · ASN
리소스
- resourceType
- businessLabel
- sensitivity
- actionFamily
프로필 7 종
- SessionNarrative
- Work
- RoleScope
- PeerCohort
- Friction
- ReasoningMemory
- ObservedScope
정보 완성도 네 단계
채워진 필드 수와 프로필 유무를 종합해 ContextCoverageEvaluator 가 완성도 등급을 매깁니다. 등급이 낮으면 LLM 에게 업무 패턴 기반 결론을 내리지 말라는 경고 문구가 자동 삽입됩니다.
Stage 5 · 조립
표준화된 컨텍스트는 이제 프롬프트가 됩니다. SecurityDecisionPromptSections 가 오케스트레이션하며, 2 개 시스템 섹션과 15 개 사용자 섹션(총 17 개 섹션 계획)을 렌더링합니다. 필드가 없으면 해당 빌더는 자기 섹션을 아예 출력하지 않습니다.
시스템 영역과 사용자 영역
LLM 에게 역할 · 정책 · 출력 형식을 지시합니다. 요청마다 달라지지 않는 부분.
- 보안 정책 지시
- 형식 · 길이 제약
- JSON 스키마 강제
- 거버넌스 버전 기록
현재 요청의 증거를 섹션별로 나열합니다. 요청마다 달라집니다.
- 현재 이벤트
- 정규 컨텍스트 · 완성도
- 신원 · 권한
- 디바이스 · 위치 · 세션
- 위임 · 마찰 · 행동 패턴
- 위협 지식 · 조직 학습 증거 · 명시적 누락 지식
17 개 섹션 계획
CanonicalContextFieldPolicy.has*() 를 먼저 질의하고, 누락 지식 섹션은 coverage report 와 trust profile 을 기준으로 렌더링 여부를 결정합니다. 필드가 없으면 섹션 자체가 출력되지 않으므로, 프롬프트는 항상 정직한 정보만을 담습니다. 거버넌스 식별자 PromptGovernanceDescriptor 가 모델·버전을 같이 기록해 재현성을 보장합니다.
명시적 누락 지식
명시적 누락 지식(내부 섹션 키: EXPLICIT_MISSING_KNOWLEDGE)은 LLM 이 증거 공백을 확신으로 오해하지 않도록 만드는 P0 필수 품질 지표 섹션입니다. SecurityContextQualityUserSectionBuilder 가 PromptContextComposer.composeMissingKnowledgeSection() 을 호출해 만들며, 커버리지 공백이나 신뢰 프로필의 evidence caution 이 있을 때만 출력됩니다. 결핍 신호가 없으면 섹션을 비워 두며, 이는 누락이 아니라 “명시할 지식 공백 없음”을 의미합니다.
- 커버리지 공백 —
missingCriticalFacts,remediationHints,confidenceWarnings가 있으면 누락 지식 섹션을 생성합니다. - 신뢰 한계 —
ContextEvidenceLimitation,ContextTrustLimitation,ContextTrustWarning,ContextFieldCoverage,ContextFieldLimitation을 별도 항목으로 노출합니다. - 오탐 방지 — authorization effect 가 이미 해소된 경우 오래된
AUTHORIZATION_EFFECT누락 경고는 출력하지 않습니다. - Baseline 보강 — 개인/조직 baseline 이 희박하면
BaselineGapSupport를 같은 섹션에 붙여 “증거 부족은 위험 또는 정상의 증거가 아니다”라는 제약을 전달합니다. - 압축 보존 — compact budget 에서도
BaselineGapSupport,ConfidenceWarning,ContextEvidenceLimitation,ContextTrustLimitation,ContextTrustWarning을 우선 보존합니다. 그래도 예산을 넘으면 요약/생략 내역을 compression ledger 에 남깁니다.
Stage 6 · 보정
LLM 이 응답을 돌려주면 끝이 아닙니다. 두 개의 안전장치가 순서대로 결과를 재조정합니다. 첫째는 자율성 제약, 둘째는 런타임 보정 입니다.
자율성 제약 (Autonomy Guardrail)
LLM 의 confidence 가 임계값 미만이거나 출력이 스키마를 벗어나면, PromptConfidenceGuardrail 이 최종 실행 액션을 더 안전한 상위 단계로 강제합니다. 제안 액션과 실행 액션이 분리 기록되어 감사 추적이 가능합니다.
런타임 보정 (Calibration)
제약이 적용되지 않은 결정은 SecurityDecisionCalibrationService 가 학습된 프로필로 미세 조정합니다. 과거 관찰 데이터에 근거해 신뢰도 가감과 액션 편향을 적용합니다.
- 시나리오 분류 — 현재 요청을 과거 유사 시나리오로 분류 (예: 낯선 위치 + 평소와 다른 리소스)
- 프로필 선택 — 최대 샘플 수와 운영자 검토가 완료된 프로필만 선택 (가장 강한 근거)
- 액션 편향 적용 — INCREASE_CHALLENGE · DECREASE_CHALLENGE · NONE 중 하나
- BLOCK 불변 보장 — BLOCK 액션은 어떤 편향으로도 변경 불가 (안전 원칙)
- 제약 우선 — 자율성 제약이 걸린 결정은 보정을 무시 (이중 개입 방지)
최종 결정 레코드
모든 단계를 통과한 뒤 만들어지는 SecurityDecision 은 단순히 ALLOW · BLOCK 한 값이 아닙니다. LLM 의 원시 판단, 정책 개입, 학습 보정이 모두 기록된 감사 가능한 레코드입니다.
SecurityDecision 필드
사람과 Agent 의 프롬프트 차이
같은 파이프라인을 통과해도 주체 유형에 따라 프롬프트의 무게 중심이 달라집니다. 사람은 평소 행동 기준과의 편차가 핵심이고, Agent 는 허용된 목표 범위의 이탈이 핵심입니다.
| 주체 유형 | HUMAN |
|---|---|
| 위임 도장 | 일반적으로 부재 |
| 핵심 프로필 | Work · PeerCohort · Friction |
| 핵심 섹션 | IdentityAuthority · BehaviorProfile |
| 판정 축 | 평소 행동 기준과의 편차 |
| MFA 신호 | 로그인 시점 검증 |
| 주체 유형 | AGENT · SERVICE_ACCOUNT |
|---|---|
| 위임 도장 | 필수. delegated = true + agentId |
| 핵심 프로필 | ObservedScope · RoleScope |
| 핵심 섹션 | Delegation · ObjectiveDrift |
| 판정 축 | 허용된 목표 범위 이탈 여부 |
| MFA 신호 | 위임 토큰 발급 시점 검증 |