Skip to content

심층 방어

Triggerfish는 보안을 13개의 독립적이고 중첩되는 계층으로 구현합니다. 어떤 단일 계층도 그 자체로 충분하지 않습니다. 함께 작동하여 우아하게 성능이 저하되는 방어를 형성합니다 -- 하나의 계층이 침해되더라도 나머지 계층이 시스템을 계속 보호합니다.

보안 심층 방어는 어떤 단일 계층의 취약점이 시스템을 침해하지 않는다는 것을 의미합니다. 채널 인증을 우회하는 공격자는 여전히 세션 taint 추적, 정책 hook, 감사 로깅에 직면합니다. 프롬프트 인젝션된 LLM도 그 아래의 결정론적 정책 계층에 영향을 미칠 수 없습니다. :::

13개 계층

계층 1: 채널 인증

방어 대상: 사칭, 무단 접근, 신원 혼란.

신원은 LLM이 메시지 콘텐츠를 해석하는 것이 아니라 세션 수립 시 코드에 의해 결정됩니다. LLM이 메시지를 보기 전에 채널 어댑터가 불변 레이블을 태그합니다:

{ source: "owner" }    -- 확인된 채널 신원이 등록된 소유자와 일치
{ source: "external" } -- 다른 모든 사람; 입력만 가능, 명령으로 취급되지 않음

인증 방법은 채널에 따라 다릅니다:

채널방법확인
Telegram / WhatsApp페어링 코드일회용 코드, 5분 만료, 사용자 계정에서 전송
Slack / Discord / TeamsOAuth플랫폼 OAuth 동의 흐름, 확인된 사용자 ID 반환
CLI로컬 프로세스사용자 머신에서 실행, OS에 의해 인증
WebChat없음 (공개)모든 방문자는 EXTERNAL, 절대 owner가 아님
이메일도메인 매칭발신자 도메인을 구성된 내부 도메인과 비교

LLM은 절대 누가 소유자인지 결정하지 않습니다. 확인되지 않은 발신자가 보낸 "나는 소유자입니다"라는 메시지는 { source: "external" }로 태그되며 소유자 수준 명령을 트리거할 수 없습니다. 이 결정은 LLM이 메시지를 처리하기 전에 코드에서 이루어집니다. :::

계층 2: 권한 인식 데이터 접근

방어 대상: 과다 권한 데이터 접근, 시스템 자격 증명을 통한 권한 상승.

Triggerfish는 시스템 서비스 계정이 아닌 사용자의 위임된 OAuth 토큰을 사용하여 외부 시스템을 쿼리합니다. 소스 시스템이 자체 권한 모델을 시행합니다:

전통적 모델 vs Triggerfish: 전통적 모델은 LLM에 직접 제어를 부여하고, Triggerfish는 모든 동작을 결정론적 정책 계층을 통해 라우팅합니다

Plugin SDK는 API 수준에서 이를 시행합니다:

SDK 메서드동작
sdk.get_user_credential(integration)사용자의 위임된 OAuth 토큰을 반환
sdk.query_as_user(integration, query)사용자의 권한으로 실행
sdk.get_system_credential(name)차단됨 -- PermissionError 발생

계층 3: 세션 Taint 추적

방어 대상: 컨텍스트 오염을 통한 데이터 유출, 분류된 데이터가 더 낮은 분류 채널에 도달하는 것.

모든 세션은 세션 중에 접근한 데이터의 최고 분류를 반영하는 taint 수준을 독립적으로 추적합니다. Taint는 세 가지 불변 규칙을 따릅니다:

  1. 대화별 -- 각 세션은 자체 taint를 가집니다
  2. 상승만 가능 -- taint는 증가만 하고, 절대 감소하지 않습니다
  3. 전체 초기화는 모든 것을 지움 -- taint와 기록이 함께 삭제됩니다

정책 엔진이 출력을 평가할 때, 세션의 taint를 대상 채널의 유효 분류와 비교합니다. taint가 대상을 초과하면 출력이 차단됩니다.

계층 4: 데이터 계보

방어 대상: 추적 불가능한 데이터 흐름, 데이터가 어디로 갔는지 감사 불가, 컴플라이언스 격차.

