API Access Key Core
multi-saas-kit는 API 인증을 프로젝트별 임시 구현이 아니라 공용 Core 보안 기능으로 다룹니다.
현재 이 구조는 apis.how, speech-service, llm.apis.how 연동에서 먼저 적용되어 있고, 다른 API 서비스도 같은 방식을 따르는 것이 권장됩니다.
왜 Core인가
다음 요구가 반복되기 때문입니다.
- 평문 API key 저장 금지
- 서비스별 ability 제어
- rate limit / timeout / 만료 / network restriction
- Laravel, Go, Python 서비스의 공통 검증
- 사용량과 비용 추적
이 기능을 서비스마다 따로 만들면 정책이 쉽게 어긋납니다.
핵심 구조
Browser / App / Server
│
│ Bearer access key
▼
speech.apis.how / tts / stt / llm
│
├─ auth middleware
├─ short cache
└─ introspection
│
▼
API Access Key Authority (Laravel Core)
│
├─ public_key_id + secret_hash
├─ policy evaluation
├─ revoke / rotate
└─ usage / audit
저장 원칙
- DB에는 plain token을 저장하지 않습니다.
- 토큰은
public_key_id + secret구조로 발급합니다. - UI에서는 발급 직후 1회만 plain token을 보여줍니다.
- 이후에는
Edit,Rotate,Revoke중심으로 운영합니다.
정책으로 제어하는 항목
serviceabilitiesallowed_routesallowed_aliasesallowed_ip_cidrsallowed_originsallowed_domainsallow_restallow_websocketrate_limitmax_timeout_msmax_concurrent_requestsexpires_at
키 타입
| 타입 | 용도 | 권장 제약 |
|---|---|---|
internal_service | 서비스 간 내부 호출 | IP 제한, 높은 신뢰 |
server_secret | 프로젝트 백엔드 | 장기 키, IP 제한 권장 |
browser_restricted | 브라우저 직접 호출 | origin/domain 제한, 낮은 권한 |
session_ephemeral | WebSocket/실시간 세션 | 짧은 TTL, 세션 전용 |
speech-service에 어떻게 적용되나
- 내부
LLM_API_KEYspeech-service -> llm.apis.how호출용 internal key
- 외부
Speech API Token- 사용자가
speech.apis.how를 호출할 때 쓰는 access key
- 사용자가
- 검증 방식
speech-service가 중앙 introspection endpoint를 조회- 결과를 짧게 cache
- 요청별 route / IP / origin / domain / websocket 제약을 다시 평가
사용량과 비용
공용 access key 구조는 인증만 담당하지 않습니다.
- 어떤 토큰이 어떤 서비스를 호출했는지
- 어떤 endpoint를 얼마나 썼는지
- estimated cost와 actual cost를 어떻게 비교할지
이 정보도 함께 남길 수 있게 설계되어 있습니다.
현재 speech-service는 api_usage_logs에 사용량을 남기고, LiteLLM spend 로그를 이용해 실제 LLM 비용을 backfill할 수 있는 구조를 사용합니다.
운영 권장사항
- 브라우저에는 장기 키보다
session_ephemeral을 우선 고려하세요. - server token에는
allowed_ip_cidrs를 우선 적용하세요. - browser token에는
allowed_origins,allowed_domains를 함께 쓰세요. - high-cost feature는 별도 ability로 분리하세요.
- plain token은 발급 직후 안전한 장소에만 보관하세요.