mirror of
https://github.com/openziti/ziti.git
synced 2026-09-10 00:35:41 +00:00
respect service policies for admin identities (#1919)
respect service policies for admin identities
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user