NGF를 통한 ReferenceGrant 리소스 사용 가이드
네임스페이스의 경계를 넘어 트래픽을 전달하려면 ReferenceGrant 리소스가 필요합니다. ReferenceGrant는 백엔드 리소스 소유자가 자신의 서비스를 참조할 수 있는 외부 네임스페이스와 리소스 유형을 명시적으로 선언하는 역할을 합니다. 즉, 호출자가 아닌 대상 리소스의 소유자가 권한을 부여하는 상향식(Bottom-up) 보안 모델을 따릅니다.
NGINX Gateway Fabric 환경에서 이 보안 메커니즘이 어떻게 동작하는지 계층별 구성을 통해 확인합니다. 인프라 관리자가 정의하는 게이트웨이 설정부터 각 팀이 관리하는 라우팅 정책, 그리고 공용 백엔드 서비스에 적용되는 참조 허용 정책까지의 흐름을 정리합니다.
목차
1. ReferenceGrant란?
2. 환경 구성
3. NGINX Gateway Fabric + Shared Backend 구성
3-1. Gateway 및 NginxProxy 구성
3-2. Shared Backend 및 HTTPRoute 구성
3-3. ReferenceGrant 구성
4. 결과 확인
4-1. Gateway 상태 확인
4-2. HTTPRoute 상태 확인
5. 결론
1. ReferenceGrant란?
ReferenceGrant는 Gateway API에서 서로 다른 Namespace에 있는 HTTProute가 Service를 연결할 수 있게 해주는 리소스입니다.
Gateway API는 보안상의 이유로 기본적으로 다른 네임스페이스의 라우팅을 차단합니다. ReferenceGrant는 네임스페이스 간의 리소스 접근을 명시적으로 승인하여 Namespace 간의 리소스를 접근을 허용할 수 있습니다.
2. 환경 구성
- kubernetes : v1.34.4
- NGINX Gateway Fabric : 2.5.0
- Gateway API Version : v1.5.0
3. NGINX Gateway Fabric + Shared Backend 구성
3-1. Gateway 및 NginxProxy 구성
NginxProxy 리소스는 게이트웨이 인프라의 세부 구현 방식을 정의합니다. 서비스 타입이나 Data Plane의 설정을 라우팅 정책과 분리하여 관리할 수 있게 하며, 이는 인프라 운영자가 라우팅 설정 변경에 구애받지 않고 하위 시스템을 최적화할 수 있는 기반이 됩니다. 게이트웨이는 이 NginxProxy를 infrastructure 항목에서 참조하여 구동합니다.
apiVersion: v1kind: Namespacemetadata: name: infra-gw---apiVersion: v1kind: Namespacemetadata: name: team-a---apiVersion: v1kind: Namespacemetadata: name: team-b---apiVersion: v1kind: Namespacemetadata: name: shared-backend---apiVersion: gateway.nginx.org/v1alpha2kind: NginxProxymetadata: name: gateway-proxy namespace: infra-gwspec: kubernetes: service: type: NodePort---apiVersion: gateway.networking.k8s.io/v1kind: Gatewaymetadata: name: shared-gateway namespace: infra-gwspec: gatewayClassName: nginx infrastructure: parametersRef: group: gateway.nginx.org kind: NginxProxy name: gateway-proxy listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All # Gateway 리소스는 모든 NS의 접근을 허용합니다.
3-2. Shared Backend 배포
백엔드 서비스인 api-svc는 shared-backend 네임스페이스에 위치해 있습니다.
apiVersion: apps/v1kind: Deploymentmetadata: name: api namespace: shared-backendspec: replicas: 1 selector: matchLabels: app: api template: metadata: labels: app: api spec: containers: - name: echo image: hashicorp/http-echo:1.0.0 args: - "-text=shared-backend/api-svc reached through approved ReferenceGrant" ports: - containerPort: 5678---apiVersion: v1kind: Servicemetadata: name: api-svc namespace: shared-backendspec: selector: app: api ports: - protocol: TCP port: 80 targetPort: 5678
3-3. ReferenceGrant 구성
ReferenceGrant는 백엔드 서비스가 위치한 shared-backend 네임스페이스에 생성합니다. from 항목에서는 접근을 시도하는 리소스의 종류인 HTTPRoute와 네임스페이스인 team-a를 정의하고, to 항목에서는 접근을 허용할 리소스 유형인 Service를 지정합니다. 이 선언을 통해 team-a 소속 Route만 shared-backend 내 자원을 참조할 수 있는 권한을 부여합니다.
apiVersion: gateway.networking.k8s.io/v1kind: ReferenceGrantmetadata: name: allow-team-a-to-shared-backend namespace: shared-backendspec: from: - group: gateway.networking.k8s.io kind: HTTPRoute namespace: team-a to: - group: "" kind: Service
개별 네임스페이스인 team-a, team-b에 위치한 HTTPRoute 리소스는 서로 다른 Host을 사용하면서 동일한 api-svc를 백엔드로 참조하도록 구성합니다.
이 지점에서 HTTPRoute의 backendRefs 설정은 자신의 네임스페이스가 아닌 외부 네임스페이스를 명시합니다. 기본 보안 정책에 따라 이러한 참조는 무효화되며, 게이트웨이는 대상 서비스의 존재 여부와 관계없이 권한 부족으로 인해 해당 경로를 생성하지 않습니다.
apiVersion: gateway.networking.k8s.io/v1kind: HTTPRoutemetadata: name: team-a-route namespace: team-aspec: parentRefs: - name: shared-gateway namespace: infra-gw hostnames: - app.example.com rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: api-svc namespace: shared-backend port: 80---apiVersion: gateway.networking.k8s.io/v1kind: HTTPRoutemetadata: name: team-b-route namespace: team-bspec: parentRefs: - name: shared-gateway namespace: infra-gw hostnames: - denied.example.com rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: api-svc namespace: shared-backend port: 80
4. 결과 확인
4-1. Gateway 상태 확인
게이트웨이 리소스를 조회하여 IP 주소 할당 상태를 확인합니다. NGINX Gateway Fabric 컨트롤러가 인프라 설정을 감지하고 정상적인 진입점을 생성했는지 먼저 확인합니다.
$ kubectl get gateway -n infra-gwNAME CLASS ADDRESS PROGRAMMED AGEshared-gateway nginx 172.30.203.44 True 10m
HTTPRoute가 배포되었는지 확인합니다.
$ kubectl get httproute -n team-a NAME HOSTNAMES AGEteam-a-route ["app.example.com"] 6d18$ kubectl get httproute -n team-bNAME HOSTNAMES AGEteam-b-route ["denied.example.com"] 6d18h
4-2. HTTPRoute 상태 확인
각 팀의 HTTPRoute 상태를 조회하여 ReferenceGrant 적용 결과를 비교합니다. 상태 메시지의 ResolvedRefs 항목은 게이트웨이가 참조하는 백엔드 서비스의 권한 여부를 직접적으로 보여줍니다.
# team-a-route 확인 (ReferenceGrant 허용됨)$ kubectl describe httproute team-a-route -n team-aStatus: Parents: Conditions: Last Transition Time: 2026-04-13T16:55:00Z Message: Accepted Reason: Accepted Status: True Type: Accepted Last Transition Time: 2026-04-13T16:55:00Z Message: ResolvedRefs Reason: ResolvedRefs Status: True Type: ResolvedRefs# team-b-route 확인 (ReferenceGrant 없음)$ kubectl describe httproute team-b-route -n team-bStatus: Parents: Conditions: Last Transition Time: 2026-04-13T16:55:00Z Message: Accepted Reason: Accepted Status: True Type: Accepted Last Transition Time: 2026-04-13T16:55:00Z Message: spec.rules[0].backendRefs[0].namespace: Forbidden: Backend ref to Service shared-backend/api-svc not permitted by any ReferenceGrant Reason: RefNotPermitted Status: False Type: ResolvedRefs
team-a-route는 ResolvedRefs 상태가 True로 표시되며 정상적으로 백엔드를 연결합니다.
반면 team-b-route는 Accepted가 True여도 ResolvedRefs는 False가 되고 RefNotPermitted 이유가 표시됩니다. 이는 게이트웨이가 설정 자체는 수락했지만, 보안 규칙 위반으로 인해 실제 트래픽 경로는 생성하지 않았음을 의미합니다.
서비스에 접속하여 정상적으로 응답이 오는지 확인합니다.

