LAB-030: gRPC Security¶
Status¶
- Theory prerequisite:
docs/theory/grpc-security.md - Implementation:
grpc-servicemodule - Tests:
GrpcSecurityLabTest - Verification:
JAVA_HOME=/opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk/Contents/Home ./gradlew :grpc-service:test --tests '*GrpcSecurityLabTest'
Measurable objective¶
Implement ServerInterceptor logic for gRPC bearer-token metadata and mTLS peer-certificate identity. Tests must prove the interceptors reject missing/invalid tokens and missing/invalid client certificates before the service handler runs.
Source artifact map¶
| File | Purpose |
|---|---|
GrpcAuthInterceptor.java | Reads Authorization metadata, validates Bearer valid-token, rejects invalid calls |
GrpcMtlsInterceptor.java | Extracts peer X509Certificate from the TLS SSLSession, parses the CN, rejects missing certs |
GrpcSecurityLabTest.java | Mockito tests for token and mTLS interceptor behavior |
Exercises¶
- Review
GrpcAuthInterceptorand identify whycall.closeis called before the service handler is invoked. - Trace how
GrpcMtlsInterceptorobtains the client certificate from the gRPC transport attributes. - Run
GrpcSecurityLabTestand explain why a missingAuthorizationheader returnsUNAUTHENTICATEDwhile a wrong token returnsPERMISSION_DENIED. - Identify the production changes needed to attach these interceptors to a real
NettyServerBuilderwith TLS.
Commands¶
JAVA_HOME=/opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk/Contents/Home ./gradlew :grpc-service:test --tests '*GrpcSecurityLabTest'
Positive and negative test expectations¶
| Scenario | Expected |
|---|---|
Missing Authorization metadata | call.close(Status.UNAUTHENTICATED) |
Bearer wrong-token | call.close(Status.PERMISSION_DENIED) |
Bearer valid-token | next.startCall invoked |
No TLS SSLSession in attributes | call.close(Status.UNAUTHENTICATED) |
Valid client certificate with CN=client | next.startCall invoked |
Production extension¶
- Wire
GrpcAuthInterceptorandGrpcMtlsInterceptorinto aNettyServerBuilderfor a real service. - Configure
SslContextwith a trust manager that validates client certificates against a CA. - Replace the hardcoded
valid-tokenwith a JWT or token-introspection check. - Map the extracted
CNto a Spring SecurityAuthenticationand useAuthorizationManagerfor method-level checks. - Add request-id metadata and redacted logging for gRPC calls.
Completion evidence¶
JAVA_HOME=/opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk/Contents/Home ./gradlew :grpc-service:test --tests '*GrpcSecurityLabTest'
BUILD SUCCESSFUL
GrpcSecurityLabTest: 5 passed
Next lab¶
LAB-031 — WebSocket Security.