gRPC는 고성능 통신을 위한 프레임워크이지만, 보안 없이 사용될 경우 민감한 데이터가 외부에 노출될 수 있다. 특히 마이크로서비스 아키텍처에서 다양한 서비스 간 통신이 빈번히 발생하기 때문에 gRPC 보안 계층(Security Layer)의 적용은 선택이 아닌 필수이다.
gRPC의 채널과 스트림의 이해
gRPC는 클라이언트-서버 간의 통신을 위한 추상화된 개념으로, 핵심은 채널(Channel)과 스트림(Stream)에 기반한다.

채널 (Channel)
- 클라이언트와 서버 사이의 TCP 연결을 설정하고 관리하는 논리적 객체이다.
- 하나의 채널을 통해 여러 gRPC 호출이 다중 스트림(HTTP/2 기반)으로 이루어진다.
- 연결 재사용, 로드 밸런싱, TLS 설정 등도 채널에서 담당한다.
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051)
.usePlaintext() // TLS 미사용 (테스트용)
.build();
스트림 (Stream)
- 채널 위에서 실제 요청/응답이 단방향 또는 양방향으로 흐르는 단위이다.
- gRPC는 HTTP/2의 멀티플렉싱 기능을 이용하여 하나의 채널 위에 여러 스트림을 동시에 처리할 수 있다.
gRPC 보안 계층이란?
gRPC는 HTTP/2 기반에서 동작하며, 보안을 위해 다양한 계층을 설정할 수 있다.
계층 | 설명 |
TLS/SSL | 데이터 암호화를 통해 중간자 공격(MITH) 방지 |
서버 인증 | 서버의 신원을 클라이언트에게 보장 |
클라이언트 인증 (Mutual TLS) | 클라이언트의 신원을 서버가 확인 (양방향 인증) |
토큰 기반 인증 (JWT, OAuth2) | 인증 및 권한 제어 수행 |
Interceptor | gRPC 내부 요청을 가로채 보안 검사 수행 |
gRPC의 보안 계층: TLS의 이해
🔐 TLS (Transport Layer Security)란?

TLS는 인터넷 상에서 안전한 통신을 보장하기 위한 표준 보안 프로토콜이다.
- 암호화: 클라이언트와 서버 간 전송되는 모든 데이터는 암호화되어 제3자가 내용을 볼 수 없음
- 무결성: 데이터가 전송 중 변조되지 않았음을 확인 (메시지 인증 코드 사용)
- 인증: 서버와 클라이언트의 인증서를 통해 신원을 확인하고, 신뢰할 수 있는 대상과만 통신
TLS 설정 예시 (서버)
Server server = NettyServerBuilder.forPort(8443)
.useTransportSecurity(new File("server.crt"), new File("server.key"))
.addService(new MyGrpcService())
.build()
.start();
gRPC의 보안 계층: 스트림 암호화
TLS는 단순히 연결만 보호하는 것이 아니라, gRPC에서 스트림 단위로 암호화를 적용한다.

