비용, 감사, ClawHub, 자격 증명 API
비용 추적 및 예산 상태, 감사 로그 조회/검증, ClawHub 마켓플레이스, 암호화된 자격 증명 및 gcloud 설정 저장소.
이 엔드포인트들은 실행 중인 Revka 게이트웨이의 운영 및 보안 영역을 담당합니다: 에이전트의 비용 지출 현황, 보안 관련 이벤트의 변조 방지 감사 추적, ClawHub 스킬 마켓플레이스, 그리고 워크플로우 자격 증명과 Cloud Run 설정을 지원하는 두 가지 메타데이터 전용 저장소가 포함됩니다. 이를 활용해 대시보드의 비용 및 감사 페이지를 구동하거나, 자체 도구로 지출 데이터를 수집하거나, 커뮤니티 스킬을 설치하거나, 워크플로우 단계를 암호화된 자격 증명에 연결할 수 있습니다.
여기에 있는 대부분의 라우트는 페어링 흐름에서 발급된 bearer 토큰을 필요로 합니다. 일부는 의도적으로 다르게 동작합니다: GET /api/cost는 인증 없이 읽기 전용 텔레메트리를 제공하며, 비용 수집 및 자격 증명 확인 엔드포인트는 사용자 bearer 토큰이 아닌 내부 서비스 토큰을 요구합니다 — 이 경우 명시적으로 안내되어 있습니다. 비용 및 관찰 가능성 설정에 대해서는 비용 추적 및 예산과 관찰 가능성 및 트레이싱을 참고하세요. 감사 로그 내부 구조는 감사 로그를 참고하세요.
모든 /api/* 라우트는 64 KiB의 요청 본문 제한과 설정 가능한 타임아웃(기본값 30초, 환경 변수 REVKA_GATEWAY_TIMEOUT_SECS)을 공유하며, 일부 라우트에는 별도 오버라이드가 있습니다.
비용 추적
섹션 제목: “비용 추적”Revka는 모든 LLM API 호출의 토큰 수와 계산된 USD 비용을 <workspace>/state/costs.jsonl에 JSONL 원장으로 저장합니다. 추적기는 세션, 일별, 월별 합계를 집계하고 모델별, 에이전트별, 런타임 소스별(gateway, channel, sidecar)로 지출을 분류합니다. 프로세스 전역 싱글톤이 게이트웨이와 채널 경로가 단일 원장과 단일 예산 확인을 공유하도록 보장합니다. 레거시 .revka/costs.db 저장소는 첫 시작 시 자동으로 마이그레이션되며, 잘못된 형식의 JSONL 줄은 읽기 실패 대신 경고와 함께 건너뜁니다.
비용은 [cost.prices] 아래에 설정된 모델별 가격을 사용하여 (tokens / 1_000_000) × price_per_million으로 계산됩니다. 모델 조회는 퍼지 매칭 방식으로 동작합니다: 정확히 일치하는 항목, provider/model 형식, / 이후의 접미사, 접두사 순으로 시도합니다. 일치하는 가격 항목이 없으면 해당 레코드는 비용 0으로 저장됩니다(디버그 로그 기록).
게이트웨이 비용 엔드포인트
섹션 제목: “게이트웨이 비용 엔드포인트”GET /api/cost는 비용 요약을 반환합니다. 인증이 필요하지 않습니다 — 이는 대시보드가 사용하는 읽기 전용 운영자 텔레메트리입니다. 비용 추적이 비활성화된 경우, 오류 대신 완전히 0으로 채워진 요약을 반환합니다(budget.state가 "disabled"로 설정), 이를 통해 대시보드가 정상적으로 저하됩니다.
GET /api/cost{ "cost": { "session_cost_usd": 0.42, "daily_cost_usd": 1.87, "monthly_cost_usd": 12.34, "total_tokens": 184320, "request_count": 57, "by_model": { }, "by_agent": { }, "by_source": { }, "budget": { "enabled": true, "daily_limit_usd": 10.0, "monthly_limit_usd": 100.0, "warn_at_percent": 80, "daily_remaining_usd": 8.13, "monthly_remaining_usd": 87.66, "daily_percent": 18.7, "monthly_percent": 12.34, "state": "ok" } }}by_model, by_agent, by_source 분류는 현재 프로세스 수명 기간만 집계합니다. daily_cost_usd와 monthly_cost_usd는 전체 원장에서 읽어옵니다. 소스 태그가 없는 레코드는 by_source에서 "runtime"으로 분류됩니다.
신뢰할 수 있는 사이드카(예: operator-mcp 런타임)에서 공유 원장으로 토큰 사용량을 전달하려면 POST /api/cost/usage를 사용하세요. 이 엔드포인트는 예산 원장을 변경하므로 서비스 토큰으로 제한됩니다 — bearer 토큰이 아닌 X-Revka-Service-Token 헤더에 전달해야 합니다.
POST /api/cost/usageX-Revka-Service-Token: <service-token>Content-Type: application/json{ "model": "gpt-4o", "provider": "openai", "input_tokens": 1000, "output_tokens": 250, "source": "sidecar", "agent_id": "my-agent", "agent_title": "My Agent"}model만 필수입니다. provider와 source는 생략하거나 비워두면 "sidecar"로 기본 설정됩니다. 수집에 성공하면 { "recorded": true, "usage": { ... } }를 반환합니다. 비용 추적이 비활성화된 경우 200과 함께 { "recorded": false, "reason": "cost tracking disabled" }를 반환하며, 유효한 서비스 토큰이 없는 요청은 401을 반환합니다.
예산 적용
섹션 제목: “예산 적용”예산은 [cost] 섹션에서 설정하며, 전역 추적기에 의해 세션이 아닌 프로세스 단위로 적용됩니다. 경고 및 초과 임계값은 현재 사용량만이 아니라 예상 합계(현재 사용량 + 대기 중인 호출의 예상 비용)와 비교됩니다.
[cost]enabled = truedaily_limit_usd = 10.0 # defaultmonthly_limit_usd = 100.0 # defaultwarn_at_percent = 80 # warn at 80% of a limitallow_override = false # allow a --override flag to bypass
[cost.enforcement]mode = "warn" # "warn" | "block" | "route_down"route_down_model = "gpt-4o-mini" # used with "route_down"reserve_percent = 10 # reserve 10% for critical ops
[cost.prices]"claude-sonnet-4-20250514" = { input = 3.0, output = 15.0 } # USD per 1M tokens"gpt-4o" = { input = 2.5, output = 10.0 }mode 설정은 한도 초과 시 동작을 제어합니다:
| 모드 | 예산 초과 시 동작 |
|---|---|
warn | 경고를 기록하고 요청을 허용합니다 (기본값) |
block | 요청을 거부합니다 |
route_down | 더 저렴한 route_down_model로 전환합니다 |
비용 요약의 budget.state 필드는 현재 상태를 반영합니다: "ok", "warning" (warn_at_percent 초과), "exceeded" (한도 초과), 또는 "disabled". 전체 설정 참조 및 가격 테이블 형식은 비용 추적 및 예산을 참고하세요.
감사 로그
섹션 제목: “감사 로그”감사 로그는 보안 관련 이벤트(명령 실행, 파일 접근, 설정 변경, 인증 성공/실패, 정책 위반, 일반 보안 이벤트)의 추가 전용 변조 방지 기록입니다. 각 항목은 SHA-256 해시 체인(entry_hash = SHA-256(prev_hash || canonical_JSON_of_content))으로 연결되며 단조 증가하는 sequence를 가지므로, 과거 항목을 수정하면 이후의 모든 항목이 무효화됩니다. 항목은 선택적으로 HMAC-SHA256으로 서명할 수 있습니다. 로그를 사용하려면 설정에서 [security.audit] enabled = true가 필요합니다(기본값).
[security.audit]enabled = true # defaultlog_path = "audit.log" # relative to the revka dirmax_size_mb = 100 # rotate at this sizesign_events = false # optional HMAC-SHA256 signingGET /api/audit는 bearer 토큰 인증 후 최근 이벤트를 최신순으로 반환합니다.
GET /api/audit?limit=50&event_type=command_execution&since=2026-01-01T00:00:00ZAuthorization: Bearer <token>| 파라미터 | 타입 | 기본값 | 설명 |
|---|---|---|---|
limit | int | 50 (최대 500) | 반환할 최대 이벤트 수 |
event_type | string | — | 타입으로 필터링 (아래 참조) |
since | RFC 3339 | — | 이벤트 타임스탬프의 하한값 |
event_type은 command_execution, file_access, config_change, auth_success, auth_failure, policy_violation, 또는 security_event를 허용합니다. 응답은 이벤트 목록에 개수와 audit_enabled 플래그를 함께 반환합니다:
{ "events": [ { "timestamp": "2026-06-18T10:00:00Z", "event_id": "<uuid>", "event_type": "command_execution", "actor": { "channel": "telegram", "user_id": "123", "username": "@alice" }, "action": { "command": "ls -la", "risk_level": "low", "approved": false, "allowed": true }, "result": { "success": true, "exit_code": 0, "duration_ms": 15 }, "security": { "policy_violation": false, "rate_limit_remaining": 19, "sandbox_backend": "firejail" }, "sequence": 42, "prev_hash": "<64 hex>", "entry_hash": "<64 hex>", "signature": "<64 hex>" } ], "count": 1, "audit_enabled": true}signature 필드는 sign_events = true일 때만 포함됩니다. 감사 로깅이 비활성화된 경우, 엔드포인트는 빈 events 배열, count: 0, audit_enabled: false와 함께 200을 반환합니다 — 감사가 비활성화된 경우에도 대시보드가 오류를 반환하지 않습니다.
감사 /verify
섹션 제목: “감사 /verify”GET /api/audit/verify는 온디스크 로그를 순회하며 해시 체인을 처음부터 끝까지 검증합니다. 변조를 감지하는 가장 빠른 방법입니다: 항목이 수정, 삭제, 또는 순서가 변경된 경우 검증이 실패합니다.
GET /api/audit/verifyAuthorization: Bearer <token>{ "verified": true, "entry_count": 1842 }체인이 손상된 경우(또는 감사가 활성화되지 않은 경우), verified: false와 함께 실패 내용을 설명하는 error를 반환합니다:
{ "verified": false, "error": "chain broken at sequence 41" }HMAC 서명을 활성화하려면 게이트웨이 시작 전에 REVKA_AUDIT_SIGNING_KEY 환경 변수에 32바이트 키(64자리 16진수)를 설정하세요 — 로거는 생성 시점에 이를 읽으며, 키가 누락되거나 길이가 잘못된 경우 시작이 실패합니다. 로그 로테이션은 체인을 genesis로 초기화하므로, 각 로테이션된 .N.log 아카이브는 독립적으로 검증할 수 있습니다. 체인 형식, 서명 설정, CLI 검증에 대해서는 감사 로그를 참고하세요.
ClawHub 마켓플레이스
섹션 제목: “ClawHub 마켓플레이스”ClawHub는 clawhub.ai의 스킬 마켓플레이스입니다. 이 라우트들은 마켓플레이스 API를 프록시하여 스킬을 검색하고, 트렌딩 스킬을 탐색하고, 상세 정보를 확인하고, 원클릭으로 로컬 Kumiho 메모리 및 워크스페이스에 스킬을 설치할 수 있습니다. 네 가지 라우트 모두 bearer 토큰이 필요합니다.
GET /api/clawhub/search?q=rust+debugging&limit=20GET /api/clawhub/trending?limit=20GET /api/clawhub/skills/{slug}POST /api/clawhub/install/{slug}Authorization: Bearer <token>| 파라미터 | 위치 | 기본값 | 설명 |
|---|---|---|---|
q | query | 필수 (검색 시) | 검색어 |
limit | query | 20 | 최대 결과 수 |
slug | path | — | ClawHub 스킬 슬러그 |
GET /api/clawhub/skills/{slug}는 스킬 상세 정보를 반환하며, 사용 가능한 경우 렌더링된 SKILL.md를 skill_md 필드에 첨부합니다. POST /api/clawhub/install/{slug}는 스킬의 SKILL.md를 가져와 ~/.revka/workspace/skills/<slug>.md에 저장하고, Kumiho memory_project의 Skills 공간에 스킬을 아이템으로 등록(published로 리비전 태그 지정)한 후 다음을 반환합니다:
{ "installed": true, "slug": "rust-debugging", "name": "Rust Debugging", "kref": "kref://CognitiveMemory/Skills/rust-debugging.skill", "description": "Systematic Rust debugging workflow"}ClawHub가 비활성화된 경우 라우트는 400과 {"error": "ClawHub integration disabled"}를 반환하며, 마켓플레이스에 연결할 수 없는 경우 502를 반환합니다.
[clawhub] 설정
섹션 제목: “[clawhub] 설정”[clawhub]enabled = true # defaultapi_url = "https://clawhub.ai" # default — base URL for the ClawHub APIapi_token = "clh_..." # optional; only required to publish skills| 키 | 타입 | 기본값 | 설명 |
|---|---|---|---|
enabled | bool | true | ClawHub 통합 활성화 |
api_url | string | "https://clawhub.ai" | ClawHub API의 기본 URL (사설 인스턴스를 사용하는 경우 변경) |
api_token | string? | 미설정 | clh_… 토큰; 스킬 게시 시에만 필요 — 익명 탐색 및 설치는 토큰 없이 동작 |
설치된 스킬은 대시보드에서 생성된 스킬과 동일한 등록 경로를 사용하므로, 스킬, 도구 및 통합 페이지와 스킬 API에 표시됩니다.
인증 프로필 — 자격 증명 저장소
섹션 제목: “인증 프로필 — 자격 증명 저장소”인증된 서비스를 호출하는 워크플로우 단계는 인증 프로필에 바인딩됩니다: 게이트웨이의 SecretStore를 통해 ChaCha20-Poly1305 AEAD로 저장 시 암호화된 자격 증명입니다. 저장소는 서로 다른 신뢰 수준을 가진 두 가지 인터페이스로 나뉩니다 — bearer 인증 메타데이터 뷰, 그리고 자격 증명을 복호화하는 유일한 수단인 서비스 토큰 전용 resolve 경로입니다.
GET /api/auth/profiles # list metadata (bearer)POST /api/auth/profiles # create a static-token profile (bearer)DELETE /api/auth/profiles/{id} # delete a profile (bearer)POST /api/auth/profiles/{id}/resolve # decrypt the credential (service token only)GET /api/auth/profiles는 메타데이터 요약을 반환합니다 — 토큰 필드가 없음에 유의하세요:
{ "profiles": [ { "id": "github:My Token", "provider": "github", "profile_name": "My Token", "kind": "token", "account_id": null, "workspace_id": null, "expires_at": null, "created_at": "2026-06-18T10:00:00Z", "updated_at": "2026-06-18T10:00:00Z" } ]}POST /api/auth/profiles는 정적 토큰(API 키) 프로필을 생성합니다. 평문 token은 저장 전에 저장소에서 암호화되며 응답에 포함되지 않습니다. 응답은 새 메타데이터 요약과 201 Created입니다.
POST /api/auth/profilesAuthorization: Bearer <token>Content-Type: application/json{ "provider": "github", "profile_name": "My Token", "token": "ghp_..." }| 필드 | 필수 여부 | 참고 |
|---|---|---|
provider | 예 | 공급자 식별자, 예: github |
profile_name | 예 | 사람이 읽을 수 있는 레이블; provider와 결합하여 id를 형성 |
token | 예 | 원시 bearer / API 키 (저장 시 암호화) |
account_id | 아니요 | 선택적 계정 힌트 |
kind | 아니요 | 기본값은 "token". "api_key"는 동의어. "oauth"는 400으로 거부됩니다 — OAuth 프로필은 /config 동의 흐름을 통해 생성해야 합니다 |
처리가 필요한 생성 응답: 필드 누락 또는 지원되지 않는 kind의 경우 400, 동일한 provider+profile_name 프로필이 이미 존재하는 경우 409, 그리고 IP당 속도 제한 도달 시 429(60초 내 10회 시도 후 5분 잠금, 루프백 호출자는 제외). 제한기는 소켓 피어만 신뢰하며 X-Forwarded-For는 무시합니다.
POST /api/auth/profiles/{id}/resolve는 자격 증명을 복호화하여 반환합니다. X-Revka-Service-Token 헤더(상수 시간 비교)가 필요하며, 중간 요소가 비밀을 캐시하지 않도록 응답에 Cache-Control: no-store를 설정합니다.
POST /api/auth/profiles/{id}/resolveX-Revka-Service-Token: <service-token>{ "token": "ghp_...", "kind": "token", "provider": "github", "profile_name": "My Token", "expires_at": null}알 수 없는 id는 404를 반환합니다. 빈 정적 토큰은 410 Gone(auth_profile_empty 코드 포함)을 반환하며, expires_at이 과거인 OAuth 프로필은 410 Gone(auth_profile_expired 코드 포함)을 반환합니다. 이를 통해 런타임이 만료된 자격 증명을 전송하는 대신 해당 단계를 실패 처리합니다.
서비스 토큰은 게이트웨이 시작 시 생성되어 <state_dir>/service-token에 저장됩니다(POSIX에서 모드 0600). 이는 사용자 대상 페어링 bearer 토큰과 구별됩니다 — 페어링 및 인증과 보안 모델을 참고하세요.
GCloud 설정 프로필
섹션 제목: “GCloud 설정 프로필”이 메타데이터 전용 엔드포인트들은 호스트의 gcloud SDK 설정 프로필을 나열하고 생성하며, 워크플로우 편집기의 Cloud Run / A2A IAM 선택기를 지원합니다. gcloud 설정은 로컬 Cloud SDK 자격 증명 저장소의 자격 증명을 참조하지만 그 자체는 비밀이 아니므로, 응답에는 표시 메타데이터만 포함됩니다 — 액세스, 리프레시, 또는 ID 토큰은 포함되지 않습니다. 두 라우트 모두 bearer 토큰과 20초 타임아웃으로 gcloud를 실행합니다.
GET /api/gcloud/configsPOST /api/gcloud/configsAuthorization: Bearer <token>GET /api/gcloud/configs는 gcloud config configurations list를 실행하고 파싱된 설정을 반환합니다. gcloud가 PATH에 없으면 오류 대신 available: false를 반환하여 UI가 해당 기능을 숨길 수 있습니다:
{ "available": true, "configs": [ { "name": "default", "is_active": true, "project": "construct-498201", "run_region": "us-central1", "compute_region": "us-central1" } ], "error": null}POST /api/gcloud/configs는 새 설정을 생성하고(gcloud config configurations create --no-activate) 제공된 속성을 설정합니다.
POST /api/gcloud/configsAuthorization: Bearer <token>Content-Type: application/json{ "name": "my-config", "project": "my-gcp-project", "run_region": "us-central1", "compute_region": "us-central1"}| 필드 | 필수 여부 | 참고 |
|---|---|---|
name | 예 | ASCII 영숫자와 -, _, .; 문자 또는 숫자로 시작해야 함; 최대 64자 |
project | 예 | GCP 프로젝트 ID (core/project) |
account | 아니요 | 계정 이메일 (core/account) |
run_region | 아니요 | Cloud Run 리전 (run/region) |
compute_region | 아니요 | 컴퓨트 리전 (compute/region) |
성공 시 응답은 생성된 GcloudConfigSummary와 201입니다. 중복 이름은 409를 반환하고, gcloud 바이너리가 없으면 503(gcloud_not_found 코드)을 반환하며, 잘못된 입력은 특정 코드와 함께 400을 반환합니다(예: gcloud_config_invalid_name).
엔드포인트 요약
섹션 제목: “엔드포인트 요약”| 메서드 및 경로 | 인증 | 용도 |
|---|---|---|
GET /api/cost | 없음 | 비용 요약 및 예산 상태 |
POST /api/cost/usage | 서비스 토큰 | 사이드카 토큰 사용량을 원장에 수집 |
GET /api/audit | bearer | 최근 감사 이벤트 (필터링 가능) |
GET /api/audit/verify | bearer | 감사 해시 체인 검증 |
GET /api/clawhub/search | bearer | ClawHub 스킬 검색 |
GET /api/clawhub/trending | bearer | ClawHub 트렌딩 스킬 |
GET /api/clawhub/skills/{slug} | bearer | ClawHub 스킬 상세 정보 |
POST /api/clawhub/install/{slug} | bearer | 로컬 Kumiho에 스킬 설치 |
GET /api/auth/profiles | bearer | 자격 증명 프로필 메타데이터 목록 조회 |
POST /api/auth/profiles | bearer | 정적 토큰 자격 증명 프로필 생성 |
DELETE /api/auth/profiles/{id} | bearer | 자격 증명 프로필 삭제 |
POST /api/auth/profiles/{id}/resolve | 서비스 토큰 | 자격 증명 복호화 및 반환 |
GET /api/gcloud/configs | bearer | gcloud 설정 프로필 목록 조회 |
POST /api/gcloud/configs | bearer | gcloud 설정 프로필 생성 |
관련 페이지
섹션 제목: “관련 페이지”- 게이트웨이 API 개요 — 전송 방식, 인증 모델, 라우트 규칙
- 상태, 헬스, 설정 및 도구 엔드포인트 — 헬스, 닥터, 메트릭, 설정
- 비용 추적 및 예산 —
[cost]설정 참조 - 관찰 가능성 및 트레이싱 — 메트릭 백엔드 및 비용 원장
- 감사 로그 — 체인 형식, 서명, CLI 검증
- 보안 모델 — bearer 토큰 vs. 서비스 토큰 및 비밀 저장소
- 워크플로우 및 Architect API — 단계에서 인증 프로필이 사용되는 방식