respect service policies for admin identities (#1919)

respect service policies for admin identities
This commit is contained in:
Shawn Carey
2024-04-09 18:34:15 +00:00
committed by GitHub
parent 6be77e96a5
commit 4dfdabff8c
3 changed files with 45 additions and 40 deletions
+20
View File
@@ -1,3 +1,23 @@
# Release 1.0.0
## What's New
* Bugfixes
## DEFAULT Bind/Dial SERVICE PERMISSIONS FOR Admin IDENTITIES HAVE CHANGED
Admin identities were able to Dial and Bind all services regardless of the effective service policies
prior to this release. This could lead to a confusing situation where a tunneler that was assuming an Admin
identity would put itself into an infinite connect-loop when a service's host.v1 address overlapped with
any addresses in its intercept configuration.
Please create service policies to grant Bind or Dial permissions to Admin identities as needed.
## Component Updates and Bug Fixes
* github.com/openziti/ziti: [v0.34.2 -> v1.0.0](https://github.com/openziti/ziti/compare/v0.34.2...v1.0.0)
* [Issue #1781](https://github.com/openziti/ziti/issues/1781) - Admin identities have bind and dial permissions to services
# Release 0.34.2
## What's New
+15 -30
View File
@@ -119,34 +119,15 @@ func (self *EdgeServiceManager) ReadForIdentity(id string, identityId string, co
}
func (self *EdgeServiceManager) ReadForIdentityInTx(tx *bbolt.Tx, id string, identityId string, configTypes map[string]struct{}) (*ServiceDetail, error) {
edgeServiceStore := self.env.GetStores().EdgeService
identity, err := self.GetEnv().GetManagers().Identity.readInTx(tx, identityId)
if err != nil {
return nil, err
}
var service *ServiceDetail
if identity.IsAdmin {
service, err = self.readInTx(tx, id)
if err == nil && service != nil {
service.Permissions = []string{db.PolicyTypeBindName, db.PolicyTypeDialName}
}
} else {
service, err = self.ReadForNonAdminIdentityInTx(tx, id, identityId)
}
if err == nil && len(configTypes) > 0 {
identityServiceConfigs := self.env.GetStores().Identity.LoadServiceConfigsByServiceAndType(tx, identityId, configTypes)
self.mergeConfigs(tx, configTypes, service, identityServiceConfigs)
}
return service, err
}
func (self *EdgeServiceManager) ReadForNonAdminIdentityInTx(tx *bbolt.Tx, id string, identityId string) (*ServiceDetail, error) {
edgeServiceStore := self.env.GetStores().EdgeService
isBindable := edgeServiceStore.IsBindableByIdentity(tx, id, identityId)
isDialable := edgeServiceStore.IsDialableByIdentity(tx, id, identityId)
if !isBindable && !isDialable {
if !isBindable && !isDialable && !identity.IsAdmin { // admin can view services even if policies don't permit bind/dial {
return nil, boltz.NewNotFoundError(self.GetStore().GetSingularEntityType(), "id", id)
}
@@ -163,7 +144,17 @@ func (self *EdgeServiceManager) ReadForNonAdminIdentityInTx(tx *bbolt.Tx, id str
if isDialable {
result.Permissions = append(result.Permissions, db.PolicyTypeDialName)
}
return result, nil
if result.Permissions == nil {
// don't return results with no permissions, since some SDKs assume non-nil permissions
result.Permissions = []string{db.PolicyTypeInvalidName}
}
if len(configTypes) > 0 {
identityServiceConfigs := self.env.GetStores().Identity.LoadServiceConfigsByServiceAndType(tx, identityId, configTypes)
self.mergeConfigs(tx, configTypes, result, identityServiceConfigs)
}
return result, err
}
func (self *EdgeServiceManager) PublicQueryForIdentity(sessionIdentity *Identity, configTypes map[string]struct{}, query ast.Query) (*ServiceListResult, error) {
@@ -259,14 +250,8 @@ func (result *ServiceListResult) collect(tx *bbolt.Tx, ids []string, queryMetaDa
identityServiceConfigs := result.manager.env.GetStores().Identity.LoadServiceConfigsByServiceAndType(tx, result.identityId, result.configTypes)
for _, key := range ids {
if !result.isAdmin && result.identityId != "" {
service, err = result.manager.ReadForNonAdminIdentityInTx(tx, key, result.identityId)
} else {
service, err = result.manager.readInTx(tx, key)
if service != nil && result.isAdmin {
service.Permissions = []string{db.PolicyTypeBindName, db.PolicyTypeDialName}
}
}
// service permissions for admin & non-admin identities will be set according to policies
service, err = result.manager.ReadForIdentityInTx(tx, key, result.identityId, result.configTypes)
if err != nil {
return err
}
+10 -10
View File
@@ -20,9 +20,9 @@ package tests
import (
"fmt"
"github.com/openziti/ziti/common/eid"
"github.com/openziti/foundation/v2/errorz"
"github.com/openziti/foundation/v2/stringz"
"github.com/openziti/ziti/common/eid"
"net/url"
"sort"
"testing"
@@ -50,7 +50,7 @@ func Test_Services(t *testing.T) {
ctx.testContextChanged(t)
now := time.Now()
service := ctx.AdminManagementSession.requireNewService(nil, nil)
service.permissions = []string{"Dial", "Bind"}
service.permissions = []string{"Invalid"}
entityJson := ctx.AdminManagementSession.validateEntityWithQuery(service)
ctx.validateDateFieldsForCreate(now, entityJson)
})
@@ -58,11 +58,11 @@ func Test_Services(t *testing.T) {
t.Run("list as admin should return 3 services", func(t *testing.T) {
ctx.testContextChanged(t)
service1 := ctx.AdminManagementSession.requireNewService(nil, nil)
service1.permissions = []string{"Dial", "Bind"}
service1.permissions = []string{"Invalid"}
service2 := ctx.AdminManagementSession.requireNewService(nil, nil)
service2.permissions = []string{"Dial", "Bind"}
service2.permissions = []string{"Invalid"}
service3 := ctx.AdminManagementSession.requireNewService(nil, nil)
service3.permissions = []string{"Dial", "Bind"}
service3.permissions = []string{"Invalid"}
ctx.AdminManagementSession.validateEntityWithLookup(service1)
ctx.AdminManagementSession.validateEntityWithQuery(service1)
@@ -108,7 +108,7 @@ func Test_Services(t *testing.T) {
t.Run("lookup as admin should pass", func(t *testing.T) {
ctx.testContextChanged(t)
service := ctx.AdminManagementSession.requireNewService(nil, nil)
service.permissions = []string{"Dial", "Bind"}
service.permissions = []string{"Invalid"}
ctx.AdminManagementSession.validateEntityWithLookup(service)
})
@@ -163,7 +163,7 @@ func Test_Services(t *testing.T) {
ctx.testContextChanged(t)
now := time.Now()
service := ctx.AdminManagementSession.requireNewService(nil, nil)
service.permissions = []string{"Bind", "Dial"}
service.permissions = []string{"Invalid"}
entityJson := ctx.AdminManagementSession.validateEntityWithQuery(service)
createdAt := ctx.validateDateFieldsForCreate(now, entityJson)
@@ -364,7 +364,7 @@ func Test_ServiceRoleAttributes(t *testing.T) {
role1 := eid.New()
role2 := eid.New()
service := ctx.AdminManagementSession.requireNewService(s(role1, role2), nil)
service.permissions = []string{"Dial", "Bind"}
service.permissions = []string{"Invalid"}
ctx.AdminManagementSession.validateEntityWithQuery(service)
ctx.AdminManagementSession.validateEntityWithLookup(service)
@@ -375,7 +375,7 @@ func Test_ServiceRoleAttributes(t *testing.T) {
role1 := eid.New()
role2 := eid.New()
service := ctx.AdminManagementSession.requireNewService(s(role1, role2), nil)
service.permissions = []string{"Dial", "Bind"}
service.permissions = []string{"Invalid"}
role3 := eid.New()
service.roleAttributes = []string{role2, role3}
@@ -423,7 +423,7 @@ func Test_ServiceRoleAttributes(t *testing.T) {
now := time.Now()
newService := ctx.AdminManagementSession.requireNewService(nil, nil)
newService.permissions = []string{"Dial", "Bind"}
newService.permissions = []string{"Invalid"}
entityJson := ctx.AdminManagementSession.validateEntityWithQuery(newService)