✔ 인증서 교환
- 서버는 클라이언트에게 자신의 인증서를 전송하고, 클라이언트는 이를 검증한다.
- Mutual TLS의 경우, 클라이언트도 자신의 인증서를 서버에 전송함으로써 양방향 인증이 가능해진다.
✔ 신원 인증 및 키 교환
- TLS 핸드셰이크 과정에서 RSA, ECDHE 등의 알고리즘을 사용해 암호 키를 안정하게 교환한다.
- 이후 세션 키 (Session Key)를 사용해 대칭키 방식으로 모든 스트림 데이터를 암호화한다.
이로 인해 gRPC의 데이터 스트림은 항상 TLS로 보호되며, 평문으로 노출되지 않는다.
gRPC 사용자 인증 종류: Mutual TLS (mTLS, 양방향 인증)
Mutual TLS는 TLS를 기반으로 한 양방향 인증 방식이다. 일반적인 TLS가 서버 인증만 수행하는 반면, 클라이언트와 서버가 서로의 인증서를 검증하는 방식이다.
mTLS의 주요 특징
- 높은 보안성: 서버와 클라이언트 모두의 신원을 확인하므로 안전함
- 양방향 인증: 상호 간에 신뢰를 보장해야 하는 환경에서 적합 (금융, 사내 인프라)
- 복잡한 인증서 관리: 인증서 발급/갱신 등의 관리가 필요함
- 초기 비용: 인증서 기반 인프라 구축 및 설정 필요
서버 & 클라이언트 설정 예제
// 서버 설정
Server server = NettyServerBuilder.forPort(8443)
.useTransportSecurity(new File("server.crt"), new File("server.key"))
.sslContext(GrpcSslContexts.configure(SslContextBuilder.forServer(...))
.trustManager(new File("ca.crt"))
.clientAuth(ClientAuth.REQUIRE))
.build();
// 클라이언트 설정
ManagedChannel channel = NettyChannelBuilder.forAddress("localhost", 8443)
.sslContext(GrpcSslContexts.forClient()
.keyManager(new File("client.crt"), new File("client.key"))
.trustManager(new File("ca.crt"))
.build())
.build();
서버도 클라이언트의 인증서에서 서명된 신원을 확인하고 통신을 허용한다.
인증 및 인가 (JWT, OAUTH2)
TLS는 통신 채널의 보안(암호화)을 담당하지만, 실제 사용자 인증 및 권한 관리는 애플리케이션 레벨에서 수행해야 한다.
JWT 기반 인증 예시 (Interceptor 활용)
gRPC는 요청을 처리하기 전 또는 후에 특정 작업을 가로채 처리할 수 있도록 Interceptor 기능을 제공한다. 인증을 포함한 다양한 기능을 처리할 수 있다.
클라이언트는 요청 시 'Authorization: Berear <token>' 형식의 메타데이터를 전송한다.
Interceptor의 기능
- 인증 처리: JWT, OAuth 토큰 검사 등
- 로깅 및 모니터링: 요청/응답 정보 기록
- 메시지 변환: 메타데이터 기반 처리
- 오류 처리: 예외 상황 포착 및 응답 구성
Interceptor의 유형
유형 | 설명 |
서버 인터셉터 | 서버 측 요청을 가로채 보안 및 인증 처리 수행 |
클라이언트 인터셉터 | 클라이언트 측에서 메타데이터 첨부 및 요청 로깅 등 처리 |
클라이언트 코드
Metadata metadata = new Metadata();
metadata.put(Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER), "Bearer eyJhbGciOi...");
stub.withInterceptors(MetadataUtils.newAttachHeadersInterceptor(metadata));
서버 Interceptor
public class AuthInterceptor implements ServerInterceptor {
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
ServerCall<ReqT, RespT> call,
Metadata headers,
ServerCallHandler<ReqT, RespT> next) {
String token = headers.get(Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER));
if (!isValidToken(token)) {
call.close(Status.UNAUTHENTICATED.withDescription("Invalid or missing token"), headers);
return new ServerCall.Listener<>() {};
}
return next.startCall(call, headers);
}
}
JWT 토큰은 서버에서 유효성 검사 및 사용자 권한(roles, scopes) 기반 인가까지 처리할 수 있다.
'기술(Tech) > Network & System' 카테고리의 다른 글
[GraphQL] GraphQL의 스키마와 타입 시스템 (0) | 2025.03.16 |
---|---|
[GraphQL] GraphQL 개요 (0) | 2025.03.15 |
[gRPC] gRPC 예외 처리 및 에러 핸들링 (0) | 2025.03.13 |
[gRPC] gRPC 상태 코드 (0) | 2025.03.03 |
[gRPC] RESTful API와 gRPC 간 변환 방법 (with. gRPC-Web) (1) | 2025.03.02 |
gRPC는 고성능 통신을 위한 프레임워크이지만, 보안 없이 사용될 경우 민감한 데이터가 외부에 노출될 수 있다. 특히 마이크로서비스 아키텍처에서 다양한 서비스 간 통신이 빈번히 발생하기 때문에 gRPC 보안 계층(Security Layer)의 적용은 선택이 아닌 필수이다.
gRPC의 채널과 스트림의 이해
gRPC는 클라이언트-서버 간의 통신을 위한 추상화된 개념으로, 핵심은 채널(Channel)과 스트림(Stream)에 기반한다.

