tls: implement SPIFFE Certificate Validator for independent multiple trust domain support (#14884)

Adds the extension point for certificate validations, and its first implementation for SPIFFE multi trust domain support in a single listener or cluster. Resolves https://github.com/envoyproxy/envoy/issues/14614 and https://github.com/envoyproxy/envoy/issues/9284.
Risk Level: low (only adding the new extension point and one implementation for it)
Testing: unit tests and integration tests.
Docs Changes:
Release Notes: tls: implement SPIFFE Certificate Validator for independent multiple trust domain support.

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>

Mirrored from https://github.com/envoyproxy/envoy @ 50e81276fd8f109ba3a6134e790f65c1cc5bdec9
pull/624/head
data-plane-api(Azure Pipelines) 4 years ago
parent d962072e44
commit 4e664ccffb
  1. 15
      envoy/extensions/transport_sockets/tls/v3/common.proto
  2. 54
      envoy/extensions/transport_sockets/tls/v3/tls_spiffe_validator_config.proto
  3. 15
      envoy/extensions/transport_sockets/tls/v4alpha/common.proto
  4. 60
      envoy/extensions/transport_sockets/tls/v4alpha/tls_spiffe_validator_config.proto

@ -3,6 +3,7 @@ syntax = "proto3";
package envoy.extensions.transport_sockets.tls.v3;
import "envoy/config/core/v3/base.proto";
import "envoy/config/core/v3/extension.proto";
import "envoy/type/matcher/v3/string.proto";
import "google/protobuf/any.proto";
@ -211,7 +212,7 @@ message TlsSessionTicketKeys {
[(validate.rules).repeated = {min_items: 1}, (udpa.annotations.sensitive) = true];
}
// [#next-free-field: 12]
// [#next-free-field: 13]
message CertificateValidationContext {
option (udpa.annotations.versioning).previous_message_type =
"envoy.api.v2.auth.CertificateValidationContext";
@ -371,4 +372,16 @@ message CertificateValidationContext {
// Certificate trust chain verification mode.
TrustChainVerification trust_chain_verification = 10
[(validate.rules).enum = {defined_only: true}];
// The configuration of an extension specific certificate validator.
// If specified, all validation is done by the specified validator,
// and the behavior of all other validation settings is defined by the specified validator (and may be entirely ignored, unused, and unvalidated).
// Refer to the documentation for the specified validator. If you do not want a custom validation algorithm, do not set this field.
// The following names are available here:
//
// .. _extension_envoy.tls.cert_validator.spiffe:
//
// **envoy.tls.cert_validator.spiffe**: `SPIFFE <https://github.com/spiffe/spiffe>`_ certificate validator.
// Please refer to :ref:`envoy.extensions.transport_sockets.tls.v3.SPIFFECertValidatorConfig <envoy_v3_api_msg_extensions.transport_sockets.tls.v3.SPIFFECertValidatorConfig>` for more information.
config.core.v3.TypedExtensionConfig custom_validator_config = 12;
}

@ -0,0 +1,54 @@
syntax = "proto3";
package envoy.extensions.transport_sockets.tls.v3;
import "envoy/config/core/v3/base.proto";
import "udpa/annotations/sensitive.proto";
import "udpa/annotations/status.proto";
import "udpa/annotations/versioning.proto";
import "validate/validate.proto";
option java_package = "io.envoyproxy.envoy.extensions.transport_sockets.tls.v3";
option java_outer_classname = "TlsSpiffeValidatorConfigProto";
option java_multiple_files = true;
option (udpa.annotations.file_status).package_version_status = ACTIVE;
// [#protodoc-title: SPIFFE Certificate Validator]
// Configuration specific to the SPIFFE certificate validator provided at
// :ref:`envoy.extensions.transport_sockets.tls.v3.CertificateValidationContext.custom_validator_config<envoy_api_field_extensions.transport_sockets.tls.v3.CertificateValidationContext.custom_validator_config>`.
//
// Example:
//
// .. code-block:: yaml
//
// custom_validator_config:
// name: envoy.tls.cert_validator.spiffe
// typed_config:
// "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.SPIFFECertValidatorConfig
// trust_domains:
// - name: foo.com
// trust_bundle:
// filename: "foo.pem"
// - name: envoy.com
// trust_bundle:
// filename: "envoy.pem"
//
// In this example, a presented peer certificate whose SAN matches `spiffe//foo.com/**` is validated against
// the "foo.pem" x.509 certificate. All the trust bundles are isolated from each other, so no trust domain can mint
// a SVID belonging to another trust domain. That means, in this example, a SVID signed by `envoy.com`'s CA with `spiffe//foo.com/**`
// SAN would be rejected since Envoy selects the trust bundle according to the presented SAN before validate the certificate.
message SPIFFECertValidatorConfig {
message TrustDomain {
// Name of the trust domain, `example.com`, `foo.bar.gov` for example.
// Note that this must *not* have "spiffe://" prefix.
string name = 1 [(validate.rules).string = {min_len: 1}];
// Specify a data source holding x.509 trust bundle used for validating incoming SVID(s) in this trust domain.
config.core.v3.DataSource trust_bundle = 2;
}
// This field specifies trust domains used for validating incoming X.509-SVID(s).
repeated TrustDomain trust_domains = 1 [(validate.rules).repeated = {min_items: 1}];
}

@ -3,6 +3,7 @@ syntax = "proto3";
package envoy.extensions.transport_sockets.tls.v4alpha;
import "envoy/config/core/v4alpha/base.proto";
import "envoy/config/core/v4alpha/extension.proto";
import "envoy/type/matcher/v4alpha/string.proto";
import "google/protobuf/any.proto";
@ -213,7 +214,7 @@ message TlsSessionTicketKeys {
[(validate.rules).repeated = {min_items: 1}, (udpa.annotations.sensitive) = true];
}
// [#next-free-field: 12]
// [#next-free-field: 13]
message CertificateValidationContext {
option (udpa.annotations.versioning).previous_message_type =
"envoy.extensions.transport_sockets.tls.v3.CertificateValidationContext";
@ -373,4 +374,16 @@ message CertificateValidationContext {
// Certificate trust chain verification mode.
TrustChainVerification trust_chain_verification = 10
[(validate.rules).enum = {defined_only: true}];
// The configuration of an extension specific certificate validator.
// If specified, all validation is done by the specified validator,
// and the behavior of all other validation settings is defined by the specified validator (and may be entirely ignored, unused, and unvalidated).
// Refer to the documentation for the specified validator. If you do not want a custom validation algorithm, do not set this field.
// The following names are available here:
//
// .. _extension_envoy.tls.cert_validator.spiffe:
//
// **envoy.tls.cert_validator.spiffe**: `SPIFFE <https://github.com/spiffe/spiffe>`_ certificate validator.
// Please refer to :ref:`envoy.extensions.transport_sockets.tls.v3.SPIFFECertValidatorConfig <envoy_v3_api_msg_extensions.transport_sockets.tls.v3.SPIFFECertValidatorConfig>` for more information.
config.core.v4alpha.TypedExtensionConfig custom_validator_config = 12;
}

@ -0,0 +1,60 @@
syntax = "proto3";
package envoy.extensions.transport_sockets.tls.v4alpha;
import "envoy/config/core/v4alpha/base.proto";
import "udpa/annotations/sensitive.proto";
import "udpa/annotations/status.proto";
import "udpa/annotations/versioning.proto";
import "validate/validate.proto";
option java_package = "io.envoyproxy.envoy.extensions.transport_sockets.tls.v4alpha";
option java_outer_classname = "TlsSpiffeValidatorConfigProto";
option java_multiple_files = true;
option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSION_CANDIDATE;
// [#protodoc-title: SPIFFE Certificate Validator]
// Configuration specific to the SPIFFE certificate validator provided at
// :ref:`envoy.extensions.transport_sockets.tls.v3.CertificateValidationContext.custom_validator_config<envoy_api_field_extensions.transport_sockets.tls.v4alpha.CertificateValidationContext.custom_validator_config>`.
//
// Example:
//
// .. code-block:: yaml
//
// custom_validator_config:
// name: envoy.tls.cert_validator.spiffe
// typed_config:
// "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.SPIFFECertValidatorConfig
// trust_domains:
// - name: foo.com
// trust_bundle:
// filename: "foo.pem"
// - name: envoy.com
// trust_bundle:
// filename: "envoy.pem"
//
// In this example, a presented peer certificate whose SAN matches `spiffe//foo.com/**` is validated against
// the "foo.pem" x.509 certificate. All the trust bundles are isolated from each other, so no trust domain can mint
// a SVID belonging to another trust domain. That means, in this example, a SVID signed by `envoy.com`'s CA with `spiffe//foo.com/**`
// SAN would be rejected since Envoy selects the trust bundle according to the presented SAN before validate the certificate.
message SPIFFECertValidatorConfig {
option (udpa.annotations.versioning).previous_message_type =
"envoy.extensions.transport_sockets.tls.v3.SPIFFECertValidatorConfig";
message TrustDomain {
option (udpa.annotations.versioning).previous_message_type =
"envoy.extensions.transport_sockets.tls.v3.SPIFFECertValidatorConfig.TrustDomain";
// Name of the trust domain, `example.com`, `foo.bar.gov` for example.
// Note that this must *not* have "spiffe://" prefix.
string name = 1 [(validate.rules).string = {min_len: 1}];
// Specify a data source holding x.509 trust bundle used for validating incoming SVID(s) in this trust domain.
config.core.v4alpha.DataSource trust_bundle = 2;
}
// This field specifies trust domains used for validating incoming X.509-SVID(s).
repeated TrustDomain trust_domains = 1 [(validate.rules).repeated = {min_items: 1}];
}
Loading…
Cancel
Save