통제된 Search Runtime
Typesense를 우선 lexical engine으로 사용하면서 후보 검색과 테넌트 DB 권한 검증을 분리하는 Core 실행 구조를 설명합니다.
통제된 Search Runtime
App은 SDK 계약으로 Resource 식별자, 검색 필드, 권한을 게시합니다. Core가 검색 참여 여부를 정하고 후보 ID의 권한을 다시 확인한 뒤 결과를 공개합니다. App 작업은 Resource 계약, 운영 engine 선택은 Search 설정 프로필을 참고하세요. Index에 있다는 이유만으로 결과에 표시되지는 않습니다.
무엇인가
Nexia Search는 교체 가능한 후보 검색 단계와 Core가 소유하는 권한 검증 단계를 분리한 실행 파이프라인입니다. Typesense가 우선 lexical engine이지만 권한의 원본은 아니며, 유일한 후보 gateway도 아닙니다. 외부 검색 서비스를 두기 어려운 배포는 database gateway를 선택할 수 있고, 같은 Core 계약을 구현하면 다른 engine adapter도 추가할 수 있습니다.
이 구조를 이해하려면 **후보(candidate)**와 **결과(result)**를 구분해야 합니다.
Gateway가 돌려줄 수 있는 것은 public identifier와 rank입니다. 그것을 브라우저나
Agent가 볼 결과로 바꾸는 주체는 CoreSearchService 하나뿐입니다. Core는 현재
테넌트 데이터베이스에서 레코드를 다시 읽고, 최신 type·record 권한을 검사한 뒤,
검증된 모델에서만 제목과 표시 값을 만듭니다.
Core 안에서의 위치
| 단계 | 담당 | 신뢰 범위 |
|---|---|---|
| Searchable Resource 등록 | Core catalog와 명시적 allowlist | 검색에 참여 가능한 Resource 종류 결정 |
| 후보 index | Scout와 선택한 index adapter | 다시 만들 수 있는 파생 데이터 |
| 후보 검색 | SearchCandidateGateway | 신뢰하지 않는 ID와 rank만 반환 |
| 레코드 재조회 | 테넌트 데이터베이스 | 현재 테넌트가 소유한 사실 |
| 권한 검사 | CoreSearchService, Policy, permission service | 정보 공개 전 필수 단계 |
| 응답 구성 | CoreSearchService | 검증된 필드만 사용 |
Engine 선택은 Search 설정 프로필을 따르세요. 어느 쪽을 쓰더라도 App의 Resource 계약은 같습니다.
Typesense의 테넌트 제한
Typesense adapter는 테넌트 컨텍스트 없이 검색하지 않습니다. 미리 발급한
search-only parent key에서 만료 시간이 있는 테넌트 전용 child key를 만들고,
query에도 tenant_key filter를 강제로 넣습니다. Parent는 Typesense에 실제로
등록된 검색 전용 키여야 합니다. 임의 문자열이 아니며 Scout가 서버에서 쓰는
관리용 key와도 구분해야 합니다.
이 제한은 다층 방어입니다. Scoped key 하나가 Nexia의 모든 Policy와 레코드 scope를 표현할 수 없으므로 Core의 DB 재조회와 권한 검사는 그대로 실행됩니다.
경계
검색은 권한을 부여하지 않습니다. 어떤 Resource가 index에 들어갔다는 이유로 행위자에게 보이는 것은 아닙니다. 브라우저가 Typesense를 직접 호출하는 경로는 Core 재검증을 건너뛰므로 지원되는 제품 경로가 아닙니다.
외부 index는 지속되어야 하는 제품 원본도 아닙니다. Index를 재생성하거나 다른 engine으로 교체해도 업무 레코드와 permission grant, audit history가 바뀌면 안 됩니다. 명시적으로 allowlist에 등록한 Resource만 외부로 내보내며, App 모델을 추가하려면 먼저 안정된 Resource identity 계약이 있어야 합니다.
Knowledge semantic retrieval은 별도 경계입니다. 기본값이 비활성화된 Knowledge 전용 기능이며, 일반 provider 이름이 아니라 불변 embedding profile로 선택합니다. Profile은 provider, model·version, vector dimension, extraction 계약, storage generation 전체를 함께 식별합니다. Persisted vector가 이전 공간에 남아 있는데 운영자가 model 이름만 바꾸는 불일치를 막기 위한 계약입니다.
현재 릴리스가 제공하는 profile은
deterministic-local-test-vector-16-v1뿐이며 Core는 local·testing 밖에서 이를
거부합니다. 아직 운영용 Knowledge embedding profile은 없습니다. Typesense
lexical search를 켠다고 semantic retrieval이 활성화되지 않으며, 어느 경로를
켜더라도 행위자의 권한 범위는 넓어지지 않습니다.
동작 예시
행위자가 Q-1842를 검색하면 Typesense gateway는 테넌트 filter가 포함된
query로 후보 public ID와 rank를 받습니다. Core는 각 Resource Key에 등록된
모델을 찾고, 현재 테넌트 연결에서 ID를 다시 조회한 뒤, type permission과
레코드 가시성을 검사합니다. 오래된 후보나 방금 권한이 회수된 레코드는 결과에서
빠집니다. Gateway를 database로 바꾸면 후보 검색 기능과 순위 특성은 달라져도
권한 검사 순서는 바뀌지 않습니다.
함께 읽기
- 권한과 역할 — Search가 매번 다시 평가해야 하는 권한 모델입니다.
- 테넌트와 컨텍스트 — 검색 전에 현재 DB와 행위자가 확립되어야 하는 이유입니다.
- Resource 계약 — Search가 등록할 수 있는 안정된 Resource identity를 제공합니다.
- Artisan 명령어 — index 설정을 바꾼 뒤 사용할 수 있는 운영 명령을 찾습니다.