본문 바로가기
서버구축 (WEB,DB)

Kong API Gateway 권한 모델 설계 Consumer·Key·ACL 그룹 기반 제어

by 날으는물고기 2025. 12. 24.

Kong API Gateway 권한 모델 설계 Consumer·Key·ACL 그룹 기반 제어

728x90

Kong에서 API 호출 주체(Consumer)를 식별하고
Route(=라우터) / Service 단위로 접근 권한(인가)을 그룹 기반으로 제어하며
✅ 필요 시 Key-Auth(JWT) 등 인증 플러그인 + ACL 플러그인 조합으로 운영한다.

핵심 개념 정리: Consumer / Route / Service / Plugin

1. Consumer는 “누가 호출하는가”

  • Consumer는 “사람”일 수도 있고 “애플리케이션/연동 시스템”일 수도 있습니다.
  • 실무에서는 대개 연동 앱/서비스 1개 = Consumer 1개가 운영이 편합니다.
    (사람 단위 Consumer는 관리량이 폭증)

2. Route/Service는 “어디로 들어오는가 / 어디로 보내는가”

  • Route: 외부 요청 매칭 규칙(경로/호스트/메서드 등)
  • Service: 업스트림 서비스(백엔드) 정의

3. Plugin은 “정책(인증/인가/제어)을 어디에 붙일 것인가”

  • 인증: key-auth, jwt, oidc 등
  • 인가(권한): acl (대표적인 방식)
  • 제한/보호: rate-limiting 등

“Consumer 1개씩 만들면 되나?”에 대한 결론

  • 가능하지만 “사용자(사람) 1명=1 Consumer”가 항상 정답은 아닙니다.
  • 권장 기본
    • B2B/서버연동: 시스템/앱 단위 Consumer
    • 사람 단위 권한/과금/추적이 꼭 필요: 사람 단위 Consumer 또는 OIDC/JWT claim 기반으로 업스트림에서 처리

Route별/Service별 권한 부여가 가능한가?

가능합니다. 다만 “권한”은 Kong의 엔티티가 아니라 플러그인(ACL 등)로 구현합니다.

표준 패턴

  1. 인증 플러그인으로 Consumer를 확정 (Key-Auth / JWT 등)
  2. ACL 플러그인으로 “이 Consumer가 이 Route/Service에 접근 가능한가” 판정

그룹 기반 권한 제어: 두 가지 “그룹”의 차이

1. /consumer_groups 엔드포인트(Consumer Group 엔티티)

  • 스레드 중간에 /consumer_groups를 POST했더니 Not found가 나왔죠.
  • 이건 보통 해당 엔드포인트가 현재 배포/에디션/구성에서 노출되지 않음을 의미합니다.
  • 하지만 여기서 핵심은: 이 기능이 없어도 “그룹 기반 권한”은 ACL로 충분히 구현 가능하다는 점입니다.

2. ACL의 “group 문자열 라벨 방식” (실무 표준)

  • Consumer에 acls를 붙이면서 group=team 같은 라벨(문자열)을 달고
  • Route/Service에 acl 플러그인에서 config.allow=team을 설정하면 됩니다.

“그룹이면 Consumer 목록이 복사돼서 들어가나?” 오해 정리

복사/고정되지 않습니다.

  • ACL의 group은 그룹 엔티티가 아니라 “문자열 라벨”입니다.
  • Route의 allow에는 Consumer 목록이 들어가는 게 아니라 그룹명 문자열만 들어갑니다.
  • Consumer의 그룹 라벨을 바꾸면 즉시 권한이 바뀝니다.
    → “그룹 바뀌면 의미 없잖아?”가 아니라, 그룹 변경 자체가 권한 변경 수단입니다.

실제로 겪은 오류의 정체: UNIQUE constraint violation

상황

Route spms에 이미 acl 플러그인이 붙어 있었는데, 다시

POST /routes/spms/plugins  name=acl ...

를 실행하니

"UNIQUE violation detected on '{consumer=null,name=\"acl\",route={id=...},service=null}'"

의미

에러처럼 보이지만 사실은 “이미 같은 Route에 같은 이름(acl)의 플러그인이 1개 존재”해서 중복 생성이 차단된 정상 동작입니다.

해결 원칙

  • POST는 “새로 만들기”
  • 이미 있으면 PATCH로 “수정”해야 합니다.

"deny": null 이면 기본 전체 차단인가?

