JamJet

엔터프라이즈 보안

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 ManagerAWS 네이티브 배포

런타임은 시작 시 우선순위 순서대로 백엔드를 확인하여 시크릿을 확인합니다.


예제

각 엔터프라이즈 기능에 대한 실행 가능한 예제:

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 위임 및 연합 인증.

On this page