채널 (Channel)
- 클라이언트와 서버 사이의 TCP 연결을 설정하고 관리하는 논리적 객체이다.
- 하나의 채널을 통해 여러 gRPC 호출이 다중 스트림(HTTP/2 기반)으로 이루어진다.
- 연결 재사용, 로드 밸런싱, TLS 설정 등도 채널에서 담당한다.
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051)
.usePlaintext() // TLS 미사용 (테스트용)
.build();
스트림 (Stream)
- 채널 위에서 실제 요청/응답이 단방향 또는 양방향으로 흐르는 단위이다.
- gRPC는 HTTP/2의 멀티플렉싱 기능을 이용하여 하나의 채널 위에 여러 스트림을 동시에 처리할 수 있다.
gRPC 보안 계층이란?
gRPC는 HTTP/2 기반에서 동작하며, 보안을 위해 다양한 계층을 설정할 수 있다.
계층 | 설명 |
TLS/SSL | 데이터 암호화를 통해 중간자 공격(MITH) 방지 |
서버 인증 | 서버의 신원을 클라이언트에게 보장 |
클라이언트 인증 (Mutual TLS) | 클라이언트의 신원을 서버가 확인 (양방향 인증) |
토큰 기반 인증 (JWT, OAuth2) | 인증 및 권한 제어 수행 |
Interceptor | gRPC 내부 요청을 가로채 보안 검사 수행 |
gRPC의 보안 계층: TLS의 이해
🔐 TLS (Transport Layer Security)란?

TLS는 인터넷 상에서 안전한 통신을 보장하기 위한 표준 보안 프로토콜이다.
- 암호화: 클라이언트와 서버 간 전송되는 모든 데이터는 암호화되어 제3자가 내용을 볼 수 없음
- 무결성: 데이터가 전송 중 변조되지 않았음을 확인 (메시지 인증 코드 사용)
- 인증: 서버와 클라이언트의 인증서를 통해 신원을 확인하고, 신뢰할 수 있는 대상과만 통신
TLS 설정 예시 (서버)
Server server = NettyServerBuilder.forPort(8443)
.useTransportSecurity(new File("server.crt"), new File("server.key"))
.addService(new MyGrpcService())
.build()
.start();
gRPC의 보안 계층: 스트림 암호화
TLS는 단순히 연결만 보호하는 것이 아니라, gRPC에서 스트림 단위로 암호화를 적용한다.

