mirror of
https://github.com/pomerium/pomerium.git
synced 2025-04-28 18:06:34 +02:00
core/config: add kubernetes_service_account_token_file (#5322)
* core/config: add kubernetes_service_account_token_file * fix loading of token file
This commit is contained in:
parent
a68046e340
commit
ee38346ca2
8 changed files with 739 additions and 712 deletions
|
@ -298,7 +298,10 @@ func (e *Evaluator) evaluatePolicy(ctx context.Context, req *Request) (*PolicyRe
|
|||
}
|
||||
|
||||
func (e *Evaluator) evaluateHeaders(ctx context.Context, req *Request) (*HeadersResponse, error) {
|
||||
headersReq := NewHeadersRequestFromPolicy(req.Policy, req.HTTP)
|
||||
headersReq, err := NewHeadersRequestFromPolicy(req.Policy, req.HTTP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
headersReq.Session = req.Session
|
||||
res, err := e.headersEvaluators.Evaluate(ctx, headersReq)
|
||||
if err != nil {
|
||||
|
|
|
@ -30,21 +30,25 @@ type HeadersRequest struct {
|
|||
}
|
||||
|
||||
// NewHeadersRequestFromPolicy creates a new HeadersRequest from a policy.
|
||||
func NewHeadersRequestFromPolicy(policy *config.Policy, http RequestHTTP) *HeadersRequest {
|
||||
func NewHeadersRequestFromPolicy(policy *config.Policy, http RequestHTTP) (*HeadersRequest, error) {
|
||||
input := new(HeadersRequest)
|
||||
input.Issuer = http.Hostname
|
||||
if policy != nil {
|
||||
input.EnableGoogleCloudServerlessAuthentication = policy.EnableGoogleCloudServerlessAuthentication
|
||||
input.EnableRoutingKey = policy.EnvoyOpts.GetLbPolicy() == envoy_config_cluster_v3.Cluster_RING_HASH ||
|
||||
policy.EnvoyOpts.GetLbPolicy() == envoy_config_cluster_v3.Cluster_MAGLEV
|
||||
input.KubernetesServiceAccountToken = policy.KubernetesServiceAccountToken
|
||||
var err error
|
||||
input.KubernetesServiceAccountToken, err = policy.GetKubernetesServiceAccountToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, wu := range policy.To {
|
||||
input.ToAudience = "https://" + wu.URL.Hostname()
|
||||
}
|
||||
input.ClientCertificate = http.ClientCertificate
|
||||
input.SetRequestHeaders = policy.SetRequestHeaders
|
||||
}
|
||||
return input
|
||||
return input, nil
|
||||
}
|
||||
|
||||
// HeadersResponse is the output from the headers.rego script.
|
||||
|
|
|
@ -29,7 +29,7 @@ import (
|
|||
)
|
||||
|
||||
func TestNewHeadersRequestFromPolicy(t *testing.T) {
|
||||
req := NewHeadersRequestFromPolicy(&config.Policy{
|
||||
req, _ := NewHeadersRequestFromPolicy(&config.Policy{
|
||||
EnableGoogleCloudServerlessAuthentication: true,
|
||||
From: "https://*.example.com",
|
||||
To: config.WeightedURLs{
|
||||
|
@ -54,7 +54,7 @@ func TestNewHeadersRequestFromPolicy(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewHeadersRequestFromPolicy_nil(t *testing.T) {
|
||||
req := NewHeadersRequestFromPolicy(nil, RequestHTTP{Hostname: "from.example.com"})
|
||||
req, _ := NewHeadersRequestFromPolicy(nil, RequestHTTP{Hostname: "from.example.com"})
|
||||
assert.Equal(t, &HeadersRequest{
|
||||
Issuer: "from.example.com",
|
||||
}, req)
|
||||
|
|
|
@ -29,18 +29,19 @@ import (
|
|||
envoy_config_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
"github.com/pomerium/csrf"
|
||||
"github.com/pomerium/pomerium/internal/testutil"
|
||||
"github.com/pomerium/pomerium/pkg/cryptutil"
|
||||
configpb "github.com/pomerium/pomerium/pkg/grpc/config"
|
||||
"github.com/pomerium/pomerium/pkg/identity/oauth/apple"
|
||||
"github.com/pomerium/protoutil/protorand"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
"google.golang.org/protobuf/types/known/fieldmaskpb"
|
||||
|
||||
"github.com/pomerium/csrf"
|
||||
"github.com/pomerium/pomerium/internal/testutil"
|
||||
"github.com/pomerium/pomerium/pkg/cryptutil"
|
||||
configpb "github.com/pomerium/pomerium/pkg/grpc/config"
|
||||
"github.com/pomerium/pomerium/pkg/identity/oauth/apple"
|
||||
"github.com/pomerium/protoutil/protorand"
|
||||
)
|
||||
|
||||
var cmpOptIgnoreUnexported = cmpopts.IgnoreUnexported(Options{}, Policy{})
|
||||
|
|
186
config/policy.go
186
config/policy.go
|
@ -233,52 +233,53 @@ func NewPolicyFromProto(pb *configpb.Route) (*Policy, error) {
|
|||
}
|
||||
|
||||
p := &Policy{
|
||||
ID: pb.GetId(),
|
||||
From: pb.GetFrom(),
|
||||
AllowedUsers: pb.GetAllowedUsers(),
|
||||
AllowAnyAuthenticatedUser: pb.GetAllowAnyAuthenticatedUser(),
|
||||
AllowedDomains: pb.GetAllowedDomains(),
|
||||
AllowedIDPClaims: identity.NewFlattenedClaimsFromPB(pb.GetAllowedIdpClaims()),
|
||||
Prefix: pb.GetPrefix(),
|
||||
Path: pb.GetPath(),
|
||||
Regex: pb.GetRegex(),
|
||||
PrefixRewrite: pb.GetPrefixRewrite(),
|
||||
RegexRewritePattern: pb.GetRegexRewritePattern(),
|
||||
RegexRewriteSubstitution: pb.GetRegexRewriteSubstitution(),
|
||||
RegexPriorityOrder: pb.RegexPriorityOrder,
|
||||
CORSAllowPreflight: pb.GetCorsAllowPreflight(),
|
||||
AllowedUsers: pb.GetAllowedUsers(),
|
||||
AllowPublicUnauthenticatedAccess: pb.GetAllowPublicUnauthenticatedAccess(),
|
||||
AllowAnyAuthenticatedUser: pb.GetAllowAnyAuthenticatedUser(),
|
||||
UpstreamTimeout: timeout,
|
||||
IdleTimeout: idleTimeout,
|
||||
AllowWebsockets: pb.GetAllowWebsockets(),
|
||||
AllowSPDY: pb.GetAllowSpdy(),
|
||||
TLSSkipVerify: pb.GetTlsSkipVerify(),
|
||||
TLSServerName: pb.GetTlsServerName(),
|
||||
TLSDownstreamServerName: pb.GetTlsDownstreamServerName(),
|
||||
TLSUpstreamServerName: pb.GetTlsUpstreamServerName(),
|
||||
TLSUpstreamAllowRenegotiation: pb.GetTlsUpstreamAllowRenegotiation(),
|
||||
TLSCustomCA: pb.GetTlsCustomCa(),
|
||||
TLSCustomCAFile: pb.GetTlsCustomCaFile(),
|
||||
TLSClientCert: pb.GetTlsClientCert(),
|
||||
TLSClientKey: pb.GetTlsClientKey(),
|
||||
TLSClientCertFile: pb.GetTlsClientCertFile(),
|
||||
TLSClientKeyFile: pb.GetTlsClientKeyFile(),
|
||||
TLSDownstreamClientCA: pb.GetTlsDownstreamClientCa(),
|
||||
TLSDownstreamClientCAFile: pb.GetTlsDownstreamClientCaFile(),
|
||||
SetRequestHeaders: pb.GetSetRequestHeaders(),
|
||||
RemoveRequestHeaders: pb.GetRemoveRequestHeaders(),
|
||||
PreserveHostHeader: pb.GetPreserveHostHeader(),
|
||||
HostRewrite: pb.GetHostRewrite(),
|
||||
HostRewriteHeader: pb.GetHostRewriteHeader(),
|
||||
HostPathRegexRewritePattern: pb.GetHostPathRegexRewritePattern(),
|
||||
HostPathRegexRewriteSubstitution: pb.GetHostPathRegexRewriteSubstitution(),
|
||||
PassIdentityHeaders: pb.PassIdentityHeaders,
|
||||
KubernetesServiceAccountToken: pb.GetKubernetesServiceAccountToken(),
|
||||
SetResponseHeaders: pb.GetSetResponseHeaders(),
|
||||
AllowWebsockets: pb.GetAllowWebsockets(),
|
||||
CORSAllowPreflight: pb.GetCorsAllowPreflight(),
|
||||
EnableGoogleCloudServerlessAuthentication: pb.GetEnableGoogleCloudServerlessAuthentication(),
|
||||
IDPClientID: pb.GetIdpClientId(),
|
||||
IDPClientSecret: pb.GetIdpClientSecret(),
|
||||
ShowErrorDetails: pb.GetShowErrorDetails(),
|
||||
From: pb.GetFrom(),
|
||||
HostPathRegexRewritePattern: pb.GetHostPathRegexRewritePattern(),
|
||||
HostPathRegexRewriteSubstitution: pb.GetHostPathRegexRewriteSubstitution(),
|
||||
HostRewrite: pb.GetHostRewrite(),
|
||||
HostRewriteHeader: pb.GetHostRewriteHeader(),
|
||||
ID: pb.GetId(),
|
||||
IdleTimeout: idleTimeout,
|
||||
IDPClientID: pb.GetIdpClientId(),
|
||||
IDPClientSecret: pb.GetIdpClientSecret(),
|
||||
KubernetesServiceAccountToken: pb.GetKubernetesServiceAccountToken(),
|
||||
KubernetesServiceAccountTokenFile: pb.GetKubernetesServiceAccountTokenFile(),
|
||||
PassIdentityHeaders: pb.PassIdentityHeaders,
|
||||
Path: pb.GetPath(),
|
||||
Prefix: pb.GetPrefix(),
|
||||
PrefixRewrite: pb.GetPrefixRewrite(),
|
||||
PreserveHostHeader: pb.GetPreserveHostHeader(),
|
||||
Regex: pb.GetRegex(),
|
||||
RegexPriorityOrder: pb.RegexPriorityOrder,
|
||||
RegexRewritePattern: pb.GetRegexRewritePattern(),
|
||||
RegexRewriteSubstitution: pb.GetRegexRewriteSubstitution(),
|
||||
RemoveRequestHeaders: pb.GetRemoveRequestHeaders(),
|
||||
SetRequestHeaders: pb.GetSetRequestHeaders(),
|
||||
SetResponseHeaders: pb.GetSetResponseHeaders(),
|
||||
ShowErrorDetails: pb.GetShowErrorDetails(),
|
||||
TLSClientCert: pb.GetTlsClientCert(),
|
||||
TLSClientCertFile: pb.GetTlsClientCertFile(),
|
||||
TLSClientKey: pb.GetTlsClientKey(),
|
||||
TLSClientKeyFile: pb.GetTlsClientKeyFile(),
|
||||
TLSCustomCA: pb.GetTlsCustomCa(),
|
||||
TLSCustomCAFile: pb.GetTlsCustomCaFile(),
|
||||
TLSDownstreamClientCA: pb.GetTlsDownstreamClientCa(),
|
||||
TLSDownstreamClientCAFile: pb.GetTlsDownstreamClientCaFile(),
|
||||
TLSDownstreamServerName: pb.GetTlsDownstreamServerName(),
|
||||
TLSServerName: pb.GetTlsServerName(),
|
||||
TLSSkipVerify: pb.GetTlsSkipVerify(),
|
||||
TLSUpstreamAllowRenegotiation: pb.GetTlsUpstreamAllowRenegotiation(),
|
||||
TLSUpstreamServerName: pb.GetTlsUpstreamServerName(),
|
||||
UpstreamTimeout: timeout,
|
||||
}
|
||||
if pb.Redirect.IsSet() {
|
||||
p.Redirect = &PolicyRedirect{
|
||||
|
@ -372,49 +373,50 @@ func (p *Policy) ToProto() (*configpb.Route, error) {
|
|||
}
|
||||
|
||||
pb := &configpb.Route{
|
||||
Name: fmt.Sprint(p.RouteID()),
|
||||
Id: p.ID,
|
||||
From: p.From,
|
||||
AllowedUsers: p.AllowedUsers,
|
||||
AllowAnyAuthenticatedUser: p.AllowAnyAuthenticatedUser,
|
||||
AllowedDomains: p.AllowedDomains,
|
||||
AllowedIdpClaims: p.AllowedIDPClaims.ToPB(),
|
||||
Prefix: p.Prefix,
|
||||
Path: p.Path,
|
||||
Regex: p.Regex,
|
||||
PrefixRewrite: p.PrefixRewrite,
|
||||
RegexRewritePattern: p.RegexRewritePattern,
|
||||
RegexRewriteSubstitution: p.RegexRewriteSubstitution,
|
||||
RegexPriorityOrder: p.RegexPriorityOrder,
|
||||
CorsAllowPreflight: p.CORSAllowPreflight,
|
||||
AllowedUsers: p.AllowedUsers,
|
||||
AllowPublicUnauthenticatedAccess: p.AllowPublicUnauthenticatedAccess,
|
||||
AllowAnyAuthenticatedUser: p.AllowAnyAuthenticatedUser,
|
||||
Timeout: timeout,
|
||||
IdleTimeout: idleTimeout,
|
||||
AllowWebsockets: p.AllowWebsockets,
|
||||
AllowSpdy: p.AllowSPDY,
|
||||
TlsSkipVerify: p.TLSSkipVerify,
|
||||
TlsServerName: p.TLSServerName,
|
||||
TlsUpstreamServerName: p.TLSUpstreamServerName,
|
||||
TlsDownstreamServerName: p.TLSDownstreamServerName,
|
||||
TlsCustomCa: p.TLSCustomCA,
|
||||
TlsCustomCaFile: p.TLSCustomCAFile,
|
||||
TlsClientCert: p.TLSClientCert,
|
||||
TlsClientKey: p.TLSClientKey,
|
||||
TlsClientCertFile: p.TLSClientCertFile,
|
||||
TlsClientKeyFile: p.TLSClientKeyFile,
|
||||
TlsDownstreamClientCa: p.TLSDownstreamClientCA,
|
||||
TlsDownstreamClientCaFile: p.TLSDownstreamClientCAFile,
|
||||
TlsUpstreamAllowRenegotiation: p.TLSUpstreamAllowRenegotiation,
|
||||
SetRequestHeaders: p.SetRequestHeaders,
|
||||
RemoveRequestHeaders: p.RemoveRequestHeaders,
|
||||
PreserveHostHeader: p.PreserveHostHeader,
|
||||
PassIdentityHeaders: p.PassIdentityHeaders,
|
||||
KubernetesServiceAccountToken: p.KubernetesServiceAccountToken,
|
||||
AllowWebsockets: p.AllowWebsockets,
|
||||
CorsAllowPreflight: p.CORSAllowPreflight,
|
||||
EnableGoogleCloudServerlessAuthentication: p.EnableGoogleCloudServerlessAuthentication,
|
||||
Policies: sps,
|
||||
EnvoyOpts: p.EnvoyOpts,
|
||||
SetResponseHeaders: p.SetResponseHeaders,
|
||||
ShowErrorDetails: p.ShowErrorDetails,
|
||||
EnvoyOpts: p.EnvoyOpts,
|
||||
From: p.From,
|
||||
Id: p.ID,
|
||||
IdleTimeout: idleTimeout,
|
||||
KubernetesServiceAccountToken: p.KubernetesServiceAccountToken,
|
||||
KubernetesServiceAccountTokenFile: p.KubernetesServiceAccountTokenFile,
|
||||
Name: fmt.Sprint(p.RouteID()),
|
||||
PassIdentityHeaders: p.PassIdentityHeaders,
|
||||
Path: p.Path,
|
||||
Policies: sps,
|
||||
Prefix: p.Prefix,
|
||||
PrefixRewrite: p.PrefixRewrite,
|
||||
PreserveHostHeader: p.PreserveHostHeader,
|
||||
Regex: p.Regex,
|
||||
RegexPriorityOrder: p.RegexPriorityOrder,
|
||||
RegexRewritePattern: p.RegexRewritePattern,
|
||||
RegexRewriteSubstitution: p.RegexRewriteSubstitution,
|
||||
RemoveRequestHeaders: p.RemoveRequestHeaders,
|
||||
SetRequestHeaders: p.SetRequestHeaders,
|
||||
SetResponseHeaders: p.SetResponseHeaders,
|
||||
ShowErrorDetails: p.ShowErrorDetails,
|
||||
Timeout: timeout,
|
||||
TlsClientCert: p.TLSClientCert,
|
||||
TlsClientCertFile: p.TLSClientCertFile,
|
||||
TlsClientKey: p.TLSClientKey,
|
||||
TlsClientKeyFile: p.TLSClientKeyFile,
|
||||
TlsCustomCa: p.TLSCustomCA,
|
||||
TlsCustomCaFile: p.TLSCustomCAFile,
|
||||
TlsDownstreamClientCa: p.TLSDownstreamClientCA,
|
||||
TlsDownstreamClientCaFile: p.TLSDownstreamClientCAFile,
|
||||
TlsDownstreamServerName: p.TLSDownstreamServerName,
|
||||
TlsServerName: p.TLSServerName,
|
||||
TlsSkipVerify: p.TLSSkipVerify,
|
||||
TlsUpstreamAllowRenegotiation: p.TLSUpstreamAllowRenegotiation,
|
||||
TlsUpstreamServerName: p.TLSUpstreamServerName,
|
||||
}
|
||||
if p.HostPathRegexRewritePattern != "" {
|
||||
pb.HostPathRegexRewritePattern = proto.String(p.HostPathRegexRewritePattern)
|
||||
|
@ -568,16 +570,8 @@ func (p *Policy) Validate() error {
|
|||
p.TLSDownstreamClientCA = base64.StdEncoding.EncodeToString(bs)
|
||||
}
|
||||
|
||||
if p.KubernetesServiceAccountTokenFile != "" {
|
||||
if p.KubernetesServiceAccountToken != "" {
|
||||
return fmt.Errorf("config: specified both `kubernetes_service_account_token_file` and `kubernetes_service_account_token`")
|
||||
}
|
||||
|
||||
token, err := os.ReadFile(p.KubernetesServiceAccountTokenFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("config: failed to load kubernetes service account token: %w", err)
|
||||
}
|
||||
p.KubernetesServiceAccountToken = string(token)
|
||||
if p.KubernetesServiceAccountTokenFile != "" && p.KubernetesServiceAccountToken != "" {
|
||||
return fmt.Errorf("config: specified both `kubernetes_service_account_token_file` and `kubernetes_service_account_token`")
|
||||
}
|
||||
|
||||
if p.PrefixRewrite != "" && p.RegexRewritePattern != "" {
|
||||
|
@ -732,6 +726,20 @@ func (p *Policy) AllAllowedUsers() []string {
|
|||
return aus
|
||||
}
|
||||
|
||||
// GetKubernetesServiceAccountToken gets the kubernetes service account token from a file or from the config option.
|
||||
func (p *Policy) GetKubernetesServiceAccountToken() (string, error) {
|
||||
if p.KubernetesServiceAccountTokenFile != "" {
|
||||
bs, err := os.ReadFile(p.KubernetesServiceAccountTokenFile)
|
||||
return string(bs), err
|
||||
}
|
||||
|
||||
if p.KubernetesServiceAccountToken != "" {
|
||||
return p.KubernetesServiceAccountToken, nil
|
||||
}
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// GetPassIdentityHeaders gets the pass identity headers option. If not set in the policy, use the setting from the
|
||||
// options. If not set in either, return false.
|
||||
func (p *Policy) GetPassIdentityHeaders(options *Options) bool {
|
||||
|
|
|
@ -47,7 +47,6 @@ func Test_PolicyValidate(t *testing.T) {
|
|||
{"bad key file", Policy{From: "https://httpbin.corp.example", To: mustParseWeightedURLs(t, "https://httpbin.corp.notatld"), TLSClientCertFile: "testdata/example-cert.pem", TLSClientKeyFile: "testdata/example-key-404.pem"}, true},
|
||||
{"good tls server name", Policy{From: "https://httpbin.corp.example", To: mustParseWeightedURLs(t, "https://internal-host-name"), TLSServerName: "httpbin.corp.notatld"}, false},
|
||||
{"good kube service account token file", Policy{From: "https://httpbin.corp.example", To: mustParseWeightedURLs(t, "https://internal-host-name"), KubernetesServiceAccountTokenFile: "testdata/kubeserviceaccount.token"}, false},
|
||||
{"bad kube service account token file", Policy{From: "https://httpbin.corp.example", To: mustParseWeightedURLs(t, "https://internal-host-name"), KubernetesServiceAccountTokenFile: "testdata/missing.token"}, true},
|
||||
{"good kube service account token", Policy{From: "https://httpbin.corp.example", To: mustParseWeightedURLs(t, "https://internal-host-name"), KubernetesServiceAccountToken: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE1OTY1MDk4MjIsImV4cCI6MTYyODA0NTgyMiwiYXVkIjoid3d3LmV4YW1wbGUuY29tIiwic3ViIjoianJvY2tldEBleGFtcGxlLmNvbSIsIkdpdmVuTmFtZSI6IkpvaG5ueSIsIlN1cm5hbWUiOiJSb2NrZXQiLCJFbWFpbCI6Impyb2NrZXRAZXhhbXBsZS5jb20iLCJSb2xlIjpbIk1hbmFnZXIiLCJQcm9qZWN0IEFkbWluaXN0cmF0b3IiXX0.H0I6ccQrL6sKobsKQj9dqNcLw_INhU9_xJsVyCkgkiY"}, false},
|
||||
{"bad kube service account token and file", Policy{From: "https://httpbin.corp.example", To: mustParseWeightedURLs(t, "https://internal-host-name"), KubernetesServiceAccountToken: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE1OTY1MDk4MjIsImV4cCI6MTYyODA0NTgyMiwiYXVkIjoid3d3LmV4YW1wbGUuY29tIiwic3ViIjoianJvY2tldEBleGFtcGxlLmNvbSIsIkdpdmVuTmFtZSI6IkpvaG5ueSIsIlN1cm5hbWUiOiJSb2NrZXQiLCJFbWFpbCI6Impyb2NrZXRAZXhhbXBsZS5jb20iLCJSb2xlIjpbIk1hbmFnZXIiLCJQcm9qZWN0IEFkbWluaXN0cmF0b3IiXX0.H0I6ccQrL6sKobsKQj9dqNcLw_INhU9_xJsVyCkgkiY", KubernetesServiceAccountTokenFile: "testdata/kubeserviceaccount.token"}, true},
|
||||
{"TCP To URLs", Policy{From: "tcp+https://httpbin.corp.example:4000", To: mustParseWeightedURLs(t, "tcp://one.example.com:5000", "tcp://two.example.com:5000")}, false},
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -38,7 +38,7 @@ message RouteDirectResponse {
|
|||
string body = 2;
|
||||
}
|
||||
|
||||
// Next ID: 63.
|
||||
// Next ID: 65.
|
||||
message Route {
|
||||
string name = 1;
|
||||
|
||||
|
@ -103,6 +103,7 @@ message Route {
|
|||
optional bool pass_identity_headers = 25;
|
||||
|
||||
string kubernetes_service_account_token = 26;
|
||||
string kubernetes_service_account_token_file = 64;
|
||||
bool enable_google_cloud_serverless_authentication = 42;
|
||||
|
||||
envoy.config.cluster.v3.Cluster envoy_opts = 36;
|
||||
|
@ -121,9 +122,7 @@ message Route {
|
|||
bool show_error_details = 59;
|
||||
}
|
||||
|
||||
message PPLPolicy {
|
||||
bytes raw = 1;
|
||||
}
|
||||
message PPLPolicy { bytes raw = 1; }
|
||||
|
||||
message Policy {
|
||||
string id = 1;
|
||||
|
|
Loading…
Add table
Reference in a new issue