envoy: add a filter to store client cert info (#4372)

Add a new Lua filter that will store client certificate info as dynamic
metadata. This will allow us to configure client certificate validation
at the Envoy listener level, and then pass the results of that
validation into our ExtAuthz service.

This also allows us to pass the entire client certificate chain (and not
just the leaf certificate, which is how the 'include_peer_certificate'
ExtAuthz setting behaves). This will allow us to add support for
intermediate CA certificates supplied by the client.

However, if a client certificate does not validate successfully by
Envoy, we will not store the certificate chain. (This should help guard
against any possibility of making policy decisions based on unvalidated
client certificate data.)
This commit is contained in:
Kenneth Jenkins 2023-07-19 13:02:13 -07:00 committed by GitHub
parent df8ff26332
commit 8e4f728c11
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 8 deletions

View file

@ -9,18 +9,20 @@ import (
var luaFS embed.FS
var luascripts struct {
ExtAuthzSetCookie string
CleanUpstream string
RemoveImpersonateHeaders string
RewriteHeaders string
ExtAuthzSetCookie string
CleanUpstream string
RemoveImpersonateHeaders string
RewriteHeaders string
SetClientCertificateMetadata string
}
func init() {
fileToField := map[string]*string{
"luascripts/clean-upstream.lua": &luascripts.CleanUpstream,
"luascripts/ext-authz-set-cookie.lua": &luascripts.ExtAuthzSetCookie,
"luascripts/remove-impersonate-headers.lua": &luascripts.RemoveImpersonateHeaders,
"luascripts/rewrite-headers.lua": &luascripts.RewriteHeaders,
"luascripts/clean-upstream.lua": &luascripts.CleanUpstream,
"luascripts/ext-authz-set-cookie.lua": &luascripts.ExtAuthzSetCookie,
"luascripts/remove-impersonate-headers.lua": &luascripts.RemoveImpersonateHeaders,
"luascripts/rewrite-headers.lua": &luascripts.RewriteHeaders,
"luascripts/set-client-certificate-metadata.lua": &luascripts.SetClientCertificateMetadata,
}
err := fs.WalkDir(luaFS, "luascripts", func(p string, d fs.DirEntry, err error) error {

View file

@ -0,0 +1,14 @@
function envoy_on_request(request_handle)
local metadata = request_handle:streamInfo():dynamicMetadata()
local ssl = request_handle:streamInfo():downstreamSslConnection()
metadata:set("com.pomerium.client-certificate-info", "presented",
ssl:peerCertificatePresented())
local validated = ssl:peerCertificateValidated()
metadata:set("com.pomerium.client-certificate-info", "validated", validated)
if validated then
metadata:set("com.pomerium.client-certificate-info", "chain",
ssl:urlEncodedPemEncodedPeerCertificateChain())
end
end
function envoy_on_response(response_handle) end