Repository: owncloud/ocis
Pull request #5721 (2023-03-02 23:40:15)

reduce duplication in configuration code
Let's see if this will lower our "Bugs" and "Code Smells" scores on sonarcloud.

Todos:
- [x] Add tests for `structs.CopyOrZeroValue`
- [x] Add missing comments to the config code.

update-docs[bot]: Thanks for opening this pull request! The maintainers of this repository would appreciate it if you would create a [changelog](https://github.com/owncloud/ocis/blob/master/changelog/README.md) item based on your changes.

ownclouders: :boom: Acceptance test [<strong>Core-API-Tests-ocis-storage-1</strong>](https://drone.owncloud.com/owncloud/ocis/19775/52/1) failed. Further test are cancelled...
<!-- id: pr-5721 -->

sonarcloud[bot]: SonarCloud Quality Gate failed.&nbsp; &nbsp; [![Quality Gate failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=5721)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=5721&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=5721&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=5721&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=5721&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=5721&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=5721&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=5721&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=5721&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=5721&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=5721&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=5721&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=5721&resolved=false&types=CODE_SMELL)

[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/0-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=5721&metric=new_coverage&view=list) [0.0% Coverage](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=5721&metric=new_coverage&view=list)  
[![54.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/20plus-16px.png '54.0%')](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=5721&metric=new_duplicated_lines_density&view=list) [54.0% Duplication](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=5721&metric=new_duplicated_lines_density&view=list)



Patch:
diff --git a/go.mod b/go.mod
index dbd74cf7218..03623a8d608 100644
--- a/go.mod
+++ b/go.mod
@@ -8,7 +8,7 @@ require (
 	github.com/MicahParks/keyfunc v1.5.1
 	github.com/armon/go-radix v1.0.0
 	github.com/bbalet/stopwords v1.0.0
-	github.com/blevesearch/bleve/v2 v2.3.6
+	github.com/blevesearch/bleve/v2 v2.3.5
 	github.com/coreos/go-oidc/v3 v3.4.0
 	github.com/cs3org/go-cs3apis v0.0.0-20221012090518-ef2996678965
 	github.com/cs3org/reva/v2 v2.12.1-0.20230306101206-3de7ec137baf
@@ -117,21 +117,21 @@ require (
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/bitly/go-simplejson v0.5.0 // indirect
 	github.com/bits-and-blooms/bitset v1.2.1 // indirect
-	github.com/blevesearch/bleve_index_api v1.0.5 // indirect
-	github.com/blevesearch/geo v0.1.16 // indirect
+	github.com/blevesearch/bleve_index_api v1.0.4 // indirect
+	github.com/blevesearch/geo v0.1.15 // indirect
 	github.com/blevesearch/go-porterstemmer v1.0.3 // indirect
 	github.com/blevesearch/gtreap v0.1.1 // indirect
 	github.com/blevesearch/mmap-go v1.0.4 // indirect
-	github.com/blevesearch/scorch_segment_api/v2 v2.1.4 // indirect
+	github.com/blevesearch/scorch_segment_api/v2 v2.1.3 // indirect
 	github.com/blevesearch/segment v0.9.0 // indirect
 	github.com/blevesearch/snowballstem v0.9.0 // indirect
 	github.com/blevesearch/upsidedown_store_api v1.0.1 // indirect
 	github.com/blevesearch/vellum v1.0.9 // indirect
-	github.com/blevesearch/zapx/v11 v11.3.7 // indirect
-	github.com/blevesearch/zapx/v12 v12.3.7 // indirect
-	github.com/blevesearch/zapx/v13 v13.3.7 // indirect
-	github.com/blevesearch/zapx/v14 v14.3.7 // indirect
-	github.com/blevesearch/zapx/v15 v15.3.8 // indirect
+	github.com/blevesearch/zapx/v11 v11.3.6 // indirect
+	github.com/blevesearch/zapx/v12 v12.3.6 // indirect
+	github.com/blevesearch/zapx/v13 v13.3.6 // indirect
+	github.com/blevesearch/zapx/v14 v14.3.6 // indirect
+	github.com/blevesearch/zapx/v15 v15.3.6 // indirect
 	github.com/bluele/gcache v0.0.2 // indirect
 	github.com/bmizerany/pat v0.0.0-20210406213842-e4b6760bdd6f // indirect
 	github.com/bombsimon/logrusr/v3 v3.1.0 // indirect
diff --git a/go.sum b/go.sum
index 21ab7190f58..ee2b9914536 100644
--- a/go.sum
+++ b/go.sum
@@ -237,20 +237,21 @@ github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edY
 github.com/bits-and-blooms/bitset v1.2.1 h1:M+/hrU9xlMp7t4TyTDQW97d3tRPVuKFC6zBEK16QnXY=
 github.com/bits-and-blooms/bitset v1.2.1/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
 github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
-github.com/blevesearch/bleve/v2 v2.3.6 h1:NlntUHcV5CSWIhpugx4d/BRMGCiaoI8ZZXrXlahzNq4=
-github.com/blevesearch/bleve/v2 v2.3.6/go.mod h1:JM2legf1cKVkdV8Ehu7msKIOKC0McSw0Q16Fmv9vsW4=
-github.com/blevesearch/bleve_index_api v1.0.5 h1:Lc986kpC4Z0/n1g3gg8ul7H+lxgOQPcXb9SxvQGu+tw=
-github.com/blevesearch/bleve_index_api v1.0.5/go.mod h1:YXMDwaXFFXwncRS8UobWs7nvo0DmusriM1nztTlj1ms=
-github.com/blevesearch/geo v0.1.16 h1:unVaqUmlwprk56596OQRkGjtq1VZ8XFWSARj+h2cIBY=
-github.com/blevesearch/geo v0.1.16/go.mod h1:a1OlySNE+oDQ5qY0vJGYNoLIsMpbKbx8dnmuRP8D7H0=
+github.com/blevesearch/bleve/v2 v2.3.5 h1:1wuR7eB8Fk9UaCaBUfnQt5V7zIpi4VDok9ExN7Rl+/8=
+github.com/blevesearch/bleve/v2 v2.3.5/go.mod h1:FneKGHMRrCLrp4X9+iy3wlBqgM2ALucg7bp8jUuAi/s=
+github.com/blevesearch/bleve_index_api v1.0.3/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
+github.com/blevesearch/bleve_index_api v1.0.4 h1:mtlzsyJjMIlDngqqB1mq8kPryUMIuEVVbRbJHOWEexU=
+github.com/blevesearch/bleve_index_api v1.0.4/go.mod h1:YXMDwaXFFXwncRS8UobWs7nvo0DmusriM1nztTlj1ms=
+github.com/blevesearch/geo v0.1.15 h1:0NybEduqE5fduFRYiUKF0uqybAIFKXYjkBdXKYn7oA4=
+github.com/blevesearch/geo v0.1.15/go.mod h1:cRIvqCdk3cgMhGeHNNe6yPzb+w56otxbfo1FBJfR2Pc=
 github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo=
 github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M=
 github.com/blevesearch/gtreap v0.1.1 h1:2JWigFrzDMR+42WGIN/V2p0cUvn4UP3C4Q5nmaZGW8Y=
 github.com/blevesearch/gtreap v0.1.1/go.mod h1:QaQyDRAT51sotthUWAH4Sj08awFSSWzgYICSZ3w0tYk=
 github.com/blevesearch/mmap-go v1.0.4 h1:OVhDhT5B/M1HNPpYPBKIEJaD0F3Si+CrEKULGCDPWmc=
 github.com/blevesearch/mmap-go v1.0.4/go.mod h1:EWmEAOmdAS9z/pi/+Toxu99DnsbhG1TIxUoRmJw/pSs=
-github.com/blevesearch/scorch_segment_api/v2 v2.1.4 h1:LmGmo5twU3gV+natJbKmOktS9eMhokPGKWuR+jX84vk=
-github.com/blevesearch/scorch_segment_api/v2 v2.1.4/go.mod h1:PgVnbbg/t1UkgezPDu8EHLi1BHQ17xUwsFdU6NnOYS0=
+github.com/blevesearch/scorch_segment_api/v2 v2.1.3 h1:2UzpR2dR5DvSZk8tVJkcQ7D5xhoK/UBelYw8ttBHrRQ=
+github.com/blevesearch/scorch_segment_api/v2 v2.1.3/go.mod h1:eZrfp1y+lUh+DzFjUcTBUSnKGuunyFIpBIvqYVzJfvc=
 github.com/blevesearch/segment v0.9.0 h1:5lG7yBCx98or7gK2cHMKPukPZ/31Kag7nONpoBt22Ac=
 github.com/blevesearch/segment v0.9.0/go.mod h1:9PfHYUdQCgHktBgvtUOF4x+pc4/l8rdH0u5spnW85UQ=
 github.com/blevesearch/snowballstem v0.9.0 h1:lMQ189YspGP6sXvZQ4WZ+MLawfV8wOmPoD/iWeNXm8s=
@@ -259,16 +260,16 @@ github.com/blevesearch/upsidedown_store_api v1.0.1 h1:1SYRwyoFLwG3sj0ed89RLtM15a
 github.com/blevesearch/upsidedown_store_api v1.0.1/go.mod h1:MQDVGpHZrpe3Uy26zJBf/a8h0FZY6xJbthIMm8myH2Q=
 github.com/blevesearch/vellum v1.0.9 h1:PL+NWVk3dDGPCV0hoDu9XLLJgqU4E5s/dOeEJByQ2uQ=
 github.com/blevesearch/vellum v1.0.9/go.mod h1:ul1oT0FhSMDIExNjIxHqJoGpVrBpKCdgDQNxfqgJt7k=
-github.com/blevesearch/zapx/v11 v11.3.7 h1:Y6yIAF/DVPiqZUA/jNgSLXmqewfzwHzuwfKyfdG+Xaw=
-github.com/blevesearch/zapx/v11 v11.3.7/go.mod h1:Xk9Z69AoAWIOvWudNDMlxJDqSYGf90LS0EfnaAIvXCA=
-github.com/blevesearch/zapx/v12 v12.3.7 h1:DfQ6rsmZfEK4PzzJJRXjiM6AObG02+HWvprlXQ1Y7eI=
-github.com/blevesearch/zapx/v12 v12.3.7/go.mod h1:SgEtYIBGvM0mgIBn2/tQE/5SdrPXaJUaT/kVqpAPxm0=
-github.com/blevesearch/zapx/v13 v13.3.7 h1:igIQg5eKmjw168I7av0Vtwedf7kHnQro/M+ubM4d2l8=
-github.com/blevesearch/zapx/v13 v13.3.7/go.mod h1:yyrB4kJ0OT75UPZwT/zS+Ru0/jYKorCOOSY5dBzAy+s=
-github.com/blevesearch/zapx/v14 v14.3.7 h1:gfe+fbWslDWP/evHLtp/GOvmNM3sw1BbqD7LhycBX20=
-github.com/blevesearch/zapx/v14 v14.3.7/go.mod h1:9J/RbOkqZ1KSjmkOes03AkETX7hrXT0sFMpWH4ewC4w=
-github.com/blevesearch/zapx/v15 v15.3.8 h1:q4uMngBHzL1IIhRc8AJUEkj6dGOE3u1l3phLu7hq8uk=
-github.com/blevesearch/zapx/v15 v15.3.8/go.mod h1:m7Y6m8soYUvS7MjN9eKlz1xrLCcmqfFadmu7GhWIrLY=
+github.com/blevesearch/zapx/v11 v11.3.6 h1:50jET4HUJ6eCqGxdhUt+mjybMvEX2MWyqLGtCx3yUgc=
+github.com/blevesearch/zapx/v11 v11.3.6/go.mod h1:B0CzJRj/pS7hJIroflRtFsa9mRHpMSucSgre0FVINns=
+github.com/blevesearch/zapx/v12 v12.3.6 h1:G304NHBLgQeZ+IHK/XRCM0nhHqAts8MEvHI6LhoDNM4=
+github.com/blevesearch/zapx/v12 v12.3.6/go.mod h1:iYi7tIKpauwU5os5wTxJITixr5Km21Hl365otMwdaP0=
+github.com/blevesearch/zapx/v13 v13.3.6 h1:vavltQHNdjQezhLZs5nIakf+w/uOa1oqZxB58Jy/3Ig=
+github.com/blevesearch/zapx/v13 v13.3.6/go.mod h1:X+FsTwCU8qOHtK0d/ArvbOH7qiIgViSQ1GQvcR6LSkI=
+github.com/blevesearch/zapx/v14 v14.3.6 h1:b9lub7TvcwUyJxK/cQtnN79abngKxsI7zMZnICU0WhE=
+github.com/blevesearch/zapx/v14 v14.3.6/go.mod h1:9X8W3XoikagU0rwcTqwZho7p9cC7m7zhPZO94S4wUvM=
+github.com/blevesearch/zapx/v15 v15.3.6 h1:VSswg/ysDxHgitcNkpUNtaTYS4j3uItpXWLAASphl6k=
+github.com/blevesearch/zapx/v15 v15.3.6/go.mod h1:5DbhhDTGtuQSns1tS2aJxJLPc91boXCvjOMeCLD1saM=
 github.com/bluele/gcache v0.0.2 h1:WcbfdXICg7G/DGBh1PFfcirkWOQV+v077yF1pSy3DGw=
 github.com/bluele/gcache v0.0.2/go.mod h1:m15KV+ECjptwSPxKhOhQoAFQVtUFjTVkc3H8o0t/fp0=
 github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
diff --git a/ocis-pkg/config/parser/parse.go b/ocis-pkg/config/parser/parse.go
index aa25038dd87..54c94d1e987 100644
--- a/ocis-pkg/config/parser/parse.go
+++ b/ocis-pkg/config/parser/parse.go
@@ -6,6 +6,7 @@ import (
 	"github.com/owncloud/ocis/v2/ocis-pkg/config"
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/envdecode"
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 )
 
 // ParseConfig loads the ocis configuration and
@@ -36,7 +37,7 @@ func ParseConfig(cfg *config.Config, skipValidate bool) error {
 	return Validate(cfg)
 }
 
-// EnsureDefaults, ensures that all pointers in the
+// EnsureDefaults ensures that all pointers in the
 // oCIS config (not the services configs) are initialized
 func EnsureDefaults(cfg *config.Config) {
 	if cfg.Tracing == nil {
@@ -67,39 +68,9 @@ func EnsureCommons(cfg *config.Config) {
 		cfg.Commons = &shared.Commons{}
 	}
 
-	// copy config to the commons part if set
-	if cfg.Log != nil {
-		cfg.Commons.Log = &shared.Log{
-			Level:  cfg.Log.Level,
-			Pretty: cfg.Log.Pretty,
-			Color:  cfg.Log.Color,
-			File:   cfg.File,
-		}
-	} else {
-		cfg.Commons.Log = &shared.Log{}
-	}
-
-	// copy tracing to the commons part if set
-	if cfg.Tracing != nil {
-		cfg.Commons.Tracing = &shared.Tracing{
-			Enabled:   cfg.Tracing.Enabled,
-			Type:      cfg.Tracing.Type,
-			Endpoint:  cfg.Tracing.Endpoint,
-			Collector: cfg.Tracing.Collector,
-		}
-	} else {
-		cfg.Commons.Tracing = &shared.Tracing{}
-	}
-
-	if cfg.CacheStore != nil {
-		cfg.Commons.CacheStore = &shared.CacheStore{
-			Type:    cfg.CacheStore.Type,
-			Address: cfg.CacheStore.Address,
-			Size:    cfg.CacheStore.Size,
-		}
-	} else {
-		cfg.Commons.CacheStore = &shared.CacheStore{}
-	}
+	cfg.Commons.Log = structs.CopyOrZeroValue(cfg.Log)
+	cfg.Commons.Tracing = structs.CopyOrZeroValue(cfg.Tracing)
+	cfg.Commons.CacheStore = structs.CopyOrZeroValue(cfg.CacheStore)
 
 	if cfg.GRPCClientTLS != nil {
 		cfg.Commons.GRPCClientTLS = cfg.GRPCClientTLS
@@ -111,12 +82,7 @@ func EnsureCommons(cfg *config.Config) {
 
 	cfg.Commons.HTTPServiceTLS = cfg.HTTPServiceTLS
 
-	// copy token manager to the commons part if set
-	if cfg.TokenManager != nil {
-		cfg.Commons.TokenManager = cfg.TokenManager
-	} else {
-		cfg.Commons.TokenManager = &shared.TokenManager{}
-	}
+	cfg.Commons.TokenManager = structs.CopyOrZeroValue(cfg.TokenManager)
 
 	// copy machine auth api key to the commons part if set
 	if cfg.MachineAuthAPIKey != "" {
@@ -147,6 +113,8 @@ func EnsureCommons(cfg *config.Config) {
 	}
 }
 
+// Validate checks that all required configs are set. If a required config value
+// is missing an error will be returned.
 func Validate(cfg *config.Config) error {
 	if cfg.TokenManager.JWTSecret == "" {
 		return shared.MissingJWTTokenError("ocis")
diff --git a/ocis-pkg/structs/structs.go b/ocis-pkg/structs/structs.go
new file mode 100644
index 00000000000..b6545d048a1
--- /dev/null
+++ b/ocis-pkg/structs/structs.go
@@ -0,0 +1,11 @@
+// Package structs provides some utility functions for dealing with structs.
+package structs
+
+// CopyOrZeroValue returns a copy of s if s is not nil otherwise the zero value of T will be returned.
+func CopyOrZeroValue[T any](s *T) *T {
+	cp := new(T)
+	if s != nil {
+		*cp = *s
+	}
+	return cp
+}
diff --git a/services/app-provider/pkg/config/defaults/defaultconfig.go b/services/app-provider/pkg/config/defaults/defaultconfig.go
index 57a4be83433..33e1506bdd9 100644
--- a/services/app-provider/pkg/config/defaults/defaultconfig.go
+++ b/services/app-provider/pkg/config/defaults/defaultconfig.go
@@ -2,9 +2,11 @@ package defaults
 
 import (
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/app-provider/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -12,6 +14,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -39,6 +42,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -63,13 +67,8 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.Tracing = &config.Tracing{}
 	}
 
-	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
-		cfg.Reva = &shared.Reva{
-			Address: cfg.Commons.Reva.Address,
-			TLS:     cfg.Commons.Reva.TLS,
-		}
-	} else if cfg.Reva == nil {
-		cfg.Reva = &shared.Reva{}
+	if cfg.Reva == nil && cfg.Commons != nil {
+		cfg.Reva = structs.CopyOrZeroValue(cfg.Commons.Reva)
 	}
 
 	if cfg.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
@@ -80,20 +79,18 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.TokenManager = &config.TokenManager{}
 	}
 
-	if cfg.GRPC.TLS == nil {
-		cfg.GRPC.TLS = &shared.GRPCServiceTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCServiceTLS != nil {
-			cfg.GRPC.TLS.Enabled = cfg.Commons.GRPCServiceTLS.Enabled
-			cfg.GRPC.TLS.Cert = cfg.Commons.GRPCServiceTLS.Cert
-			cfg.GRPC.TLS.Key = cfg.Commons.GRPCServiceTLS.Key
-		}
+	if cfg.GRPC.TLS == nil && cfg.Commons != nil {
+		cfg.GRPC.TLS = structs.CopyOrZeroValue(cfg.Commons.GRPCServiceTLS)
 	}
 }
 
+// Sanitize sanitized the configuration
 func Sanitize(cfg *config.Config) {
 	// nothing to sanitize here atm
 }
 
+// Validate checks that all required configs are set. If a required config value
+// is missing an error will be returned.
 func Validate(cfg *config.Config) error {
 	if cfg.TokenManager.JWTSecret == "" {
 		return shared.MissingJWTTokenError(cfg.Service.Name)
diff --git a/services/app-registry/pkg/config/defaults/defaultconfig.go b/services/app-registry/pkg/config/defaults/defaultconfig.go
index de7e019529f..5cbc26c7153 100644
--- a/services/app-registry/pkg/config/defaults/defaultconfig.go
+++ b/services/app-registry/pkg/config/defaults/defaultconfig.go
@@ -2,9 +2,11 @@ package defaults
 
 import (
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/app-registry/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -12,6 +14,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -104,6 +107,7 @@ func defaultMimeTypeConfig() []config.MimeTypeConfig {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -128,13 +132,8 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.Tracing = &config.Tracing{}
 	}
 
-	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
-		cfg.Reva = &shared.Reva{
-			Address: cfg.Commons.Reva.Address,
-			TLS:     cfg.Commons.Reva.TLS,
-		}
-	} else if cfg.Reva == nil {
-		cfg.Reva = &shared.Reva{}
+	if cfg.Reva == nil && cfg.Commons != nil {
+		cfg.Reva = structs.CopyOrZeroValue(cfg.Commons.Reva)
 	}
 
 	if cfg.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
@@ -145,13 +144,8 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.TokenManager = &config.TokenManager{}
 	}
 
-	if cfg.GRPC.TLS == nil {
-		cfg.GRPC.TLS = &shared.GRPCServiceTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCServiceTLS != nil {
-			cfg.GRPC.TLS.Enabled = cfg.Commons.GRPCServiceTLS.Enabled
-			cfg.GRPC.TLS.Cert = cfg.Commons.GRPCServiceTLS.Cert
-			cfg.GRPC.TLS.Key = cfg.Commons.GRPCServiceTLS.Key
-		}
+	if cfg.GRPC.TLS == nil && cfg.Commons != nil {
+		cfg.GRPC.TLS = structs.CopyOrZeroValue(cfg.Commons.GRPCServiceTLS)
 	}
 }
 
diff --git a/services/auth-basic/pkg/config/defaults/defaultconfig.go b/services/auth-basic/pkg/config/defaults/defaultconfig.go
index 630aec30b6a..82d6c254e10 100644
--- a/services/auth-basic/pkg/config/defaults/defaultconfig.go
+++ b/services/auth-basic/pkg/config/defaults/defaultconfig.go
@@ -5,9 +5,11 @@ import (
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/defaults"
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/auth-basic/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -15,6 +17,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -78,6 +81,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -102,13 +106,8 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.Tracing = &config.Tracing{}
 	}
 
-	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
-		cfg.Reva = &shared.Reva{
-			Address: cfg.Commons.Reva.Address,
-			TLS:     cfg.Commons.Reva.TLS,
-		}
-	} else if cfg.Reva == nil {
-		cfg.Reva = &shared.Reva{}
+	if cfg.Reva == nil && cfg.Commons != nil {
+		cfg.Reva = structs.CopyOrZeroValue(cfg.Commons.Reva)
 	}
 
 	if cfg.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
@@ -119,16 +118,12 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.TokenManager = &config.TokenManager{}
 	}
 
-	if cfg.GRPC.TLS == nil {
-		cfg.GRPC.TLS = &shared.GRPCServiceTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCServiceTLS != nil {
-			cfg.GRPC.TLS.Enabled = cfg.Commons.GRPCServiceTLS.Enabled
-			cfg.GRPC.TLS.Cert = cfg.Commons.GRPCServiceTLS.Cert
-			cfg.GRPC.TLS.Key = cfg.Commons.GRPCServiceTLS.Key
-		}
+	if cfg.GRPC.TLS == nil && cfg.Commons != nil {
+		cfg.GRPC.TLS = structs.CopyOrZeroValue(cfg.Commons.GRPCServiceTLS)
 	}
 }
 
+// Sanitize sanitized the configuration
 func Sanitize(cfg *config.Config) {
 	// nothing to sanitize here atm
 }
diff --git a/services/auth-bearer/pkg/config/defaults/defaultconfig.go b/services/auth-bearer/pkg/config/defaults/defaultconfig.go
index e9a3eaf2da5..457eae88f03 100644
--- a/services/auth-bearer/pkg/config/defaults/defaultconfig.go
+++ b/services/auth-bearer/pkg/config/defaults/defaultconfig.go
@@ -2,9 +2,11 @@ package defaults
 
 import (
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/auth-bearer/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -12,6 +14,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -37,6 +40,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -61,13 +65,8 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.Tracing = &config.Tracing{}
 	}
 
-	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
-		cfg.Reva = &shared.Reva{
-			Address: cfg.Commons.Reva.Address,
-			TLS:     cfg.Commons.Reva.TLS,
-		}
-	} else if cfg.Reva == nil {
-		cfg.Reva = &shared.Reva{}
+	if cfg.Reva == nil && cfg.Commons != nil {
+		cfg.Reva = structs.CopyOrZeroValue(cfg.Commons.Reva)
 	}
 
 	if cfg.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
@@ -78,16 +77,12 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.TokenManager = &config.TokenManager{}
 	}
 
-	if cfg.GRPC.TLS == nil {
-		cfg.GRPC.TLS = &shared.GRPCServiceTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCServiceTLS != nil {
-			cfg.GRPC.TLS.Enabled = cfg.Commons.GRPCServiceTLS.Enabled
-			cfg.GRPC.TLS.Cert = cfg.Commons.GRPCServiceTLS.Cert
-			cfg.GRPC.TLS.Key = cfg.Commons.GRPCServiceTLS.Key
-		}
+	if cfg.GRPC.TLS == nil && cfg.Commons != nil {
+		cfg.GRPC.TLS = structs.CopyOrZeroValue(cfg.Commons.GRPCServiceTLS)
 	}
 }
 
+// Sanitize sanitized the configuration
 func Sanitize(cfg *config.Config) {
 	// nothing to sanitize here atm
 }
diff --git a/services/auth-machine/pkg/config/defaults/defaultconfig.go b/services/auth-machine/pkg/config/defaults/defaultconfig.go
index 242db54a57f..3123334d56b 100644
--- a/services/auth-machine/pkg/config/defaults/defaultconfig.go
+++ b/services/auth-machine/pkg/config/defaults/defaultconfig.go
@@ -2,9 +2,11 @@ package defaults
 
 import (
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/auth-machine/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -12,6 +14,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -32,6 +35,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -56,13 +60,8 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.Tracing = &config.Tracing{}
 	}
 
-	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
-		cfg.Reva = &shared.Reva{
-			Address: cfg.Commons.Reva.Address,
-			TLS:     cfg.Commons.Reva.TLS,
-		}
-	} else if cfg.Reva == nil {
-		cfg.Reva = &shared.Reva{}
+	if cfg.Reva == nil && cfg.Commons != nil {
+		cfg.Reva = structs.CopyOrZeroValue(cfg.Commons.Reva)
 	}
 
 	if cfg.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
@@ -77,16 +76,12 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.MachineAuthAPIKey = cfg.Commons.MachineAuthAPIKey
 	}
 
-	if cfg.GRPC.TLS == nil {
-		cfg.GRPC.TLS = &shared.GRPCServiceTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCServiceTLS != nil {
-			cfg.GRPC.TLS.Enabled = cfg.Commons.GRPCServiceTLS.Enabled
-			cfg.GRPC.TLS.Cert = cfg.Commons.GRPCServiceTLS.Cert
-			cfg.GRPC.TLS.Key = cfg.Commons.GRPCServiceTLS.Key
-		}
+	if cfg.GRPC.TLS == nil && cfg.Commons != nil {
+		cfg.GRPC.TLS = structs.CopyOrZeroValue(cfg.Commons.GRPCServiceTLS)
 	}
 }
 
+// Sanitize sanitized the configuration
 func Sanitize(cfg *config.Config) {
 	// nothing to sanitize here atm
 }
diff --git a/services/eventhistory/pkg/command/root.go b/services/eventhistory/pkg/command/root.go
index 73107f10856..f2cf6638995 100644
--- a/services/eventhistory/pkg/command/root.go
+++ b/services/eventhistory/pkg/command/root.go
@@ -43,7 +43,7 @@ type SutureService struct {
 
 // NewSutureService creates a new eventhistory.SutureService
 func NewSutureService(cfg *ociscfg.Config) suture.Service {
-	cfg.Notifications.Commons = cfg.Commons
+	cfg.EventHistory.Commons = cfg.Commons
 	return SutureService{
 		cfg: cfg.EventHistory,
 	}
diff --git a/services/eventhistory/pkg/config/defaults/defaultconfig.go b/services/eventhistory/pkg/config/defaults/defaultconfig.go
index a61d411c4b9..d37b6fbe1b3 100644
--- a/services/eventhistory/pkg/config/defaults/defaultconfig.go
+++ b/services/eventhistory/pkg/config/defaults/defaultconfig.go
@@ -3,7 +3,7 @@ package defaults
 import (
 	"time"
 
-	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/eventhistory/pkg/config"
 )
 
@@ -51,20 +51,12 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.Log = &config.Log{}
 	}
 
-	if cfg.GRPCClientTLS == nil {
-		cfg.GRPCClientTLS = &shared.GRPCClientTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCClientTLS != nil {
-			cfg.GRPCClientTLS = cfg.Commons.GRPCClientTLS
-		}
+	if cfg.GRPCClientTLS == nil && cfg.Commons != nil {
+		cfg.GRPCClientTLS = structs.CopyOrZeroValue(cfg.Commons.GRPCClientTLS)
 	}
 
-	if cfg.GRPC.TLS == nil {
-		cfg.GRPC.TLS = &shared.GRPCServiceTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCServiceTLS != nil {
-			cfg.GRPC.TLS.Enabled = cfg.Commons.GRPCServiceTLS.Enabled
-			cfg.GRPC.TLS.Cert = cfg.Commons.GRPCServiceTLS.Cert
-			cfg.GRPC.TLS.Key = cfg.Commons.GRPCServiceTLS.Key
-		}
+	if cfg.GRPC.TLS == nil && cfg.Commons != nil {
+		cfg.GRPC.TLS = structs.CopyOrZeroValue(cfg.Commons.GRPCServiceTLS)
 	}
 }
 
diff --git a/services/frontend/pkg/config/defaults/defaultconfig.go b/services/frontend/pkg/config/defaults/defaultconfig.go
index 526d5a81b6a..ed035127733 100644
--- a/services/frontend/pkg/config/defaults/defaultconfig.go
+++ b/services/frontend/pkg/config/defaults/defaultconfig.go
@@ -2,9 +2,11 @@ package defaults
 
 import (
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/frontend/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -12,6 +14,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -114,6 +117,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -138,13 +142,8 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.Tracing = &config.Tracing{}
 	}
 
-	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
-		cfg.Reva = &shared.Reva{
-			Address: cfg.Commons.Reva.Address,
-			TLS:     cfg.Commons.Reva.TLS,
-		}
-	} else if cfg.Reva == nil {
-		cfg.Reva = &shared.Reva{}
+	if cfg.Reva == nil && cfg.Commons != nil {
+		cfg.Reva = structs.CopyOrZeroValue(cfg.Commons.Reva)
 	}
 
 	if cfg.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
@@ -165,6 +164,7 @@ func EnsureDefaults(cfg *config.Config) {
 
 }
 
+// Sanitize sanitized the configuration
 func Sanitize(cfg *config.Config) {
 	// nothing to sanitize here atm
 }
diff --git a/services/gateway/pkg/config/defaults/defaultconfig.go b/services/gateway/pkg/config/defaults/defaultconfig.go
index adf7a84226b..72ffb74b001 100644
--- a/services/gateway/pkg/config/defaults/defaultconfig.go
+++ b/services/gateway/pkg/config/defaults/defaultconfig.go
@@ -2,9 +2,11 @@ package defaults
 
 import (
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/gateway/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -12,6 +14,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -61,6 +64,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -85,13 +89,8 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.Tracing = &config.Tracing{}
 	}
 
-	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
-		cfg.Reva = &shared.Reva{
-			Address: cfg.Commons.Reva.Address,
-			TLS:     cfg.Commons.Reva.TLS,
-		}
-	} else if cfg.Reva == nil {
-		cfg.Reva = &shared.Reva{}
+	if cfg.Reva == nil && cfg.Commons != nil {
+		cfg.Reva = structs.CopyOrZeroValue(cfg.Commons.Reva)
 	}
 
 	if cfg.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
@@ -106,16 +105,12 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.TransferSecret = cfg.Commons.TransferSecret
 	}
 
-	if cfg.GRPC.TLS == nil {
-		cfg.GRPC.TLS = &shared.GRPCServiceTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCServiceTLS != nil {
-			cfg.GRPC.TLS.Enabled = cfg.Commons.GRPCServiceTLS.Enabled
-			cfg.GRPC.TLS.Cert = cfg.Commons.GRPCServiceTLS.Cert
-			cfg.GRPC.TLS.Key = cfg.Commons.GRPCServiceTLS.Key
-		}
+	if cfg.GRPC.TLS == nil && cfg.Commons != nil {
+		cfg.GRPC.TLS = structs.CopyOrZeroValue(cfg.Commons.GRPCServiceTLS)
 	}
 }
 
+// Sanitize sanitized the configuration
 func Sanitize(cfg *config.Config) {
 	// nothing to sanitize here atm
 }
diff --git a/services/graph/pkg/config/config.go b/services/graph/pkg/config/config.go
index 382ba7898e5..385de2bab52 100644
--- a/services/graph/pkg/config/config.go
+++ b/services/graph/pkg/config/config.go
@@ -62,7 +62,7 @@ type LDAP struct {
 	UserNameAttribute        string `yaml:"user_name_attribute" env:"LDAP_USER_SCHEMA_USERNAME;GRAPH_LDAP_USER_NAME_ATTRIBUTE" desc:"LDAP Attribute to use for username of users."`
 	UserIDAttribute          string `yaml:"user_id_attribute" env:"LDAP_USER_SCHEMA_ID;GRAPH_LDAP_USER_UID_ATTRIBUTE" desc:"LDAP Attribute to use as the unique ID for users. This should be a stable globally unique ID like a UUID."`
 	UserEnabledAttribute     string `yaml:"user_enabled_attribute" env:"LDAP_USER_ENABLED_ATTRIBUTE;GRAPH_USER_ENABLED_ATTRIBUTE" desc:"LDAP Attribute to use as a flag telling if the user is enabled or disabled."`
-	DisableUserMechanism     string `yaml:"disable_user_mechanism" env:"LDAP_DISABLE_USER_MECHANISM;GRAPH_DISABLE_USER_MECHANISM" desc:"An option to control the behavior for disabling users. Supported options are 'none', 'attribute' and 'group'. If set to 'group', disabling a user via API will add the user to the configured group for disabled users, if set to 'attribute' this will be done in the ldap user entry, if set to 'none' the disable request is not processed. Default is 'attribute'."`
+	DisableUserMechanism     string `yaml:"disable_user_mechanism" env:"LDAP_DISABLE_USER_MECHANISM;GRAPH_DISABLE_USER_MECHANISM" desc:"An option to control the behavior for disabling users. Valid options are 'none', 'attribute' and 'group'. If set to 'group', disabling a user via API will add the user to the configured group for disabled users, if set to 'attribute' this will be done in the ldap user entry, if set to 'none' the disable request is not processed. Default is 'attribute'."`
 	LdapDisabledUsersGroupDN string `yaml:"ldap_disabled_users_group_dn" env:"LDAP_DISABLED_USERS_GROUP_DN;GRAPH_DISABLED_USERS_GROUP_DN" desc:"The distinguished name of the group to which added users will be classified as disabled when 'disable_user_mechanism' is set to 'group'."`
 
 	GroupBaseDN        string `yaml:"group_base_dn" env:"LDAP_GROUP_BASE_DN;GRAPH_LDAP_GROUP_BASE_DN" desc:"Search base DN for looking up LDAP groups."`
diff --git a/services/graph/pkg/config/defaults/defaultconfig.go b/services/graph/pkg/config/defaults/defaultconfig.go
index 7b9a4563db5..d6c11b6f962 100644
--- a/services/graph/pkg/config/defaults/defaultconfig.go
+++ b/services/graph/pkg/config/defaults/defaultconfig.go
@@ -7,9 +7,11 @@ import (
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/defaults"
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -17,6 +19,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -88,6 +91,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -130,12 +134,8 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.TokenManager = &config.TokenManager{}
 	}
 
-	if cfg.GRPCClientTLS == nil {
-		cfg.GRPCClientTLS = &shared.GRPCClientTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCClientTLS != nil {
-			cfg.GRPCClientTLS.Mode = cfg.Commons.GRPCClientTLS.Mode
-			cfg.GRPCClientTLS.CACert = cfg.Commons.GRPCClientTLS.CACert
-		}
+	if cfg.GRPCClientTLS == nil && cfg.Commons != nil {
+		cfg.GRPCClientTLS = structs.CopyOrZeroValue(cfg.Commons.GRPCClientTLS)
 	}
 
 	if cfg.Commons != nil {
@@ -143,6 +143,7 @@ func EnsureDefaults(cfg *config.Config) {
 	}
 }
 
+// Sanitize sanitized the configuration
 func Sanitize(cfg *config.Config) {
 	// sanitize config
 	if cfg.HTTP.Root != "/" {
diff --git a/services/groups/pkg/config/config.go b/services/groups/pkg/config/config.go
index 5bbb20da05e..2e96c51ad5d 100644
--- a/services/groups/pkg/config/config.go
+++ b/services/groups/pkg/config/config.go
@@ -76,7 +76,7 @@ type LDAPDriver struct {
 	GroupBaseDN              string          `yaml:"group_base_dn" env:"LDAP_GROUP_BASE_DN;GROUPS_LDAP_GROUP_BASE_DN" desc:"Search base DN for looking up LDAP groups."`
 	UserScope                string          `yaml:"user_scope" env:"LDAP_USER_SCOPE;GROUPS_LDAP_USER_SCOPE" desc:"LDAP search scope to use when looking up users. Supported scopes are 'base', 'one' and 'sub'."`
 	GroupScope               string          `yaml:"group_scope" env:"LDAP_GROUP_SCOPE;GROUPS_LDAP_GROUP_SCOPE" desc:"LDAP search scope to use when looking up groups. Supported scopes are 'base', 'one' and 'sub'."`
-	GroupSubstringFilterType string          `yaml:"group_substring_filter_type" env:"LDAP_GROUP_SUBSTRING_FILTER_TYPE;GROUP_LDAP_GROUP_SUBSTRING_FILTER_TYPE" desc:"Type of substring search filter to use for substring searches for groups. Supported values are 'initial', 'final' and 'any'. The value 'initial' is used for doing prefix only searches, 'final' for doing suffix only searches or 'any' for doing full substring searches"`
+	GroupSubstringFilterType string          `yaml:"group_substring_filter_type" env:"LDAP_GROUP_SUBSTRING_FILTER_TYPE;GROUP_LDAP_GROUP_SUBSTRING_FILTER_TYPE" desc:"Type of substring search filter to use for substring searches for groups. Possible values: 'initial' for doing prefix only searches, 'final' for doing suffix only searches or 'any' for doing full substring searches"`
 	UserFilter               string          `yaml:"user_filter" env:"LDAP_USER_FILTER;GROUPS_LDAP_USER_FILTER" desc:"LDAP filter to add to the default filters for user search like '(objectclass=ownCloud)'."`
 	GroupFilter              string          `yaml:"group_filter" env:"LDAP_GROUP_FILTER;GROUPS_LDAP_GROUP_FILTER" desc:"LDAP filter to add to the default filters for group searches."`
 	UserObjectClass          string          `yaml:"user_object_class" env:"LDAP_USER_OBJECTCLASS;GROUPS_LDAP_USER_OBJECTCLASS" desc:"The object class to use for users in the default user search filter ('inetOrgPerson')."`
diff --git a/services/groups/pkg/config/defaults/defaultconfig.go b/services/groups/pkg/config/defaults/defaultconfig.go
index 62cfe0e4e95..1a93ea1525b 100644
--- a/services/groups/pkg/config/defaults/defaultconfig.go
+++ b/services/groups/pkg/config/defaults/defaultconfig.go
@@ -5,9 +5,11 @@ import (
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/defaults"
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/groups/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -15,6 +17,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -79,6 +82,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -103,13 +107,8 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.Tracing = &config.Tracing{}
 	}
 
-	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
-		cfg.Reva = &shared.Reva{
-			Address: cfg.Commons.Reva.Address,
-			TLS:     cfg.Commons.Reva.TLS,
-		}
-	} else if cfg.Reva == nil {
-		cfg.Reva = &shared.Reva{}
+	if cfg.Reva == nil && cfg.Commons != nil {
+		cfg.Reva = structs.CopyOrZeroValue(cfg.Commons.Reva)
 	}
 
 	if cfg.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
@@ -120,16 +119,12 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.TokenManager = &config.TokenManager{}
 	}
 
-	if cfg.GRPC.TLS == nil {
-		cfg.GRPC.TLS = &shared.GRPCServiceTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCServiceTLS != nil {
-			cfg.GRPC.TLS.Enabled = cfg.Commons.GRPCServiceTLS.Enabled
-			cfg.GRPC.TLS.Cert = cfg.Commons.GRPCServiceTLS.Cert
-			cfg.GRPC.TLS.Key = cfg.Commons.GRPCServiceTLS.Key
-		}
+	if cfg.GRPC.TLS == nil && cfg.Commons != nil {
+		cfg.GRPC.TLS = structs.CopyOrZeroValue(cfg.Commons.GRPCServiceTLS)
 	}
 }
 
+// Sanitize sanitized the configuration
 func Sanitize(cfg *config.Config) {
 	// nothing to sanitize here atm
 }
diff --git a/services/idm/pkg/config/defaults/defaultconfig.go b/services/idm/pkg/config/defaults/defaultconfig.go
index c44dc131246..2a977b354e2 100644
--- a/services/idm/pkg/config/defaults/defaultconfig.go
+++ b/services/idm/pkg/config/defaults/defaultconfig.go
@@ -7,6 +7,7 @@ import (
 	"github.com/owncloud/ocis/v2/services/idm/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -14,6 +15,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -32,6 +34,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -61,6 +64,7 @@ func EnsureDefaults(cfg *config.Config) {
 	}
 }
 
+// Sanitize sanitizes the configuration
 func Sanitize(cfg *config.Config) {
 	// nothing to sanitize here
 }
diff --git a/services/idp/pkg/config/defaults/defaultconfig.go b/services/idp/pkg/config/defaults/defaultconfig.go
index c65dafda06a..c996b42795c 100644
--- a/services/idp/pkg/config/defaults/defaultconfig.go
+++ b/services/idp/pkg/config/defaults/defaultconfig.go
@@ -6,9 +6,11 @@ import (
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/defaults"
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/idp/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -16,6 +18,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -128,6 +131,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -152,13 +156,8 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.Tracing = &config.Tracing{}
 	}
 
-	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
-		cfg.Reva = &shared.Reva{
-			Address: cfg.Commons.Reva.Address,
-			TLS:     cfg.Commons.Reva.TLS,
-		}
-	} else if cfg.Reva == nil {
-		cfg.Reva = &shared.Reva{}
+	if cfg.Reva == nil && cfg.Commons != nil {
+		cfg.Reva = structs.CopyOrZeroValue(cfg.Commons.Reva)
 	}
 
 	if cfg.MachineAuthAPIKey == "" && cfg.Commons != nil && cfg.Commons.MachineAuthAPIKey != "" {
@@ -166,6 +165,7 @@ func EnsureDefaults(cfg *config.Config) {
 	}
 }
 
+// Sanitize sanitizes the configuration
 func Sanitize(cfg *config.Config) {
 	// sanitize config
 	if cfg.HTTP.Root != "/" {
diff --git a/services/nats/pkg/config/defaults/defaultconfig.go b/services/nats/pkg/config/defaults/defaultconfig.go
index 30ef1ace248..f4bf4f64e22 100644
--- a/services/nats/pkg/config/defaults/defaultconfig.go
+++ b/services/nats/pkg/config/defaults/defaultconfig.go
@@ -10,6 +10,7 @@ import (
 // NOTE: Most of this configuration is not needed to keep it as simple as possible
 // TODO: Clean up unneeded configuration
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -17,6 +18,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -37,6 +39,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -51,6 +54,7 @@ func EnsureDefaults(cfg *config.Config) {
 	}
 }
 
+// Sanitize sanitizes the configuration
 func Sanitize(cfg *config.Config) {
 	// nothing to sanitize here atm
 }
diff --git a/services/notifications/pkg/config/defaults/defaultconfig.go b/services/notifications/pkg/config/defaults/defaultconfig.go
index 20e3582d879..20cd4733042 100644
--- a/services/notifications/pkg/config/defaults/defaultconfig.go
+++ b/services/notifications/pkg/config/defaults/defaultconfig.go
@@ -2,9 +2,11 @@ package defaults
 
 import (
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/notifications/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -15,6 +17,7 @@ func FullDefaultConfig() *config.Config {
 // NOTE: Most of this configuration is not needed to keep it as simple as possible
 // TODO: Clean up unneeded configuration
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -43,6 +46,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -59,14 +63,12 @@ func EnsureDefaults(cfg *config.Config) {
 	if cfg.Notifications.MachineAuthAPIKey == "" && cfg.Commons != nil && cfg.Commons.MachineAuthAPIKey != "" {
 		cfg.Notifications.MachineAuthAPIKey = cfg.Commons.MachineAuthAPIKey
 	}
-	if cfg.Notifications.GRPCClientTLS == nil {
-		cfg.Notifications.GRPCClientTLS = &shared.GRPCClientTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCClientTLS != nil {
-			cfg.Notifications.GRPCClientTLS = cfg.Commons.GRPCClientTLS
-		}
+	if cfg.Notifications.GRPCClientTLS == nil && cfg.Commons != nil {
+		cfg.Notifications.GRPCClientTLS = structs.CopyOrZeroValue(cfg.Commons.GRPCClientTLS)
 	}
 }
 
+// Sanitize sanitizes the configuration
 func Sanitize(cfg *config.Config) {
 	// nothing to sanitize here atm
 }
diff --git a/services/ocdav/pkg/config/defaults/defaultconfig.go b/services/ocdav/pkg/config/defaults/defaultconfig.go
index 6d6fae5223c..e29abfe39a7 100644
--- a/services/ocdav/pkg/config/defaults/defaultconfig.go
+++ b/services/ocdav/pkg/config/defaults/defaultconfig.go
@@ -2,10 +2,12 @@ package defaults
 
 import (
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
 	"github.com/owncloud/ocis/v2/services/ocdav/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -13,6 +15,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -49,6 +52,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -73,13 +77,8 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.Tracing = &config.Tracing{}
 	}
 
-	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
-		cfg.Reva = &shared.Reva{
-			Address: cfg.Commons.Reva.Address,
-			TLS:     cfg.Commons.Reva.TLS,
-		}
-	} else if cfg.Reva == nil {
-		cfg.Reva = &shared.Reva{}
+	if cfg.Reva == nil && cfg.Commons != nil {
+		cfg.Reva = structs.CopyOrZeroValue(cfg.Commons.Reva)
 	}
 
 	if cfg.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
@@ -95,6 +94,7 @@ func EnsureDefaults(cfg *config.Config) {
 	}
 }
 
+// Sanitize sanitizes the configuration
 func Sanitize(cfg *config.Config) {
 	// nothing to sanitize here atm
 }
diff --git a/services/ocs/pkg/config/defaults/defaultconfig.go b/services/ocs/pkg/config/defaults/defaultconfig.go
index 9b04fb99f8b..eaf58ede56d 100644
--- a/services/ocs/pkg/config/defaults/defaultconfig.go
+++ b/services/ocs/pkg/config/defaults/defaultconfig.go
@@ -6,6 +6,7 @@ import (
 	"github.com/owncloud/ocis/v2/services/ocs/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -13,6 +14,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -38,6 +40,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -85,6 +88,7 @@ func EnsureDefaults(cfg *config.Config) {
 	}
 }
 
+// Sanitize sanitizes the configuration
 func Sanitize(cfg *config.Config) {
 	// sanitize config
 	if cfg.HTTP.Root != "/" {
diff --git a/services/proxy/pkg/config/defaults/defaultconfig.go b/services/proxy/pkg/config/defaults/defaultconfig.go
index daf3a7534ec..f1316cf9125 100644
--- a/services/proxy/pkg/config/defaults/defaultconfig.go
+++ b/services/proxy/pkg/config/defaults/defaultconfig.go
@@ -6,9 +6,11 @@ import (
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/defaults"
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/proxy/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -16,6 +18,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -63,6 +66,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// DefaultPolicies returns the default proxy policies.
 func DefaultPolicies() []config.Policy {
 	return []config.Policy{
 		{
@@ -249,21 +253,12 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.MachineAuthAPIKey = cfg.Commons.MachineAuthAPIKey
 	}
 
-	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
-		cfg.Reva = &shared.Reva{
-			Address: cfg.Commons.Reva.Address,
-			TLS:     cfg.Commons.Reva.TLS,
-		}
-	} else if cfg.Reva == nil {
-		cfg.Reva = &shared.Reva{}
+	if cfg.Reva == nil && cfg.Commons != nil {
+		cfg.Reva = structs.CopyOrZeroValue(cfg.Commons.Reva)
 	}
 
-	if cfg.GRPCClientTLS == nil {
-		cfg.GRPCClientTLS = &shared.GRPCClientTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCClientTLS != nil {
-			cfg.GRPCClientTLS.Mode = cfg.Commons.GRPCClientTLS.Mode
-			cfg.GRPCClientTLS.CACert = cfg.Commons.GRPCClientTLS.CACert
-		}
+	if cfg.GRPCClientTLS == nil && cfg.Commons != nil {
+		cfg.GRPCClientTLS = structs.CopyOrZeroValue(cfg.Commons.GRPCClientTLS)
 	}
 }
 
diff --git a/services/search/pkg/config/defaults/defaultconfig.go b/services/search/pkg/config/defaults/defaultconfig.go
index 7fb9ef946fd..095a6891bf9 100644
--- a/services/search/pkg/config/defaults/defaultconfig.go
+++ b/services/search/pkg/config/defaults/defaultconfig.go
@@ -5,9 +5,11 @@ import (
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/defaults"
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/search/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 
@@ -16,6 +18,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -83,28 +86,14 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.MachineAuthAPIKey = cfg.Commons.MachineAuthAPIKey
 	}
 
-	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
-		cfg.Reva = &shared.Reva{
-			Address: cfg.Commons.Reva.Address,
-			TLS:     cfg.Commons.Reva.TLS,
-		}
-	} else if cfg.Reva == nil {
-		cfg.Reva = &shared.Reva{}
+	if cfg.Reva == nil && cfg.Commons != nil {
+		cfg.Reva = structs.CopyOrZeroValue(cfg.Commons.Reva)
 	}
-	if cfg.GRPCClientTLS == nil {
-		cfg.GRPCClientTLS = &shared.GRPCClientTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCClientTLS != nil {
-			cfg.GRPCClientTLS.Mode = cfg.Commons.GRPCClientTLS.Mode
-			cfg.GRPCClientTLS.CACert = cfg.Commons.GRPCClientTLS.CACert
-		}
+	if cfg.GRPCClientTLS == nil && cfg.Commons != nil {
+		cfg.GRPCClientTLS = structs.CopyOrZeroValue(cfg.Commons.GRPCClientTLS)
 	}
-	if cfg.GRPC.TLS == nil {
-		cfg.GRPC.TLS = &shared.GRPCServiceTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCServiceTLS != nil {
-			cfg.GRPC.TLS.Enabled = cfg.Commons.GRPCServiceTLS.Enabled
-			cfg.GRPC.TLS.Cert = cfg.Commons.GRPCServiceTLS.Cert
-			cfg.GRPC.TLS.Key = cfg.Commons.GRPCServiceTLS.Key
-		}
+	if cfg.GRPC.TLS == nil && cfg.Commons != nil {
+		cfg.GRPC.TLS = structs.CopyOrZeroValue(cfg.Commons.GRPCServiceTLS)
 	}
 }
 
diff --git a/services/settings/pkg/config/defaults/defaultconfig.go b/services/settings/pkg/config/defaults/defaultconfig.go
index 1c07e7005a5..bb216f51b6e 100644
--- a/services/settings/pkg/config/defaults/defaultconfig.go
+++ b/services/settings/pkg/config/defaults/defaultconfig.go
@@ -7,12 +7,13 @@ import (
 	"strings"
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/defaults"
-	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/settings/pkg/config"
 	rdefaults "github.com/owncloud/ocis/v2/services/settings/pkg/store/defaults"
 	"github.com/pkg/errors"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -60,6 +61,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -104,20 +106,11 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.AdminUserID = cfg.Commons.AdminUserID
 	}
 
-	if cfg.GRPCClientTLS == nil {
-		cfg.GRPCClientTLS = &shared.GRPCClientTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCClientTLS != nil {
-			cfg.GRPCClientTLS.Mode = cfg.Commons.GRPCClientTLS.Mode
-			cfg.GRPCClientTLS.CACert = cfg.Commons.GRPCClientTLS.CACert
-		}
+	if cfg.GRPCClientTLS == nil && cfg.Commons != nil {
+		cfg.GRPCClientTLS = structs.CopyOrZeroValue(cfg.Commons.GRPCClientTLS)
 	}
-	if cfg.GRPC.TLS == nil {
-		cfg.GRPC.TLS = &shared.GRPCServiceTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCServiceTLS != nil {
-			cfg.GRPC.TLS.Enabled = cfg.Commons.GRPCServiceTLS.Enabled
-			cfg.GRPC.TLS.Cert = cfg.Commons.GRPCServiceTLS.Cert
-			cfg.GRPC.TLS.Key = cfg.Commons.GRPCServiceTLS.Key
-		}
+	if cfg.GRPC.TLS == nil && cfg.Commons != nil {
+		cfg.GRPC.TLS = structs.CopyOrZeroValue(cfg.Commons.GRPCServiceTLS)
 	}
 
 	if cfg.Commons != nil {
@@ -125,6 +118,7 @@ func EnsureDefaults(cfg *config.Config) {
 	}
 }
 
+// Sanitize sanitized the configuration
 func Sanitize(cfg *config.Config) {
 	// sanitize config
 	if cfg.HTTP.Root != "/" {
diff --git a/services/sharing/pkg/config/defaults/defaultconfig.go b/services/sharing/pkg/config/defaults/defaultconfig.go
index 5049e1d8eae..044e4694a36 100644
--- a/services/sharing/pkg/config/defaults/defaultconfig.go
+++ b/services/sharing/pkg/config/defaults/defaultconfig.go
@@ -5,9 +5,11 @@ import (
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/defaults"
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/sharing/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -15,6 +17,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -75,14 +78,14 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
 		cfg.Log = &config.Log{
 			Level:  cfg.Commons.Log.Level,
-			Pretty: cfg.Commons.Log.Pretty,
-			Color:  cfg.Commons.Log.Color,
-			File:   cfg.Commons.Log.File,
+			Pretty: cfg.Commons.Log.Pretty, Color: cfg.Commons.Log.Color,
+			File: cfg.Commons.Log.File,
 		}
 	} else if cfg.Log == nil {
 		cfg.Log = &config.Log{}
@@ -99,13 +102,8 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.Tracing = &config.Tracing{}
 	}
 
-	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
-		cfg.Reva = &shared.Reva{
-			Address: cfg.Commons.Reva.Address,
-			TLS:     cfg.Commons.Reva.TLS,
-		}
-	} else if cfg.Reva == nil {
-		cfg.Reva = &shared.Reva{}
+	if cfg.Reva == nil && cfg.Commons != nil {
+		cfg.Reva = structs.CopyOrZeroValue(cfg.Commons.Reva)
 	}
 
 	if cfg.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
@@ -116,13 +114,8 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.TokenManager = &config.TokenManager{}
 	}
 
-	if cfg.GRPC.TLS == nil {
-		cfg.GRPC.TLS = &shared.GRPCServiceTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCServiceTLS != nil {
-			cfg.GRPC.TLS.Enabled = cfg.Commons.GRPCServiceTLS.Enabled
-			cfg.GRPC.TLS.Cert = cfg.Commons.GRPCServiceTLS.Cert
-			cfg.GRPC.TLS.Key = cfg.Commons.GRPCServiceTLS.Key
-		}
+	if cfg.GRPC.TLS == nil && cfg.Commons != nil {
+		cfg.GRPC.TLS = structs.CopyOrZeroValue(cfg.Commons.GRPCServiceTLS)
 	}
 
 	if cfg.UserSharingDrivers.CS3.SystemUserAPIKey == "" && cfg.Commons != nil && cfg.Commons.SystemUserAPIKey != "" {
@@ -158,6 +151,7 @@ func EnsureDefaults(cfg *config.Config) {
 	}
 }
 
+// Sanitize sanitized the configuration
 func Sanitize(cfg *config.Config) {
 	// nothing to sanitize here atm
 }
diff --git a/services/storage-publiclink/pkg/config/defaults/defaultconfig.go b/services/storage-publiclink/pkg/config/defaults/defaultconfig.go
index 9497a28ed0c..c69e97616e0 100644
--- a/services/storage-publiclink/pkg/config/defaults/defaultconfig.go
+++ b/services/storage-publiclink/pkg/config/defaults/defaultconfig.go
@@ -2,9 +2,11 @@ package defaults
 
 import (
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/storage-publiclink/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -12,6 +14,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -35,6 +38,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -59,13 +63,8 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.Tracing = &config.Tracing{}
 	}
 
-	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
-		cfg.Reva = &shared.Reva{
-			Address: cfg.Commons.Reva.Address,
-			TLS:     cfg.Commons.Reva.TLS,
-		}
-	} else if cfg.Reva == nil {
-		cfg.Reva = &shared.Reva{}
+	if cfg.Reva == nil && cfg.Commons != nil {
+		cfg.Reva = structs.CopyOrZeroValue(cfg.Commons.Reva)
 	}
 
 	if cfg.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
@@ -76,16 +75,12 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.TokenManager = &config.TokenManager{}
 	}
 
-	if cfg.GRPC.TLS == nil {
-		cfg.GRPC.TLS = &shared.GRPCServiceTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCServiceTLS != nil {
-			cfg.GRPC.TLS.Enabled = cfg.Commons.GRPCServiceTLS.Enabled
-			cfg.GRPC.TLS.Cert = cfg.Commons.GRPCServiceTLS.Cert
-			cfg.GRPC.TLS.Key = cfg.Commons.GRPCServiceTLS.Key
-		}
+	if cfg.GRPC.TLS == nil && cfg.Commons != nil {
+		cfg.GRPC.TLS = structs.CopyOrZeroValue(cfg.Commons.GRPCServiceTLS)
 	}
 }
 
+// Sanitize sanitized the configuration
 func Sanitize(cfg *config.Config) {
 	// nothing to sanitize here atm
 }
diff --git a/services/storage-shares/pkg/config/defaults/defaultconfig.go b/services/storage-shares/pkg/config/defaults/defaultconfig.go
index dcc1d3c4f57..44680f424ad 100644
--- a/services/storage-shares/pkg/config/defaults/defaultconfig.go
+++ b/services/storage-shares/pkg/config/defaults/defaultconfig.go
@@ -2,9 +2,11 @@ package defaults
 
 import (
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/storage-shares/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -12,6 +14,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -35,6 +38,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -59,13 +63,8 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.Tracing = &config.Tracing{}
 	}
 
-	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
-		cfg.Reva = &shared.Reva{
-			Address: cfg.Commons.Reva.Address,
-			TLS:     cfg.Commons.Reva.TLS,
-		}
-	} else if cfg.Reva == nil {
-		cfg.Reva = &shared.Reva{}
+	if cfg.Reva == nil && cfg.Commons != nil {
+		cfg.Reva = structs.CopyOrZeroValue(cfg.Commons.Reva)
 	}
 
 	if cfg.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
@@ -76,16 +75,12 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.TokenManager = &config.TokenManager{}
 	}
 
-	if cfg.GRPC.TLS == nil {
-		cfg.GRPC.TLS = &shared.GRPCServiceTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCServiceTLS != nil {
-			cfg.GRPC.TLS.Enabled = cfg.Commons.GRPCServiceTLS.Enabled
-			cfg.GRPC.TLS.Cert = cfg.Commons.GRPCServiceTLS.Cert
-			cfg.GRPC.TLS.Key = cfg.Commons.GRPCServiceTLS.Key
-		}
+	if cfg.GRPC.TLS == nil && cfg.Commons != nil {
+		cfg.GRPC.TLS = structs.CopyOrZeroValue(cfg.Commons.GRPCServiceTLS)
 	}
 }
 
+// Sanitize sanitized the configuration
 func Sanitize(cfg *config.Config) {
 	// nothing to sanitize here atm
 }
diff --git a/services/storage-system/pkg/config/defaults/defaultconfig.go b/services/storage-system/pkg/config/defaults/defaultconfig.go
index 01a1a459ece..141ccc725cc 100644
--- a/services/storage-system/pkg/config/defaults/defaultconfig.go
+++ b/services/storage-system/pkg/config/defaults/defaultconfig.go
@@ -5,9 +5,11 @@ import (
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/defaults"
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/storage-system/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -15,6 +17,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -54,6 +57,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -78,13 +82,8 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.Tracing = &config.Tracing{}
 	}
 
-	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
-		cfg.Reva = &shared.Reva{
-			Address: cfg.Commons.Reva.Address,
-			TLS:     cfg.Commons.Reva.TLS,
-		}
-	} else if cfg.Reva == nil {
-		cfg.Reva = &shared.Reva{}
+	if cfg.Reva == nil && cfg.Commons != nil {
+		cfg.Reva = structs.CopyOrZeroValue(cfg.Commons.Reva)
 	}
 
 	if cfg.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
@@ -103,17 +102,13 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.SystemUserID = cfg.Commons.SystemUserID
 	}
 
-	if cfg.GRPC.TLS == nil {
-		cfg.GRPC.TLS = &shared.GRPCServiceTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCServiceTLS != nil {
-			cfg.GRPC.TLS.Enabled = cfg.Commons.GRPCServiceTLS.Enabled
-			cfg.GRPC.TLS.Cert = cfg.Commons.GRPCServiceTLS.Cert
-			cfg.GRPC.TLS.Key = cfg.Commons.GRPCServiceTLS.Key
-		}
+	if cfg.GRPC.TLS == nil && cfg.Commons != nil {
+		cfg.GRPC.TLS = structs.CopyOrZeroValue(cfg.Commons.GRPCServiceTLS)
 	}
 
 }
 
+// Sanitize sanitized the configuration
 func Sanitize(cfg *config.Config) {
 	// nothing to sanitize here atm
 }
diff --git a/services/storage-users/pkg/config/defaults/defaultconfig.go b/services/storage-users/pkg/config/defaults/defaultconfig.go
index 494a7c8ea85..78f982fd206 100644
--- a/services/storage-users/pkg/config/defaults/defaultconfig.go
+++ b/services/storage-users/pkg/config/defaults/defaultconfig.go
@@ -6,9 +6,11 @@ import (
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/defaults"
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/storage-users/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -16,6 +18,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -99,6 +102,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -123,13 +127,8 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.Tracing = &config.Tracing{}
 	}
 
-	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
-		cfg.Reva = &shared.Reva{
-			Address: cfg.Commons.Reva.Address,
-			TLS:     cfg.Commons.Reva.TLS,
-		}
-	} else if cfg.Reva == nil {
-		cfg.Reva = &shared.Reva{}
+	if cfg.Reva == nil && cfg.Commons != nil {
+		cfg.Reva = structs.CopyOrZeroValue(cfg.Commons.Reva)
 	}
 
 	if cfg.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
@@ -140,13 +139,8 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.TokenManager = &config.TokenManager{}
 	}
 
-	if cfg.GRPC.TLS == nil {
-		cfg.GRPC.TLS = &shared.GRPCServiceTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCServiceTLS != nil {
-			cfg.GRPC.TLS.Enabled = cfg.Commons.GRPCServiceTLS.Enabled
-			cfg.GRPC.TLS.Cert = cfg.Commons.GRPCServiceTLS.Cert
-			cfg.GRPC.TLS.Key = cfg.Commons.GRPCServiceTLS.Key
-		}
+	if cfg.GRPC.TLS == nil && cfg.Commons != nil {
+		cfg.GRPC.TLS = structs.CopyOrZeroValue(cfg.Commons.GRPCServiceTLS)
 	}
 
 	if cfg.Tasks.PurgeTrashBin.UserID == "" && cfg.Commons != nil {
@@ -154,6 +148,7 @@ func EnsureDefaults(cfg *config.Config) {
 	}
 }
 
+// Sanitize sanitized the configuration
 func Sanitize(cfg *config.Config) {
 	// nothing to sanitize here atm
 }
diff --git a/services/store/pkg/config/defaults/defaultconfig.go b/services/store/pkg/config/defaults/defaultconfig.go
index ffd1dc0ad3c..c07c3161e23 100644
--- a/services/store/pkg/config/defaults/defaultconfig.go
+++ b/services/store/pkg/config/defaults/defaultconfig.go
@@ -4,10 +4,11 @@ import (
 	"path"
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/defaults"
-	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/store/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -15,6 +16,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -34,6 +36,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -58,23 +61,15 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.Tracing = &config.Tracing{}
 	}
 
-	if cfg.GRPCClientTLS == nil {
-		cfg.GRPCClientTLS = &shared.GRPCClientTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCClientTLS != nil {
-			cfg.GRPCClientTLS.Mode = cfg.Commons.GRPCClientTLS.Mode
-			cfg.GRPCClientTLS.CACert = cfg.Commons.GRPCClientTLS.CACert
-		}
+	if cfg.GRPCClientTLS == nil && cfg.Commons != nil {
+		cfg.GRPCClientTLS = structs.CopyOrZeroValue(cfg.Commons.GRPCClientTLS)
 	}
-	if cfg.GRPC.TLS == nil {
-		cfg.GRPC.TLS = &shared.GRPCServiceTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCServiceTLS != nil {
-			cfg.GRPC.TLS.Enabled = cfg.Commons.GRPCServiceTLS.Enabled
-			cfg.GRPC.TLS.Cert = cfg.Commons.GRPCServiceTLS.Cert
-			cfg.GRPC.TLS.Key = cfg.Commons.GRPCServiceTLS.Key
-		}
+	if cfg.GRPC.TLS == nil && cfg.Commons != nil {
+		cfg.GRPC.TLS = structs.CopyOrZeroValue(cfg.Commons.GRPCServiceTLS)
 	}
 }
 
+// Sanitize sanitized the configuration
 func Sanitize(cfg *config.Config) {
 	// nothing to sanitize here atm
 }
diff --git a/services/thumbnails/pkg/config/defaults/defaultconfig.go b/services/thumbnails/pkg/config/defaults/defaultconfig.go
index 3349521a724..84c1011ef66 100644
--- a/services/thumbnails/pkg/config/defaults/defaultconfig.go
+++ b/services/thumbnails/pkg/config/defaults/defaultconfig.go
@@ -6,9 +6,11 @@ import (
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/defaults"
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/thumbnails/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -16,6 +18,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -49,6 +52,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -73,20 +77,11 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.Tracing = &config.Tracing{}
 	}
 
-	if cfg.GRPCClientTLS == nil {
-		cfg.GRPCClientTLS = &shared.GRPCClientTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCClientTLS != nil {
-			cfg.GRPCClientTLS.Mode = cfg.Commons.GRPCClientTLS.Mode
-			cfg.GRPCClientTLS.CACert = cfg.Commons.GRPCClientTLS.CACert
-		}
+	if cfg.GRPCClientTLS == nil && cfg.Commons != nil {
+		cfg.GRPCClientTLS = structs.CopyOrZeroValue(cfg.Commons.GRPCClientTLS)
 	}
-	if cfg.GRPC.TLS == nil {
-		cfg.GRPC.TLS = &shared.GRPCServiceTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCServiceTLS != nil {
-			cfg.GRPC.TLS.Enabled = cfg.Commons.GRPCServiceTLS.Enabled
-			cfg.GRPC.TLS.Cert = cfg.Commons.GRPCServiceTLS.Cert
-			cfg.GRPC.TLS.Key = cfg.Commons.GRPCServiceTLS.Key
-		}
+	if cfg.GRPC.TLS == nil && cfg.Commons != nil {
+		cfg.GRPC.TLS = structs.CopyOrZeroValue(cfg.Commons.GRPCServiceTLS)
 	}
 
 	if cfg.Commons != nil {
@@ -94,6 +89,7 @@ func EnsureDefaults(cfg *config.Config) {
 	}
 }
 
+// Sanitize sanitized the configuration
 func Sanitize(cfg *config.Config) {
 	// nothing to sanitize here atm
 	if len(cfg.Thumbnail.Resolutions) == 1 && strings.Contains(cfg.Thumbnail.Resolutions[0], ",") {
diff --git a/services/userlog/pkg/config/config.go b/services/userlog/pkg/config/config.go
index 04e74cf3bae..c3173f5c4d1 100644
--- a/services/userlog/pkg/config/config.go
+++ b/services/userlog/pkg/config/config.go
@@ -32,7 +32,7 @@ type Config struct {
 type Store struct {
 	Type      string `yaml:"type" env:"USERLOG_STORE_TYPE" desc:"The type of the userlog store. Supported values are: 'mem', 'ocmem', 'etcd', 'redis', 'nats-js', 'noop'. See the text description for details."`
 	Addresses string `yaml:"addresses" env:"USERLOG_STORE_ADDRESSES" desc:"A comma separated list of addresses to access the configured store. This has no effect when 'in-memory' stores are configured. Note that the behaviour how addresses are used is dependent on the library of the configured store."`
-	Database  string `yaml:"database" env:"USERLOG_STORE_DATABASE" desc:"(optional) The database name the configured store should use. This has no effect when 'in-memory' stores or 'redis' is configured."`
+	Database  string `yaml:"database" env:"USERLOG_STORE_DATABASE" desc:"(optional) The database name the configured store should use. This has no effect when 'in-memory' stores are configured."`
 	Table     string `yaml:"table" env:"USERLOG_STORE_TABLE" desc:"(optional) The database table the store should use. This has no effect when 'in-memory' stores are configured."`
 	Size      int    `yaml:"size" env:"USERLOG_STORE_SIZE" desc:"The maximum quantity of items in the store. Only applies when store type 'ocmem' is configured. Defaults to 512."`
 }
diff --git a/services/userlog/pkg/config/defaults/defaultconfig.go b/services/userlog/pkg/config/defaults/defaultconfig.go
index 5db2b5ce583..a228e387e6e 100644
--- a/services/userlog/pkg/config/defaults/defaultconfig.go
+++ b/services/userlog/pkg/config/defaults/defaultconfig.go
@@ -4,6 +4,7 @@ import (
 	"strings"
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/userlog/pkg/config"
 )
 
@@ -62,11 +63,8 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.MachineAuthAPIKey = cfg.Commons.MachineAuthAPIKey
 	}
 
-	if cfg.GRPCClientTLS == nil {
-		cfg.GRPCClientTLS = &shared.GRPCClientTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCClientTLS != nil {
-			cfg.GRPCClientTLS = cfg.Commons.GRPCClientTLS
-		}
+	if cfg.GRPCClientTLS == nil && cfg.Commons != nil {
+		cfg.GRPCClientTLS = structs.CopyOrZeroValue(cfg.Commons.GRPCClientTLS)
 	}
 
 	if cfg.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
diff --git a/services/users/pkg/config/defaults/defaultconfig.go b/services/users/pkg/config/defaults/defaultconfig.go
index 1fe0ee094c3..8bfb21245ef 100644
--- a/services/users/pkg/config/defaults/defaultconfig.go
+++ b/services/users/pkg/config/defaults/defaultconfig.go
@@ -5,9 +5,11 @@ import (
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/defaults"
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/users/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -15,6 +17,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -80,6 +83,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -104,13 +108,8 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.Tracing = &config.Tracing{}
 	}
 
-	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
-		cfg.Reva = &shared.Reva{
-			Address: cfg.Commons.Reva.Address,
-			TLS:     cfg.Commons.Reva.TLS,
-		}
-	} else if cfg.Reva == nil {
-		cfg.Reva = &shared.Reva{}
+	if cfg.Reva == nil && cfg.Commons != nil {
+		cfg.Reva = structs.CopyOrZeroValue(cfg.Commons.Reva)
 	}
 
 	if cfg.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
@@ -121,16 +120,12 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.TokenManager = &config.TokenManager{}
 	}
 
-	if cfg.GRPC.TLS == nil {
-		cfg.GRPC.TLS = &shared.GRPCServiceTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCServiceTLS != nil {
-			cfg.GRPC.TLS.Enabled = cfg.Commons.GRPCServiceTLS.Enabled
-			cfg.GRPC.TLS.Cert = cfg.Commons.GRPCServiceTLS.Cert
-			cfg.GRPC.TLS.Key = cfg.Commons.GRPCServiceTLS.Key
-		}
+	if cfg.GRPC.TLS == nil && cfg.Commons != nil {
+		cfg.GRPC.TLS = structs.CopyOrZeroValue(cfg.Commons.GRPCServiceTLS)
 	}
 }
 
+// Sanitize sanitized the configuration
 func Sanitize(cfg *config.Config) {
 	// nothing to sanitize here atm
 }
diff --git a/services/web/pkg/config/defaults/defaultconfig.go b/services/web/pkg/config/defaults/defaultconfig.go
index af64d6635a6..1c1446320d9 100644
--- a/services/web/pkg/config/defaults/defaultconfig.go
+++ b/services/web/pkg/config/defaults/defaultconfig.go
@@ -8,6 +8,7 @@ import (
 	"github.com/owncloud/ocis/v2/services/web/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -15,6 +16,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -72,6 +74,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -108,6 +111,7 @@ func EnsureDefaults(cfg *config.Config) {
 	}
 }
 
+// Sanitize sanitized the configuration
 func Sanitize(cfg *config.Config) {
 	// sanitize config
 	if cfg.HTTP.Root != "/" {
diff --git a/services/webdav/pkg/config/defaults/defaultconfig.go b/services/webdav/pkg/config/defaults/defaultconfig.go
index 083d0a1a325..3b8350436b7 100644
--- a/services/webdav/pkg/config/defaults/defaultconfig.go
+++ b/services/webdav/pkg/config/defaults/defaultconfig.go
@@ -4,9 +4,11 @@ import (
 	"strings"
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
 	"github.com/owncloud/ocis/v2/services/webdav/pkg/config"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -14,6 +16,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -42,6 +45,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -66,12 +70,8 @@ func EnsureDefaults(cfg *config.Config) {
 		cfg.Tracing = &config.Tracing{}
 	}
 
-	if cfg.GRPCClientTLS == nil {
-		cfg.GRPCClientTLS = &shared.GRPCClientTLS{}
-		if cfg.Commons != nil && cfg.Commons.GRPCClientTLS != nil {
-			cfg.GRPCClientTLS.Mode = cfg.Commons.GRPCClientTLS.Mode
-			cfg.GRPCClientTLS.CACert = cfg.Commons.GRPCClientTLS.CACert
-		}
+	if cfg.GRPCClientTLS == nil && cfg.Commons != nil {
+		cfg.GRPCClientTLS = structs.CopyOrZeroValue(cfg.Commons.GRPCClientTLS)
 	}
 
 	if cfg.Commons != nil {
@@ -79,6 +79,7 @@ func EnsureDefaults(cfg *config.Config) {
 	}
 }
 
+// Sanitize sanitized the configuration
 func Sanitize(cfg *config.Config) {
 	// sanitize config
 	if cfg.HTTP.Root != "/" {
diff --git a/services/webfinger/pkg/config/defaults/defaultconfig.go b/services/webfinger/pkg/config/defaults/defaultconfig.go
index 8804756b37f..1fc4cf9f2e6 100644
--- a/services/webfinger/pkg/config/defaults/defaultconfig.go
+++ b/services/webfinger/pkg/config/defaults/defaultconfig.go
@@ -7,6 +7,7 @@ import (
 	"github.com/owncloud/ocis/v2/services/webfinger/pkg/relations"
 )
 
+// FullDefaultConfig returns a fully initialized default configuration
 func FullDefaultConfig() *config.Config {
 	cfg := DefaultConfig()
 	EnsureDefaults(cfg)
@@ -14,6 +15,7 @@ func FullDefaultConfig() *config.Config {
 	return cfg
 }
 
+// DefaultConfig returns a basic default configuration
 func DefaultConfig() *config.Config {
 	return &config.Config{
 		Debug: config.Debug{
@@ -49,6 +51,7 @@ func DefaultConfig() *config.Config {
 	}
 }
 
+// EnsureDefaults adds default values to the configuration if they are not set yet
 func EnsureDefaults(cfg *config.Config) {
 	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
 	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
@@ -78,6 +81,7 @@ func EnsureDefaults(cfg *config.Config) {
 	}
 }
 
+// Sanitize sanitized the configuration
 func Sanitize(cfg *config.Config) {
 	// sanitize config
 	if cfg.HTTP.Root != "/" {


Test patch:
diff --git a/ocis-pkg/structs/structs_test.go b/ocis-pkg/structs/structs_test.go
new file mode 100644
index 00000000000..1e8f4096cd2
--- /dev/null
+++ b/ocis-pkg/structs/structs_test.go
@@ -0,0 +1,38 @@
+package structs
+
+import "testing"
+
+type example struct {
+	Attribute1 string
+	Attribute2 string
+}
+
+func TestCopyOrZeroValue(t *testing.T) {
+	var e *example
+
+	zv := CopyOrZeroValue(e)
+
+	if zv == nil {
+		t.Error("CopyOrZeroValue returned nil")
+	}
+
+	if zv.Attribute1 != "" || zv.Attribute2 != "" {
+		t.Error("CopyOrZeroValue didn't return zero value")
+	}
+
+	e2 := &example{Attribute1: "One", Attribute2: "Two"}
+
+	cp := CopyOrZeroValue(e2)
+
+	if cp == nil {
+		t.Error("CopyOrZeroValue returned nil")
+	}
+
+	if cp == e2 {
+		t.Error("CopyOrZeroValue returned reference with same address")
+	}
+
+	if cp.Attribute1 != e2.Attribute1 || cp.Attribute2 != e2.Attribute2 {
+		t.Error("CopyOrZeroValue didn't correctly copy attributes")
+	}
+}