전체 문서
이 페이지 목차
보안·승인 경계
ARTEX에는 task scope data, prompt constraint, asset block/allow gate, tool-input intercept, optional LLM judge, human approval, JWT API auth가 있다. 이들은 한 개의 일관된 “scope firewall”이 아니라 서로 다른 단계에 적용되는 경계다.
강제 지점 지도
강제 지점 지도 · 관계
이 대상을 사용하는 기능·모듈·계약 · 1개
- 계약 사용 · ARTEX 현재 시스템 지도 · 기능/모듈이 적용하는 보안·신뢰 규칙 · rule-edge-6
Mermaid 원문
flowchart LR
INPUT[Goal / description / operator rules] --> DEC[Goal decomposer]
DEC --> SCOPE[(task_scope)]
DEC --> CONS[(task_constraints)]
CONS -->|prompt injection| PLAN[Planner]
CONS -->|prompt injection| WORK[Worker]
CHAT[ChatAgent] --> HOOK[Guard PreToolUse]
WORK --> HOOK
DEC --> NOHOOK[ARTEX Guard 미배선]
PLAN --> NOHOOK
MAIN[Task MainAgent] --> NOHOOK
HOOK -->|intercept-enabled tool| IR[Intercept rules]
HOOK -->|그 밖의 tool| DISPATCH[Tool handler]
NOHOOK --> DISPATCH
IR -->|no match| J{LLM judge enabled?}
IR -->|matched action| DECISION{allow / ask / deny}
J -->|off: allow| DISPATCH
J -->|verdict / fail action| DECISION
DECISION -->|allow| DISPATCH
DECISION -->|ask| HUMAN{human / timeout decision}
DECISION -->|deny| BLOCK[Blocked]
HUMAN -->|allow| DISPATCH
HUMAN -->|deny / cancel| BLOCK
DISPATCH -->|add_intent| AIG{Anchor asset gate}
DISPATCH -->|insert_assets| ASG{Insert asset gate\nloaded rules only}
DISPATCH -->|other tool| EXEC[Execution]
AIG -->|allow| GRAPH[(Exploration graph)]
AIG -->|deny / rule read error| BLOCK
ASG -->|no loaded-rule denial| GRAPH
ASG -->|loaded rule deny| BLOCK
EXEC --> AUDIT[(intercept/activity audit)]
BLOCK --> AUDIT
click SCOPE "#scope-gap" "task scope"
click CONS "#scope-gap" "prompt constraints"
click AIG "#asset-gate" "intent asset gate"
click ASG "#asset-gate" "insert asset gate"
click IR "#tool-boundary" "tool intercept"
click J "#judge" "LLM judge"
click AUDIT "#auditability" "audit"
| 판단 | deterministic인가 | 적용 범위 | 기본/실패 동작 |
|---|---|---|---|
| API JWT 검증 | 예 | /api/auth/*, /api/health를 제외한 API |
HMAC 서명과 jwt.Parse 기본 claim 검증에 의존; exp/sub/iss/aud 존재·기대값은 별도 요구하지 않음. change-password는 면제 prefix 아래라 handler가 다시 JWT를 검사 |
| anchored intent의 asset match | 예 | add_intent의 asset ids |
rule 조회 오류도 거부(fail-closed) |
| 새 asset의 block/allow match | 예 | insert_assets의 입력 candidate |
읽힌 rule에는 block/allow 적용; rule 조회 오류는 무시 |
| task constraint 준수 | 아니오 | planner/worker prompt | 모델 자기검사 |
| tool intercept rule match | 예 | Guard hook가 배선된 Worker/ChatAgent의 intercept-enabled tool | first priority match의 allow/deny/ask; config/rule lazy-load 오류는 차단으로 승격되지 않음 |
| unmatched tool 판단 | 선택적 AI | judge가 enabled+wired일 때 | 기본 judge off → allow |
| judge 오류/파싱 실패 | 설정 | judge path | 기본 fail action allow |
| ask 승인 | 사람/timeout | matched call | rule별 timeout, 없으면 취소/결정까지 대기 |
| finding semantic validity | 아니오 | report_finding 결과 |
worker 주장으로 writeback |
Task scope와 실제 outbound의 차이
Task scope와 실제 outbound의 차이 · 관계
이 대상을 사용하는 기능·모듈·계약 · 1개
- 계약 사용 · Company scope와 task scope · 기능/모듈이 적용하는 보안·신뢰 규칙 · rule-edge-2
goal decomposer가 task_scope와 task_constraints를 만들 수 있고, constraints는 planner/worker system prompt 최상위 block으로 들어간다. prompt는 out-of-scope 발견을 fact로만 남기고 새 intent/action을 만들지 말라고 지시한다. constraint 근거 goal 근거
그러나 guard package 주석은 과거 RoE authorization-scope mechanism이 제거됐고 대체가 나중에 추가될 수 있다고 명시한다. 모든 Bash/WebFetch/browser/MCP request의 실제 목적지를 파싱해 task_scope와 대조하는 중앙 gateway는 이 소스에서 확인되지 않았다. guard 근거
더 세부적으로:
add_intent는 asset id가 있을 때 asset gate를 검사한다. unanchored intent는 같은 검사를 통과하지 않으며, rule 조회가 실패하면 intent 생성을 거부한다.insert_assets도 입력 candidate에 asset rules를 적용하지만 global/task rule 조회 오류를 무시한다. 읽기에 실패한 rule set은 적용되지 않은 채 insert가 진행될 수 있다.- 이 검사는 그래프에 넣을 asset/intent를 막는 것이지, 임의 Bash script나 WebFetch URL의 모든 network destination을 승인하는 것은 아니다.
- worker에는 task Guard를 감싼 steer hook가 배선되고 일반·custom 대화의
ChatAgent에는 chat Guard가 배선된다. 현재 정적 호출 경로상 goals decomposer, planner, taskMainAgent의 session options에는 ARTEX Guard hook가 없다. 이 경로들도 tools와PermissionModeBypass를 사용할 수 있다. Norma 내부 보완은 이 저장소 범위 밖이다. - proxy는 capture/forward 계층이며 authorization gateway로 구현되지 않았다. MITM 실패 host를 transparent tunnel로 fail-open하는 경로도 있다.
따라서 task_scope row가 있다 = 모든 network I/O가 강제 제한된다는 주장은 할 수 없다. 승인된 테스트 시스템으로 사용하려면 실제 egress gateway 또는 모든 네트워크 tool adapter가 공통 destination policy를 호출하는지 별도 검증·보완해야 한다.
Asset block/allow gate
Asset block/allow gate · 관계
이 대상을 사용하는 기능·모듈·계약 · 1개
- 계약 사용 · Block/allow 판정 순서와 장애 정책 · 기능/모듈이 적용하는 보안·신뢰 규칙 · rule-edge-1
global asset rules와 task-level block rules를 먼저 적용해 하나라도 맞으면 거부한다. 그 뒤 task allow rule이 하나라도 활성화돼 있으면 그중 어느 것도 맞지 않는 candidate를 “허용 범위 밖”으로 거부한다. domain/IP/URL exact/fuzzy와 CIDR match가 있다. 다만 add_intent는 rule 조회 오류를 거부하는 반면 insert_assets는 global/task rule 조회 오류를 무시하므로, 같은 정책도 호출 지점에 따라 실패 동작이 다르다. asset gate 근거 intent 근거
기본 seed에는 .gov, .gov.cn, .edu, .edu.cn fuzzy block이 있지만 settings flag로 한 번만 넣고 이후 사용자가 disable/delete한 것을 되살리지 않는다. 이 기본 목록은 완전한 authorization policy가 아니며 국가·프로그램별 scope를 표현하지 않는다. DB seed 근거
Tool intercept와 승인
Tool intercept와 승인 · 관계
이 대상을 사용하는 기능·모듈·계약 · 1개
- 계약 사용 · Tool intercept·승인·실행 trace · 기능/모듈이 적용하는 보안·신뢰 규칙 · rule-edge-3
Guard가 배선된 Worker/ChatAgent 경로에서 PreToolUse는 intercept 대상 tool이면 priority 순 DB rule을 먼저 평가한다. 기본 대상은 Bash, WebFetch, web_search, shell_open, shell_send, Write, Edit, MultiEdit다. 규칙은 tool name 또는 raw JSON input에 substring/regex match하며 첫 match의 allow, deny, ask를 따른다. Goals/Planner/MainAgent에는 현재 이 hook 배선이 없다. guard 근거 intercept 근거 worker 근거
enabled-tool config의 lazy load가 실패하면 tool이 disabled처럼 보여 Guard가 바로 allow할 수 있다. enabled 확인 뒤 Match의 rule load가 실패한 경로는 no-match로 처리돼 judge가 활성·배선됐으면 judge로, 아니면 allow로 간다. 따라서 intercept store 장애는 독립적인 fail-closed 경계가 아니다. intercept 근거
seeded destructive/exfil patterns는 일반 DB row다. 사용자가 disable/delete할 수 있고, data-exfil pipe rule 일부는 오탐 때문에 기본 disabled라고 코드가 설명한다. 따라서 built-in rule은 변경 불가능한 safety floor가 아니다. bad regex는 load 중 skip된다. DB seed 근거
ask는 pending row와 activity card를 만들고 사람이 결정할 때까지 worker를 block한다. timeout이 없으면 결정/취소까지 무기한이며, timeout이 있으면 rule의 allow/deny 정책을 따른다. cancellation은 pending을 denied/not-executed로 정리한다. intercept 근거
PermissionModeBypass가 각 역할의 session option에 사용되므로 “Norma가 알아서 매 호출 승인한다”는 가정은 맞지 않는다. Worker와 ChatAgent에서는 ARTEX Guard와 intercept-enabled tool 목록이 통제 경계이고, Goals/Planner/MainAgent에는 같은 Guard가 정적 경로상 배선되지 않는다. worker 근거
Optional LLM judge
아무 deterministic rule도 맞지 않을 때 judge가 켜져 있고 reviewer가 배선돼 있으면 full tool input과 context를 모델에 준다. verdict는 allow/ask/deny다. context build 실패는 사람 ask로 보내지만, model error 또는 parse 실패는 설정된 fail action을 쓴다. 기본은 judge 비활성, model timeout 15초, fail action allow, ask timeout 300초, ask timeout action deny다. judge 근거
LLM judge는 규칙을 보완하는 분류기이며 authorization source of truth로 보기 어렵다. 모델 profile/prompt/config digest와 input digest를 audit에 남기는 것은 사후 설명성을 높이지만, prompt injection과 분류 오류를 deterministic하게 제거하지 않는다.
API 인증과 secret 위치
API 인증과 secret 위치 · 관계
이 대상을 사용하는 기능·모듈·계약 · 1개
- 계약 사용 · Router와 middleware · 기능/모듈이 적용하는 보안·신뢰 규칙 · rule-edge-4
공통 middleware는 /api/auth/*와 /api/health를 면제한다. /api/auth/change-password도 prefix상 면제되지만 handler 안에서 JWT와 기존 암호를 다시 검증한다. extractToken은 Bearer header, cookie, query token을 route 구분 없이 순서대로 읽으므로 middleware 보호 256개 operation과 change-password 1개, 합계 257개에서 query token이 유효하다. SSE 전용 제한은 구현돼 있지 않다. auth 근거
발급 token은 subject ARTEX, 7일 expiry, HS256을 사용하고 password hash는 settings에 bcrypt로 저장한다. 그러나 verifyJWT는 signing method가 SigningMethodHMAC인지 검사하므로 같은 key를 쓴 HS384/HS512도 수락하며, exp, sub, iss, aud의 존재나 기대 값을 별도로 요구하지 않는다. JWT signing key는 BaseDir/jwt.key에 mode 0600으로 만들며, 과거 data/jwt.key가 있으면 browsable workspace 밖으로 옮긴다.
Docker compose는 /app/data와 /app/skills만 bind mount하고 /app/jwt.key를 명시적으로 mount하지 않는다. container replacement에서 key 지속성이 어떻게 되는지는 이미지/volume 실제 동작을 실행하지 않아 미확인이다. 코드와 manifest 조합상 session invalidation 가능성을 운영 검증해야 한다. compose 근거
LLM API keys, notification secrets, MCP headers, web-search keys 등은 DB/settings/config/env에 걸쳐 있다. UI/API가 redacted view를 주는지 각 handler별 확인이 필요하며, task archive와 전체 DB backup의 secret 포함 범위를 별도로 정해야 한다.
frontend는 token을 localStorage와 JavaScript가 쓰는 SameSite=Lax cookie에 함께 저장한다. 이 cookie에는 HttpOnly와 Secure가 없으므로 browser script에서 읽을 수 있고 HTTP에서도 전송될 수 있다. frontend auth 근거
Provenance와 audit
intercept trace는 tool name과 input digest로 decision, tool call, execution result를 연결한다. 같은 concurrent request가 모호하면 추측 연결을 하지 않도록 설계됐다. explicit allow/deny와 model verdict도 history row로 남고, ask는 pending→decision→execution 상태를 갖는다. trace 근거
agent activity는 tool_use/tool_result/usage/result를 PostgreSQL에 남기고 finding evidence는 traffic snapshot hash와 ordered binding을 보유한다. 이 조합으로 “어떤 모델/세션이 어떤 호출을 하고 어떤 bytes를 근거로 무엇을 기록했는가”를 상당 부분 재구성할 수 있다. 다만 activity append drop, proxy bypass/unrecorded tunnel, 외부 MCP 자체 로그, DB 밖 tool side effect는 완전성의 빈틈이다.
Finding 신뢰 경계
Finding 신뢰 경계 · 관계
이 대상을 사용하는 기능·모듈·계약 · 1개
- 계약 사용 · Finding writeback transaction · 기능/모듈이 적용하는 보안·신뢰 규칙 · rule-edge-5
report_finding 성공 시 graph node는 즉시 confirmed다. traffic evidence는 optional이고 evidence store는 bytes 무결성만 검증한다. Reporter는 trace/traffic을 문장으로 정리하며 기본적으로 exploit을 다시 수행하지 않는다. Retest는 사람이 시작하는 별도 경로다. finding 흐름
따라서 automation이 finding을 외부 제출하기 전에 별도 validation policy가 필요하다. 최소한 재현 가능성, identity/tenant 대조, 영향 범위, scope, duplicate, evidence completeness를 검사하고 불충분하면 candidate 성격으로 취급해야 한다.
실패 조건 요약
| 실패 | 현재 코드가 주는 신호 | 필요한 검증/보완 |
|---|---|---|
| out-of-scope direct request | prompt/asset rule로 일부 예방 | central egress policy와 destination parser |
| Guard 미배선 역할의 tool call | Goals/Planner/MainAgent에는 hook 없음 | 모든 실행 역할에 공통 pre-tool policy 배선 |
| asset rule 조회 장애 | intent는 거부, insert는 해당 rule 없이 진행 가능 | 동일한 fail-closed 정책과 오류 관측 |
| rule 미매치 또는 DB rule 조회 장애 | judge off/unwired면 조용히 allow | 조회 오류를 분리 관측하고 필요한 action class는 fail-closed 적용 |
| judge 장애 | 기본 allow | fail-closed가 필요한 action class 정의 |
| tool 우회 | intercept-enabled 목록 밖 tool/MCP | capability inventory와 공통 hook 적용 확인 |
| unrecorded traffic | proxy fail-open/pass/direct path | egress와 evidence completeness marker |
| false positive finding | 즉시 confirmed | independent validator/retest gate |
| audit gap | append/drop/외부 tool | trace completeness metric과 reconciliation |
| token 노출 | localStorage, JS-readable/non-Secure cookie, 257개 operation의 query token fallback | XSS 완화, HTTPS 강제, access-log redaction, 저장·전달 방식 재설계 |