정상적으로 백엔드와 연결한 app.example.com 도메인은 정상적으로 응답이 오는 것을 확인할 수 있습니다.

백엔드와 연결하지 못한 HTTPRoute 도메인은 백엔드 서비스를 찾지 못하고 500 에러를 반환하는 것을 확인할 수 있습니다.

5. 결론
ReferenceGrant는 멀티테넌트 쿠버네티스 환경에서 서비스 간 격리 보안을 구현하는 핵심 도구입니다. 단순한 네트워크 연결을 넘어 관리 주체 간 의사를 코드로 명시함으로써, 복잡한 마이크로서비스 구조에서도 트래픽 흐름에 대한 통제권을 리소스 소유자가 유지할 수 있게 합니다. 이는 의도치 않은 서비스 노출을 방지하고 보안 기준을 준수하는 데 중요한 역할을 합니다.
NGINX Gateway Fabric은 이러한 Gateway API 스펙을 충실히 구현하여 운영 효율성을 높여줍니다. 인프라 설정과 보안 정책이 명확하게 분리된 구조는 대규모 클러스터 운영 시 설정 오류를 줄이고, 서비스 간 상호 참조 관계를 더 직관적으로 파악할 수 있게 합니다. 결과적으로 더 안전하고 확장 가능한 애플리케이션 전달 인프라를 구성할 수 있습니다.
NGINX Plus Gateway Fabric를 사용해보시고 싶으시다면 NGINX STORE를 통해 문의하세요.
댓글을 달려면 로그인해야 합니다.