“deny가 null”이라서 차단이 되는 게 아닙니다. allow가 있으면 allow만 허용, 나머지 차단이 됩니다.

참고 규칙

  • allow만 있음: allow만 허용 (나머지 차단)
  • deny만 있음: deny만 차단 (나머지 허용)
  • 둘 다 없음: 사실상 모두 허용(ACL 의미 약함)
  • 둘 다 있음: deny가 우선(블랙리스트 우선 차단)

Consumer에서 Key 생성 방법 (Key-Auth)

1. Consumer에 Key 발급

Consumer가 admin이라면

curl -k -X POST https://localhost/kong-admin/consumers/admin/key-auth | jq .

응답에 key가 나오고, 그 값이 클라이언트가 붙일 API Key입니다.

2. Route/Service에 key-auth 플러그인 활성화

예: route spms에 적용

curl -k -X POST https://localhost/kong-admin/routes/spms/plugins \
  --data "name=key-auth"

이미 붙어 있으면 또 붙일 수 없고(UNIQUE), 그때는 확인/수정(PATCH)로 관리합니다.

3. 호출 테스트

curl -k https://<KONG_PROXY>/<spms-path> \
  -H "apikey: <발급받은 key>"

key-auth + jwt 플러그인을 둘 다 켜면?

기본적으로 둘 다 통과해야 합니다(AND)

  • key-auth가 요구되면 apikey가 있어야 하고
  • jwt가 요구되면 Authorization Bearer 토큰도 있어야 합니다
300x250

“둘 중 하나(OR)만 되게” 하려면 보통

  • Route를 분리하거나
  • 별도 설계(커스텀/전환 전략)를 써야 합니다.

Consumer 식별자: username vs consumer_id

  • 진짜 핵심 키(PK)id(UUID)
  • username, custom_id(=consumer_id로 부르는 경우 많음)유니크 별칭(alias)

권장 운영 패턴

  • username: 사람이 읽기 쉬운 서비스명 (예: svc-spms-api)
  • custom_id: 외부 시스템 연계 키(사내 고정 ID 등)
  • id: Kong 내부 참조(플러그인/credential 연관의 기준)

“정석 운영 흐름” 템플릿

아래 템플릿대로 하면 그룹 기반 Route 권한 제어 + 키 인증이 깔끔하게 동작합니다.

1. Consumer 준비

# consumer 생성
curl -k -X POST https://localhost/kong-admin/consumers --data "username=admin"

# api key 발급
curl -k -X POST https://localhost/kong-admin/consumers/admin/key-auth | jq .

2. Consumer에 그룹 라벨 부여 (ACL 그룹)

curl -k -X POST https://localhost/kong-admin/consumers/admin/acls \
  --data "group=team"

3. Route에 인증/인가 플러그인 부착

# 인증
curl -k -X POST https://localhost/kong-admin/routes/spms/plugins \
  --data "name=key-auth"

# 인가
curl -k -X POST https://localhost/kong-admin/routes/spms/plugins \
  --data "name=acl" \
  --data "config.allow=team"

만약 이미 acl 플러그인이 붙어있다면: POST 대신 PATCH로 allow 갱신/추가하세요.

보안 관점 “필수 점검 포인트”

1. Admin API 보호 (가장 중요)

  • 지금처럼 /kong-admin/ 프록시로 열려 있으면 특히 위험도가 큽니다.
  • 반드시: 접근 IP 제한 + 인증(mTLS/SSO) + 변경 이력 로깅을 붙이세요.

2. 그룹명은 “조직명”이 아니라 “권한명”으로

  • team처럼 포괄적 이름은 운영 중 사고를 부릅니다.
  • 권장: spms-read, spms-write, spms-admin처럼 권한 의미가 드러나게.

3. 변경은 PATCH/DELETE 기반으로 “관리 절차화”

  • 플러그인은 같은 스코프(route/service)에서 이름당 1개 → 중복 불가
  • 운영 자동화(IaC: deck/Terraform 등)로 “원천을 하나”로 두는 것이 안전합니다.

다음으로 가장 유용한 것

  1. 권한 모델 3단계(route-read/write/admin)
  2. 그룹명 표준안 + Consumer 매핑표
  3. “추가/변경/회수”까지 포함한 운영 절차서 커맨드 세트
  4. 키 회전(rotate) 시나리오(무중단: key 2개 운영 → old 폐기)
728x90
그리드형(광고전용)

댓글