Summary
현재 JWT 인증(HS256 + exp/iss/aud)은 구현되어 있으나, 인가(Authorization)가 없음.
유효한 토큰만 있으면 namespace/service/capability 구분 없이 전체 API 접근 가능.
"인증은 있는데 인가가 없는" 전형적인 Broken Access Control
현재 상태
src/auth.ts: JWT 유효성만 검사, payload를 request.user에 붙이기만 함
src/k8s/routes.ts: target.namespace 기본값 "*" — cluster-wide 조회
/v1/pods: podIP, labels, annotations, nodeName 전체 반환
/v1/bundles, /download: scope 제한 없음
src/standalone/routes.ts: /v1/services 서비스 메타(metrics URL, logs 경로) 전체 노출
요구사항
JWT Claim 기반 권한 설계
{
"sub": "agent-01",
"allowedNamespaces": ["prod", "monitoring"],
"allowedServices": ["validator-*"],
"capabilities": ["pods", "logs", "events", "metrics"],
"admin": false
}
라우트별 적용
/v1/pods: allowedNamespaces + capabilities 에 pods 포함 필수
/v1/bundles: namespace/service scope 적용
/v1/bundles/:id/download: 동일 scope
/v1/services (standalone): allowedServices 필터링
namespace="*": admin: true 토큰에서만 허용
응답 축소 (관련 Medium 이슈 포함)
/v1/pods 기본 응답에서 annotations, nodeName, podIP 제거 (관리자 scope에서만)
/v1/services에서 metrics URL, logs 경로 등 민감 필드 축소
추가 보강 항목 (같은 이슈에서 추적)
Acceptance Criteria
Test Scenarios
- Token A (
allowedNamespaces: ["prod"], capabilities: ["pods"]) -> ns=* 호출 -> 403
- Token B (
allowedNamespaces: ["prod"], capabilities: ["logs"]) -> metrics 요청 -> 403
- Admin token ->
ns=* 호출 -> 성공
/v1/bundles/:id/download scope 정책 적용 확인
Context
Summary
현재 JWT 인증(HS256 + exp/iss/aud)은 구현되어 있으나, 인가(Authorization)가 없음.
유효한 토큰만 있으면 namespace/service/capability 구분 없이 전체 API 접근 가능.
현재 상태
src/auth.ts: JWT 유효성만 검사, payload를request.user에 붙이기만 함src/k8s/routes.ts:target.namespace기본값"*"— cluster-wide 조회/v1/pods: podIP, labels, annotations, nodeName 전체 반환/v1/bundles,/download: scope 제한 없음src/standalone/routes.ts:/v1/services서비스 메타(metrics URL, logs 경로) 전체 노출요구사항
JWT Claim 기반 권한 설계
{ "sub": "agent-01", "allowedNamespaces": ["prod", "monitoring"], "allowedServices": ["validator-*"], "capabilities": ["pods", "logs", "events", "metrics"], "admin": false }라우트별 적용
/v1/pods:allowedNamespaces+capabilities에pods포함 필수/v1/bundles: namespace/service scope 적용/v1/bundles/:id/download: 동일 scope/v1/services(standalone):allowedServices필터링namespace="*":admin: true토큰에서만 허용응답 축소 (관련 Medium 이슈 포함)
/v1/pods기본 응답에서annotations,nodeName,podIP제거 (관리자 scope에서만)/v1/services에서metricsURL,logs경로 등 민감 필드 축소추가 보강 항목 (같은 이슈에서 추적)
trustProxy=true+OA_ALLOWED_IPS동시 사용 시 경고/차단 로직OA_SERVICES기반 standalonelogs경로에path.resolve()+ allowlist 디렉토리 체크OA_SERVICES기반 standalonemetricsURL에 protocol/host allowlistmaxAge옵션 추가 (토큰 수명 정책)Acceptance Criteria
ns=*호출 시403403/v1/bundles/:id/download에도 동일 scope 적용Test Scenarios
allowedNamespaces: ["prod"],capabilities: ["pods"]) ->ns=*호출 -> 403allowedNamespaces: ["prod"],capabilities: ["logs"]) -> metrics 요청 -> 403ns=*호출 -> 성공/v1/bundles/:id/downloadscope 정책 적용 확인Context
36a7aa4cedbaee5452e0ad906545f17b1a6689c8