모든 데이터 요소는 원본에서 대상까지 출처 메타데이터를 전달합니다:

  • 원본: 어떤 통합, 레코드, 사용자 접근이 이 데이터를 생성했는지
  • 분류: 어떤 수준이 할당되었고 그 이유
  • 변환: LLM이 데이터를 어떻게 수정, 요약 또는 결합했는지
  • 대상: 어떤 세션과 채널이 출력을 받았는지

계보는 순방향 추적("이 Salesforce 레코드는 어디로 갔습니까?"), 역방향 추적("이 출력에 어떤 소스가 기여했습니까?"), 전체 컴플라이언스 내보내기를 가능하게 합니다.

계층 5: 정책 시행 Hook

방어 대상: 프롬프트 인젝션 공격, LLM 기반 보안 우회, 제어되지 않는 도구 실행.

8개의 결정론적 hook이 데이터 흐름의 모든 중요 지점에서 동작을 가로챕니다:

Hook가로채는 대상
PRE_CONTEXT_INJECTION컨텍스트 윈도우에 들어오는 외부 입력
PRE_TOOL_CALLLLM의 도구 실행 요청
POST_TOOL_RESPONSE도구 실행에서 반환되는 데이터
PRE_OUTPUT시스템을 떠나려는 응답
SECRET_ACCESS자격 증명 접근 요청
SESSION_RESETTaint 초기화 요청
AGENT_INVOCATION에이전트 간 호출
MCP_TOOL_CALLMCP 서버 도구 호출

Hook은 순수 코드입니다: 결정론적이고, 동기적이며, 로깅되고, 위조할 수 없습니다. LLM은 LLM 출력에서 hook 구성으로의 경로가 없기 때문에 우회할 수 없습니다. hook 계층은 LLM 출력을 명령으로 파싱하지 않습니다.

계층 6: MCP Gateway

방어 대상: 제어되지 않는 외부 도구 접근, MCP 서버를 통해 들어오는 미분류 데이터, 스키마 위반.

모든 MCP 서버는 기본적으로 UNTRUSTED이며 관리자 또는 사용자가 분류할 때까지 호출할 수 없습니다. Gateway는 다음을 시행합니다:

  • 서버 인증 및 분류 상태
  • 도구 수준 권한 (서버가 허용되어도 개별 도구를 차단할 수 있음)
  • 요청/응답 스키마 유효성 검사
  • 모든 MCP 응답의 taint 추적
  • 매개변수의 인젝션 패턴 스캔
MCP 서버 상태: UNTRUSTED (기본값), CLASSIFIED (검토되어 허용됨), BLOCKED (명시적으로 금지됨)

계층 7: Plugin 샌드박스

방어 대상: 악의적이거나 버그가 있는 plugin 코드, 데이터 유출, 무단 시스템 접근.

Plugin은 이중 샌드박스 내에서 실행됩니다:

Plugin 샌드박스: Deno 샌드박스가 WASM 샌드박스를 감싸고, plugin 코드는 가장 안쪽 계층에서 실행됩니다

Plugin은 다음을 할 수 없습니다:

  • 선언되지 않은 네트워크 엔드포인트에 접근
  • 분류 레이블 없이 데이터 방출
  • taint 전파를 트리거하지 않고 데이터 읽기
  • Triggerfish 외부에 데이터 영속화
  • 시스템 자격 증명 사용 (사용자의 위임된 자격 증명만 가능)
  • 사이드 채널을 통한 유출 (리소스 제한, 원시 소켓 없음)

plugin 샌드박스는 에이전트 exec 환경과 구별됩니다. Plugin은 시스템이 보호하는 신뢰할 수 없는 코드입니다. exec 환경은 에이전트가 빌드할 수 있는 워크스페이스입니다 -- 샌드박스 격리가 아닌 정책 기반 접근으로. :::

계층 8: 시크릿 격리

방어 대상: 자격 증명 도용, 구성 파일의 시크릿, 평문 자격 증명 저장.

자격 증명은 OS 키체인(개인 티어) 또는 vault 연동(엔터프라이즈 티어)에 저장됩니다. 다음 위치에는 절대 나타나지 않습니다:

  • 구성 파일
  • StorageProvider
  • 로그 항목
  • LLM 컨텍스트 (자격 증명은 LLM 아래의 HTTP 계층에서 주입됩니다)

