From 41e6f6cd8be293fcd382ae8226f53c1428bfec53 Mon Sep 17 00:00:00 2001 From: "Chris S. Kim" Date: Tue, 3 Oct 2023 14:57:53 -0400 Subject: [PATCH 1/6] Reduce number of ports that consul test agents take (#19047) --- agent/testagent.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/agent/testagent.go b/agent/testagent.go index 39a83a087f40..8ae2220adc6c 100644 --- a/agent/testagent.go +++ b/agent/testagent.go @@ -17,9 +17,9 @@ import ( "text/template" "time" - metrics "github.com/armon/go-metrics" + "github.com/armon/go-metrics" "github.com/hashicorp/go-hclog" - uuid "github.com/hashicorp/go-uuid" + "github.com/hashicorp/go-uuid" "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/config" @@ -414,12 +414,12 @@ func (a *TestAgent) consulConfig() *consul.Config { // Instead of relying on one set of ports to be sufficient we retry // starting the agent with different ports on port conflict. func randomPortsSource(t *testing.T, useHTTPS bool) string { - ports := freeport.GetN(t, 8) + ports := freeport.GetN(t, 7) var http, https int if useHTTPS { http = -1 - https = ports[2] + https = ports[1] } else { http = ports[1] https = -1 @@ -430,11 +430,11 @@ func randomPortsSource(t *testing.T, useHTTPS bool) string { dns = ` + strconv.Itoa(ports[0]) + ` http = ` + strconv.Itoa(http) + ` https = ` + strconv.Itoa(https) + ` - serf_lan = ` + strconv.Itoa(ports[3]) + ` - serf_wan = ` + strconv.Itoa(ports[4]) + ` - server = ` + strconv.Itoa(ports[5]) + ` - grpc = ` + strconv.Itoa(ports[6]) + ` - grpc_tls = ` + strconv.Itoa(ports[7]) + ` + serf_lan = ` + strconv.Itoa(ports[2]) + ` + serf_wan = ` + strconv.Itoa(ports[3]) + ` + server = ` + strconv.Itoa(ports[4]) + ` + grpc = ` + strconv.Itoa(ports[5]) + ` + grpc_tls = ` + strconv.Itoa(ports[6]) + ` } ` } From d67e5c6e358fbc60f9a73eceadaa06d4ac43e626 Mon Sep 17 00:00:00 2001 From: John Murret Date: Tue, 3 Oct 2023 16:02:23 -0600 Subject: [PATCH 2/6] NET-5590 - authorization: check for identity:write in CA certs, xds server, and getting envoy bootstrap params (#19049) * NET-5590 - authorization: check for identity:write in CA certs, xds server, and getting envoy bootstrap params * gofmt file --- agent/consul/leader_connect_ca.go | 5 +- agent/consul/leader_connect_ca_test.go | 15 ++++ .../dataplane/get_envoy_bootstrap_params.go | 5 +- .../get_envoy_bootstrap_params_test.go | 27 +++++-- agent/grpc-external/testutils/acl.go | 12 +++ .../mesh/proxy-tracker/proxy_state_exports.go | 9 ++- .../proxy-tracker/proxy_state_exports_test.go | 78 +++++++++++++++++++ 7 files changed, 142 insertions(+), 9 deletions(-) create mode 100644 internal/mesh/proxy-tracker/proxy_state_exports_test.go diff --git a/agent/consul/leader_connect_ca.go b/agent/consul/leader_connect_ca.go index fd190ed35e6e..92cdf40a6abd 100644 --- a/agent/consul/leader_connect_ca.go +++ b/agent/consul/leader_connect_ca.go @@ -1456,7 +1456,10 @@ func (c *CAManager) AuthorizeAndSignCertificate(csr *x509.CertificateRequest, au "we are %s", v.Datacenter, dc) } case *connect.SpiffeIDWorkloadIdentity: - // TODO: Check for identity:write on the token when identity permissions are supported. + v.GetEnterpriseMeta().FillAuthzContext(&authzContext) + if err := allow.IdentityWriteAllowed(v.WorkloadIdentity, &authzContext); err != nil { + return nil, err + } case *connect.SpiffeIDAgent: v.GetEnterpriseMeta().FillAuthzContext(&authzContext) if err := allow.NodeWriteAllowed(v.Agent, &authzContext); err != nil { diff --git a/agent/consul/leader_connect_ca_test.go b/agent/consul/leader_connect_ca_test.go index b3e8fdc9d0ed..e372c010a706 100644 --- a/agent/consul/leader_connect_ca_test.go +++ b/agent/consul/leader_connect_ca_test.go @@ -1317,6 +1317,12 @@ func TestCAManager_AuthorizeAndSignCertificate(t *testing.T) { Host: "test-host", Partition: "test-partition", }.URI() + identityURL := connect.SpiffeIDWorkloadIdentity{ + TrustDomain: "test-trust-domain", + Partition: "test-partition", + Namespace: "test-namespace", + WorkloadIdentity: "test-workload-identity", + }.URI() tests := []struct { name string @@ -1412,6 +1418,15 @@ func TestCAManager_AuthorizeAndSignCertificate(t *testing.T) { } }, }, + { + name: "err_identity_write_not_allowed", + expectErr: "Permission denied", + getCSR: func() *x509.CertificateRequest { + return &x509.CertificateRequest{ + URIs: []*url.URL{identityURL}, + } + }, + }, } for _, tc := range tests { diff --git a/agent/grpc-external/services/dataplane/get_envoy_bootstrap_params.go b/agent/grpc-external/services/dataplane/get_envoy_bootstrap_params.go index aaa3a33728d7..ea5d9c47b488 100644 --- a/agent/grpc-external/services/dataplane/get_envoy_bootstrap_params.go +++ b/agent/grpc-external/services/dataplane/get_envoy_bootstrap_params.go @@ -80,7 +80,10 @@ func (s *Server) GetEnvoyBootstrapParams(ctx context.Context, req *pbdataplane.G return nil, status.Errorf(codes.InvalidArgument, "workload %q doesn't have identity associated with it", req.ProxyId) } - // todo (ishustava): ACL enforcement ensuring there's identity:write permissions. + // verify identity:write is allowed. if not, give permission denied error. + if err := authz.ToAllowAuthorizer().IdentityWriteAllowed(workload.Identity, &authzContext); err != nil { + return nil, err + } // Get all proxy configurations for this workload. Currently we're only looking // for proxy configurations in the same tenancy as the workload. diff --git a/agent/grpc-external/services/dataplane/get_envoy_bootstrap_params_test.go b/agent/grpc-external/services/dataplane/get_envoy_bootstrap_params_test.go index ff365d9ff13a..a3761305e97a 100644 --- a/agent/grpc-external/services/dataplane/get_envoy_bootstrap_params_test.go +++ b/agent/grpc-external/services/dataplane/get_envoy_bootstrap_params_test.go @@ -34,6 +34,7 @@ import ( ) const ( + testIdentity = "test-identity" testToken = "acl-token-get-envoy-bootstrap-params" testServiceName = "web" proxyServiceID = "web-proxy" @@ -308,7 +309,23 @@ func TestGetEnvoyBootstrapParams_Success_EnableV2(t *testing.T) { } aclResolver.On("ResolveTokenAndDefaultMeta", testToken, mock.Anything, mock.Anything). - Return(testutils.ACLServiceRead(t, workloadResource.Id.Name), nil) + Return(testutils.ACLUseProvidedPolicy(t, + &acl.Policy{ + PolicyRules: acl.PolicyRules{ + Services: []*acl.ServiceRule{ + { + Name: workloadResource.Id.Name, + Policy: acl.PolicyRead, + }, + }, + Identities: []*acl.IdentityRule{ + { + Name: testIdentity, + Policy: acl.PolicyWrite, + }, + }, + }, + }), nil) resp, err := client.GetEnvoyBootstrapParams(ctx, req) require.NoError(t, err) @@ -328,14 +345,14 @@ func TestGetEnvoyBootstrapParams_Success_EnableV2(t *testing.T) { { name: "workload without node", workloadData: &pbcatalog.Workload{ - Identity: "test-identity", + Identity: testIdentity, }, expBootstrapCfg: &pbmesh.BootstrapConfig{}, }, { name: "workload with node", workloadData: &pbcatalog.Workload{ - Identity: "test-identity", + Identity: testIdentity, NodeName: "test-node", }, expBootstrapCfg: &pbmesh.BootstrapConfig{}, @@ -343,7 +360,7 @@ func TestGetEnvoyBootstrapParams_Success_EnableV2(t *testing.T) { { name: "single proxy configuration", workloadData: &pbcatalog.Workload{ - Identity: "test-identity", + Identity: testIdentity, }, proxyCfgs: []*pbmesh.ProxyConfiguration{ { @@ -360,7 +377,7 @@ func TestGetEnvoyBootstrapParams_Success_EnableV2(t *testing.T) { { name: "multiple proxy configurations", workloadData: &pbcatalog.Workload{ - Identity: "test-identity", + Identity: testIdentity, }, proxyCfgs: []*pbmesh.ProxyConfiguration{ { diff --git a/agent/grpc-external/testutils/acl.go b/agent/grpc-external/testutils/acl.go index caa5c7ae81f5..72e0897e71fd 100644 --- a/agent/grpc-external/testutils/acl.go +++ b/agent/grpc-external/testutils/acl.go @@ -84,6 +84,18 @@ func ACLServiceRead(t *testing.T, serviceName string) resolver.Result { } } +func ACLUseProvidedPolicy(t *testing.T, aclPolicy *acl.Policy) resolver.Result { + t.Helper() + + authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{aclPolicy}, nil) + require.NoError(t, err) + + return resolver.Result{ + Authorizer: authz, + ACLIdentity: randomACLIdentity(t), + } +} + func ACLOperatorRead(t *testing.T) resolver.Result { t.Helper() diff --git a/internal/mesh/proxy-tracker/proxy_state_exports.go b/internal/mesh/proxy-tracker/proxy_state_exports.go index d1051c3cac42..cdc6d6d84580 100644 --- a/internal/mesh/proxy-tracker/proxy_state_exports.go +++ b/internal/mesh/proxy-tracker/proxy_state_exports.go @@ -5,6 +5,7 @@ package proxytracker import ( "github.com/hashicorp/consul/acl" + "github.com/hashicorp/consul/internal/resource" pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" ) @@ -34,9 +35,13 @@ func (p *ProxyState) AllowEmptyClusters() bool { } func (p *ProxyState) Authorize(authz acl.Authorizer) error { - // TODO(proxystate): we'll need to implement this once identity policy is implemented + // authorize for mesh proxies. + // TODO(proxystate): implement differently for gateways + allow := authz.ToAllowAuthorizer() + if err := allow.IdentityWriteAllowed(p.Identity.Name, resource.AuthorizerContext(p.Identity.Tenancy)); err != nil { + return err + } - // Authed OK! return nil } diff --git a/internal/mesh/proxy-tracker/proxy_state_exports_test.go b/internal/mesh/proxy-tracker/proxy_state_exports_test.go new file mode 100644 index 000000000000..18d15fb53dad --- /dev/null +++ b/internal/mesh/proxy-tracker/proxy_state_exports_test.go @@ -0,0 +1,78 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package proxytracker + +import ( + "github.com/hashicorp/consul/acl" + pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" + "github.com/hashicorp/consul/proto-public/pbresource" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + "strings" + "testing" +) + +func TestProxyState_Authorize(t *testing.T) { + testIdentity := &pbresource.Reference{ + Type: &pbresource.Type{ + Group: "mesh", + GroupVersion: "v1alpha1", + Kind: "Identity", + }, + Tenancy: &pbresource.Tenancy{ + Partition: "default", + Namespace: "default", + PeerName: "local", + }, + Name: "test-identity", + } + + type testCase struct { + description string + proxyState *ProxyState + configureAuthorizer func(authorizer *acl.MockAuthorizer) + expectedErrorMessage string + } + testsCases := []testCase{ + { + description: "ProxyState - if identity write is allowed for the workload then allow.", + proxyState: &ProxyState{ + ProxyState: &pbmesh.ProxyState{ + Identity: testIdentity, + }, + }, + expectedErrorMessage: "", + configureAuthorizer: func(authz *acl.MockAuthorizer) { + authz.On("IdentityWrite", testIdentity.Name, mock.Anything).Return(acl.Allow) + }, + }, + { + description: "ProxyState - if identity write is not allowed for the workload then deny.", + proxyState: &ProxyState{ + ProxyState: &pbmesh.ProxyState{ + Identity: testIdentity, + }, + }, + expectedErrorMessage: "Permission denied: token with AccessorID '' lacks permission 'identity:write' on \"test-identity\"", + configureAuthorizer: func(authz *acl.MockAuthorizer) { + authz.On("IdentityWrite", testIdentity.Name, mock.Anything).Return(acl.Deny) + }, + }, + } + for _, tc := range testsCases { + t.Run(tc.description, func(t *testing.T) { + authz := &acl.MockAuthorizer{} + authz.On("ToAllow").Return(acl.AllowAuthorizer{Authorizer: authz}) + tc.configureAuthorizer(authz) + err := tc.proxyState.Authorize(authz) + errMsg := "" + if err != nil { + errMsg = err.Error() + } + // using contains because Enterprise tests append the parition and namespace + // information to the message. + require.True(t, strings.Contains(errMsg, tc.expectedErrorMessage)) + }) + } +} From f2b7b4591a95796c00a4c4453291492a7ab3ce73 Mon Sep 17 00:00:00 2001 From: Eric Haberkorn Date: Wed, 4 Oct 2023 09:58:28 -0400 Subject: [PATCH 3/6] Fix Traffic Permissions Default Deny (#19028) Whenver a traffic permission exists for a given workload identity, turn on default deny. Previously, this was only working at the port level. --- agent/xds/rbac_test.go | 38 +---- .../rbac/v2-default-allow-one-allow.golden | 30 ---- .../rbac/v2-default-allow-one-deny.golden | 43 ----- agent/xdsv2/listener_resources.go | 6 +- agent/xdsv2/rbac_resources.go | 11 +- .../trafficpermissions/controller.go | 10 +- .../trafficpermissions/controller_test.go | 54 +++++-- .../controllers/trafficpermissions/status.go | 50 +++--- .../sidecarproxy/builder/builder.go | 1 - .../sidecarproxy/builder/local_app.go | 19 ++- .../sidecarproxy/builder/local_app_test.go | 129 ++++++++++++++- ...kload-addresses-with-specific-ports.golden | 3 +- .../sidecarproxy/controller_test.go | 66 +++++--- .../mesh/proxy-tracker/proxy_tracker_test.go | 8 +- .../computed_traffic_permissions.pb.go | 52 +++--- .../computed_traffic_permissions.proto | 1 + .../pbproxystate/traffic_permissions.pb.go | 101 +++++++----- .../pbproxystate/traffic_permissions.proto | 4 + proto-public/pbmesh/v2beta1/proxy_state.pb.go | 151 ++++++++---------- proto-public/pbmesh/v2beta1/proxy_state.proto | 6 +- .../multiport/explicit_destination_test.go | 1 + 21 files changed, 441 insertions(+), 343 deletions(-) delete mode 100644 agent/xds/testdata/rbac/v2-default-allow-one-allow.golden delete mode 100644 agent/xds/testdata/rbac/v2-default-allow-one-deny.golden diff --git a/agent/xds/rbac_test.go b/agent/xds/rbac_test.go index 1b89826b1859..f51904954487 100644 --- a/agent/xds/rbac_test.go +++ b/agent/xds/rbac_test.go @@ -739,44 +739,18 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { intentionDefaultAllow: true, v2L4TrafficPermissions: &pbproxystate.TrafficPermissions{}, }, - "v2-default-allow-one-allow": { - intentionDefaultAllow: true, - v2L4TrafficPermissions: &pbproxystate.TrafficPermissions{ - AllowPermissions: []*pbproxystate.Permission{ - { - Principals: []*pbproxystate.Principal{ - { - Spiffe: makeSpiffe("web", nil), - }, - }, - }, - }, - }, - }, - // In v2, having a single permission turns on default deny. - "v2-default-allow-one-deny": { - intentionDefaultAllow: true, - v2L4TrafficPermissions: &pbproxystate.TrafficPermissions{ - DenyPermissions: []*pbproxystate.Permission{ - { - Principals: []*pbproxystate.Principal{ - { - Spiffe: makeSpiffe("web", nil), - }, - }, - }, - }, - }, - }, // This validates that we don't send xDS messages to Envoy that will fail validation. // Traffic permissions validations prevent this from being written to the IR, so the thing // that matters is that the snapshot is valid to Envoy. "v2-ignore-empty-permissions": { - intentionDefaultAllow: true, + intentionDefaultAllow: false, v2L4TrafficPermissions: &pbproxystate.TrafficPermissions{ DenyPermissions: []*pbproxystate.Permission{ {}, }, + AllowPermissions: []*pbproxystate.Permission{ + {}, + }, }, }, "default-allow-kitchen-sink": { @@ -1109,7 +1083,9 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { return } - filters, err := xdsv2.MakeL4RBAC(tt.intentionDefaultAllow, tt.v2L4TrafficPermissions) + tt.v2L4TrafficPermissions.DefaultAllow = tt.intentionDefaultAllow + + filters, err := xdsv2.MakeL4RBAC(tt.v2L4TrafficPermissions) require.NoError(t, err) var gotJSON string diff --git a/agent/xds/testdata/rbac/v2-default-allow-one-allow.golden b/agent/xds/testdata/rbac/v2-default-allow-one-allow.golden deleted file mode 100644 index a02fd3518c1e..000000000000 --- a/agent/xds/testdata/rbac/v2-default-allow-one-allow.golden +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": { - "policies": { - "consul-intentions-layer4": { - "permissions": [ - { - "any": true - } - ], - "principals": [ - { - "authenticated": { - "principalName": { - "safeRegex": { - "googleRe2": {}, - "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" - } - } - } - } - ] - } - } - }, - "statPrefix": "connect_authz" - } -} \ No newline at end of file diff --git a/agent/xds/testdata/rbac/v2-default-allow-one-deny.golden b/agent/xds/testdata/rbac/v2-default-allow-one-deny.golden deleted file mode 100644 index 38e9fed973fd..000000000000 --- a/agent/xds/testdata/rbac/v2-default-allow-one-deny.golden +++ /dev/null @@ -1,43 +0,0 @@ -{ - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": { - "action": "DENY", - "policies": { - "consul-intentions-layer4": { - "permissions": [ - { - "any": true - } - ], - "principals": [ - { - "authenticated": { - "principalName": { - "safeRegex": { - "googleRe2": {}, - "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" - } - } - } - } - ] - } - } - }, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } - } - ] -} \ No newline at end of file diff --git a/agent/xdsv2/listener_resources.go b/agent/xdsv2/listener_resources.go index 57c108c9f816..a112d75bf5cd 100644 --- a/agent/xdsv2/listener_resources.go +++ b/agent/xdsv2/listener_resources.go @@ -308,7 +308,7 @@ func (pr *ProxyResources) makeEnvoyResourcesForL4Destination(l4 *pbproxystate.Ro if err != nil { return nil, err } - envoyFilters, err := makeL4Filters(pr.proxyState.TrafficPermissionDefaultAllow, l4.L4) + envoyFilters, err := makeL4Filters(l4.L4) return envoyFilters, err } @@ -333,10 +333,10 @@ func getAlpnProtocols(protocol pbproxystate.L7Protocol) []string { return alpnProtocols } -func makeL4Filters(defaultAllow bool, l4 *pbproxystate.L4Destination) ([]*envoy_listener_v3.Filter, error) { +func makeL4Filters(l4 *pbproxystate.L4Destination) ([]*envoy_listener_v3.Filter, error) { var envoyFilters []*envoy_listener_v3.Filter if l4 != nil { - rbacFilters, err := MakeL4RBAC(defaultAllow, l4.TrafficPermissions) + rbacFilters, err := MakeL4RBAC(l4.TrafficPermissions) if err != nil { return nil, err } diff --git a/agent/xdsv2/rbac_resources.go b/agent/xdsv2/rbac_resources.go index 10c21cd25fed..76d19a6f900d 100644 --- a/agent/xdsv2/rbac_resources.go +++ b/agent/xdsv2/rbac_resources.go @@ -20,7 +20,7 @@ const ( baseL4PermissionKey = "consul-intentions-layer4" ) -func MakeL4RBAC(defaultAllow bool, trafficPermissions *pbproxystate.TrafficPermissions) ([]*envoy_listener_v3.Filter, error) { +func MakeL4RBAC(trafficPermissions *pbproxystate.TrafficPermissions) ([]*envoy_listener_v3.Filter, error) { var filters []*envoy_listener_v3.Filter if trafficPermissions == nil { @@ -41,7 +41,7 @@ func MakeL4RBAC(defaultAllow bool, trafficPermissions *pbproxystate.TrafficPermi } // Only include the allow RBAC when Consul is in default deny. - if includeAllowFilter(defaultAllow, trafficPermissions) { + if !trafficPermissions.DefaultAllow { allowRBAC := &envoy_rbac_v3.RBAC{ Action: envoy_rbac_v3.RBAC_ALLOW, Policies: make(map[string]*envoy_rbac_v3.Policy), @@ -58,13 +58,6 @@ func MakeL4RBAC(defaultAllow bool, trafficPermissions *pbproxystate.TrafficPermi return filters, nil } -// includeAllowFilter determines if an Envoy RBAC allow filter will be included in the filter chain. -// We include this filter with default deny or whenever any permissions are configured. -func includeAllowFilter(defaultAllow bool, trafficPermissions *pbproxystate.TrafficPermissions) bool { - hasPermissions := len(trafficPermissions.DenyPermissions)+len(trafficPermissions.AllowPermissions) > 0 - return !defaultAllow || hasPermissions -} - func makeRBACFilter(rbac *envoy_rbac_v3.RBAC) (*envoy_listener_v3.Filter, error) { cfg := &envoy_network_rbac_v3.RBAC{ StatPrefix: "connect_authz", diff --git a/internal/auth/internal/controllers/trafficpermissions/controller.go b/internal/auth/internal/controllers/trafficpermissions/controller.go index 530191f519af..9e5912dc5e3c 100644 --- a/internal/auth/internal/controllers/trafficpermissions/controller.go +++ b/internal/auth/internal/controllers/trafficpermissions/controller.go @@ -126,7 +126,7 @@ func (r *reconciler) Reconcile(ctx context.Context, rt controller.Runtime, req c newStatus := &pbresource.Status{ ObservedGeneration: rsp.Resource.Generation, Conditions: []*pbresource.Condition{ - ConditionComputed(req.ID.Name), + ConditionComputed(req.ID.Name, latestTrafficPermissions.IsDefault), }, } _, err = rt.Client.WriteStatus(ctx, &pbresource.WriteStatusRequest{ @@ -167,6 +167,7 @@ func computeNewTrafficPermissions(ctx context.Context, rt controller.Runtime, wm } ap := make([]*pbauth.Permission, 0) dp := make([]*pbauth.Permission, 0) + isDefault := true for _, t := range trackedTPs { rsp, err := resource.GetDecodedResource[*pbauth.TrafficPermissions](ctx, rt.Client, resource.IDFromReference(t)) if err != nil { @@ -179,11 +180,16 @@ func computeNewTrafficPermissions(ctx context.Context, rt controller.Runtime, wm wm.UntrackTrafficPermissions(resource.IDFromReference(t)) continue } + isDefault = false if rsp.Data.Action == pbauth.Action_ACTION_ALLOW { ap = append(ap, rsp.Data.Permissions...) } else { dp = append(dp, rsp.Data.Permissions...) } } - return &pbauth.ComputedTrafficPermissions{AllowPermissions: ap, DenyPermissions: dp}, nil + return &pbauth.ComputedTrafficPermissions{ + AllowPermissions: ap, + DenyPermissions: dp, + IsDefault: isDefault, + }, nil } diff --git a/internal/auth/internal/controllers/trafficpermissions/controller_test.go b/internal/auth/internal/controllers/trafficpermissions/controller_test.go index 0f5795770147..910a6fb88e71 100644 --- a/internal/auth/internal/controllers/trafficpermissions/controller_test.go +++ b/internal/auth/internal/controllers/trafficpermissions/controller_test.go @@ -57,8 +57,8 @@ func (suite *controllerSuite) requireTrafficPermissionsTracking(tp *pbresource.R } func (suite *controllerSuite) requireCTP(resource *pbresource.Resource, allowExpected []*pbauth.Permission, denyExpected []*pbauth.Permission) { - var ctp pbauth.ComputedTrafficPermissions - require.NoError(suite.T(), resource.Data.UnmarshalTo(&ctp)) + dec := rtest.MustDecode[*pbauth.ComputedTrafficPermissions](suite.T(), resource) + ctp := dec.Data require.Len(suite.T(), ctp.AllowPermissions, len(allowExpected)) require.Len(suite.T(), ctp.DenyPermissions, len(denyExpected)) prototest.AssertElementsMatch(suite.T(), allowExpected, ctp.AllowPermissions) @@ -218,6 +218,9 @@ func (suite *controllerSuite) TestReconcile_TrafficPermissionsCreate_Destination err := suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id}) require.NoError(suite.T(), err) + ctpResource := suite.client.RequireResourceExists(suite.T(), id) + assertCTPDefaultStatus(suite.T(), ctpResource, true) + // create traffic permissions p1 := &pbauth.Permission{ Sources: []*pbauth.Source{ @@ -236,6 +239,7 @@ func (suite *controllerSuite) TestReconcile_TrafficPermissionsCreate_Destination Permissions: []*pbauth.Permission{p1}, }).Write(suite.T(), suite.client) suite.requireTrafficPermissionsTracking(tp1, id) + p2 := &pbauth.Permission{ Sources: []*pbauth.Source{ { @@ -258,9 +262,10 @@ func (suite *controllerSuite) TestReconcile_TrafficPermissionsCreate_Destination require.NoError(suite.T(), err) // Ensure that the CTP was updated - ctp := suite.client.RequireResourceExists(suite.T(), id) - suite.requireCTP(ctp, []*pbauth.Permission{p2}, []*pbauth.Permission{p1}) - rtest.RequireOwner(suite.T(), ctp, wi.Id, true) + ctpResource = suite.client.RequireResourceExists(suite.T(), id) + suite.requireCTP(ctpResource, []*pbauth.Permission{p2}, []*pbauth.Permission{p1}) + rtest.RequireOwner(suite.T(), ctpResource, wi.Id, true) + assertCTPDefaultStatus(suite.T(), ctpResource, false) // Add another TP p3 := &pbauth.Permission{ @@ -285,9 +290,23 @@ func (suite *controllerSuite) TestReconcile_TrafficPermissionsCreate_Destination require.NoError(suite.T(), err) // Ensure that the CTP was updated - ctp = suite.client.RequireResourceExists(suite.T(), id) - suite.requireCTP(ctp, []*pbauth.Permission{p2}, []*pbauth.Permission{p1, p3}) - rtest.RequireOwner(suite.T(), ctp, wi.Id, true) + ctpResource = suite.client.RequireResourceExists(suite.T(), id) + suite.requireCTP(ctpResource, []*pbauth.Permission{p2}, []*pbauth.Permission{p1, p3}) + rtest.RequireOwner(suite.T(), ctpResource, wi.Id, true) + assertCTPDefaultStatus(suite.T(), ctpResource, false) + + // Delete the traffic permissions without updating the caches. Ensure is default is right even when the caches contain stale data. + suite.client.MustDelete(suite.T(), tp1.Id) + suite.client.MustDelete(suite.T(), tp2.Id) + suite.client.MustDelete(suite.T(), tp3.Id) + + err = suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id}) + require.NoError(suite.T(), err) + + ctpResource = suite.client.RequireResourceExists(suite.T(), id) + suite.requireCTP(ctpResource, []*pbauth.Permission{}, []*pbauth.Permission{}) + rtest.RequireOwner(suite.T(), ctpResource, wi.Id, true) + assertCTPDefaultStatus(suite.T(), ctpResource, true) } func (suite *controllerSuite) TestReconcile_TrafficPermissionsDelete_DestinationWorkloadIdentityExists() { @@ -425,7 +444,7 @@ func (suite *controllerSuite) TestControllerBasic() { // Wait for the controller to record that the CTP has been computed res := suite.client.WaitForReconciliation(suite.T(), resource.ReplaceType(pbauth.ComputedTrafficPermissionsType, workloadIdentity.Id), StatusKey) // Check that the status was updated - rtest.RequireStatusCondition(suite.T(), res, StatusKey, ConditionComputed("wi1")) + rtest.RequireStatusCondition(suite.T(), res, StatusKey, ConditionComputed("wi1", true)) // Check that the CTP resource exists and contains no permissions ctpID := rtest.Resource(pbauth.ComputedTrafficPermissionsType, "wi1").ID() @@ -449,10 +468,10 @@ func (suite *controllerSuite) TestControllerBasic() { }).Write(suite.T(), suite.client) suite.client.RequireResourceExists(suite.T(), tp1.Id) // Wait for the controller to record that the CTP has been re-computed - res = suite.client.WaitForReconciliation(suite.T(), resource.ReplaceType(pbauth.ComputedTrafficPermissionsType, workloadIdentity.Id), StatusKey) - rtest.RequireStatusCondition(suite.T(), res, StatusKey, ConditionComputed("wi1")) + suite.client.WaitForReconciliation(suite.T(), resource.ReplaceType(pbauth.ComputedTrafficPermissionsType, workloadIdentity.Id), StatusKey) // Check that the ctp has been regenerated ctpObject = suite.client.WaitForNewVersion(suite.T(), ctpID, ctpObject.Version) + rtest.RequireStatusCondition(suite.T(), ctpObject, StatusKey, ConditionComputed("wi1", false)) // check wi1 suite.requireCTP(ctpObject, []*pbauth.Permission{p1}, nil) @@ -553,7 +572,7 @@ func (suite *controllerSuite) TestControllerMultipleTrafficPermissions() { ctpID := resource.ReplaceType(pbauth.ComputedTrafficPermissionsType, workloadIdentity.Id) // Wait for the controller to record that the CTP has been computed res := suite.client.WaitForReconciliation(suite.T(), ctpID, StatusKey) - rtest.RequireStatusCondition(suite.T(), res, StatusKey, ConditionComputed("wi1")) + rtest.RequireStatusCondition(suite.T(), res, StatusKey, ConditionComputed("wi1", false)) // check ctp1 has tp1 and tp2 ctpObject := suite.client.RequireResourceExists(suite.T(), res.Id) suite.requireCTP(ctpObject, []*pbauth.Permission{p1, p2}, nil) @@ -584,7 +603,7 @@ func (suite *controllerSuite) TestControllerMultipleTrafficPermissions() { suite.client.WaitForDeletion(suite.T(), ctpObject.Id) // check ctp regenerated, has all permissions res = suite.client.WaitForReconciliation(suite.T(), ctpID, StatusKey) - rtest.RequireStatusCondition(suite.T(), res, StatusKey, ConditionComputed("wi1")) + rtest.RequireStatusCondition(suite.T(), res, StatusKey, ConditionComputed("wi1", false)) ctpObject = suite.client.RequireResourceExists(suite.T(), res.Id) suite.requireCTP(ctpObject, []*pbauth.Permission{p1, p2}, []*pbauth.Permission{p3}) @@ -596,7 +615,7 @@ func (suite *controllerSuite) TestControllerMultipleTrafficPermissions() { rtest.Resource(pbauth.WorkloadIdentityType, "wi1").Write(suite.T(), suite.client) // check ctp regenerated, has all permissions res = suite.client.WaitForReconciliation(suite.T(), ctpID, StatusKey) - rtest.RequireStatusCondition(suite.T(), res, StatusKey, ConditionComputed("wi1")) + rtest.RequireStatusCondition(suite.T(), res, StatusKey, ConditionComputed("wi1", false)) ctpObject = suite.client.RequireResourceExists(suite.T(), res.Id) suite.requireCTP(ctpObject, []*pbauth.Permission{p1, p2}, []*pbauth.Permission{p3}) @@ -613,7 +632,7 @@ func (suite *controllerSuite) TestControllerMultipleTrafficPermissions() { workloadIdentity2 := rtest.Resource(pbauth.WorkloadIdentityType, "wi2").Write(suite.T(), suite.client) // Wait for the controller to record that the CTP has been computed res2 := suite.client.WaitForReconciliation(suite.T(), resource.ReplaceType(pbauth.ComputedTrafficPermissionsType, workloadIdentity2.Id), StatusKey) - rtest.RequireStatusCondition(suite.T(), res2, StatusKey, ConditionComputed("wi2")) + rtest.RequireStatusCondition(suite.T(), res2, StatusKey, ConditionComputed("wi2", false)) // check ctp2 has no permissions ctpObject2 := suite.client.RequireResourceExists(suite.T(), res2.Id) suite.requireCTP(ctpObject2, nil, nil) @@ -655,3 +674,8 @@ func (suite *controllerSuite) TestControllerMultipleTrafficPermissions() { func TestController(t *testing.T) { suite.Run(t, new(controllerSuite)) } + +func assertCTPDefaultStatus(t *testing.T, resource *pbresource.Resource, isDefault bool) { + dec := rtest.MustDecode[*pbauth.ComputedTrafficPermissions](t, resource) + require.Equal(t, isDefault, dec.Data.IsDefault) +} diff --git a/internal/auth/internal/controllers/trafficpermissions/status.go b/internal/auth/internal/controllers/trafficpermissions/status.go index 6baf4a1db7e1..bfcc64bc131c 100644 --- a/internal/auth/internal/controllers/trafficpermissions/status.go +++ b/internal/auth/internal/controllers/trafficpermissions/status.go @@ -12,31 +12,35 @@ import ( const ( StatusKey = "consul.io/traffic-permissions" StatusTrafficPermissionsComputed = "Traffic permissions have been computed" - StatusTrafficPermissionsNotComputed = "Traffic permissions have been computed" - ConditionPermissionsAppliedMsg = "Workload identity %s has new permission set" + StatusTrafficPermissionsNotComputed = "Traffic permissions have not been computed" + ConditionPermissionsAppliedMsg = "Workload identity %s has new permissions" + ConditionNoPermissionsMsg = "Workload identity %s has no permissions" ConditionPermissionsFailedMsg = "Unable to calculate new permission set for Workload identity %s" ) -var ( - ConditionComputed = func(workloadIdentity string) *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusTrafficPermissionsComputed, - State: pbresource.Condition_STATE_TRUE, - Message: fmt.Sprintf(ConditionPermissionsAppliedMsg, workloadIdentity), - } +func ConditionComputed(workloadIdentity string, isDefault bool) *pbresource.Condition { + msgTpl := ConditionPermissionsAppliedMsg + if isDefault { + msgTpl = ConditionNoPermissionsMsg } - ConditionFailedToCompute = func(workloadIdentity string, trafficPermissions string, errDetail string) *pbresource.Condition { - message := fmt.Sprintf(ConditionPermissionsFailedMsg, workloadIdentity) - if len(trafficPermissions) > 0 { - message = message + fmt.Sprintf(", traffic permission %s cannot be computed", trafficPermissions) - } - if len(errDetail) > 0 { - message = message + fmt.Sprintf(", error details: %s", errDetail) - } - return &pbresource.Condition{ - Type: StatusTrafficPermissionsNotComputed, - State: pbresource.Condition_STATE_FALSE, - Message: message, - } + return &pbresource.Condition{ + Type: StatusTrafficPermissionsComputed, + State: pbresource.Condition_STATE_TRUE, + Message: fmt.Sprintf(msgTpl, workloadIdentity), } -) +} + +func ConditionFailedToCompute(workloadIdentity string, trafficPermissions string, errDetail string) *pbresource.Condition { + message := fmt.Sprintf(ConditionPermissionsFailedMsg, workloadIdentity) + if len(trafficPermissions) > 0 { + message = message + fmt.Sprintf(", traffic permission %s cannot be computed", trafficPermissions) + } + if len(errDetail) > 0 { + message = message + fmt.Sprintf(", error details: %s", errDetail) + } + return &pbresource.Condition{ + Type: StatusTrafficPermissionsNotComputed, + State: pbresource.Condition_STATE_FALSE, + Message: message, + } +} diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/builder.go b/internal/mesh/internal/controllers/sidecarproxy/builder/builder.go index 36bccfb50253..ec173b6e7e8b 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/builder.go +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/builder.go @@ -58,7 +58,6 @@ func (b *Builder) Build() *pbmesh.ProxyStateTemplate { b.proxyStateTemplate.RequiredTrustBundles[b.id.Tenancy.PeerName] = &pbproxystate.TrustBundleRef{ Peer: b.id.Tenancy.PeerName, } - b.proxyStateTemplate.ProxyState.TrafficPermissionDefaultAllow = b.defaultAllow finalCleanupOfProxyStateTemplate(b.proxyStateTemplate) diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app.go b/internal/mesh/internal/controllers/sidecarproxy/builder/local_app.go index e3c8bd157037..3313b3ffae72 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app.go +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/local_app.go @@ -18,7 +18,7 @@ func (b *Builder) BuildLocalApp(workload *pbcatalog.Workload, ctp *pbauth.Comput lb := b.addInboundListener(xdscommon.PublicListenerName, workload) lb.buildListener() - trafficPermissions := buildTrafficPermissions(b.trustDomain, workload, ctp) + trafficPermissions := buildTrafficPermissions(b.defaultAllow, b.trustDomain, workload, ctp) // Go through workload ports and add the routers, clusters, endpoints, and TLS. // Note that the order of ports is non-deterministic here but the xds generation @@ -47,8 +47,15 @@ func (b *Builder) BuildLocalApp(workload *pbcatalog.Workload, ctp *pbauth.Comput return b } -func buildTrafficPermissions(trustDomain string, workload *pbcatalog.Workload, computed *pbauth.ComputedTrafficPermissions) map[string]*pbproxystate.TrafficPermissions { +func buildTrafficPermissions(globalDefaultAllow bool, trustDomain string, workload *pbcatalog.Workload, computed *pbauth.ComputedTrafficPermissions) map[string]*pbproxystate.TrafficPermissions { portsWithProtocol := workload.GetPortsByProtocol() + var defaultAllow bool + // If the computed traffic permissions don't exist yet, use default deny just to be safe. + // When it exists, use default deny unless no traffic permissions exist and default allow + // is configured globally. + if computed != nil && computed.IsDefault && globalDefaultAllow { + defaultAllow = true + } out := make(map[string]*pbproxystate.TrafficPermissions) portToProtocol := make(map[string]pbcatalog.Protocol) @@ -61,7 +68,9 @@ func buildTrafficPermissions(trustDomain string, workload *pbcatalog.Workload, c for _, p := range ports { allPorts = append(allPorts, p) portToProtocol[p] = protocol - out[p] = &pbproxystate.TrafficPermissions{} + out[p] = &pbproxystate.TrafficPermissions{ + DefaultAllow: defaultAllow, + } } } @@ -83,6 +92,10 @@ func buildTrafficPermissions(trustDomain string, workload *pbcatalog.Workload, c drsByPort := destinationRulesByPort(allPorts, p.DestinationRules) principals := makePrincipals(trustDomain, p) for port := range drsByPort { + if _, ok := out[port]; !ok { + continue + } + out[port].AllowPermissions = append(out[port].AllowPermissions, &pbproxystate.Permission{ Principals: principals, }) diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go b/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go index b1f4faa95eda..2b117155abc5 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go @@ -122,11 +122,13 @@ func TestBuildL4TrafficPermissions(t *testing.T) { testTrustDomain := "test.consul" cases := map[string]struct { + defaultAllow bool workloadPorts map[string]*pbcatalog.WorkloadPort ctp *pbauth.ComputedTrafficPermissions expected map[string]*pbproxystate.TrafficPermissions }{ "empty": { + defaultAllow: true, workloadPorts: map[string]*pbcatalog.WorkloadPort{ "p1": { Protocol: pbcatalog.Protocol_PROTOCOL_TCP, @@ -140,12 +142,131 @@ func TestBuildL4TrafficPermissions(t *testing.T) { }, }, expected: map[string]*pbproxystate.TrafficPermissions{ - "p1": {}, - "p2": {}, + "p1": { + DefaultAllow: false, + }, + "p2": { + DefaultAllow: false, + }, + "p3": { + DefaultAllow: false, + }, + }, + }, + "default allow everywhere": { + defaultAllow: true, + workloadPorts: map[string]*pbcatalog.WorkloadPort{ + "p1": { + Protocol: pbcatalog.Protocol_PROTOCOL_TCP, + }, + "p2": { + Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, + }, "p3": {}, + "mesh": { + Protocol: pbcatalog.Protocol_PROTOCOL_MESH, + }, + }, + ctp: &pbauth.ComputedTrafficPermissions{ + IsDefault: true, + }, + expected: map[string]*pbproxystate.TrafficPermissions{ + "p1": { + DefaultAllow: true, + }, + "p2": { + DefaultAllow: true, + }, + "p3": { + DefaultAllow: true, + }, + }, + }, + "preserves default deny": { + defaultAllow: false, + workloadPorts: map[string]*pbcatalog.WorkloadPort{ + "p1": { + Protocol: pbcatalog.Protocol_PROTOCOL_TCP, + }, + "p2": { + Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, + }, + }, + ctp: &pbauth.ComputedTrafficPermissions{ + AllowPermissions: []*pbauth.Permission{ + { + Sources: []*pbauth.Source{ + { + IdentityName: "foo", + Partition: "default", + Namespace: "default", + }, + }, + DestinationRules: []*pbauth.DestinationRule{ + { + PortNames: []string{"p1"}, + }, + }, + }, + }, + }, + expected: map[string]*pbproxystate.TrafficPermissions{ + "p1": { + DefaultAllow: false, + AllowPermissions: []*pbproxystate.Permission{ + { + Principals: []*pbproxystate.Principal{ + { + Spiffe: &pbproxystate.Spiffe{Regex: "^spiffe://test.consul/ap/default/ns/default/identity/foo$"}, + }, + }, + }, + }, + }, + "p2": { + DefaultAllow: false, + }, + }, + }, + "default allow with a non-empty ctp becomes default deny on all ports": { + defaultAllow: true, + workloadPorts: map[string]*pbcatalog.WorkloadPort{ + "p1": { + Protocol: pbcatalog.Protocol_PROTOCOL_TCP, + }, + "p2": { + Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, + }, + }, + ctp: &pbauth.ComputedTrafficPermissions{ + AllowPermissions: []*pbauth.Permission{ + { + Sources: []*pbauth.Source{ + { + IdentityName: "baz", + Partition: "default", + Namespace: "default", + }, + }, + DestinationRules: []*pbauth.DestinationRule{ + { + PortNames: []string{"no-match"}, + }, + }, + }, + }, + }, + expected: map[string]*pbproxystate.TrafficPermissions{ + "p1": { + DefaultAllow: false, + }, + "p2": { + DefaultAllow: false, + }, }, }, "kitchen sink": { + defaultAllow: true, workloadPorts: map[string]*pbcatalog.WorkloadPort{ "p1": { Protocol: pbcatalog.Protocol_PROTOCOL_TCP, @@ -232,6 +353,7 @@ func TestBuildL4TrafficPermissions(t *testing.T) { }, expected: map[string]*pbproxystate.TrafficPermissions{ "p1": { + DefaultAllow: false, DenyPermissions: []*pbproxystate.Permission{ { Principals: []*pbproxystate.Principal{ @@ -262,6 +384,7 @@ func TestBuildL4TrafficPermissions(t *testing.T) { }, }, "p2": { + DefaultAllow: false, DenyPermissions: []*pbproxystate.Permission{ { Principals: []*pbproxystate.Principal{ @@ -306,7 +429,7 @@ func TestBuildL4TrafficPermissions(t *testing.T) { workload := &pbcatalog.Workload{ Ports: tc.workloadPorts, } - permissions := buildTrafficPermissions(testTrustDomain, workload, tc.ctp) + permissions := buildTrafficPermissions(tc.defaultAllow, testTrustDomain, workload, tc.ctp) require.Equal(t, len(tc.expected), len(permissions)) for k, v := range tc.expected { prototest.AssertDeepEqual(t, v, permissions[k]) diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-multiple-workload-addresses-with-specific-ports.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-multiple-workload-addresses-with-specific-ports.golden index 987999513a8d..153c5b3ddaf5 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-multiple-workload-addresses-with-specific-ports.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-multiple-workload-addresses-with-specific-ports.golden @@ -78,8 +78,7 @@ } ] } - ], - "trafficPermissionDefaultAllow": true + ] }, "requiredLeafCertificates": { "test-identity": { diff --git a/internal/mesh/internal/controllers/sidecarproxy/controller_test.go b/internal/mesh/internal/controllers/sidecarproxy/controller_test.go index 846d625749cf..7c6d634c3637 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/controller_test.go +++ b/internal/mesh/internal/controllers/sidecarproxy/controller_test.go @@ -43,15 +43,15 @@ type meshControllerTestSuite struct { ctl *reconciler ctx context.Context - apiWorkloadID *pbresource.ID - apiWorkload *pbcatalog.Workload - computedTrafficPermissions *pbresource.Resource - computedTrafficPermissionsData *pbauth.ComputedTrafficPermissions - apiService *pbresource.Resource - apiServiceData *pbcatalog.Service - apiEndpoints *pbresource.Resource - apiEndpointsData *pbcatalog.ServiceEndpoints - webWorkload *pbresource.Resource + apiWorkloadID *pbresource.ID + apiWorkload *pbcatalog.Workload + apiComputedTrafficPermissions *pbresource.Resource + apiComputedTrafficPermissionsData *pbauth.ComputedTrafficPermissions + apiService *pbresource.Resource + apiServiceData *pbcatalog.Service + apiEndpoints *pbresource.Resource + apiEndpointsData *pbcatalog.ServiceEndpoints + webWorkload *pbresource.Resource dbWorkloadID *pbresource.ID dbWorkload *pbcatalog.Workload @@ -147,7 +147,8 @@ func (suite *meshControllerTestSuite) SetupTest() { }, } - suite.computedTrafficPermissionsData = &pbauth.ComputedTrafficPermissions{ + suite.apiComputedTrafficPermissionsData = &pbauth.ComputedTrafficPermissions{ + IsDefault: false, AllowPermissions: []*pbauth.Permission{ { Sources: []*pbauth.Source{ @@ -162,8 +163,8 @@ func (suite *meshControllerTestSuite) SetupTest() { }, } - suite.computedTrafficPermissions = resourcetest.Resource(pbauth.ComputedTrafficPermissionsType, suite.apiWorkload.Identity). - WithData(suite.T(), suite.computedTrafficPermissionsData). + suite.apiComputedTrafficPermissions = resourcetest.Resource(pbauth.ComputedTrafficPermissionsType, suite.apiWorkload.Identity). + WithData(suite.T(), suite.apiComputedTrafficPermissionsData). Write(suite.T(), resourceClient) suite.apiService = resourcetest.Resource(pbcatalog.ServiceType, "api-service"). @@ -200,6 +201,10 @@ func (suite *meshControllerTestSuite) SetupTest() { WithData(suite.T(), webWorkloadData). Write(suite.T(), suite.client) + resourcetest.Resource(pbauth.ComputedTrafficPermissionsType, webWorkloadData.Identity). + WithData(suite.T(), &pbauth.ComputedTrafficPermissions{IsDefault: true}). + Write(suite.T(), resourceClient) + resourcetest.Resource(pbcatalog.ServiceType, "web"). WithData(suite.T(), &pbcatalog.Service{ Workloads: &pbcatalog.WorkloadSelector{Names: []string{"web-def"}}, @@ -227,7 +232,7 @@ func (suite *meshControllerTestSuite) SetupTest() { } suite.proxyStateTemplate = builder.New(suite.apiWorkloadID, identityRef, "test.consul", "dc1", false, nil). - BuildLocalApp(suite.apiWorkload, suite.computedTrafficPermissionsData). + BuildLocalApp(suite.apiWorkload, suite.apiComputedTrafficPermissionsData). Build() } @@ -555,19 +560,20 @@ func (suite *meshControllerTestSuite) TestController() { }) testutil.RunStep(suite.T(), "traffic permissions", func(t *testing.T) { - dec := resourcetest.MustDecode[*pbmesh.ProxyStateTemplate](t, apiProxyStateTemplate) - require.False(t, dec.Data.ProxyState.TrafficPermissionDefaultAllow) + // Global default deny applies to all identities. + assertTrafficPermissionDefaultPolicy(t, false, apiProxyStateTemplate) + assertTrafficPermissionDefaultPolicy(t, false, webProxyStateTemplate) suite.runtime.Logger.Trace("deleting computed traffic permissions") - _, err := suite.client.Delete(suite.ctx, &pbresource.DeleteRequest{Id: suite.computedTrafficPermissions.Id}) + _, err := suite.client.Delete(suite.ctx, &pbresource.DeleteRequest{Id: suite.apiComputedTrafficPermissions.Id}) require.NoError(t, err) - suite.client.WaitForDeletion(t, suite.computedTrafficPermissions.Id) + suite.client.WaitForDeletion(t, suite.apiComputedTrafficPermissions.Id) apiProxyStateTemplate = suite.client.WaitForNewVersion(t, apiProxyStateTemplateID, apiProxyStateTemplate.Version) suite.runtime.Logger.Trace("creating computed traffic permissions") resourcetest.Resource(pbauth.ComputedTrafficPermissionsType, suite.apiWorkload.Identity). - WithData(t, suite.computedTrafficPermissionsData). + WithData(t, suite.apiComputedTrafficPermissionsData). Write(t, suite.client) suite.client.WaitForNewVersion(t, apiProxyStateTemplateID, apiProxyStateTemplate.Version) @@ -646,14 +652,17 @@ func (suite *meshControllerTestSuite) TestControllerDefaultAllow() { var ( // Create proxy state template IDs to check against in this test. + apiProxyStateTemplateID = resourcetest.Resource(pbmesh.ProxyStateTemplateType, "api-abc").ID() webProxyStateTemplateID = resourcetest.Resource(pbmesh.ProxyStateTemplateType, "web-def").ID() ) retry.Run(suite.T(), func(r *retry.R) { - suite.client.RequireResourceExists(r, webProxyStateTemplateID) webProxyStateTemplate := suite.client.RequireResourceExists(r, webProxyStateTemplateID) - dec := resourcetest.MustDecode[*pbmesh.ProxyStateTemplate](r, webProxyStateTemplate) - require.True(r, dec.Data.ProxyState.TrafficPermissionDefaultAllow) + apiProxyStateTemplate := suite.client.RequireResourceExists(r, apiProxyStateTemplateID) + + // Default deny because api has non-empty computed traffic permissions. + assertTrafficPermissionDefaultPolicy(r, false, apiProxyStateTemplate) + assertTrafficPermissionDefaultPolicy(r, true, webProxyStateTemplate) }) } @@ -771,3 +780,18 @@ func resourceID(rtype *pbresource.Type, name string) *pbresource.ID { Name: name, } } + +func assertTrafficPermissionDefaultPolicy(t resourcetest.T, defaultAllow bool, resource *pbresource.Resource) { + dec := resourcetest.MustDecode[*pbmesh.ProxyStateTemplate](t, resource) + var listener *pbproxystate.Listener + for _, l := range dec.Data.ProxyState.Listeners { + if l.Name == "public_listener" { + listener = l + break + } + } + require.Len(t, listener.Routers, 1) + l4 := listener.Routers[0].GetL4() + require.NotNil(t, l4) + require.Equal(t, defaultAllow, l4.TrafficPermissions.DefaultAllow) +} diff --git a/internal/mesh/proxy-tracker/proxy_tracker_test.go b/internal/mesh/proxy-tracker/proxy_tracker_test.go index e32af216857e..d6c1fc1ce5e0 100644 --- a/internal/mesh/proxy-tracker/proxy_tracker_test.go +++ b/internal/mesh/proxy-tracker/proxy_tracker_test.go @@ -194,9 +194,7 @@ func TestProxyTracker_PushChange(t *testing.T) { require.NoError(t, err) // PushChange - proxyState := &ProxyState{ProxyState: &pbmesh.ProxyState{ - TrafficPermissionDefaultAllow: true, - }} + proxyState := &ProxyState{ProxyState: &pbmesh.ProxyState{}} // using a goroutine so that the channel and main test thread do not cause // blocking issues with each other @@ -227,9 +225,7 @@ func TestProxyTracker_PushChanges_ErrorProxyNotConnected(t *testing.T) { }) // PushChange - proxyState := &ProxyState{ProxyState: &pbmesh.ProxyState{ - TrafficPermissionDefaultAllow: true, - }} + proxyState := &ProxyState{ProxyState: &pbmesh.ProxyState{}} err := pt.PushChange(resourceID, proxyState) require.Error(t, err) diff --git a/proto-public/pbauth/v2beta1/computed_traffic_permissions.pb.go b/proto-public/pbauth/v2beta1/computed_traffic_permissions.pb.go index 09bc912a4a31..b88c2e86bd03 100644 --- a/proto-public/pbauth/v2beta1/computed_traffic_permissions.pb.go +++ b/proto-public/pbauth/v2beta1/computed_traffic_permissions.pb.go @@ -28,6 +28,7 @@ type ComputedTrafficPermissions struct { AllowPermissions []*Permission `protobuf:"bytes,1,rep,name=allow_permissions,json=allowPermissions,proto3" json:"allow_permissions,omitempty"` DenyPermissions []*Permission `protobuf:"bytes,2,rep,name=deny_permissions,json=denyPermissions,proto3" json:"deny_permissions,omitempty"` + IsDefault bool `protobuf:"varint,3,opt,name=is_default,json=isDefault,proto3" json:"is_default,omitempty"` } func (x *ComputedTrafficPermissions) Reset() { @@ -76,6 +77,13 @@ func (x *ComputedTrafficPermissions) GetDenyPermissions() []*Permission { return nil } +func (x *ComputedTrafficPermissions) GetIsDefault() bool { + if x != nil { + return x.IsDefault + } + return false +} + var File_pbauth_v2beta1_computed_traffic_permissions_proto protoreflect.FileDescriptor var file_pbauth_v2beta1_computed_traffic_permissions_proto_rawDesc = []byte{ @@ -88,7 +96,7 @@ var file_pbauth_v2beta1_computed_traffic_permissions_proto_rawDesc = []byte{ 0x61, 0x31, 0x2f, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd2, 0x01, 0x0a, 0x1a, 0x43, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf1, 0x01, 0x0a, 0x1a, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x56, 0x0a, 0x11, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, @@ -101,26 +109,28 @@ var file_pbauth_v2beta1_computed_traffic_permissions_proto_rawDesc = []byte{ 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x64, 0x65, 0x6e, 0x79, 0x50, 0x65, 0x72, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x42, - 0xa0, 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x1f, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x54, - 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x2f, 0x70, 0x62, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x3b, 0x61, 0x75, 0x74, 0x68, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, - 0x48, 0x43, 0x41, 0xaa, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0xca, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, - 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x41, 0x75, 0x74, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0xe2, 0x02, 0x29, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, - 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x41, 0x75, 0x74, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, - 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x41, 0x75, 0x74, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x64, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x44, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x42, 0xa0, + 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, + 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x42, 0x1f, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x54, 0x72, + 0x61, 0x66, 0x66, 0x69, 0x63, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, + 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x2f, 0x70, 0x62, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x3b, 0x61, 0x75, 0x74, 0x68, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, + 0x43, 0x41, 0xaa, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, + 0x61, 0x31, 0xca, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x41, 0x75, 0x74, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, + 0x61, 0x31, 0xe2, 0x02, 0x29, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x41, 0x75, 0x74, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, + 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, + 0x75, 0x6c, 0x3a, 0x3a, 0x41, 0x75, 0x74, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto-public/pbauth/v2beta1/computed_traffic_permissions.proto b/proto-public/pbauth/v2beta1/computed_traffic_permissions.proto index c684c19b51c9..24127cc6a468 100644 --- a/proto-public/pbauth/v2beta1/computed_traffic_permissions.proto +++ b/proto-public/pbauth/v2beta1/computed_traffic_permissions.proto @@ -10,4 +10,5 @@ message ComputedTrafficPermissions { repeated Permission allow_permissions = 1; repeated Permission deny_permissions = 2; + bool is_default = 3; } diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.pb.go b/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.pb.go index 2e53a1d29810..def42e933f97 100644 --- a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.pb.go +++ b/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.pb.go @@ -30,6 +30,10 @@ type TrafficPermissions struct { AllowPermissions []*Permission `protobuf:"bytes,1,rep,name=allow_permissions,json=allowPermissions,proto3" json:"allow_permissions,omitempty"` DenyPermissions []*Permission `protobuf:"bytes,2,rep,name=deny_permissions,json=denyPermissions,proto3" json:"deny_permissions,omitempty"` + // default_allow determines if the workload is in default allow mode. This is determined + // by combining the cluster's default allow setting with the is_default property on + // computed traffic permissions. + DefaultAllow bool `protobuf:"varint,4,opt,name=default_allow,json=defaultAllow,proto3" json:"default_allow,omitempty"` } func (x *TrafficPermissions) Reset() { @@ -78,6 +82,13 @@ func (x *TrafficPermissions) GetDenyPermissions() []*Permission { return nil } +func (x *TrafficPermissions) GetDefaultAllow() bool { + if x != nil { + return x.DefaultAllow + } + return false +} + type Permission struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -247,7 +258,7 @@ var file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_rawDesc = []byte{ 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x2a, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x22, 0xdc, 0x01, 0x0a, 0x12, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x50, + 0x61, 0x74, 0x65, 0x22, 0x81, 0x02, 0x0a, 0x12, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x63, 0x0a, 0x11, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, @@ -261,51 +272,53 @@ var file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_rawDesc = []byte{ 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x64, 0x65, 0x6e, 0x79, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x22, 0x63, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x12, 0x55, 0x0a, 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x2e, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x52, 0x0a, 0x70, 0x72, 0x69, - 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x22, 0xb4, 0x01, 0x0a, 0x09, 0x50, 0x72, 0x69, 0x6e, - 0x63, 0x69, 0x70, 0x61, 0x6c, 0x12, 0x4a, 0x0a, 0x06, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2e, 0x53, 0x70, 0x69, 0x66, 0x66, 0x65, 0x52, 0x06, 0x73, 0x70, 0x69, 0x66, 0x66, - 0x65, 0x12, 0x5b, 0x0a, 0x0f, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x73, 0x70, 0x69, - 0x66, 0x66, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, 0x61, 0x73, + 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x61, 0x6c, + 0x6c, 0x6f, 0x77, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x64, 0x65, 0x66, 0x61, 0x75, + 0x6c, 0x74, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x22, 0x63, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x55, 0x0a, 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, + 0x61, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, + 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, + 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, + 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, + 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x22, 0xb4, 0x01, 0x0a, + 0x09, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x12, 0x4a, 0x0a, 0x06, 0x73, 0x70, + 0x69, 0x66, 0x66, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x70, 0x69, 0x66, 0x66, 0x65, 0x52, 0x0e, - 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, 0x70, 0x69, 0x66, 0x66, 0x65, 0x73, 0x22, 0x3d, - 0x0a, 0x06, 0x53, 0x70, 0x69, 0x66, 0x66, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x67, 0x65, - 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x72, 0x65, 0x67, 0x65, 0x78, 0x12, 0x1d, - 0x0a, 0x0a, 0x78, 0x66, 0x63, 0x63, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x78, 0x66, 0x63, 0x63, 0x52, 0x65, 0x67, 0x65, 0x78, 0x42, 0xdd, 0x02, - 0x0a, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x42, 0x17, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x44, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, - 0x65, 0xa2, 0x02, 0x05, 0x48, 0x43, 0x4d, 0x56, 0x50, 0xaa, 0x02, 0x2a, 0x48, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, - 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xca, 0x02, 0x2a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, - 0x61, 0x74, 0x65, 0xe2, 0x02, 0x36, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, - 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x2e, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3a, - 0x3a, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x70, 0x69, 0x66, 0x66, 0x65, 0x52, 0x06, + 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x12, 0x5b, 0x0a, 0x0f, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, + 0x65, 0x5f, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, + 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x70, 0x69, + 0x66, 0x66, 0x65, 0x52, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, 0x70, 0x69, 0x66, + 0x66, 0x65, 0x73, 0x22, 0x3d, 0x0a, 0x06, 0x53, 0x70, 0x69, 0x66, 0x66, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x72, 0x65, + 0x67, 0x65, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x78, 0x66, 0x63, 0x63, 0x5f, 0x72, 0x65, 0x67, 0x65, + 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x78, 0x66, 0x63, 0x63, 0x52, 0x65, 0x67, + 0x65, 0x78, 0x42, 0xdd, 0x02, 0x0a, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, + 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, + 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x42, 0x17, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x50, 0x65, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, + 0x5a, 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, + 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, + 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, + 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xa2, 0x02, 0x05, 0x48, 0x43, 0x4d, 0x56, 0x50, 0xaa, 0x02, + 0x2a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, + 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xca, 0x02, 0x2a, 0x48, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, + 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, 0x72, + 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xe2, 0x02, 0x36, 0x48, 0x61, 0x73, 0x68, 0x69, + 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, + 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0xea, 0x02, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x3a, 0x3a, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.proto b/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.proto index 84b51b939707..918b092c0a36 100644 --- a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.proto +++ b/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.proto @@ -8,6 +8,10 @@ package hashicorp.consul.mesh.v2beta1.pbproxystate; message TrafficPermissions { repeated Permission allow_permissions = 1; repeated Permission deny_permissions = 2; + // default_allow determines if the workload is in default allow mode. This is determined + // by combining the cluster's default allow setting with the is_default property on + // computed traffic permissions. + bool default_allow = 4; } message Permission { diff --git a/proto-public/pbmesh/v2beta1/proxy_state.pb.go b/proto-public/pbmesh/v2beta1/proxy_state.pb.go index d49bf6b2ba16..4f19f7b6af62 100644 --- a/proto-public/pbmesh/v2beta1/proxy_state.pb.go +++ b/proto-public/pbmesh/v2beta1/proxy_state.pb.go @@ -121,12 +121,10 @@ type ProxyState struct { TrustBundles map[string]*pbproxystate.TrustBundle `protobuf:"bytes,7,rep,name=trust_bundles,json=trustBundles,proto3" json:"trust_bundles,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // tls has TLS configuration for this proxy. Tls *pbproxystate.TLS `protobuf:"bytes,8,opt,name=tls,proto3" json:"tls,omitempty"` - // traffic_permission_default_allow is the default action for traffic permissions. This determines how the Envoy RBAC filters are generated. - TrafficPermissionDefaultAllow bool `protobuf:"varint,9,opt,name=traffic_permission_default_allow,json=trafficPermissionDefaultAllow,proto3" json:"traffic_permission_default_allow,omitempty"` // escape defines top level escape hatches. These are user configured json strings that configure an entire piece of listener or cluster Envoy configuration. - Escape *pbproxystate.EscapeHatches `protobuf:"bytes,10,opt,name=escape,proto3" json:"escape,omitempty"` + Escape *pbproxystate.EscapeHatches `protobuf:"bytes,9,opt,name=escape,proto3" json:"escape,omitempty"` // access_logs configures access logging for this proxy. - AccessLogs *pbproxystate.AccessLogs `protobuf:"bytes,11,opt,name=access_logs,json=accessLogs,proto3" json:"access_logs,omitempty"` + AccessLogs *pbproxystate.AccessLogs `protobuf:"bytes,10,opt,name=access_logs,json=accessLogs,proto3" json:"access_logs,omitempty"` } func (x *ProxyState) Reset() { @@ -217,13 +215,6 @@ func (x *ProxyState) GetTls() *pbproxystate.TLS { return nil } -func (x *ProxyState) GetTrafficPermissionDefaultAllow() bool { - if x != nil { - return x.TrafficPermissionDefaultAllow - } - return false -} - func (x *ProxyState) GetEscape() *pbproxystate.EscapeHatches { if x != nil { return x.Escape @@ -328,7 +319,7 @@ var file_pbmesh_v2beta1_proxy_state_proto_rawDesc = []byte{ 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x66, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x06, 0xa2, - 0x93, 0x04, 0x02, 0x08, 0x03, 0x22, 0xf8, 0x0b, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, + 0x93, 0x04, 0x02, 0x08, 0x03, 0x22, 0xaf, 0x0b, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x40, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, @@ -371,77 +362,73 @@ var file_pbmesh_v2beta1_proxy_state_proto_rawDesc = []byte{ 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2e, 0x54, 0x4c, 0x53, 0x52, 0x03, 0x74, 0x6c, 0x73, 0x12, 0x47, 0x0a, 0x20, 0x74, 0x72, 0x61, - 0x66, 0x66, 0x69, 0x63, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, - 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x18, 0x09, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x1d, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x50, 0x65, 0x72, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x41, 0x6c, 0x6c, - 0x6f, 0x77, 0x12, 0x51, 0x0a, 0x06, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x18, 0x0a, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, - 0x45, 0x73, 0x63, 0x61, 0x70, 0x65, 0x48, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x52, 0x06, 0x65, - 0x73, 0x63, 0x61, 0x70, 0x65, 0x12, 0x57, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, - 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, - 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, - 0x67, 0x73, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x1a, 0x70, - 0x0a, 0x0d, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x49, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x33, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x43, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x1a, 0x6c, 0x0a, 0x0b, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x47, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x31, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x6f, - 0x75, 0x74, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x73, - 0x0a, 0x0e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x12, 0x4b, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, + 0x2e, 0x54, 0x4c, 0x53, 0x52, 0x03, 0x74, 0x6c, 0x73, 0x12, 0x51, 0x0a, 0x06, 0x65, 0x73, 0x63, + 0x61, 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, + 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, + 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, + 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x45, 0x73, 0x63, 0x61, 0x70, 0x65, 0x48, 0x61, 0x74, + 0x63, 0x68, 0x65, 0x73, 0x52, 0x06, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x12, 0x57, 0x0a, 0x0b, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x36, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x45, - 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x1a, 0x80, 0x01, 0x0a, 0x15, 0x4c, 0x65, 0x61, 0x66, 0x43, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x51, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, - 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x65, 0x61, 0x66, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x78, 0x0a, 0x11, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, - 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x4d, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, - 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x42, 0x90, 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x0f, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x3b, 0x6d, 0x65, 0x73, 0x68, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, - 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x29, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0xea, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x1a, 0x70, 0x0a, 0x0d, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x49, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, + 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x6c, 0x0a, 0x0b, 0x52, 0x6f, 0x75, 0x74, 0x65, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x47, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, + 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x73, 0x0a, 0x0e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x4b, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, + 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, + 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x80, 0x01, 0x0a, 0x15, 0x4c, + 0x65, 0x61, 0x66, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x51, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, + 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x2e, 0x4c, 0x65, 0x61, 0x66, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x78, 0x0a, + 0x11, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x4d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, + 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x2e, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x90, 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, + 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, + 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x0f, 0x50, + 0x72, 0x6f, 0x78, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, + 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, + 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, + 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x6d, 0x65, 0x73, 0x68, 0x76, 0x32, + 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x1d, 0x48, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, + 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x1d, 0x48, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, + 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x29, 0x48, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, + 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, + 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( diff --git a/proto-public/pbmesh/v2beta1/proxy_state.proto b/proto-public/pbmesh/v2beta1/proxy_state.proto index 773ee3b9a119..38debef6f655 100644 --- a/proto-public/pbmesh/v2beta1/proxy_state.proto +++ b/proto-public/pbmesh/v2beta1/proxy_state.proto @@ -49,10 +49,8 @@ message ProxyState { map trust_bundles = 7; // tls has TLS configuration for this proxy. pbproxystate.TLS tls = 8; - // traffic_permission_default_allow is the default action for traffic permissions. This determines how the Envoy RBAC filters are generated. - bool traffic_permission_default_allow = 9; // escape defines top level escape hatches. These are user configured json strings that configure an entire piece of listener or cluster Envoy configuration. - pbproxystate.EscapeHatches escape = 10; + pbproxystate.EscapeHatches escape = 9; // access_logs configures access logging for this proxy. - pbproxystate.AccessLogs access_logs = 11; + pbproxystate.AccessLogs access_logs = 10; } diff --git a/test/integration/consul-container/test/multiport/explicit_destination_test.go b/test/integration/consul-container/test/multiport/explicit_destination_test.go index d8b02d065470..019385fbd935 100644 --- a/test/integration/consul-container/test/multiport/explicit_destination_test.go +++ b/test/integration/consul-container/test/multiport/explicit_destination_test.go @@ -30,6 +30,7 @@ import ( // - Make sure a request from static-client to the virtual address (.virtual.consul) returns a // response from the upstream. func TestMultiportService_Explicit(t *testing.T) { + t.Skip() t.Parallel() cluster := createCluster(t) From b43cde5d193faf751464a652725b6530698e3230 Mon Sep 17 00:00:00 2001 From: "Chris S. Kim" Date: Wed, 4 Oct 2023 10:24:32 -0400 Subject: [PATCH 4/6] Add workload identity hooks (#19045) --- .../auth/internal/types/workload_identity.go | 44 +++++- .../internal/types/workload_identity_test.go | 146 ++++++++++++++++++ 2 files changed, 187 insertions(+), 3 deletions(-) create mode 100644 internal/auth/internal/types/workload_identity_test.go diff --git a/internal/auth/internal/types/workload_identity.go b/internal/auth/internal/types/workload_identity.go index c640943435a9..5379d256ba4f 100644 --- a/internal/auth/internal/types/workload_identity.go +++ b/internal/auth/internal/types/workload_identity.go @@ -4,15 +4,53 @@ package types import ( + "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/internal/resource" pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" + "github.com/hashicorp/consul/proto-public/pbresource" ) func RegisterWorkloadIdentity(r resource.Registry) { r.Register(resource.Registration{ - Type: pbauth.WorkloadIdentityType, - Proto: &pbauth.WorkloadIdentity{}, - Scope: resource.ScopeNamespace, + Type: pbauth.WorkloadIdentityType, + Proto: &pbauth.WorkloadIdentity{}, + Scope: resource.ScopeNamespace, + ACLs: &resource.ACLHooks{ + Read: aclReadHookWorkloadIdentity, + Write: aclWriteHookWorkloadIdentity, + List: aclListHookWorkloadIdentity, + }, Validate: nil, }) } + +func aclReadHookWorkloadIdentity( + authorizer acl.Authorizer, + authzCtx *acl.AuthorizerContext, + id *pbresource.ID, + res *pbresource.Resource, +) error { + if id != nil { + return authorizer.ToAllowAuthorizer().IdentityReadAllowed(id.Name, authzCtx) + } + if res != nil { + return authorizer.ToAllowAuthorizer().IdentityReadAllowed(res.Id.Name, authzCtx) + } + return resource.ErrNeedData +} + +func aclWriteHookWorkloadIdentity( + authorizer acl.Authorizer, + authzCtx *acl.AuthorizerContext, + res *pbresource.Resource) error { + if res == nil { + return resource.ErrNeedData + } + return authorizer.ToAllowAuthorizer().IdentityWriteAllowed(res.Id.Name, authzCtx) +} + +func aclListHookWorkloadIdentity(authorizer acl.Authorizer, context *acl.AuthorizerContext) error { + // No-op List permission as we want to default to filtering resources + // from the list using the Read enforcement + return nil +} diff --git a/internal/auth/internal/types/workload_identity_test.go b/internal/auth/internal/types/workload_identity_test.go new file mode 100644 index 000000000000..1ca59952ecee --- /dev/null +++ b/internal/auth/internal/types/workload_identity_test.go @@ -0,0 +1,146 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package types + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/hashicorp/consul/acl" + "github.com/hashicorp/consul/agent/structs" + "github.com/hashicorp/consul/internal/resource" + "github.com/hashicorp/consul/internal/resource/resourcetest" + pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" + "github.com/hashicorp/consul/proto-public/pbresource" +) + +func TestWorkloadIdentityACLs(t *testing.T) { + const ( + DENY = "deny" + ALLOW = "allow" + DEFAULT = "default" + ) + + registry := resource.NewRegistry() + Register(registry) + + reg, ok := registry.Resolve(pbauth.WorkloadIdentityType) + require.True(t, ok) + + type testcase struct { + rules string + check func(t *testing.T, authz acl.Authorizer, res *pbresource.Resource) + readOK string + writeOK string + listOK string + } + + checkF := func(t *testing.T, expect string, got error) { + switch expect { + case ALLOW: + if acl.IsErrPermissionDenied(got) { + t.Fatal("should be allowed") + } + case DENY: + if !acl.IsErrPermissionDenied(got) { + t.Fatal("should be denied") + } + case DEFAULT: + require.Nil(t, got, "expected fallthrough decision") + default: + t.Fatalf("unexpected expectation: %q", expect) + } + } + + run := func(t *testing.T, tc testcase) { + wid := &pbauth.WorkloadIdentity{} + res := resourcetest.Resource(pbauth.WorkloadIdentityType, "wi1"). + WithTenancy(resource.DefaultNamespacedTenancy()). + WithData(t, wid). + Build() + resourcetest.ValidateAndNormalize(t, registry, res) + + config := acl.Config{ + WildcardName: structs.WildcardSpecifier, + } + authz, err := acl.NewAuthorizerFromRules(tc.rules, &config, nil) + require.NoError(t, err) + authz = acl.NewChainedAuthorizer([]acl.Authorizer{authz, acl.DenyAll()}) + + t.Run("read", func(t *testing.T) { + err := reg.ACLs.Read(authz, &acl.AuthorizerContext{}, res.Id, res) + checkF(t, tc.readOK, err) + }) + t.Run("write", func(t *testing.T) { + err := reg.ACLs.Write(authz, &acl.AuthorizerContext{}, res) + checkF(t, tc.writeOK, err) + }) + t.Run("list", func(t *testing.T) { + err := reg.ACLs.List(authz, &acl.AuthorizerContext{}) + checkF(t, tc.listOK, err) + }) + t.Run("errors", func(t *testing.T) { + require.ErrorIs(t, reg.ACLs.Read(authz, &acl.AuthorizerContext{}, nil, nil), resource.ErrNeedData) + require.ErrorIs(t, reg.ACLs.Write(authz, &acl.AuthorizerContext{}, nil), resource.ErrNeedData) + }) + } + + cases := map[string]testcase{ + "no rules": { + rules: ``, + readOK: DENY, + writeOK: DENY, + listOK: DEFAULT, + }, + "workload identity wi1 read, no intentions": { + rules: `identity "wi1" { policy = "read" }`, + readOK: ALLOW, + writeOK: DENY, + listOK: DEFAULT, + }, + "workload identity wi1 read, deny intentions has no effect": { + rules: `identity "wi1" { policy = "read", intentions = "deny" }`, + readOK: ALLOW, + writeOK: DENY, + listOK: DEFAULT, + }, + "workload identity wi1 read, intentions read has no effect": { + rules: `identity "wi1" { policy = "read", intentions = "read" }`, + readOK: ALLOW, + writeOK: DENY, + listOK: DEFAULT, + }, + "workload identity wi1 write, write intentions has no effect": { + rules: `identity "wi1" { policy = "read", intentions = "write" }`, + readOK: ALLOW, + writeOK: DENY, + listOK: DEFAULT, + }, + "workload identity wi1 write, deny intentions has no effect": { + rules: `identity "wi1" { policy = "write", intentions = "deny" }`, + readOK: ALLOW, + writeOK: ALLOW, + listOK: DEFAULT, + }, + "workload identity wi1 write, intentions read has no effect": { + rules: `identity "wi1" { policy = "write", intentions = "read" }`, + readOK: ALLOW, + writeOK: ALLOW, + listOK: DEFAULT, + }, + "workload identity wi1 write, intentions write": { + rules: `identity "wi1" { policy = "write", intentions = "write" }`, + readOK: ALLOW, + writeOK: ALLOW, + listOK: DEFAULT, + }, + } + + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + run(t, tc) + }) + } +} From 1a9666c49d0e3a8ef1ad8724f92c0d1224a930f4 Mon Sep 17 00:00:00 2001 From: "Chris S. Kim" Date: Wed, 4 Oct 2023 11:47:47 -0400 Subject: [PATCH 5/6] Remove parallel flag (#19057) --- .github/workflows/test-integrations.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/test-integrations.yml b/.github/workflows/test-integrations.yml index 9dd7d3a3a35b..a3521dee753f 100644 --- a/.github/workflows/test-integrations.yml +++ b/.github/workflows/test-integrations.yml @@ -436,8 +436,6 @@ jobs: --rerun-fails=3 \ -- \ go test \ - -p=6 \ - -parallel=4 \ -tags "${{ env.GOTAGS }}" \ -timeout=30m \ -json \ From 9656fd157f93e3f16f69a1779dcf28ce6636da31 Mon Sep 17 00:00:00 2001 From: Eric Haberkorn Date: Wed, 4 Oct 2023 12:52:12 -0400 Subject: [PATCH 6/6] Fix Explicit Destination Integration Test (#19060) fix explicit destination integration test --- .../test/multiport/explicit_destination_test.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/integration/consul-container/test/multiport/explicit_destination_test.go b/test/integration/consul-container/test/multiport/explicit_destination_test.go index 019385fbd935..58f68a220e6e 100644 --- a/test/integration/consul-container/test/multiport/explicit_destination_test.go +++ b/test/integration/consul-container/test/multiport/explicit_destination_test.go @@ -6,6 +6,7 @@ package multiport import ( "context" "fmt" + pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" libassert "github.com/hashicorp/consul/test/integration/consul-container/libs/assert" @@ -30,7 +31,6 @@ import ( // - Make sure a request from static-client to the virtual address (.virtual.consul) returns a // response from the upstream. func TestMultiportService_Explicit(t *testing.T) { - t.Skip() t.Parallel() cluster := createCluster(t) @@ -120,6 +120,11 @@ func createServerServicesAndWorkloads(t *testing.T, resourceClient *rtest.Client }, } + rtest.ResourceID(&pbresource.ID{ + Name: "static-server-identity", + Type: pbauth.WorkloadIdentityType, + }).Write(t, resourceClient) + rtest.ResourceID(&pbresource.ID{ Name: "static-server-workload", Type: pbcatalog.WorkloadType,