* config: add customization options for logging
* config: validate log fields
* proxy: add support for logging http request headers
* log subset of headers
* add support for logging the http query
* fix test name
* use strings.Cut, add unit tests
Add a new reason "client-certificate-required" that will be returned by
the invalid_client_certificate criterion in the case that no client
certificate was provided. Determine this using the new 'presented' field
populated from the Envoy metadata.
* config: add customization options for logging
* config: validate log fields
* proxy: add support for logging http request headers
* log subset of headers
* fix test name
* dont use log.HTTPHeaders for access logs
* canonicalize http/2 headers
Currently we always add an invalid_client_certificate deny rule to all
PPL policies. Instead, let's add this rule only when a client CA is
configured. This way, if a user is not using client certificates at all,
they won't see any reason strings related to client certificates in the
authorize logs.
Change the "valid-client-certificate-or-none-required" reason string to
just "valid-client-certificate" accordingly.
Pass the main Evaluator config to NewPolicyEvaluator so that we can
determine whether there is a client CA configured or not. Extract the
existing default deny rule to a separate method. Add unit tests
exercising the new behavior.
Update the integration test templates to add a new client certificate
issued by downstream-ca-1, along with a combined CRL that revokes it.
(Setting a CRL just from downstream-ca-1 doesn't appear to work, which
surprises me.) Add a test case to verify that access is not allowed when
using the revoked certificate.
In authorize_test.go, the policy 'to' URLs are numbered from 1 to 11.
However, there is no number 8 (it looks like it was removed in commit
c178819). Update the URLs with numbers 9 through 11 to remove this gap.
Update the "any authenticated user" test case to use the corresponding
AllowAnyAuthenticatedUser policy (currently this case passes because
it's using the policy that allows any GET request, but it's not testing
what it says it should).
Configure Envoy to validate client certificates, using the union of all
relevant client CA bundles (that is, a bundle of the main client CA
setting together with all per-route client CAs). Pass the validation
status from Envoy through to the authorize service, by configuring Envoy
to use the newly-added SetClientCertificateMetadata filter, and by also
adding the relevant metadata namespace to the ExtAuthz configuration.
Remove the existing 'include_peer_certificate' setting from the ExtAuthz
configuration, as the metadata from the Lua filter will include the full
certificate chain (when it validates successfully by Envoy).
Update policy evaluation to consider the validation status from Envoy,
in addition to its own certificate chain validation. (Policy evaluation
cannot rely solely on the Envoy validation status while we still support
the per-route client CA setting.)
When building an upstream validation context for a particular URL, check
whether the hostname is an IP address. If so, configure the SAN match to
use type IP_ADDRESS rather than DNS.
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.)
Pomerium configures a gRPC listener in Envoy, for internal communication
between the various Pomerium services. Currently this listener shares
much of the same configuration as the main HTTP listener, based on the
main Pomerium configuration options.
However, some configuration options don't make sense for the gRPC
listener. Specifically, the `codec_type` option should not be applied to
the gRPC listener, as gRPC requires HTTP/2. Also, any client certificate
settings should not apply to the gRPC listener.
Separate the gRPC listener configuration from the main HTTP listener
configuration, so we can avoid applying these configuration options.
Instead set AlpnProtocols to just "h2" (HTTP/2), and do not set any
ValidationContextType on the DownstreamTlsContext (no client certificate
validation).
Specifically, inline the call to buildTLSSocket() within the body of
buildGRPCListener(). Extract a new method envoyCertificates() from
buildDownstreamTLSContextMulti(), to avoid repeating this logic.
Fetch the HPKE public key only when configured to use the hosted
authenticate service. Determine whether we are using the hosted
authenticate service by comparing the resolved authenticate domain with
a hard-coded list of hosted authenticate domains.
Extract this list of hosted authenticate domains to the internal/urlutil
package in order to keep a single source of truth for this data.
If an authorization policy requires a client certificate, but an
incoming request does not include a valid certificate, we should serve a
deny error page right away, regardless of whether the user is
authenticated via the identity provider or not. Do not redirect to the
identity provider login page in this case.
Update the existing integration tests accordingly, and add a unit test
case for this scenario.
Update OPA to v0.54.0, which changes the JSON serialization behavior for
large integers. Remove the formatting workaround and the unit test that
verified that the workaround was still needed.
Currently the Authenticate.storeIdentityProfile() method always emits an
Error log. If there is no error from cookieChunker.SetCookie(), this
results in an empty log entry:
{"level":"error","time":"2023-06-27T23:56:38Z"}
Refactor this method to instead return the error from SetCookie(), and
update the calling code so that it logs a message only when this error
is non-nil.
(Moving the log call to the calling method gives access to the request
context, so the log entry will include the request ID and other related
info.)
Allow users to clear the default IdP auth code options, by explicitly
setting an empty idp_request_params map.
To do this in a YAML config file, set:
idp_request_params: {}
* fix checkouts
* add fetch-depth for pre-commit
* remove manual caching
* cache node
* maybe fix yarn
* disable cache
* move test job to build job
* move cover to build step, use cache for docker
* only upload coverage for linux
* try again