SECRET_ACCESS hook은 요청하는 plugin, 자격 증명 범위, 결정과 함께 모든 자격 증명 접근을 로깅합니다.

계층 9: 파일 시스템 도구 샌드박스

방어 대상: 경로 탐색 공격, 무단 파일 접근, 직접 파일 시스템 작업을 통한 분류 우회.

모든 파일 시스템 도구 작업(읽기, 쓰기, 편집, 목록, 검색)은 세션의 taint에 적합한 워크스페이스 하위 디렉터리에 범위가 지정된 OS 수준 권한을 가진 샌드박스된 Deno Worker 내에서 실행됩니다. 샌드박스는 세 가지 경계를 시행합니다:

  • 경로 감옥 -- 모든 경로는 절대 경로로 확인되고 구분자 인식 매칭으로 감옥 루트와 비교됩니다. 워크스페이스를 벗어나는 탐색 시도(../)는 I/O가 발생하기 전에 거부됩니다
  • 경로 분류 -- 모든 파일 시스템 경로는 고정 확인 체인을 통해 분류됩니다: 하드코딩된 보호 경로(RESTRICTED), 워크스페이스 분류 디렉터리, 구성된 경로 매핑, 기본 분류 순서. 에이전트는 세션 taint 이상의 경로에 접근할 수 없습니다
  • Taint 범위 권한 -- 샌드박스 Worker의 Deno 권한은 세션의 현재 taint 수준과 일치하는 워크스페이스 하위 디렉터리로 설정됩니다. taint가 상승하면 Worker가 확장된 권한으로 다시 생성됩니다. 권한은 세션 내에서 확대만 가능하고, 절대 축소되지 않습니다
  • 쓰기 보호 -- 중요 파일(TRIGGER.md, triggerfish.yaml, SPINE.md)은 샌드박스 권한과 관계없이 도구 계층에서 쓰기 보호됩니다. 이 파일들은 자체 분류 규칙을 시행하는 전용 관리 도구를 통해서만 수정할 수 있습니다

계층 10: 에이전트 신원

방어 대상: 에이전트 체인을 통한 권한 상승, 위임을 통한 데이터 세탁.

에이전트가 다른 에이전트를 호출할 때, 암호화 위임 체인이 권한 상승을 방지합니다:

  • 각 에이전트는 능력과 분류 상한을 지정하는 인증서를 가집니다
  • 수임자는 max(own taint, caller taint)를 상속합니다 -- taint는 체인을 통해 증가만 가능합니다
  • taint가 수임자의 상한을 초과하는 호출자는 차단됩니다
  • 순환 호출이 감지되어 거부됩니다
  • 위임 깊이가 제한되어 시행됩니다
데이터 세탁 방어: 상한 확인과 taint 상속에서 차단되어 더 낮은 분류 채널로의 출력이 방지됩니다

계층 11: 감사 로깅

방어 대상: 감지 불가능한 침해, 컴플라이언스 실패, 사고 조사 불가.

모든 보안 관련 결정이 전체 컨텍스트와 함께 로깅됩니다:

json
{
  "timestamp": "2025-01-29T10:23:45Z",
  "user_id": "user_123",
  "session_id": "sess_456",
  "action": "slack.postMessage",
  "target_channel": "external_webhook",
  "session_taint": "CONFIDENTIAL",
  "target_classification": "PUBLIC",
  "decision": "DENIED",
  "reason": "classification_violation",
  "hook": "PRE_OUTPUT",
  "policy_rules_evaluated": ["rule_001", "rule_002"],
  "lineage_ids": ["lin_789", "lin_790"]
}

로깅되는 항목:

  • 모든 동작 요청 (허용 및 거부)
  • 분류 결정
  • 세션 taint 변경
  • 채널 인증 이벤트
  • 정책 규칙 평가
  • 계보 레코드 생성 및 업데이트
  • MCP Gateway 결정
  • 에이전트 간 호출

