v1.7.0 — 멀티 어카운트 + 실시간 스트리밍
멀티 어카운트 지원(PR #6)과 실시간 Bedrock 스트리밍을 핵심으로 한 대규모 릴리스입니다. 보안 수정 25건이 반영되었습니다.
멀티 어카운트 (PR #6) · 실시간 스트리밍 · 캐시 프리워밍 · 보안 수정 25건 · 고객 로고 커스터마이징
멀티 어카운트 아키텍처 (PR #6)
Steampipe Aggregator 패턴으로 여러 AWS 계정을 단일 대시보드에서 관리합니다. data/config.json의 accounts[] 배열만 변경하면 코드 수정 없이 계정을 추가할 수 있습니다.
| 컴포넌트 | 파일 | 역할 |
|---|---|---|
AccountContext | src/components/ | 계정 상태 관리 + useAccount() 훅 |
AccountSelector | src/components/ | 계정 전환 드롭다운 (ARIA, 키보드 지원) |
AccountBadge | src/components/ | 계정별 컬러 도트 + alias 표시 |
buildSearchPath() | src/lib/steampipe.ts | public, aws_{id}, kubernetes, trivy 반환 |
runCostQueriesPerAccount() | src/lib/steampipe.ts | 계정별 Cost 쿼리 실행 후 account_id 태깅 병합 |
/accounts 페이지 | src/app/accounts/ | 계정 추가/삭제/테스트 UI |
cross_account.py | agent/ | STS AssumeRole (credential 캐싱, ExternalId, 감사 로깅) |
| 설정 스크립트 | scripts/11-setup-multi-account.sh | Aggregator + 교차 계정 IAM 역할 자동화 |
모든 25개 SQL 쿼리에 account_id 컬럼을 추가하고, 35개 페이지에 useAccountContext()를 적용했습니다. DataTable은 isMultiAccount && data[0].account_id 감지 시 Account 컬럼을 자동 추가합니다.
config.json 구조
{
"accounts": [
{
"accountId": "111111111111",
"alias": "Host",
"connectionName": "aws_111111111111",
"region": "ap-northeast-2",
"isHost": true,
"features": {
"costEnabled": true,
"eksEnabled": true,
"k8sEnabled": true
}
},
{
"accountId": "222222222222",
"alias": "Staging",
"connectionName": "aws_222222222222",
"region": "ap-northeast-2",
"isHost": false,
"features": {
"costEnabled": false,
"eksEnabled": false,
"k8sEnabled": false
}
}
]
}
보안 수정 (25건)
3단계 심각도로 분류하여 25건의 보안 이슈를 수정했습니다.
교차 계정 AssumeRole에 감사 로그와 ExternalId를 필수화하여, 권한 에스컬레이션과 Confused Deputy 공격을 방지합니다.
| 심각도 | 건수 | 주요 항목 |
|---|---|---|
| CRITICAL | 2 | AssumeRole 감사 로그, ExternalId 필수화 |
| HIGH | 5 | Rate Limiting (5 req/min), 입력 검증 강화, execFileSync 보안 |
| MEDIUM | 18 | Pool exhaustion 방지, 커넥션 파괴, 에러 메시지 필터링 |
CRITICAL 상세:
| 이슈 | 위험 | 수정 |
|---|---|---|
| AssumeRole 감사 부재 | 교차 계정 접근 추적 불가 | cross_account.py에 모든 AssumeRole 호출 로깅 |
| ExternalId 미사용 | Confused Deputy 공격 가능 | AssumeRole에 ExternalId 필수 파라미터 추가 |
HIGH 상세:
| 이슈 | 위험 | 수정 |
|---|---|---|
| Rate Limiting 부재 | API 남용, 비용 폭증 | AI 라우트에 5 req/min 제한 적용 |
| 입력 검증 미흡 | SQL Injection 가능 | 쿼리 파라미터 화이트리스트 검증 |
execFileSync 사용 | Command Injection | 인수 배열 방식으로 변환 |
실시간 Bedrock 스트리밍
Bedrock 응답을 청크 단위로 실시간 전송합니다.
| 항목 | Before (v1.6.0) | After (v1.7.0) |
|---|---|---|
| Bedrock 응답 | 전체 텍스트 한 번에 | 청크 단위 실시간 |
| API | InvokeModelCommand | InvokeModelWithResponseStreamCommand |
| 전송 방식 | 완료 후 done 이벤트 | chunk 이벤트 연속 전송 |
| 클라이언트 | 전체 텍스트 렌더링 | streamingContent 상태로 실시간 렌더링 |
streamBedrockToSSE() 함수(src/app/api/ai/route.ts)가 Bedrock 스트림에서 청크를 읽어 SSE chunk 이벤트로 변환합니다.
캐시 프리워밍
대시보드 로딩 속도를 개선하기 위해 백그라운드 캐시 프리워밍을 도입했습니다.
| 항목 | 설명 |
|---|---|
| 쿼리 수 | 대시보드 23개 + 모니터링 10개 = 33개 |
| 갱신 주기 | 4분 (캐시 TTL 5분 만료 전) |
| 초기화 | ensureCacheWarmerStarted() — lazy-init 패턴 |
| 효과 | 첫 페이지 로딩 시 캐시 히트로 즉시 응답 |
고객 로고 커스터마이징
data/config.json에서 고객 로고를 설정하면 서버 재시작 없이 1분 내에 반영됩니다.
{
"customerLogo": "/logos/customer-logo.png",
"customerName": "Customer Corp",
"customerLogoBg": "#ffffff"
}
public/logos/디렉토리에 로고 파일 배치- config 변경만으로 브랜딩 전환 — 코드 수정 불필요
버전 비교
| 항목 | v1.6.0 | v1.7.0 | 변화 |
|---|---|---|---|
| Pages | 35 | 36 | +accounts |
| Components | 15 | 17 | +AccountBadge, AccountSelector |
| ADRs | 7 | 8 | +멀티 어카운트 |
| 배포 스크립트 | 10 | 11 | +Step 11 |
| SQL 쿼리 | 25 | 25 | +account_id 컬럼 추가 |
| 보안 수정 | - | 25건 | CRITICAL 2, HIGH 5, MEDIUM 18 |