엔터프라이즈 보안
JamJet의 멀티 테넌트 격리, PII 삭제, OAuth 위임, mTLS 연합, 데이터 보존 정책.
엔터프라이즈 보안
JamJet의 엔터프라이즈 기능은 Rust 런타임 레이어에서 강제됩니다 — 규약이나 잊어버릴 수 있는 미들웨어가 아닙니다.
멀티 테넌트 격리
모든 스토리지를 테넌트 ID별로 분할합니다. 워크플로 정의, 실행 상태, 이벤트 로그, 감사 추적, 스냅샷은 테넌트별로 범위가 지정됩니다.
# 동일한 워크플로, 다른 테넌트 — 완전히 격리됨
jamjet run workflow.yaml \
--input '{"invoice_id": "INV-001", "amount": 2500}' \
--tenant acme
jamjet run workflow.yaml \
--input '{"invoice_id": "INV-042", "amount": 75000}' \
--tenant globex런타임의 TenantScopedSqliteBackend는 모든 스토리지 쿼리를 WHERE tenant_id = ?로 래핑합니다. 워크플로 정의 테이블은 복합 기본 키 (tenant_id, workflow_id, version)를 사용합니다.
PII 삭제
워크플로에 data_policy를 선언하세요. 런타임은 상태가 감사 로그에 도달하기 전에 이를 적용합니다.
data_policy:
pii_detectors: [email, ssn, phone, credit_card, ip_address]
pii_fields: ["$.email", "$.ssn", "$.credit_card"]
redaction_mode: mask # 또는: hash, remove
retain_prompts: false # 감사 로그에서 프롬프트 제거
retain_outputs: false # 감사 로그에서 모델 출력 제거
retention_days: 90 # 90일 후 자동 삭제세 가지 삭제 모드:
| 모드 | 동작 | 예시 |
|---|---|---|
mask | 디버깅을 위한 부분 노출 | ***-**-6789 |
hash | 분석을 위한 SHA-256 가명화 | a3f2c91b...e71b |
remove | 필드 완전 삭제 | (필드 삭제됨) |
Python SDK 동등 코드:
@workflow(
id="customer-onboarding",
version="0.1.0",
data_policy={
"pii_detectors": ["email", "ssn", "phone", "credit_card"],
"pii_fields": ["$.email", "$.ssn"],
"redaction_mode": "mask",
"retain_prompts": False,
"retain_outputs": False,
"retention_days": 90,
},
)
class CustomerOnboarding:
...데이터 보관
retention_days는 모든 감사 로그 항목에 expires_at 타임스탬프를 설정합니다. 런타임의 purge_expired() 메서드는 백그라운드 작업으로 실행되어 만료일이 지난 항목을 삭제합니다.
추가 제어:
retain_prompts: false— 작성 전 감사 항목에서 모델 프롬프트 제거retain_outputs: false— 모델 출력도 동일하게 제거
감사 로그는 콘텐츠 없이 메타데이터(노드 ID, 토큰 수, 타임스탬프)를 보관합니다.
OAuth 2.0 위임
RFC 8693 토큰 교환. 사용자의 토큰이 범위가 좁은 에이전트 토큰으로 교환됩니다.
oauth:
token_endpoint: "${JAMJET_OAUTH_TOKEN_ENDPOINT}"
grant_type: "urn:ietf:params:oauth:grant-type:token-exchange"
client_id: "${JAMJET_OAUTH_CLIENT_ID}"
client_secret: "${JAMJET_OAUTH_CLIENT_SECRET}"
requested_scopes: ["expenses:read", "expenses:write"]범위 축소
에이전트의 유효 범위는 요청한 범위와 사용자가 가진 범위의 교집합입니다. 교집합이 비어 있으면 런타임이 OAuthError::ScopeNarrowingFailed를 반환합니다.
단계별 범위 지정
각 노드는 서로 다른 범위 요구 사항을 선언할 수 있습니다:
nodes:
authenticate:
oauth_scopes:
required_scopes: ["expenses:read"]
submit-expense:
oauth_scopes:
required_scopes: ["expenses:read", "expenses:write"]런타임은 워크플로우 시작 시 한 번이 아니라 모든 노드 실행 전에 범위를 확인합니다.
토큰 유효성
check_token_validity()는 모든 도구 및 모델 호출 전에 실행됩니다. 만료되거나 취소된 토큰은 명확한 오류(OAuthError::TokenExpired, OAuthError::TokenRevoked)를 생성하고 사람에게 에스컬레이션됩니다.
mTLS 및 A2A 페더레이션
조직 간 에이전트 통신:
전송: 상호 TLS. 양측 모두 인증서를 제시하고 양측 모두 검증합니다.
export JAMJET_TLS_CERT=/etc/certs/agent.pem
export JAMJET_TLS_KEY=/etc/certs/agent-key.pem
export JAMJET_TLS_CA_CERT=/etc/certs/ca.pem
export JAMJET_MTLS_REQUIRED=true애플리케이션: 에이전트 허용 목록이 포함된 기능 범위 지정 Bearer 토큰.
federation:
require_auth: true
public_agent_card: true
tokens:
- token: "tok-alpha"
name: "Research Agent"
agent_id: "agent-alpha"
scopes: ["read", "write"]
allowed_agents: ["agent-alpha"]
method_scopes:
"tasks/send": ["write"]
"tasks/get": ["read"]federation_auth_layer 미들웨어는 모든 수신 A2A 요청을 검증합니다. 권한이 없는 요청은 핸들러에 도달하기 전에 JSON-RPC 오류를 받습니다.
플러그형 시크릿 백엔드
우선순위를 지정하여 여러 시크릿 소스를 체인으로 연결합니다:
| 백엔드 | 사용 사례 |
|---|---|
| 환경 변수 | 로컬 개발, CI |
| 파일 기반 | Kubernetes 시크릿, 마운트된 볼륨 |
| HashiCorp Vault | 프로덕션 시크릿 관리 |
| AWS Secrets Manager | AWS 네이티브 배포 |
런타임은 시작 시 우선순위 순서대로 백엔드를 확인하여 시크릿을 확인합니다.
예제
각 엔터프라이즈 기능에 대한 실행 가능한 예제:
git clone https://github.com/jamjet-labs/examples
cd examples/multi-tenant # 테넌트 격리
cd examples/data-governance # PII 삭제 + 보존 정책
cd examples/oauth-delegation # OAuth 2.0 + 범위 축소tip: 전체 심화 가이드를 확인하세요: 데이터 거버넌스 및 PII 삭제, OAuth 위임 및 연합 인증.