보안 및 규정 준수
무엇이, 어떻게, 누구의 책임 하에 보호되는지 — 보안 검토를 위한 안내입니다.
보안 및 규정 준수
이 페이지는 보안 검토 담당자, IT 관리자, 그리고 "이것을 도입해도 안전한가?"에 답해야 하는 모든 사람을 위한 것입니다.
한 문장으로 보는 위협 모델
ObjectOS는 당신의 네트워크 내부에서 단일 Node.js 프로세스로 실행되며, 당신의 데이터베이스와 통신하고, 절대 외부로 연락(call home)하지 않습니다. 침해가 발생했을 때의 피해 범위(blast radius)는 연결된 데이터베이스의 데이터에 한정됩니다 — 그 이상은 없습니다.
데이터 레지던시
| 데이터 분류 | 저장 위치 | 네트워크를 벗어나는가? |
|---|---|---|
| 비즈니스 레코드 | 당신의 데이터베이스 | 아니요 |
| 사용자 계정, 세션, OAuth 토큰 | 당신의 데이터베이스 | 아니요 |
| 감사 로그 | 당신의 데이터베이스 | 아니요 |
| 설정, API 키 | 당신의 데이터베이스 / 당신의 시크릿 매니저 | 아니요 |
| 업로드된 파일 | 당신의 디스크 또는 S3 호환 버킷 | 아니요 |
| 텔레메트리 / 사용 데이터 | — | 수집하지 않음 |
ObjectOS는 명시적으로 구성하지 않는 한 외부로의 호출을 전혀 하지 않습니다(OIDC 디스커버리, 이메일 공급자, AI 공급자, 웹훅 대상, 외부 스토리지). 외부로 연락하지 않고, 라이선스 서버를 확인하지 않으며, 업데이트를 위해 핑을 보내지도 않습니다.
암호화
| 계층 | 메커니즘 | 책임 주체 |
|---|---|---|
| 전송 중 (브라우저 ↔ ObjectOS) | TLS, 당신의 엣지 / 인그레스에서 종료 | 당신 |
| 전송 중 (ObjectOS ↔ 데이터베이스) | 드라이버 수준 TLS (Postgres sslmode=require, MongoDB tls=true, …) | 당신 — 연결 문자열을 설정 |
| 저장 시 (비즈니스 데이터) | 데이터베이스 네이티브 (예: Postgres TDE, RDS 암호화) | 당신 |
| 저장 시 (업로드된 파일) | 스토리지 네이티브 (S3 SSE, R2 기본값, 디스크 수준 FDE) | 당신 |
| DB 내 시크릿 (설정, OIDC 클라이언트 시크릿) | 설정 서비스에 의해 암호화됨 | ObjectOS |
| 세션 쿠키 / 토큰 | OS_AUTH_SECRET로 HMAC 서명됨 | ObjectOS |
| API 키 값 | DB에 해시 처리됨 — 유출된 DB 행으로는 키를 복원할 수 없음 | ObjectOS |
인증
기본 제공 (@objectstack/plugin-auth를 통해, Better Auth 기반):
- 검증 + 재설정이 포함된 이메일/비밀번호
- 취소(revocation) 기능이 있는 세션 관리
- 소셜 OAuth (Google, GitHub, Microsoft, Apple, …)
- 엔터프라이즈 OIDC/SSO (Okta, Entra ID, Keycloak, Ping)
- 2단계 인증 (TOTP)
- 패스키 / WebAuthn
- 매직 링크
- CLI/브라우저 디바이스 플로우
- API 키 (해시 처리됨, 만료 가능, 취소 가능, 사용자에 바인딩됨)
Authentication을 참조하세요.
권한 부여
계층화된 적용 (@objectstack/plugin-security를 통해):
- 오브젝트 권한 — 권한 집합별, 오브젝트별 CRUD
- 행 수준 보안 — 쿼리에 주입되는 선언적 정책 표현식이며, 선택 사항이 아닙니다
- 필드 수준 보안 — 응답에서 제거되거나 쓰기 시 거부되는 필드
- 조직 범위 지정 — 멀티 테넌트 격리; 우회하려면 명시적인
viewAllRecords가 필요함
시스템 컨텍스트 작업은 내부 작업 / 마이그레이션이 실행될 수 있도록 검사를 우회합니다 — 이러한 경로는 감사 가능합니다.
Permissions을 참조하세요.
감사 및 증거
감사 기능이 로드되면 (@objectstack/plugin-audit):
- 모든 오브젝트에 걸친 모든 CRUD 작업 → 감사 행.
- 필드 변경에 대한 변경 전/후 값.
- 인증, 권한 부여, 세션 취소 이벤트.
- 감사 행은 **불변(immutable)**입니다: 수정할 수 없으며 아카이브만 가능합니다.
- 보존 기간은 구성 가능하며, DB의 아카이브 정책과 함께 사용하세요.
이것은 SOC 2 CC6/CC7, ISO 27001 A.12.4, HIPAA §164.312(b), GDPR 제30조에 대한 증거 기반이 됩니다.
규정 준수 프레임워크
ObjectOS는 모든 일반적인 프레임워크가 요구하는 **기술적 기본 요소(primitives)**를 제공합니다. 인증(certification)은 소프트웨어가 아닌 배포의 속성이지만, 컨트롤은 깔끔하게 매핑됩니다:
| 프레임워크 | ObjectOS가 제공하는 것 |
|---|---|
| SOC 2 | 접근 제어 (CC6), 변경 관리 (감사 로그), 암호화 (배포), 모니터링 (옵저버빌리티), 백업 (운영/백업) |
| ISO 27001 | A.5 정책 (RBAC), A.8 자산 관리 (오브젝트 카탈로그), A.9 접근 제어, A.12 운영, A.18 준수 |
| HIPAA | 접근 제어 (§164.312(a)), 감사 제어 (§164.312(b)), 무결성 (불변 감사), 전송 보안 (TLS) |
| GDPR | 제30조 처리 기록 (감사), 제32조 처리의 보안, 제17조 삭제권 (소프트 + 하드 삭제 지원), 데이터 레지던시 (리전을 선택) |
| CCPA / 중국 DSL / 러시아 152-FZ | 올바른 리전에서의 셀프 호스팅이 레지던시 요건을 충족하며, 접근 제어 + 감사가 대부분의 보고 의무를 커버합니다 |
ObjectOS 자체는 인증되지 않았습니다. 인증은 바이너리가 아닌 실행 중인 배포에 대한 것이기 때문입니다. 당신의 배포는 인증받을 수 있으며 — 이미 인증받은 곳도 많습니다.
시크릿 처리
| 시크릿 | 보관 위치 |
|---|---|
OS_AUTH_SECRET | 당신의 시크릿 매니저 (Vault, AWS Secrets Manager, k8s Secret); 환경 변수로 주입 |
| 자격 증명이 포함된 데이터베이스 URL | 위와 동일 |
| OIDC 클라이언트 시크릿 | 위와 동일 |
| OAuth 공급자 시크릿 | 위와 동일 |
| API 공급자 키 (이메일, 스토리지, AI) | 위와 동일 |
| DB에 저장된 설정 | 설정 서비스에 의해 저장 시 암호화됨 |
시크릿을 아티팩트(objectstack.json), Docker 이미지, compose 파일, 또는
Git에 절대 포함하지 마세요. Console의 설정 UI는 환경 변수로 관리되는
값을 잠금 상태로 표시하므로, 운영자가 실수로 이를 재정의할 수 없습니다.
네트워크 모델
필수 인바운드:
- 당신의 인그레스 / 로드 밸런서에서 ObjectOS의
:3000(기본값)으로의 HTTPS.
필수 아웃바운드 (다음 기능을 구성하는 경우에만):
- 당신의 데이터베이스 (Postgres / Mongo / Turso / …).
- S3 호환 스토리지 (
storage기능이 S3 어댑터와 함께 활성화된 경우). - OIDC 디스커버리 URL (SSO가 활성화된 경우).
- 이메일 공급자 API (Resend / Postmark).
- AI 공급자 API (OpenAI / Anthropic / Google / …).
- 웹훅 대상.
이것이 전체 이그레스(egress) 표면입니다. 이보다 더 많은 것을 차단하는 배포에 대해서는 Air-gapped를 참조하세요.
AI: 도구, 승인, 격리
AI Builder는 당신이 노출하게 될 가장 보안에 민감한 표면이므로, 위의 모든 것에 더해 자체적인 적용 계층을 가지고 있습니다.
AI가 상태를 변경하는 방법
모델은 당신의 데이터베이스에 직접 쓸 수 없습니다. 상태가 변경되는 유일한 방법은 구조화된 도구 호출을 발행하는 것이며, AI 서비스가 이를 수신하고, 검증하고, 큐에 넣습니다. 그 연쇄 과정은 다음과 같습니다:
user prompt
→ model emits tool call (e.g. add_field { object: 'ticket', name: 'severity', type: 'select' })
→ AI service validates payload against the tool's Zod schema
→ if the tool is "mutating": queue as pending action (no state change yet)
→ human reviewer approves → mutation applied → audit row written
→ if the tool is "read-only": run immediately, response returned to model11개의 기본(first-party) 메타데이터 도구
(Build → AI Builder 참조)와 더불어, 선언된
액션당 하나의 action_<name> 도구가 있습니다. 모든 도구 — 기본이든
커스텀이든 — 는 동일한 생명 주기를 갖습니다.
권한 키
| 키 | 부여 내용 |
|---|---|
ai:chat | 대화 진행; 모델 소비; 에이전트가 읽기 전용 도구를 호출하도록 허용 |
ai:complete | 원시 컴플리션 엔드포인트 (에이전트 루프 없음) |
ai:conversations | 대화 목록 조회 / 검사 / 삭제 (RBAC 범위에 따라 본인 또는 전체) |
ai:agents | 에이전트 메타데이터 관리 (호출하려면 ai:chat과 함께) |
ai:tools | 도구 카탈로그 목록 조회 |
ai:execute | REST를 통해 도구를 직접 호출 (고급 — 보통 앰비언트 에이전트만 필요) |
ai:read | 대기 중 액션 큐 및 모델 목록 읽기 |
ai:approve | 큐에 들어간 변경 승인 / 거부 |
ai:admin | 전체 AI 서비스 관리 |
핵심적인 구분은 **ai:chat ≠ ai:approve**입니다. 어시스턴트가 작동하도록
대부분의 사용자에게 ai:chat을 부여하고, 구조적 변경을 검토해야 하는
관리자 / 앱 소유자에게는 ai:approve를 따로 두세요. 따라서 최종 사용자는
안전하게 "바이브 빌드(vibe-build)"할 수 있습니다 — 그들이 할 수 있는 최악의
일은 다른 누군가가 수락해야 하는 잘못된 변경을 큐에 넣는 것뿐입니다.
테넌트 격리
- 에이전트, 대화, 지식 베이스, 대기 중 액션은 하나의 Environment(테넌트)로 범위가 지정됩니다. 테넌트 A는 테넌트 B의 대화, AI가 제안한 도구, 또는 지식 코퍼스를 볼 수 없습니다 — 동일한 marketplace 패키지에서 동일한 에이전트 정의가 설치되었더라도 마찬가지입니다.
- 메타데이터 도구(
create_object,add_field, …)는 호출자의 테넌트 내 활성 패키지에 대해 작동합니다. 그 외부에는 도달할 수 없습니다. - 도구 입력은 CEL로 검증되며, 엔진은 예약된 시스템 패키지(
sys.*) 또는 다른 테넌트의 오브젝트 이름에 대한 참조를 거부합니다.
감사 이벤트
감사 기능이 로드되면:
ai.chat.message— 모든 사용자 / 어시스턴트 메시지, 모델 + 토큰 수 포함ai.tool.call— 도구 이름, 검증된 입력, 전체 출력 (또는 오류)ai.pending_action.queued— 제안된 변경, 전체 diffai.pending_action.approved/.rejected— 누가, 언제, 왜 결정했는지ai.metadata.applied— 메타데이터 스토어에 대한 실제 쓰기, diff 포함
이 행들은 불변이며 보안 검토나 차지백(chargeback)을 위해 내보낼 수 있습니다. (공급자, 모델, 사용자)별 토큰 수는 비용 귀속(cost attribution)에 활용됩니다.
프롬프트 인젝션 대응 태세
간접 프롬프트 인젝션(예: 에이전트가 검색하는 문서 내의 악성 콘텐츠)은 실제 위험입니다. ObjectOS는 구조적으로 피해 범위를 줄입니다:
- AI는 도구 검증을 우회할 수 없습니다 — 악성 페이로드를 발행하도록 설득당하더라도, Zod 스키마가 엔진에 도달하기 전에 잘못된 입력을 거부합니다.
- 변경(mutating) 도구는 항상 큐에 들어갑니다. 주입된 프롬프트는 조용히 데이터베이스에 쓸 수 없습니다.
- 도구 호출은 모델의 서비스 계정 권한이 아닌 최종 사용자의 권한을 상속합니다. 사용자는 Console이나 REST를 통해 스스로 할 수 없는 일을 AI를 사용해 결코 할 수 없습니다.
- 에이전트에 로드된 스킬은 버전 관리되고 명시적입니다 — Build → IDE Skills와 Build → AI Builder를 참조하세요.
외부 AI 공급자 데이터 흐름
공급자(OpenAI, Anthropic, …)를 구성하면, 다음 항목만 당신의 네트워크를 벗어납니다:
- 모델이 필요로 하는 대화 기록 (당신의 AI 서비스
redact구성에 따름 — Configure → AI 참조) - 도구 정의 (이름, JSON 스키마 — 레코드 데이터 없음)
- 모델이 계속 진행하는 데 필요한 도구 출력 (예: 사용자가 명시적으로 요청한 쿼리 결과)
에어갭 배포의 경우, AI 서비스를 로컬 Ollama / vLLM / TGI 엔드포인트로 지정하면 동일한 흐름이 당신의 경계 내부에 머무릅니다.
취약점 공개
보안 문제는 security@objectstack.ai로 비공개로 신고하세요. 영업일 기준 1일 이내에 응답합니다. 보안 문제에 대해 공개 GitHub 이슈를 작성하지 마세요.
공급망
- github.com/objectstack-ai/objectos에서 재현 가능한 빌드 출처(provenance)와 함께 게시된 사전 빌드 이미지.
- 모든
@objectstack/*패키지는 GitHub에 소스가 공개되어 있습니다 — Apache-2.0, 난독화 없음. - 드리프트를 방지하기 위해 프로덕션에서는 SHA로 고정된 이미지 태그
(
sha-<short>)를 사용하세요. Docker를 참조하세요.
권장 하드닝 체크리스트
- 실제 인증서로 엣지에서 TLS 종료.
-
OS_AUTH_SECRET은 32바이트 이상의 랜덤 값이며, 시크릿 매니저에 보관됨. - 데이터베이스 연결이 TLS를 사용함.
- TLS 검증 후 HSTS 활성화됨.
- CORS 오리진이 명시적임 (자격 증명과 함께
*를 절대 사용하지 않음). - 인증 엔드포인트에 속도 제한 적용 (
10/min/IP권장). - 감사 보존 기간이 정책과 일치함.
- 사람 계정에는 OIDC; 머신 계정에는 API 키.
- 백업 + 복원 훈련을 실행하고 시간을 측정함.
- 네거티브 테스트: 조직 간 접근 거부, 필드 보안 유지, 만료된 세션 거부.
- 이미지가
sha-<short>또는 semver 태그로 고정됨. - 각 릴리스 전 CI에서
os doctor가 깨끗함.
전체 출시 체크리스트는 Production Readiness를 참조하세요.