✔ 인증서 교환
- 서버는 클라이언트에게 자신의 인증서를 전송하고, 클라이언트는 이를 검증한다.
- Mutual TLS의 경우, 클라이언트도 자신의 인증서를 서버에 전송함으로써 양방향 인증이 가능해진다.
✔ 신원 인증 및 키 교환
- TLS 핸드셰이크 과정에서 RSA, ECDHE 등의 알고리즘을 사용해 암호 키를 안정하게 교환한다.
- 이후 세션 키 (Session Key)를 사용해 대칭키 방식으로 모든 스트림 데이터를 암호화한다.
이로 인해 gRPC의 데이터 스트림은 항상 TLS로 보호되며, 평문으로 노출되지 않는다.
gRPC 사용자 인증 종류: Mutual TLS (mTLS, 양방향 인증)
Mutual TLS는 TLS를 기반으로 한 양방향 인증 방식이다. 일반적인 TLS가 서버 인증만 수행하는 반면, 클라이언트와 서버가 서로의 인증서를 검증하는 방식이다.
mTLS의 주요 특징
- 높은 보안성: 서버와 클라이언트 모두의 신원을 확인하므로 안전함
- 양방향 인증: 상호 간에 신뢰를 보장해야 하는 환경에서 적합 (금융, 사내 인프라)
- 복잡한 인증서 관리: 인증서 발급/갱신 등의 관리가 필요함
- 초기 비용: 인증서 기반 인프라 구축 및 설정 필요
서버 & 클라이언트 설정 예제
// 서버 설정
Server server = NettyServerBuilder.forPort(8443)
.useTransportSecurity(new File("server.crt"), new File("server.key"))
.sslContext(GrpcSslContexts.configure(SslContextBuilder.forServer(...))
.trustManager(new File("ca.crt"))
.clientAuth(ClientAuth.REQUIRE))
.build();
// 클라이언트 설정
ManagedChannel channel = NettyChannelBuilder.forAddress("localhost", 8443)
.sslContext(GrpcSslContexts.forClient()
.keyManager(new File("client.crt"), new File("client.key"))
.trustManager(new File("ca.crt"))
.build())
.build();
서버도 클라이언트의 인증서에서 서명된 신원을 확인하고 통신을 허용한다.
인증 및 인가 (JWT, OAUTH2)
TLS는 통신 채널의 보안(암호화)을 담당하지만, 실제 사용자 인증 및 권한 관리는 애플리케이션 레벨에서 수행해야 한다.
JWT 기반 인증 예시 (Interceptor 활용)
gRPC는 요청을 처리하기 전 또는 후에 특정 작업을 가로채 처리할 수 있도록 Interceptor 기능을 제공한다. 인증을 포함한 다양한 기능을 처리할 수 있다.
클라이언트는 요청 시 'Authorization: Berear <token>' 형식의 메타데이터를 전송한다.
Interceptor의 기능
- 인증 처리: JWT, OAuth 토큰 검사 등
- 로깅 및 모니터링: 요청/응답 정보 기록
- 메시지 변환: 메타데이터 기반 처리
- 오류 처리: 예외 상황 포착 및 응답 구성
Interceptor의 유형
유형 | 설명 |
서버 인터셉터 | 서버 측 요청을 가로채 보안 및 인증 처리 수행 |
클라이언트 인터셉터 | 클라이언트 측에서 메타데이터 첨부 및 요청 로깅 등 처리 |
클라이언트 코드
Metadata metadata = new Metadata();
metadata.put(Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER), "Bearer eyJhbGciOi...");
stub.withInterceptors(MetadataUtils.newAttachHeadersInterceptor(metadata));
서버 Interceptor
public class AuthInterceptor implements ServerInterceptor {
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
ServerCall<ReqT, RespT> call,
Metadata headers,
ServerCallHandler<ReqT, RespT> next) {
String token = headers.get(Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER));
if (!isValidToken(token)) {
call.close(Status.UNAUTHENTICATED.withDescription("Invalid or missing token"), headers);
return new ServerCall.Listener<>() {};
}
return next.startCall(call, headers);
}
}
JWT 토큰은 서버에서 유효성 검사 및 사용자 권한(roles, scopes) 기반 인가까지 처리할 수 있다.
'기술(Tech) > Network & System' 카테고리의 다른 글
[GraphQL] GraphQL의 스키마와 타입 시스템 (0) | 2025.03.16 |
---|---|
[GraphQL] GraphQL 개요 (0) | 2025.03.15 |
[gRPC] gRPC 예외 처리 및 에러 핸들링 (0) | 2025.03.13 |
[gRPC] gRPC 상태 코드 (0) | 2025.03.03 |
[gRPC] RESTful API와 gRPC 간 변환 방법 (with. gRPC-Web) (1) | 2025.03.02 |