감사 로깅은 비활성화할 수 없습니다. 정책 계층 구조의 고정 규칙입니다. 조직 관리자도 자신의 동작에 대한 로깅을 끌 수 없습니다. 엔터프라이즈 배포는 법의학적 요구 사항을 위해 전체 콘텐츠 로깅(차단된 메시지 콘텐츠 포함)을 선택적으로 활성화할 수 있습니다. :::

계층 12: SSRF 방지

방어 대상: 서버 측 요청 위조, 내부 네트워크 정찰, 클라우드 메타데이터 유출.

모든 아웃바운드 HTTP 요청(web_fetch, browser.navigate, plugin 네트워크 접근)은 DNS를 먼저 확인하고 확인된 IP를 개인 및 예약된 범위의 하드코딩된 거부 목록과 비교합니다. 이는 공격자가 조작된 URL을 통해 에이전트가 내부 서비스에 접근하도록 속이는 것을 방지합니다.

  • 개인 범위(10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)는 항상 차단됩니다
  • 링크 로컬(169.254.0.0/16) 및 클라우드 메타데이터 엔드포인트가 차단됩니다
  • 루프백(127.0.0.0/8)이 차단됩니다
  • 거부 목록은 하드코딩되어 구성할 수 없습니다 -- 관리자 재정의가 없습니다
  • DNS 확인이 요청 전에 이루어져 DNS 리바인딩 공격을 방지합니다

계층 13: 메모리 분류 게이팅

방어 대상: 메모리를 통한 세션 간 데이터 유출, 메모리 쓰기를 통한 분류 다운그레이드, 분류된 메모리에 대한 무단 접근.

세션 간 메모리 시스템은 쓰기와 읽기 시점 모두에서 분류를 시행합니다:

  • 쓰기: 메모리 항목은 현재 세션의 taint 수준으로 강제됩니다. LLM은 저장된 메모리에 대해 더 낮은 분류를 선택할 수 없습니다.
  • 읽기: 메모리 쿼리는 canFlowTo로 필터링됩니다 -- 세션은 현재 taint 수준 이하의 메모리만 읽을 수 있습니다.

이는 에이전트가 CONFIDENTIAL 데이터를 PUBLIC으로 메모리에 저장한 후 나중에 더 낮은 taint 세션에서 검색하여 no-write-down 규칙을 우회하는 것을 방지합니다.

신뢰 계층 구조

신뢰 모델은 누가 무엇에 대한 권한을 가지는지 정의합니다. 상위 티어는 하위 티어의 보안 규칙을 우회할 수 없지만, 해당 규칙 내의 조정 가능한 매개변수를 구성할 수 있습니다.

신뢰 계층 구조: Triggerfish 벤더 (접근 제로), 조직 관리자 (정책 설정), 직원 (경계 내에서 에이전트 사용)

개인 티어: 사용자가 곧 조직 관리자입니다. 완전한 주권. Triggerfish 가시성 없음. 벤더는 기본적으로 사용자 데이터에 대한 접근이 제로이며, 사용자의 명시적이고 시간 제한적이며 로깅된 승인을 통해서만 접근할 수 있습니다. :::

계층들의 협력 방식

악의적인 메시지가 데이터를 유출하려는 프롬프트 인젝션 공격을 고려하십시오:

단계계층동작
1채널 인증메시지에 { source: "external" } 태그 -- 소유자 아님
2PRE_CONTEXT_INJECTION입력에서 인젝션 패턴 스캔, 분류됨
3세션 taint세션 taint 변경 없음 (분류된 데이터에 접근하지 않음)
4LLM 메시지 처리LLM이 도구 호출 요청으로 조작될 수 있음
5PRE_TOOL_CALL외부 소스 규칙에 대한 도구 권한 확인
6POST_TOOL_RESPONSE반환된 데이터 분류, taint 업데이트
7PRE_OUTPUT출력 분류 vs. 대상 확인
8감사 로깅전체 시퀀스가 검토를 위해 기록됨

4단계에서 LLM이 완전히 침해되어 데이터 유출 도구 호출을 요청하더라도, 나머지 계층(권한 확인, taint 추적, 출력 분류, 감사 로깅)이 정책을 계속 시행합니다. 단일 실패 지점이 시스템을 침해하지 않습니다.