-
Notifications
You must be signed in to change notification settings - Fork 15
Expose the peerCertificate from mTLS to ServerContext #97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Motivation: When using gRPC, it's useful to pull the peerCertificate from a successful mTLS connection for authn and/or authz. Modifications: These changes make use of the new transportSpecific field in the ServerContext. After a successful hanshake has completed, it uses the provided handler to retrieve the verified peer certificate and populate the Server Context. There's also a simple happy path test that's been added for validation purposes. Temporarily, this commit also references specific updates in swift-nio-ssl and grpc-swift. Result: This commit allows access to the swift Certificate object in an interceptor for the Posix HTTP2 transport. It also adds a mechanism for other transports to allow their own transport specific data.
|
||
@Test( | ||
"Using the mTLS defaults, and with Posix transport, validate we get the peer cert on the server", | ||
arguments: TransportKind.supported |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
arguments: TransportKind.supported | |
arguments: [TransportKind.posix] |
arguments: TransportKind.supported | ||
) | ||
func testRPC_mTLS_TransportContext_OK(supportedTransport: TransportKind) async throws { | ||
if TransportKind.posix == supportedTransport { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can remove this if we change arguments
#expect(transportSpecific != nil) | ||
#expect(transportSpecific is HTTP2ServerTransport.Posix.Context) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need these as they're covered by the #require
below
transportSpecific as? HTTP2ServerTransport.Posix.Context | ||
) | ||
let peerCertificate = try #require(transportSpecificAsPosixContext.peerCertificate) | ||
#expect(transportSpecificAsPosixContext.peerCertificate != nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't need this one: it's covered by the #require
just above
Package.swift
Outdated
@@ -51,7 +51,7 @@ let dependencies: [Package.Dependency] = [ | |||
), | |||
.package( | |||
url: "https://github.com/apple/swift-nio-ssl.git", | |||
from: "2.29.0" | |||
revision: "874ad69" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -186,6 +199,15 @@ extension HTTP2ServerTransport { | |||
} | |||
|
|||
extension HTTP2ServerTransport.Posix { | |||
/// Context for Posix TransportSpecific | |||
public struct Context: ServerContext.TransportSpecific { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does this compose overall? Shouldn't this be something that really every transport can vend optionally so code that has to do authn/z doesn't have to become transport specific @glbrntt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The longer term move is to have mixin protocols (e.g. HasPeerCertificate
) which contexts would conform to. Any common code would then use these rather than relying on a concrete transport specific type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess my meta question is why do we consider that peer certificate needs to be a mix-in protocol and we can't make it part of the ServerContext
right away. It seems in line with remotePeer: String
to have a remotePeerCertificate: Certificate?
. Since it has to be optional anyways.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It isn't really in line with it, you can't compute on remotePeer
beyond using it as an identifier. remotePeer
is also available to all transports, whereas the peer cert is only available here.
Adding it to the context brings in three more dependencies which would only be used by the NIO transport.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why only the NIO transport? Can't we provide a Certificate
based peer identity on the NIOTS
transport as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIO transport includes NIOTS. The NIOTS transport work hasn't been done yet (I'm not sure if the right APIs currently exist to do it.)
Package.swift
Outdated
@@ -35,7 +35,7 @@ let products: [Product] = [ | |||
let dependencies: [Package.Dependency] = [ | |||
.package( | |||
url: "https://github.com/grpc/grpc-swift.git", | |||
from: "2.0.0" | |||
revision: "0d850d6" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Motivation:
When using gRPC, it's useful to pull the peerCertificate from a successful mTLS connection for authn and/or authz.
Modifications:
These changes make use of the new transportSpecific field in the ServerContext. After a successful hanshake has completed, it uses the provided handler to retrieve the verified peer certificate and populate the Server Context.
There's also a simple happy path test that's been added for validation purposes.
Temporarily, this commit also references specific updates in swift-nio-ssl and grpc-swift.
Result:
This commit allows access to the swift Certificate object in an interceptor for the Posix HTTP2 transport. It also adds a mechanism for other transports to allow their own transport specific data.