Repository: owncloud/ocis
Pull request #4955 (2022-11-02 11:06:50)

Validate Space Names
We now return `BAD REQUEST` when space names are
-  too long (max 255 characters)
-  containing evil characters (`/`, `\`, `.`, `\\`, `:`, `?`, `*`, `"`, `>`, `<`, `|`)

Additionally leading and trailing spaces will be removed silently.

fixes this: https://github.com/owncloud/ocis/issues/4925


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

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4955&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=4955&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4955&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=4955&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=4955&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4955&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=4955&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=4955&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=4955&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=4955&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=4955&resolved=false&types=CODE_SMELL) [1 Code Smell](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4955&resolved=false&types=CODE_SMELL)

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


ownclouders: :boom: Acceptance test [<strong>localApiTests-apiSpaces-ocis</strong>](https://drone.owncloud.com/owncloud/ocis/16583/42/1) failed. Further test are cancelled...
<!-- id: pr-4955 -->

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

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

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4955&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=4955&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4955&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=4955&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=4955&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4955&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=4955&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=4955&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=4955&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=4955&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=4955&resolved=false&types=CODE_SMELL) [1 Code Smell](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4955&resolved=false&types=CODE_SMELL)

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


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

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4955&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=4955&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4955&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=4955&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=4955&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4955&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=4955&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=4955&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=4955&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=4955&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=4955&resolved=false&types=CODE_SMELL) [1 Code Smell](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4955&resolved=false&types=CODE_SMELL)

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


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

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4955&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=4955&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4955&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=4955&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=4955&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4955&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=4955&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=4955&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=4955&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=4955&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=4955&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4955&resolved=false&types=CODE_SMELL)

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


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

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4955&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=4955&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4955&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=4955&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=4955&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4955&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=4955&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=4955&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=4955&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=4955&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=4955&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4955&resolved=false&types=CODE_SMELL)

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



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 77cfdeebc91..b5e5967ddce 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -36,7 +36,7 @@ The following sections list the changes for unreleased.
 * Enhancement - Deny access to resources: [#4903](https://github.com/owncloud/ocis/pull/4903)
 * Enhancement - Allow to configure applications in Web: [#4578](https://github.com/owncloud/ocis/pull/4578)
 * Enhancement - Restrict admins from self-removal: [#3713](https://github.com/owncloud/ocis/issues/3713)
-* Enhancement - Allow to setup TLS for the reva grpc services: [#4798](https://github.com/owncloud/ocis/pull/4798)
+* Enhancement - Allow to setup TLS for grpc services: [#4798](https://github.com/owncloud/ocis/pull/4798)
 * Enhancement - Logging improvements: [#4815](https://github.com/owncloud/ocis/pull/4815)
 * Enhancement - Secure the nats connection with TLS: [#4781](https://github.com/owncloud/ocis/pull/4781)
 * Enhancement - Report parent id: [#4757](https://github.com/owncloud/ocis/pull/4757)
@@ -277,11 +277,13 @@ The following sections list the changes for unreleased.
 
    https://github.com/owncloud/ocis/issues/3713
 
-* Enhancement - Allow to setup TLS for the reva grpc services: [#4798](https://github.com/owncloud/ocis/pull/4798)
+* Enhancement - Allow to setup TLS for grpc services: [#4798](https://github.com/owncloud/ocis/pull/4798)
 
-   We added config options to allow enabling TLS encrption for all reva backed grpc services.
+   We added config options to allow enabling TLS encrption for all reva and go-micro backed grpc
+   services.
 
    https://github.com/owncloud/ocis/pull/4798
+   https://github.com/owncloud/ocis/pull/4901
 
 * Enhancement - Logging improvements: [#4815](https://github.com/owncloud/ocis/pull/4815)
 
diff --git a/changelog/unreleased/grpc-tls.md b/changelog/unreleased/grpc-tls.md
index 2db05011136..7435d3dc971 100644
--- a/changelog/unreleased/grpc-tls.md
+++ b/changelog/unreleased/grpc-tls.md
@@ -1,6 +1,7 @@
-Enhancement: Allow to setup TLS for the reva grpc services
+Enhancement: Allow to setup TLS for grpc services
 
-We added config options to allow enabling TLS encrption for all reva backed
+We added config options to allow enabling TLS encrption for all reva and go-micro backed
 grpc services.
 
 https://github.com/owncloud/ocis/pull/4798
+https://github.com/owncloud/ocis/pull/4901
diff --git a/changelog/unreleased/validate-space-names.md b/changelog/unreleased/validate-space-names.md
new file mode 100644
index 00000000000..d96e255dd82
--- /dev/null
+++ b/changelog/unreleased/validate-space-names.md
@@ -0,0 +1,9 @@
+Enhancement: Validate space names
+
+We now return `BAD REQUEST` when space names are
+-  too long (max 255 characters)
+-  containing evil characters (`/`, `\`, `.`, `\\`, `:`, `?`, `*`, `"`, `>`, `<`, `|`)
+
+Additionally leading and trailing spaces will be removed silently.
+
+https://github.com/owncloud/ocis/pull/4955
diff --git a/ocis-pkg/config/config.go b/ocis-pkg/config/config.go
index 6f03ade4466..b13c4c3a574 100644
--- a/ocis-pkg/config/config.go
+++ b/ocis-pkg/config/config.go
@@ -56,9 +56,11 @@ type Runtime struct {
 type Config struct {
 	*shared.Commons `yaml:"shared"`
 
-	Tracing    *shared.Tracing    `yaml:"tracing"`
-	Log        *shared.Log        `yaml:"log"`
-	CacheStore *shared.CacheStore `yaml:"cache_store"`
+	Tracing        *shared.Tracing        `yaml:"tracing"`
+	Log            *shared.Log            `yaml:"log"`
+	CacheStore     *shared.CacheStore     `yaml:"cache_store"`
+	GRPCClientTLS  *shared.GRPCClientTLS  `yaml:"grpc_client_tls"`
+	GRPCServiceTLS *shared.GRPCServiceTLS `yaml:"grpc_service_tls"`
 
 	Mode    Mode // DEPRECATED
 	File    string
diff --git a/ocis-pkg/config/parser/parse.go b/ocis-pkg/config/parser/parse.go
index 5e25b2b9d2a..3063de201b2 100644
--- a/ocis-pkg/config/parser/parse.go
+++ b/ocis-pkg/config/parser/parse.go
@@ -51,6 +51,13 @@ func EnsureDefaults(cfg *config.Config) {
 	if cfg.CacheStore == nil {
 		cfg.CacheStore = &shared.CacheStore{}
 	}
+	if cfg.GRPCClientTLS == nil {
+		cfg.GRPCClientTLS = &shared.GRPCClientTLS{}
+	}
+	if cfg.GRPCServiceTLS == nil {
+		cfg.GRPCServiceTLS = &shared.GRPCServiceTLS{}
+	}
+
 }
 
 // EnsureCommons copies applicable parts of the oCIS config into the commons part
@@ -94,6 +101,14 @@ func EnsureCommons(cfg *config.Config) {
 		cfg.Commons.CacheStore = &shared.CacheStore{}
 	}
 
+	if cfg.GRPCClientTLS != nil {
+		cfg.Commons.GRPCClientTLS = cfg.GRPCClientTLS
+	}
+
+	if cfg.GRPCServiceTLS != nil {
+		cfg.Commons.GRPCServiceTLS = cfg.GRPCServiceTLS
+	}
+
 	// copy token manager to the commons part if set
 	if cfg.TokenManager != nil {
 		cfg.Commons.TokenManager = cfg.TokenManager
diff --git a/ocis-pkg/service/grpc/client.go b/ocis-pkg/service/grpc/client.go
new file mode 100644
index 00000000000..cee6a1fb2d8
--- /dev/null
+++ b/ocis-pkg/service/grpc/client.go
@@ -0,0 +1,101 @@
+package grpc
+
+import (
+	"crypto/tls"
+	"crypto/x509"
+	"errors"
+	"io/ioutil"
+	"sync"
+
+	mgrpcc "github.com/go-micro/plugins/v4/client/grpc"
+	mbreaker "github.com/go-micro/plugins/v4/wrapper/breaker/gobreaker"
+	"github.com/owncloud/ocis/v2/ocis-pkg/registry"
+	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"go-micro.dev/v4/client"
+)
+
+var (
+	defaultClient client.Client
+	once          sync.Once
+)
+
+// ClientOptions represent options (e.g. tls settings) for the grpc clients
+type ClientOptions struct {
+	tlsMode string
+	caCert  string
+}
+
+// Option is used to pass client options
+type ClientOption func(opts *ClientOptions)
+
+// WithTLSMode allows to set the TLSMode option for grpc clients
+func WithTLSMode(v string) ClientOption {
+	return func(o *ClientOptions) {
+		o.tlsMode = v
+	}
+}
+
+// WithTLSCACert allows to set the CA Certificate for grpc clients
+func WithTLSCACert(v string) ClientOption {
+	return func(o *ClientOptions) {
+		o.caCert = v
+	}
+}
+
+// Configure configures the default oOCIS grpc client (e.g. TLS settings)
+func Configure(opts ...ClientOption) error {
+	var options ClientOptions
+	for _, opt := range opts {
+		opt(&options)
+	}
+
+	var outerr error
+	once.Do(func() {
+		reg := registry.GetRegistry()
+		var tlsConfig *tls.Config
+		cOpts := []client.Option{
+			client.Registry(reg),
+			client.Wrap(mbreaker.NewClientWrapper()),
+		}
+		switch options.tlsMode {
+		case "insecure":
+			tlsConfig = &tls.Config{
+				InsecureSkipVerify: true,
+			}
+			cOpts = append(cOpts, mgrpcc.AuthTLS(tlsConfig))
+		case "on":
+			tlsConfig = &tls.Config{}
+			// Note: If caCert is empty we use the system's default set of trusted CAs
+			if options.caCert != "" {
+				certs := x509.NewCertPool()
+				pemData, err := ioutil.ReadFile(options.caCert)
+				if err != nil {
+					outerr = err
+					return
+				}
+				if !certs.AppendCertsFromPEM(pemData) {
+					outerr = errors.New("Error initializing LDAP Backend. Adding CA cert failed")
+					return
+				}
+				tlsConfig.RootCAs = certs
+			}
+			cOpts = append(cOpts, mgrpcc.AuthTLS(tlsConfig))
+		}
+
+		defaultClient = mgrpcc.NewClient(cOpts...)
+	})
+	return outerr
+}
+
+// DefaultClient returns a custom oCIS grpc configured client.
+func DefaultClient() client.Client {
+	return defaultClient
+}
+
+func GetClientOptions(t *shared.GRPCClientTLS) []ClientOption {
+	opts := []ClientOption{
+		WithTLSMode(t.Mode),
+		WithTLSCACert(t.CACert),
+	}
+	return opts
+}
diff --git a/ocis-pkg/service/grpc/option.go b/ocis-pkg/service/grpc/option.go
index 7004c1a9e5a..24abeb8619d 100644
--- a/ocis-pkg/service/grpc/option.go
+++ b/ocis-pkg/service/grpc/option.go
@@ -12,13 +12,16 @@ type Option func(o *Options)
 
 // Options defines the available options for this package.
 type Options struct {
-	Logger    log.Logger
-	Namespace string
-	Name      string
-	Version   string
-	Address   string
-	Context   context.Context
-	Flags     []cli.Flag
+	Logger     log.Logger
+	Namespace  string
+	Name       string
+	Version    string
+	Address    string
+	TLSEnabled bool
+	TLSCert    string
+	TLSKey     string
+	Context    context.Context
+	Flags      []cli.Flag
 }
 
 // newOptions initializes the available default options.
@@ -69,6 +72,21 @@ func Address(a string) Option {
 	}
 }
 
+// TLSEnabled provides a function to enable/disable TLS
+func TLSEnabled(v bool) Option {
+	return func(o *Options) {
+		o.TLSEnabled = v
+	}
+}
+
+// TLSCert provides a function to set the TLS server certificate and key
+func TLSCert(c string, k string) Option {
+	return func(o *Options) {
+		o.TLSCert = c
+		o.TLSKey = k
+	}
+}
+
 // Context provides a function to set the context option.
 func Context(ctx context.Context) Option {
 	return func(o *Options) {
diff --git a/ocis-pkg/service/grpc/service.go b/ocis-pkg/service/grpc/service.go
index 458841ad23e..3ea16be0481 100644
--- a/ocis-pkg/service/grpc/service.go
+++ b/ocis-pkg/service/grpc/service.go
@@ -1,54 +1,65 @@
 package grpc
 
 import (
+	"crypto/tls"
+	"fmt"
+	"net"
 	"strings"
-	"sync"
 	"time"
 
-	mgrpcc "github.com/go-micro/plugins/v4/client/grpc"
 	mgrpcs "github.com/go-micro/plugins/v4/server/grpc"
-	mbreaker "github.com/go-micro/plugins/v4/wrapper/breaker/gobreaker"
 	"github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus"
 	"github.com/go-micro/plugins/v4/wrapper/trace/opencensus"
 	"github.com/owncloud/ocis/v2/ocis-pkg/registry"
 	"go-micro.dev/v4"
-	"go-micro.dev/v4/client"
+	"go-micro.dev/v4/server"
+	mtls "go-micro.dev/v4/util/tls"
 )
 
-// DefaultClient is a custom oCIS grpc configured client.
-var (
-	defaultClient client.Client
-	once          sync.Once
-)
-
-func DefaultClient() client.Client {
-	return getDefaultGrpcClient()
-}
-
-func getDefaultGrpcClient() client.Client {
-	once.Do(func() {
-		reg := registry.GetRegistry()
-
-		defaultClient = mgrpcc.NewClient(
-			client.Registry(reg),
-			client.Wrap(mbreaker.NewClientWrapper()),
-		)
-	})
-	return defaultClient
-}
-
 // Service simply wraps the go-micro grpc service.
 type Service struct {
 	micro.Service
 }
 
 // NewService initializes a new grpc service.
-func NewService(opts ...Option) Service {
+func NewService(opts ...Option) (Service, error) {
+	var mServer server.Server
 	sopts := newOptions(opts...)
+	tlsConfig := &tls.Config{}
+	if sopts.TLSEnabled {
+		var cert tls.Certificate
+		var err error
+		if sopts.TLSCert != "" {
+			cert, err = tls.LoadX509KeyPair(sopts.TLSCert, sopts.TLSKey)
+			if err != nil {
+				sopts.Logger.Error().Err(err).Str("cert", sopts.TLSCert).Str("key", sopts.TLSKey).Msg("error loading server certifcate and key")
+				return Service{}, fmt.Errorf("grpc service error loading server certificate and key: %w", err)
+			}
+		} else {
+			// Generate a self-signed server certificate on the fly. This requires the clients
+			// to connect with InsecureSkipVerify.
+			subj := []string{sopts.Address}
+			if host, _, err := net.SplitHostPort(sopts.Address); err == nil && host != "" {
+				subj = []string{host}
+			}
+
+			sopts.Logger.Warn().Str("address", sopts.Address).
+				Msg("GRPC: No server certificate configured. Generating a temporary self-signed certificate")
+
+			cert, err = mtls.Certificate(subj...)
+			if err != nil {
+				return Service{}, fmt.Errorf("grpc service error creating temporary self-signed certificate: %w", err)
+			}
+		}
+		tlsConfig.Certificates = []tls.Certificate{cert}
+		mServer = mgrpcs.NewServer(mgrpcs.AuthTLS(tlsConfig))
+	} else {
+		mServer = mgrpcs.NewServer()
+	}
 
 	mopts := []micro.Option{
 		// first add a server because it will reset any options
-		micro.Server(mgrpcs.NewServer()),
+		micro.Server(mServer),
 		// also add a client that can be used after initializing the service
 		micro.Client(DefaultClient()),
 		micro.Address(sopts.Address),
@@ -65,5 +76,5 @@ func NewService(opts ...Option) Service {
 		micro.WrapSubscriber(opencensus.NewSubscriberWrapper()),
 	}
 
-	return Service{micro.NewService(mopts...)}
+	return Service{micro.NewService(mopts...)}, nil
 }
diff --git a/ocis-pkg/shared/reva.go b/ocis-pkg/shared/reva.go
index 4f43ca90875..cc38370903e 100644
--- a/ocis-pkg/shared/reva.go
+++ b/ocis-pkg/shared/reva.go
@@ -13,7 +13,7 @@ func DefaultRevaConfig() *Reva {
 }
 
 func (r *Reva) GetRevaOptions() []pool.Option {
-	tm, _ := pool.StringToTLSMode(r.TLSMode)
+	tm, _ := pool.StringToTLSMode(r.TLS.Mode)
 	opts := []pool.Option{
 		pool.WithTLSMode(tm),
 	}
@@ -22,7 +22,7 @@ func (r *Reva) GetRevaOptions() []pool.Option {
 
 func (r *Reva) GetGRPCClientConfig() map[string]interface{} {
 	return map[string]interface{}{
-		"tls_mode":   r.TLSMode,
-		"tls_cacert": r.TLSCACert,
+		"tls_mode":   r.TLS.Mode,
+		"tls_cacert": r.TLS.CACert,
 	}
 }
diff --git a/ocis-pkg/shared/shared_types.go b/ocis-pkg/shared/shared_types.go
index 493d0304751..ea93eb3b690 100644
--- a/ocis-pkg/shared/shared_types.go
+++ b/ocis-pkg/shared/shared_types.go
@@ -31,9 +31,19 @@ type TokenManager struct {
 
 // Reva defines all available REVA client configuration.
 type Reva struct {
-	Address   string `yaml:"address" env:"REVA_GATEWAY" desc:"The CS3 gateway endpoint."`
-	TLSMode   string `yaml:"tls_mode" env:"REVA_GATEWAY_TLS_MODE" desc:"TLS mode for grpc connection to the CS3 gateway endpoint. Possible values are 'off', 'insecure' and 'on'. 'off': disables transport security for the clients. 'insecure' allows to use transport security, but disables certificate verification (to be used with the autogenerated self-signed certificates). 'on' enables transport security, including server ceritificate verification."`
-	TLSCACert string `yaml:"tls_cacert" env:"REVA_GATEWAY_TLS_CACERT" desc:"The root CA certificate used to validate the gateway's TLS certificate."`
+	Address string        `yaml:"address" env:"REVA_GATEWAY" desc:"The CS3 gateway endpoint."`
+	TLS     GRPCClientTLS `yaml:"tls"`
+}
+
+type GRPCClientTLS struct {
+	Mode   string `yaml:"mode" env:"OCIS_GRPC_CLIENT_TLS_MODE" desc:"TLS mode for grpc connection to the go-micro based grpc services. Possible values are 'off', 'insecure' and 'on'. 'off': disables transport security for the clients. 'insecure' allows to use transport security, but disables certificate verification (to be used with the autogenerated self-signed certificates). 'on' enables transport security, including server ceritificate verification."`
+	CACert string `yaml:"cacert env:"OCIS_GRPC_CLIENT_TLS_CACERT" desc:"The root CA certificate used to validate TLS server certificates of the go-micro based grpc services."`
+}
+
+type GRPCServiceTLS struct {
+	Enabled bool   `yaml:"enabled" env:"OCIS_GRPC_TLS_ENABLED" desc:"Activates TLS for the grpcs based services using the server certifcate and key configured via OCIS_GRPC_TLS_CERTIFICATE and OCIS_GRPC_TLS_KEY. If OCIS_GRPC_TLS_CERTIFICATE is not set a temporary server certificate is generated - to be used with OCIS_GRPC_CLIENT_TLS_MODE=insecure."`
+	Cert    string `yaml:"cert" env:"OCIS_GRPC_TLS_CERTIFICATE" desc:"Path/File name of the TLS server certificate (in PEM format) for the grpc services."`
+	Key     string `yaml:"key" env:"OCIS_GRPC_TLS_KEY" desc:"Path/File name for the TLS certificate key (in PEM format) for the server certificate to use for the grpc services."`
 }
 
 type CacheStore struct {
@@ -45,15 +55,17 @@ type CacheStore struct {
 // Commons holds configuration that are common to all extensions. Each extension can then decide whether
 // to overwrite its values.
 type Commons struct {
-	Log               *Log          `yaml:"log"`
-	Tracing           *Tracing      `yaml:"tracing"`
-	CacheStore        *CacheStore   `yaml:"cache_store"`
-	OcisURL           string        `yaml:"ocis_url" env:"OCIS_URL" desc:"URL, where oCIS is reachable for users."`
-	TokenManager      *TokenManager `mask:"struct" yaml:"token_manager"`
-	Reva              *Reva         `yaml:"reva"`
-	MachineAuthAPIKey string        `mask:"password" yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used to validate internal requests necessary for the access to resources from other services."`
-	TransferSecret    string        `mask:"password" yaml:"transfer_secret,omitempty" env:"REVA_TRANSFER_SECRET"`
-	SystemUserID      string        `yaml:"system_user_id" env:"OCIS_SYSTEM_USER_ID" desc:"ID of the oCIS storage-system system user. Admins need to set the ID for the storage-system system user in this config option which is then used to reference the user. Any reasonable long string is possible, preferably this would be an UUIDv4 format."`
-	SystemUserAPIKey  string        `mask:"password" yaml:"system_user_api_key" env:"SYSTEM_USER_API_KEY"`
-	AdminUserID       string        `yaml:"admin_user_id" env:"OCIS_ADMIN_USER_ID" desc:"ID of a user, that should receive admin privileges."`
+	Log               *Log            `yaml:"log"`
+	Tracing           *Tracing        `yaml:"tracing"`
+	CacheStore        *CacheStore     `yaml:"cache_store"`
+	GRPCClientTLS     *GRPCClientTLS  `yaml:"grpc_client_tls"`
+	GRPCServiceTLS    *GRPCServiceTLS `yaml:"grpc_service_tls"`
+	OcisURL           string          `yaml:"ocis_url" env:"OCIS_URL" desc:"URL, where oCIS is reachable for users."`
+	TokenManager      *TokenManager   `mask:"struct" yaml:"token_manager"`
+	Reva              *Reva           `yaml:"reva"`
+	MachineAuthAPIKey string          `mask:"password" yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used to validate internal requests necessary for the access to resources from other services."`
+	TransferSecret    string          `mask:"password" yaml:"transfer_secret,omitempty" env:"REVA_TRANSFER_SECRET"`
+	SystemUserID      string          `yaml:"system_user_id" env:"OCIS_SYSTEM_USER_ID" desc:"ID of the oCIS storage-system system user. Admins need to set the ID for the storage-system system user in this config option which is then used to reference the user. Any reasonable long string is possible, preferably this would be an UUIDv4 format."`
+	SystemUserAPIKey  string          `mask:"password" yaml:"system_user_api_key" env:"SYSTEM_USER_API_KEY"`
+	AdminUserID       string          `yaml:"admin_user_id" env:"OCIS_ADMIN_USER_ID" desc:"ID of a user, that should receive admin privileges."`
 }
diff --git a/ocis/README.md b/ocis/README.md
new file mode 100644
index 00000000000..6d5a12fbbdc
--- /dev/null
+++ b/ocis/README.md
@@ -0,0 +1,22 @@
+# ocis
+
+The ocis package contains the Infinite Scale runtime and the commands for the Infinite Scale cli.
+
+## Service registry
+
+This package also configures the service registry which will be used to look up the service addresses. It defaults to mDNS. Keep that in mind when using systems with mDNS disabled by default (i.e. SUSE).
+
+Available registries are:
+
+-   nats
+-   kubernetes
+-   etcd
+-   consul
+-   memory
+-   mdns (default)
+
+To configure which registry to use, you have to set the environment variable `MICRO_REGISTRY`, and for all except `memory` and `mdns` you also have to set the registry address via `MICRO_REGISTRY_ADDRESS`.
+
+### etcd
+
+To authenticate the connection to the etcd registry, you have to set `ETCD_USERNAME` and `ETCD_PASSWORD`.
diff --git a/ocis/pkg/command/server.go b/ocis/pkg/command/server.go
index 60d450cf9e2..25057f58a08 100644
--- a/ocis/pkg/command/server.go
+++ b/ocis/pkg/command/server.go
@@ -5,6 +5,7 @@ import (
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/configlog"
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/parser"
 	"github.com/owncloud/ocis/v2/ocis-pkg/registry"
+	"github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
 	"github.com/owncloud/ocis/v2/ocis/pkg/register"
 	"github.com/owncloud/ocis/v2/ocis/pkg/runtime"
 	"github.com/urfave/cli/v2"
@@ -22,6 +23,10 @@ func Server(cfg *config.Config) *cli.Command {
 		Action: func(c *cli.Context) error {
 			// Prefer the in-memory registry as the default when running in single-binary mode
 			registry.Configure("memory")
+			err := grpc.Configure(grpc.GetClientOptions(cfg.GRPCClientTLS)...)
+			if err != nil {
+				return err
+			}
 			r := runtime.New(cfg)
 			return r.Start()
 		},
diff --git a/services/app-provider/pkg/config/config.go b/services/app-provider/pkg/config/config.go
index 2b62c23280e..66e6003e38f 100644
--- a/services/app-provider/pkg/config/config.go
+++ b/services/app-provider/pkg/config/config.go
@@ -52,12 +52,10 @@ type Debug struct {
 }
 
 type GRPCConfig struct {
-	Addr       string `yaml:"addr" env:"APP_PROVIDER_GRPC_ADDR" desc:"The bind address of the GRPC service."`
-	TLSEnabled bool   `yaml:"tls_enabled" env:"OCIS_GRPC_TLS_ENABLED"`
-	TLSCert    string `yaml:"tls_cert" env:"OCIS_GRPC_TLS_CERTIFICATE" desc:"Path/File name of the TLS server certificate (in PEM format) for the reva grpc services."`
-	TLSKey     string `yaml:"tls_key" env:"OCIS_GRPC_TLS_KEY" desc:"Path/File name for the TLS certificate key (in PEM format) for the server certificate."`
-	Namespace  string `yaml:"-"`
-	Protocol   string `yaml:"protocol" env:"APP_PROVIDER_GRPC_PROTOCOL" desc:"The transport protocol of the GPRC service."`
+	Addr      string                 `yaml:"addr" env:"APP_PROVIDER_GRPC_ADDR" desc:"The bind address of the GRPC service."`
+	TLS       *shared.GRPCServiceTLS `yaml:"tls"`
+	Namespace string                 `yaml:"-"`
+	Protocol  string                 `yaml:"protocol" env:"APP_PROVIDER_GRPC_PROTOCOL" desc:"The transport protocol of the GPRC service."`
 }
 
 type Drivers struct {
diff --git a/services/app-provider/pkg/config/defaults/defaultconfig.go b/services/app-provider/pkg/config/defaults/defaultconfig.go
index 92e000dc176..57a4be83433 100644
--- a/services/app-provider/pkg/config/defaults/defaultconfig.go
+++ b/services/app-provider/pkg/config/defaults/defaultconfig.go
@@ -65,9 +65,8 @@ func EnsureDefaults(cfg *config.Config) {
 
 	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
 		cfg.Reva = &shared.Reva{
-			Address:   cfg.Commons.Reva.Address,
-			TLSMode:   cfg.Commons.Reva.TLSMode,
-			TLSCACert: cfg.Commons.Reva.TLSCACert,
+			Address: cfg.Commons.Reva.Address,
+			TLS:     cfg.Commons.Reva.TLS,
 		}
 	} else if cfg.Reva == nil {
 		cfg.Reva = &shared.Reva{}
@@ -80,6 +79,15 @@ func EnsureDefaults(cfg *config.Config) {
 	} else if cfg.TokenManager == nil {
 		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
+		}
+	}
 }
 
 func Sanitize(cfg *config.Config) {
diff --git a/services/app-provider/pkg/revaconfig/config.go b/services/app-provider/pkg/revaconfig/config.go
index bf152659907..5cc523f5539 100644
--- a/services/app-provider/pkg/revaconfig/config.go
+++ b/services/app-provider/pkg/revaconfig/config.go
@@ -23,9 +23,9 @@ func AppProviderConfigFromStruct(cfg *config.Config) map[string]interface{} {
 			"network": cfg.GRPC.Protocol,
 			"address": cfg.GRPC.Addr,
 			"tls_settings": map[string]interface{}{
-				"enabled":     cfg.GRPC.TLSEnabled,
-				"certificate": cfg.GRPC.TLSCert,
-				"key":         cfg.GRPC.TLSKey,
+				"enabled":     cfg.GRPC.TLS.Enabled,
+				"certificate": cfg.GRPC.TLS.Cert,
+				"key":         cfg.GRPC.TLS.Key,
 			},
 			"services": map[string]interface{}{
 				"appprovider": map[string]interface{}{
diff --git a/services/app-registry/pkg/config/config.go b/services/app-registry/pkg/config/config.go
index b44287a19e5..1b502a1a345 100644
--- a/services/app-registry/pkg/config/config.go
+++ b/services/app-registry/pkg/config/config.go
@@ -50,12 +50,10 @@ type Debug struct {
 }
 
 type GRPCConfig struct {
-	Addr       string `yaml:"addr" env:"APP_REGISTRY_GRPC_ADDR" desc:"The bind address of the GRPC service."`
-	TLSEnabled bool   `yaml:"tls_enabled" env:"OCIS_GRPC_TLS_ENABLED"`
-	TLSCert    string `yaml:"tls_cert" env:"OCIS_GRPC_TLS_CERTIFICATE" desc:"Path/File name of the TLS server certificate (in PEM format) for the reva grpc services."`
-	TLSKey     string `yaml:"tls_key" env:"OCIS_GRPC_TLS_KEY" desc:"Path/File name for the TLS certificate key (in PEM format) for the server certificate."`
-	Namespace  string `yaml:"-"`
-	Protocol   string `yaml:"protocol" env:"APP_REGISTRY_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
+	Addr      string                 `yaml:"addr" env:"APP_REGISTRY_GRPC_ADDR" desc:"The bind address of the GRPC service."`
+	TLS       *shared.GRPCServiceTLS `yaml:"tls"`
+	Namespace string                 `yaml:"-"`
+	Protocol  string                 `yaml:"protocol" env:"APP_REGISTRY_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
 }
 
 type AppRegistry struct {
diff --git a/services/app-registry/pkg/config/defaults/defaultconfig.go b/services/app-registry/pkg/config/defaults/defaultconfig.go
index 1efd04bcc9f..de7e019529f 100644
--- a/services/app-registry/pkg/config/defaults/defaultconfig.go
+++ b/services/app-registry/pkg/config/defaults/defaultconfig.go
@@ -130,9 +130,8 @@ func EnsureDefaults(cfg *config.Config) {
 
 	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
 		cfg.Reva = &shared.Reva{
-			Address:   cfg.Commons.Reva.Address,
-			TLSMode:   cfg.Commons.Reva.TLSMode,
-			TLSCACert: cfg.Commons.Reva.TLSCACert,
+			Address: cfg.Commons.Reva.Address,
+			TLS:     cfg.Commons.Reva.TLS,
 		}
 	} else if cfg.Reva == nil {
 		cfg.Reva = &shared.Reva{}
@@ -146,6 +145,14 @@ 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
+		}
+	}
 }
 
 // Sanitize the config
diff --git a/services/app-registry/pkg/revaconfig/config.go b/services/app-registry/pkg/revaconfig/config.go
index f3e0d5ae93f..6561e0c9aaa 100644
--- a/services/app-registry/pkg/revaconfig/config.go
+++ b/services/app-registry/pkg/revaconfig/config.go
@@ -25,9 +25,9 @@ func AppRegistryConfigFromStruct(cfg *config.Config, logger log.Logger) map[stri
 			"network": cfg.GRPC.Protocol,
 			"address": cfg.GRPC.Addr,
 			"tls_settings": map[string]interface{}{
-				"enabled":     cfg.GRPC.TLSEnabled,
-				"certificate": cfg.GRPC.TLSCert,
-				"key":         cfg.GRPC.TLSKey,
+				"enabled":     cfg.GRPC.TLS.Enabled,
+				"certificate": cfg.GRPC.TLS.Cert,
+				"key":         cfg.GRPC.TLS.Key,
 			},
 			"services": map[string]interface{}{
 				"appregistry": map[string]interface{}{
diff --git a/services/auth-basic/pkg/config/config.go b/services/auth-basic/pkg/config/config.go
index 26aea8518c4..d9ed81ebb20 100644
--- a/services/auth-basic/pkg/config/config.go
+++ b/services/auth-basic/pkg/config/config.go
@@ -51,12 +51,10 @@ type Debug struct {
 }
 
 type GRPCConfig struct {
-	Addr       string `yaml:"addr" env:"AUTH_BASIC_GRPC_ADDR" desc:"The bind address of the GRPC service."`
-	TLSEnabled bool   `yaml:"tls_enabled" env:"OCIS_GRPC_TLS_ENABLED"`
-	TLSCert    string `yaml:"tls_cert" env:"OCIS_GRPC_TLS_CERTIFICATE" desc:"Path/File name of the TLS server certificate (in PEM format) for the reva grpc services."`
-	TLSKey     string `yaml:"tls_key" env:"OCIS_GRPC_TLS_KEY" desc:"Path/File name for the TLS certificate key (in PEM format) for the server certificate."`
-	Namespace  string `yaml:"-"`
-	Protocol   string `yaml:"protocol" env:"AUTH_BASIC_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
+	Addr      string                 `yaml:"addr" env:"AUTH_BASIC_GRPC_ADDR" desc:"The bind address of the GRPC service."`
+	TLS       *shared.GRPCServiceTLS `yaml:"tls"`
+	Namespace string                 `yaml:"-"`
+	Protocol  string                 `yaml:"protocol" env:"AUTH_BASIC_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
 }
 
 type AuthProviders struct {
diff --git a/services/auth-basic/pkg/config/defaults/defaultconfig.go b/services/auth-basic/pkg/config/defaults/defaultconfig.go
index a926b940822..630aec30b6a 100644
--- a/services/auth-basic/pkg/config/defaults/defaultconfig.go
+++ b/services/auth-basic/pkg/config/defaults/defaultconfig.go
@@ -104,9 +104,8 @@ func EnsureDefaults(cfg *config.Config) {
 
 	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
 		cfg.Reva = &shared.Reva{
-			Address:   cfg.Commons.Reva.Address,
-			TLSMode:   cfg.Commons.Reva.TLSMode,
-			TLSCACert: cfg.Commons.Reva.TLSCACert,
+			Address: cfg.Commons.Reva.Address,
+			TLS:     cfg.Commons.Reva.TLS,
 		}
 	} else if cfg.Reva == nil {
 		cfg.Reva = &shared.Reva{}
@@ -120,6 +119,14 @@ 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
+		}
+	}
 }
 
 func Sanitize(cfg *config.Config) {
diff --git a/services/auth-basic/pkg/revaconfig/config.go b/services/auth-basic/pkg/revaconfig/config.go
index f47f04bf494..f477f90d585 100644
--- a/services/auth-basic/pkg/revaconfig/config.go
+++ b/services/auth-basic/pkg/revaconfig/config.go
@@ -21,9 +21,9 @@ func AuthBasicConfigFromStruct(cfg *config.Config) map[string]interface{} {
 			"network": cfg.GRPC.Protocol,
 			"address": cfg.GRPC.Addr,
 			"tls_settings": map[string]interface{}{
-				"enabled":     cfg.GRPC.TLSEnabled,
-				"certificate": cfg.GRPC.TLSCert,
-				"key":         cfg.GRPC.TLSKey,
+				"enabled":     cfg.GRPC.TLS.Enabled,
+				"certificate": cfg.GRPC.TLS.Cert,
+				"key":         cfg.GRPC.TLS.Key,
 			},
 			// TODO build services dynamically
 			"services": map[string]interface{}{
diff --git a/services/auth-bearer/pkg/config/config.go b/services/auth-bearer/pkg/config/config.go
index d3bc9abe878..39c77ee2639 100644
--- a/services/auth-bearer/pkg/config/config.go
+++ b/services/auth-bearer/pkg/config/config.go
@@ -51,12 +51,10 @@ type Debug struct {
 }
 
 type GRPCConfig struct {
-	Addr       string `yaml:"addr" env:"AUTH_BEARER_GRPC_ADDR" desc:"The bind address of the GRPC service."`
-	TLSEnabled bool   `yaml:"tls_enabled" env:"OCIS_GRPC_TLS_ENABLED"`
-	TLSCert    string `yaml:"tls_cert" env:"OCIS_GRPC_TLS_CERTIFICATE" desc:"Path/File name of the TLS server certificate (in PEM format) for the reva grpc services."`
-	TLSKey     string `yaml:"tls_key" env:"OCIS_GRPC_TLS_KEY" desc:"Path/File name for the TLS certificate key (in PEM format) for the server certificate."`
-	Namespace  string `yaml:"-"`
-	Protocol   string `yaml:"protocol" env:"AUTH_BEARER_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
+	Addr      string                 `yaml:"addr" env:"AUTH_BEARER_GRPC_ADDR" desc:"The bind address of the GRPC service."`
+	TLS       *shared.GRPCServiceTLS `yaml:"tls"`
+	Namespace string                 `yaml:"-"`
+	Protocol  string                 `yaml:"protocol" env:"AUTH_BEARER_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
 }
 
 type OIDC struct {
diff --git a/services/auth-bearer/pkg/config/defaults/defaultconfig.go b/services/auth-bearer/pkg/config/defaults/defaultconfig.go
index 42117bc104b..e9a3eaf2da5 100644
--- a/services/auth-bearer/pkg/config/defaults/defaultconfig.go
+++ b/services/auth-bearer/pkg/config/defaults/defaultconfig.go
@@ -63,9 +63,8 @@ func EnsureDefaults(cfg *config.Config) {
 
 	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
 		cfg.Reva = &shared.Reva{
-			Address:   cfg.Commons.Reva.Address,
-			TLSMode:   cfg.Commons.Reva.TLSMode,
-			TLSCACert: cfg.Commons.Reva.TLSCACert,
+			Address: cfg.Commons.Reva.Address,
+			TLS:     cfg.Commons.Reva.TLS,
 		}
 	} else if cfg.Reva == nil {
 		cfg.Reva = &shared.Reva{}
@@ -78,6 +77,15 @@ func EnsureDefaults(cfg *config.Config) {
 	} else if cfg.TokenManager == nil {
 		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
+		}
+	}
 }
 
 func Sanitize(cfg *config.Config) {
diff --git a/services/auth-bearer/pkg/revaconfig/config.go b/services/auth-bearer/pkg/revaconfig/config.go
index 1445fbab4d1..d51198b3c60 100644
--- a/services/auth-bearer/pkg/revaconfig/config.go
+++ b/services/auth-bearer/pkg/revaconfig/config.go
@@ -21,9 +21,9 @@ func AuthBearerConfigFromStruct(cfg *config.Config) map[string]interface{} {
 			"network": cfg.GRPC.Protocol,
 			"address": cfg.GRPC.Addr,
 			"tls_settings": map[string]interface{}{
-				"enabled":     cfg.GRPC.TLSEnabled,
-				"certificate": cfg.GRPC.TLSCert,
-				"key":         cfg.GRPC.TLSKey,
+				"enabled":     cfg.GRPC.TLS.Enabled,
+				"certificate": cfg.GRPC.TLS.Cert,
+				"key":         cfg.GRPC.TLS.Key,
 			},
 			"services": map[string]interface{}{
 				"authprovider": map[string]interface{}{
diff --git a/services/auth-machine/pkg/config/config.go b/services/auth-machine/pkg/config/config.go
index 9989c7c35f0..431d46560e9 100644
--- a/services/auth-machine/pkg/config/config.go
+++ b/services/auth-machine/pkg/config/config.go
@@ -51,10 +51,8 @@ type Debug struct {
 }
 
 type GRPCConfig struct {
-	Addr       string `yaml:"addr" env:"AUTH_MACHINE_GRPC_ADDR" desc:"The bind address of the GRPC service."`
-	TLSEnabled bool   `yaml:"tls_enabled" env:"OCIS_GRPC_TLS_ENABLED"`
-	TLSCert    string `yaml:"tls_cert" env:"OCIS_GRPC_TLS_CERTIFICATE" desc:"Path/File name of the TLS server certificate (in PEM format) for the reva grpc services."`
-	TLSKey     string `yaml:"tls_key" env:"OCIS_GRPC_TLS_KEY" desc:"Path/File name for the TLS certificate key (in PEM format) for the server certificate."`
-	Namespace  string `yaml:"-"`
-	Protocol   string `yaml:"protocol" env:"AUTH_MACHINE_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
+	Addr      string                 `yaml:"addr" env:"AUTH_MACHINE_GRPC_ADDR" desc:"The bind address of the GRPC service."`
+	TLS       *shared.GRPCServiceTLS `yaml:"tls"`
+	Namespace string                 `yaml:"-"`
+	Protocol  string                 `yaml:"protocol" env:"AUTH_MACHINE_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
 }
diff --git a/services/auth-machine/pkg/config/defaults/defaultconfig.go b/services/auth-machine/pkg/config/defaults/defaultconfig.go
index 679e61a1fc1..242db54a57f 100644
--- a/services/auth-machine/pkg/config/defaults/defaultconfig.go
+++ b/services/auth-machine/pkg/config/defaults/defaultconfig.go
@@ -58,9 +58,8 @@ func EnsureDefaults(cfg *config.Config) {
 
 	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
 		cfg.Reva = &shared.Reva{
-			Address:   cfg.Commons.Reva.Address,
-			TLSMode:   cfg.Commons.Reva.TLSMode,
-			TLSCACert: cfg.Commons.Reva.TLSCACert,
+			Address: cfg.Commons.Reva.Address,
+			TLS:     cfg.Commons.Reva.TLS,
 		}
 	} else if cfg.Reva == nil {
 		cfg.Reva = &shared.Reva{}
@@ -77,6 +76,15 @@ func EnsureDefaults(cfg *config.Config) {
 	if cfg.MachineAuthAPIKey == "" && cfg.Commons != nil && cfg.Commons.MachineAuthAPIKey != "" {
 		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
+		}
+	}
 }
 
 func Sanitize(cfg *config.Config) {
diff --git a/services/auth-machine/pkg/revaconfig/config.go b/services/auth-machine/pkg/revaconfig/config.go
index a72300e47bf..e67b05485d4 100644
--- a/services/auth-machine/pkg/revaconfig/config.go
+++ b/services/auth-machine/pkg/revaconfig/config.go
@@ -23,9 +23,9 @@ func AuthMachineConfigFromStruct(cfg *config.Config) map[string]interface{} {
 			"network": cfg.GRPC.Protocol,
 			"address": cfg.GRPC.Addr,
 			"tls_settings": map[string]interface{}{
-				"enabled":     cfg.GRPC.TLSEnabled,
-				"certificate": cfg.GRPC.TLSCert,
-				"key":         cfg.GRPC.TLSKey,
+				"enabled":     cfg.GRPC.TLS.Enabled,
+				"certificate": cfg.GRPC.TLS.Cert,
+				"key":         cfg.GRPC.TLS.Key,
 			},
 			"services": map[string]interface{}{
 				"authprovider": map[string]interface{}{
diff --git a/services/frontend/pkg/config/defaults/defaultconfig.go b/services/frontend/pkg/config/defaults/defaultconfig.go
index 53d8f4e798e..9dfcb399e93 100644
--- a/services/frontend/pkg/config/defaults/defaultconfig.go
+++ b/services/frontend/pkg/config/defaults/defaultconfig.go
@@ -140,9 +140,8 @@ func EnsureDefaults(cfg *config.Config) {
 
 	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
 		cfg.Reva = &shared.Reva{
-			Address:   cfg.Commons.Reva.Address,
-			TLSMode:   cfg.Commons.Reva.TLSMode,
-			TLSCACert: cfg.Commons.Reva.TLSCACert,
+			Address: cfg.Commons.Reva.Address,
+			TLS:     cfg.Commons.Reva.TLS,
 		}
 	} else if cfg.Reva == nil {
 		cfg.Reva = &shared.Reva{}
diff --git a/services/gateway/pkg/config/config.go b/services/gateway/pkg/config/config.go
index 46d37ecbcbe..4b27f67b73f 100644
--- a/services/gateway/pkg/config/config.go
+++ b/services/gateway/pkg/config/config.go
@@ -73,12 +73,10 @@ type Debug struct {
 }
 
 type GRPCConfig struct {
-	Addr       string `yaml:"addr" env:"GATEWAY_GRPC_ADDR" desc:"The bind address of the GRPC service."`
-	TLSEnabled bool   `yaml:"tls_enabled" env:"OCIS_GRPC_TLS_ENABLED"`
-	TLSCert    string `yaml:"tls_cert" env:"OCIS_GRPC_TLS_CERTIFICATE" desc:"Path/File name of the TLS server certificate (in PEM format) for the reva grpc services."`
-	TLSKey     string `yaml:"tls_key" env:"OCIS_GRPC_TLS_KEY" desc:"Path/File name for the TLS certificate key (in PEM format) for the server certificate."`
-	Namespace  string `yaml:"-"`
-	Protocol   string `yaml:"protocol" env:"GATEWAY_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
+	Addr      string                 `yaml:"addr" env:"GATEWAY_GRPC_ADDR" desc:"The bind address of the GRPC service."`
+	TLS       *shared.GRPCServiceTLS `yaml:"tls"`
+	Namespace string                 `yaml:"-"`
+	Protocol  string                 `yaml:"protocol" env:"GATEWAY_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
 }
 
 type StorageRegistry struct {
diff --git a/services/gateway/pkg/config/defaults/defaultconfig.go b/services/gateway/pkg/config/defaults/defaultconfig.go
index a35b54dfefb..adf7a84226b 100644
--- a/services/gateway/pkg/config/defaults/defaultconfig.go
+++ b/services/gateway/pkg/config/defaults/defaultconfig.go
@@ -87,9 +87,8 @@ func EnsureDefaults(cfg *config.Config) {
 
 	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
 		cfg.Reva = &shared.Reva{
-			Address:   cfg.Commons.Reva.Address,
-			TLSMode:   cfg.Commons.Reva.TLSMode,
-			TLSCACert: cfg.Commons.Reva.TLSCACert,
+			Address: cfg.Commons.Reva.Address,
+			TLS:     cfg.Commons.Reva.TLS,
 		}
 	} else if cfg.Reva == nil {
 		cfg.Reva = &shared.Reva{}
@@ -106,6 +105,15 @@ func EnsureDefaults(cfg *config.Config) {
 	if cfg.TransferSecret == "" && cfg.Commons != nil && cfg.Commons.TransferSecret != "" {
 		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
+		}
+	}
 }
 
 func Sanitize(cfg *config.Config) {
diff --git a/services/gateway/pkg/revaconfig/config.go b/services/gateway/pkg/revaconfig/config.go
index 25ae057ca87..30d531f91b9 100644
--- a/services/gateway/pkg/revaconfig/config.go
+++ b/services/gateway/pkg/revaconfig/config.go
@@ -30,9 +30,9 @@ func GatewayConfigFromStruct(cfg *config.Config, logger log.Logger) map[string]i
 			"network": cfg.GRPC.Protocol,
 			"address": cfg.GRPC.Addr,
 			"tls_settings": map[string]interface{}{
-				"enabled":     cfg.GRPC.TLSEnabled,
-				"certificate": cfg.GRPC.TLSCert,
-				"key":         cfg.GRPC.TLSKey,
+				"enabled":     cfg.GRPC.TLS.Enabled,
+				"certificate": cfg.GRPC.TLS.Cert,
+				"key":         cfg.GRPC.TLS.Key,
 			},
 			// TODO build services dynamically
 			"services": map[string]interface{}{
diff --git a/services/graph/pkg/command/server.go b/services/graph/pkg/command/server.go
index 36a8a5cf946..e962eb29a2d 100644
--- a/services/graph/pkg/command/server.go
+++ b/services/graph/pkg/command/server.go
@@ -6,6 +6,7 @@ import (
 
 	"github.com/oklog/run"
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/configlog"
+	ogrpc "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/config"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/config/parser"
@@ -32,6 +33,10 @@ func Server(cfg *config.Config) *cli.Command {
 			if err != nil {
 				return err
 			}
+			err = ogrpc.Configure(ogrpc.GetClientOptions(cfg.GRPCClientTLS)...)
+			if err != nil {
+				return err
+			}
 
 			gr := run.Group{}
 			ctx, cancel := func() (context.Context, context.CancelFunc) {
diff --git a/services/graph/pkg/config/config.go b/services/graph/pkg/config/config.go
index a4f19e11505..4d213407f2b 100644
--- a/services/graph/pkg/config/config.go
+++ b/services/graph/pkg/config/config.go
@@ -19,8 +19,9 @@ type Config struct {
 
 	HTTP HTTP `yaml:"http"`
 
-	Reva         *shared.Reva  `yaml:"reva"`
-	TokenManager *TokenManager `yaml:"token_manager"`
+	Reva          *shared.Reva          `yaml:"reva"`
+	TokenManager  *TokenManager         `yaml:"token_manager"`
+	GRPCClientTLS *shared.GRPCClientTLS `yaml:"grpc_client_tls"`
 
 	Spaces   Spaces   `yaml:"spaces"`
 	Identity Identity `yaml:"identity"`
diff --git a/services/graph/pkg/config/defaults/defaultconfig.go b/services/graph/pkg/config/defaults/defaultconfig.go
index 3c7d7202218..eb3ad18fd6e 100644
--- a/services/graph/pkg/config/defaults/defaultconfig.go
+++ b/services/graph/pkg/config/defaults/defaultconfig.go
@@ -113,6 +113,14 @@ func EnsureDefaults(cfg *config.Config) {
 	} else if cfg.TokenManager == nil {
 		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
+		}
+	}
 }
 
 func Sanitize(cfg *config.Config) {
diff --git a/services/graph/pkg/service/v0/drives.go b/services/graph/pkg/service/v0/drives.go
index 05dd0aeb341..e75b09a86bf 100644
--- a/services/graph/pkg/service/v0/drives.go
+++ b/services/graph/pkg/service/v0/drives.go
@@ -33,6 +33,20 @@ import (
 	merrors "go-micro.dev/v4/errors"
 )
 
+var (
+	_invalidSpaceNameCharacters = []string{`/`, `\`, `.`, `:`, `?`, `*`, `"`, `>`, `<`, `|`}
+	_maxSpaceNameLength         = 255
+
+	// ErrNameTooLong is thrown when the spacename is too long
+	ErrNameTooLong = fmt.Errorf("spacename must be smaller than %d", _maxSpaceNameLength)
+
+	// ErrNameEmpty is thrown when the spacename is empty
+	ErrNameEmpty = errors.New("spacename must not be empty")
+
+	// ErrForbiddenCharacter is thrown when the spacename contains an invalid character
+	ErrForbiddenCharacter = fmt.Errorf("spacenames must not contain %v", _invalidSpaceNameCharacters)
+)
+
 // GetDrives lists all drives the current user has access to
 func (g Graph) GetDrives(w http.ResponseWriter, r *http.Request) {
 	g.getDrives(w, r, false)
@@ -229,10 +243,10 @@ func (g Graph) CreateDrive(w http.ResponseWriter, r *http.Request) {
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "invalid body schema definition")
 		return
 	}
-	spaceName := *drive.Name
-	if spaceName == "" {
-		logger.Debug().Str("name", spaceName).Msg("could not create drive: invalid name")
-		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "invalid name")
+	spaceName := strings.TrimSpace(*drive.Name)
+	if err := validateSpaceName(spaceName); err != nil {
+		logger.Debug().Str("name", spaceName).Err(err).Msg("could not create drive: name validation failed")
+		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, fmt.Sprintf("invalid spacename: %s", err.Error()))
 		return
 	}
 
@@ -376,7 +390,14 @@ func (g Graph) UpdateDrive(w http.ResponseWriter, r *http.Request) {
 	}
 
 	if drive.Name != nil {
-		updateSpaceRequest.StorageSpace.Name = *drive.Name
+		spacename := strings.TrimSpace(*drive.Name)
+		if err := validateSpaceName(spacename); err != nil {
+			logger.Info().Err(err).Msg("could not update drive: spacename invalid")
+			errorcode.GeneralException.Render(w, r, http.StatusBadRequest, err.Error())
+			return
+		}
+
+		updateSpaceRequest.StorageSpace.Name = spacename
 	}
 
 	if drive.Quota.HasTotal() {
@@ -901,3 +922,21 @@ func sortSpaces(req *godata.GoDataRequest, spaces []*libregraph.Drive) ([]*libre
 	sort.Sort(sorter)
 	return spaces, nil
 }
+
+func validateSpaceName(name string) error {
+	if name == "" {
+		return ErrNameEmpty
+	}
+
+	if len(name) > _maxSpaceNameLength {
+		return ErrNameTooLong
+	}
+
+	for _, c := range _invalidSpaceNameCharacters {
+		if strings.Contains(name, c) {
+			return ErrForbiddenCharacter
+		}
+	}
+
+	return nil
+}
diff --git a/services/groups/pkg/config/config.go b/services/groups/pkg/config/config.go
index 8d9d962a661..ee6a903a692 100644
--- a/services/groups/pkg/config/config.go
+++ b/services/groups/pkg/config/config.go
@@ -52,12 +52,10 @@ type Debug struct {
 }
 
 type GRPCConfig struct {
-	Addr       string `yaml:"addr" env:"GROUPS_GRPC_ADDR" desc:"The bind address of the GRPC service."`
-	TLSEnabled bool   `yaml:"tls_enabled" env:"OCIS_GRPC_TLS_ENABLED"`
-	TLSCert    string `yaml:"tls_cert" env:"OCIS_GRPC_TLS_CERTIFICATE" desc:"Path/File name of the TLS server certificate (in PEM format) for the reva grpc services."`
-	TLSKey     string `yaml:"tls_key" env:"OCIS_GRPC_TLS_KEY" desc:"Path/File name for the TLS certificate key (in PEM format) for the server certificate."`
-	Namespace  string `yaml:"-"`
-	Protocol   string `yaml:"protocol" env:"GROUPS_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
+	Addr      string                 `yaml:"addr" env:"GROUPS_GRPC_ADDR" desc:"The bind address of the GRPC service."`
+	TLS       *shared.GRPCServiceTLS `yaml:"tls"`
+	Namespace string                 `yaml:"-"`
+	Protocol  string                 `yaml:"protocol" env:"GROUPS_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
 }
 
 type Drivers struct {
diff --git a/services/groups/pkg/config/defaults/defaultconfig.go b/services/groups/pkg/config/defaults/defaultconfig.go
index 594f88518d8..62cfe0e4e95 100644
--- a/services/groups/pkg/config/defaults/defaultconfig.go
+++ b/services/groups/pkg/config/defaults/defaultconfig.go
@@ -105,9 +105,8 @@ func EnsureDefaults(cfg *config.Config) {
 
 	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
 		cfg.Reva = &shared.Reva{
-			Address:   cfg.Commons.Reva.Address,
-			TLSMode:   cfg.Commons.Reva.TLSMode,
-			TLSCACert: cfg.Commons.Reva.TLSCACert,
+			Address: cfg.Commons.Reva.Address,
+			TLS:     cfg.Commons.Reva.TLS,
 		}
 	} else if cfg.Reva == nil {
 		cfg.Reva = &shared.Reva{}
@@ -120,6 +119,15 @@ func EnsureDefaults(cfg *config.Config) {
 	} else if cfg.TokenManager == nil {
 		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
+		}
+	}
 }
 
 func Sanitize(cfg *config.Config) {
diff --git a/services/groups/pkg/revaconfig/config.go b/services/groups/pkg/revaconfig/config.go
index 2209e784b9f..f9bef1ddd7d 100644
--- a/services/groups/pkg/revaconfig/config.go
+++ b/services/groups/pkg/revaconfig/config.go
@@ -23,9 +23,9 @@ func GroupsConfigFromStruct(cfg *config.Config) map[string]interface{} {
 			"network": cfg.GRPC.Protocol,
 			"address": cfg.GRPC.Addr,
 			"tls_settings": map[string]interface{}{
-				"enabled":     cfg.GRPC.TLSEnabled,
-				"certificate": cfg.GRPC.TLSCert,
-				"key":         cfg.GRPC.TLSKey,
+				"enabled":     cfg.GRPC.TLS.Enabled,
+				"certificate": cfg.GRPC.TLS.Cert,
+				"key":         cfg.GRPC.TLS.Key,
 			},
 			// TODO build services dynamically
 			"services": map[string]interface{}{
diff --git a/services/idp/pkg/config/defaults/defaultconfig.go b/services/idp/pkg/config/defaults/defaultconfig.go
index 71ef857f55a..fbd928be42f 100644
--- a/services/idp/pkg/config/defaults/defaultconfig.go
+++ b/services/idp/pkg/config/defaults/defaultconfig.go
@@ -153,9 +153,8 @@ func EnsureDefaults(cfg *config.Config) {
 
 	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
 		cfg.Reva = &shared.Reva{
-			Address:   cfg.Commons.Reva.Address,
-			TLSMode:   cfg.Commons.Reva.TLSMode,
-			TLSCACert: cfg.Commons.Reva.TLSCACert,
+			Address: cfg.Commons.Reva.Address,
+			TLS:     cfg.Commons.Reva.TLS,
 		}
 	} else if cfg.Reva == nil {
 		cfg.Reva = &shared.Reva{}
diff --git a/services/notifications/pkg/channels/channels.go b/services/notifications/pkg/channels/channels.go
index 0a27b1f14d5..7eaa7cb5a9d 100644
--- a/services/notifications/pkg/channels/channels.go
+++ b/services/notifications/pkg/channels/channels.go
@@ -27,13 +27,13 @@ type Channel interface {
 
 // NewMailChannel instantiates a new mail communication channel.
 func NewMailChannel(cfg config.Config, logger log.Logger) (Channel, error) {
-	tm, err := pool.StringToTLSMode(cfg.Notifications.RevaGatewayTLSMode)
+	tm, err := pool.StringToTLSMode(cfg.Notifications.GRPCClientTLS.Mode)
 	if err != nil {
 		logger.Error().Err(err).Msg("could not get gateway client tls mode")
 		return nil, err
 	}
 	gc, err := pool.GetGatewayServiceClient(cfg.Notifications.RevaGateway,
-		pool.WithTLSCACert(cfg.Notifications.RevaGatewayTLSCACert),
+		pool.WithTLSCACert(cfg.Notifications.GRPCClientTLS.CACert),
 		pool.WithTLSMode(tm),
 	)
 	if err != nil {
diff --git a/services/notifications/pkg/command/server.go b/services/notifications/pkg/command/server.go
index b1902689933..e761f858817 100644
--- a/services/notifications/pkg/command/server.go
+++ b/services/notifications/pkg/command/server.go
@@ -77,13 +77,13 @@ func Server(cfg *config.Config) *cli.Command {
 			if err != nil {
 				return err
 			}
-			tm, err := pool.StringToTLSMode(cfg.Notifications.RevaGatewayTLSMode)
+			tm, err := pool.StringToTLSMode(cfg.Notifications.GRPCClientTLS.Mode)
 			if err != nil {
 				return err
 			}
 			gwclient, err := pool.GetGatewayServiceClient(
 				cfg.Notifications.RevaGateway,
-				pool.WithTLSCACert(cfg.Notifications.RevaGatewayTLSCACert),
+				pool.WithTLSCACert(cfg.Notifications.GRPCClientTLS.CACert),
 				pool.WithTLSMode(tm),
 			)
 			if err != nil {
diff --git a/services/notifications/pkg/config/config.go b/services/notifications/pkg/config/config.go
index 7d5fb3be0b2..fc3847236c3 100644
--- a/services/notifications/pkg/config/config.go
+++ b/services/notifications/pkg/config/config.go
@@ -22,13 +22,12 @@ type Config struct {
 
 // Notifications defines the config options for the notifications service.
 type Notifications struct {
-	SMTP                 SMTP   `yaml:"SMTP"`
-	Events               Events `yaml:"events"`
-	MachineAuthAPIKey    string `yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;NOTIFICATIONS_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used to validate internal requests necessary to access resources from other services."`
-	EmailTemplatePath    string `yaml:"email_template_path" env:"OCIS_EMAIL_TEMPLATE_PATH;NOTIFICATIONS_EMAIL_TEMPLATE_PATH" desc:"Path to Email notification templates overriding embedded ones."`
-	RevaGateway          string `yaml:"reva_gateway" env:"REVA_GATEWAY" desc:"CS3 gateway used to look up user metadata"`
-	RevaGatewayTLSMode   string `yaml:"reva_gateway_tls_mode" env:"REVA_GATEWAY_TLS_MODE"`
-	RevaGatewayTLSCACert string `yaml:"reva_gateway_tls_cacert" env:"REVA_GATEWAY_TLS_CACERT"`
+	SMTP              SMTP                  `yaml:"SMTP"`
+	Events            Events                `yaml:"events"`
+	MachineAuthAPIKey string                `yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;NOTIFICATIONS_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used to validate internal requests necessary to access resources from other services."`
+	EmailTemplatePath string                `yaml:"email_template_path" env:"OCIS_EMAIL_TEMPLATE_PATH;NOTIFICATIONS_EMAIL_TEMPLATE_PATH" desc:"Path to Email notification templates overriding embedded ones."`
+	RevaGateway       string                `yaml:"reva_gateway" env:"REVA_GATEWAY" desc:"CS3 gateway used to look up user metadata"`
+	GRPCClientTLS     *shared.GRPCClientTLS `yaml:"grpc_client_tls"`
 }
 
 // SMTP combines the smtp configuration options.
diff --git a/services/notifications/pkg/config/defaults/defaultconfig.go b/services/notifications/pkg/config/defaults/defaultconfig.go
index 552d9f560f8..fd61a028b46 100644
--- a/services/notifications/pkg/config/defaults/defaultconfig.go
+++ b/services/notifications/pkg/config/defaults/defaultconfig.go
@@ -37,9 +37,7 @@ func DefaultConfig() *config.Config {
 				ConsumerGroup: "notifications",
 				EnableTLS:     false,
 			},
-			RevaGateway:          shared.DefaultRevaConfig().Address,
-			RevaGatewayTLSMode:   shared.DefaultRevaConfig().TLSMode,
-			RevaGatewayTLSCACert: shared.DefaultRevaConfig().TLSCACert,
+			RevaGateway: shared.DefaultRevaConfig().Address,
 		},
 	}
 }
@@ -60,6 +58,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
+		}
+	}
 }
 
 func Sanitize(cfg *config.Config) {
diff --git a/services/ocdav/pkg/config/defaults/defaultconfig.go b/services/ocdav/pkg/config/defaults/defaultconfig.go
index 8739f0cc975..ddfb0d5a993 100644
--- a/services/ocdav/pkg/config/defaults/defaultconfig.go
+++ b/services/ocdav/pkg/config/defaults/defaultconfig.go
@@ -80,9 +80,8 @@ func EnsureDefaults(cfg *config.Config) {
 
 	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
 		cfg.Reva = &shared.Reva{
-			Address:   cfg.Commons.Reva.Address,
-			TLSMode:   cfg.Commons.Reva.TLSMode,
-			TLSCACert: cfg.Commons.Reva.TLSCACert,
+			Address: cfg.Commons.Reva.Address,
+			TLS:     cfg.Commons.Reva.TLS,
 		}
 	} else if cfg.Reva == nil {
 		cfg.Reva = &shared.Reva{}
diff --git a/services/ocs/pkg/command/server.go b/services/ocs/pkg/command/server.go
index 7c3b6c989b4..6b6ab26a463 100644
--- a/services/ocs/pkg/command/server.go
+++ b/services/ocs/pkg/command/server.go
@@ -5,6 +5,7 @@ import (
 	"fmt"
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/configlog"
+	ogrpc "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
 	"github.com/owncloud/ocis/v2/services/ocs/pkg/config/parser"
 	"github.com/owncloud/ocis/v2/services/ocs/pkg/logging"
@@ -33,6 +34,10 @@ func Server(cfg *config.Config) *cli.Command {
 			if err != nil {
 				return err
 			}
+			err = ogrpc.Configure(ogrpc.GetClientOptions(cfg.GRPCClientTLS)...)
+			if err != nil {
+				return err
+			}
 
 			var (
 				gr          = run.Group{}
diff --git a/services/ocs/pkg/config/config.go b/services/ocs/pkg/config/config.go
index 4653d516864..e4130405447 100644
--- a/services/ocs/pkg/config/config.go
+++ b/services/ocs/pkg/config/config.go
@@ -19,8 +19,9 @@ type Config struct {
 
 	HTTP HTTP `yaml:"http"`
 
-	TokenManager *TokenManager `yaml:"token_manager"`
-	Reva         *shared.Reva  `yaml:"reva"`
+	TokenManager  *TokenManager         `yaml:"token_manager"`
+	Reva          *shared.Reva          `yaml:"reva"`
+	GRPCClientTLS *shared.GRPCClientTLS `yaml:"grpc_client_tls"`
 
 	IdentityManagement IdentityManagement `yaml:"identity_management"`
 
diff --git a/services/ocs/pkg/config/defaults/defaultconfig.go b/services/ocs/pkg/config/defaults/defaultconfig.go
index dd5b389cd81..7bbc0cafb8c 100644
--- a/services/ocs/pkg/config/defaults/defaultconfig.go
+++ b/services/ocs/pkg/config/defaults/defaultconfig.go
@@ -80,9 +80,8 @@ func EnsureDefaults(cfg *config.Config) {
 
 	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
 		cfg.Reva = &shared.Reva{
-			Address:   cfg.Commons.Reva.Address,
-			TLSMode:   cfg.Commons.Reva.TLSMode,
-			TLSCACert: cfg.Commons.Reva.TLSCACert,
+			Address: cfg.Commons.Reva.Address,
+			TLS:     cfg.Commons.Reva.TLS,
 		}
 	} else if cfg.Reva == nil {
 		cfg.Reva = &shared.Reva{}
@@ -99,6 +98,14 @@ func EnsureDefaults(cfg *config.Config) {
 	if cfg.MachineAuthAPIKey == "" && cfg.Commons != nil && cfg.Commons.MachineAuthAPIKey != "" {
 		cfg.MachineAuthAPIKey = cfg.Commons.MachineAuthAPIKey
 	}
+
+	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
+		}
+	}
 }
 
 func Sanitize(cfg *config.Config) {
diff --git a/services/ocs/pkg/service/v0/users.go b/services/ocs/pkg/service/v0/users.go
index d666033d45b..84f7ab52f2c 100644
--- a/services/ocs/pkg/service/v0/users.go
+++ b/services/ocs/pkg/service/v0/users.go
@@ -14,7 +14,7 @@ import (
 	cs3 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
 	revactx "github.com/cs3org/reva/v2/pkg/ctx"
 	"github.com/go-chi/chi/v5"
-	"github.com/go-micro/plugins/v4/client/grpc"
+	"github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
 	"github.com/owncloud/ocis/v2/services/ocs/pkg/service/v0/data"
 	"github.com/owncloud/ocis/v2/services/ocs/pkg/service/v0/response"
 	ocstracing "github.com/owncloud/ocis/v2/services/ocs/pkg/tracing"
@@ -166,7 +166,7 @@ func (o Ocs) GetSigningKey(w http.ResponseWriter, r *http.Request) {
 	// use the user's UUID
 	userID := u.Id.OpaqueId
 
-	c := storesvc.NewStoreService("com.owncloud.api.store", grpc.NewClient())
+	c := storesvc.NewStoreService("com.owncloud.api.store", grpc.DefaultClient())
 	res, err := c.Read(r.Context(), &storesvc.ReadRequest{
 		Options: &storemsg.ReadOptions{
 			Database: "proxy",
@@ -186,6 +186,7 @@ func (o Ocs) GetSigningKey(w http.ResponseWriter, r *http.Request) {
 		if e.Code == http.StatusNotFound {
 			// not found is ok, so we can continue and generate the key on the fly
 		} else {
+			o.logger.Error().Err(err).Msg("error reading from server")
 			o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, "error reading from store"))
 			return
 		}
diff --git a/services/proxy/pkg/command/server.go b/services/proxy/pkg/command/server.go
index 21075a1a4d7..cca24fd2b39 100644
--- a/services/proxy/pkg/command/server.go
+++ b/services/proxy/pkg/command/server.go
@@ -17,6 +17,7 @@ import (
 	"github.com/owncloud/ocis/v2/ocis-pkg/log"
 	pkgmiddleware "github.com/owncloud/ocis/v2/ocis-pkg/middleware"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
+	ogrpc "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
 	settingssvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
 	storesvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/store/v0"
@@ -50,6 +51,10 @@ func Server(cfg *config.Config) *cli.Command {
 			if err != nil {
 				return err
 			}
+			err = ogrpc.Configure(ogrpc.GetClientOptions(cfg.GRPCClientTLS)...)
+			if err != nil {
+				return err
+			}
 
 			var (
 				m = metrics.New()
diff --git a/services/proxy/pkg/config/config.go b/services/proxy/pkg/config/config.go
index c9bce96e74d..0e3ac4461d5 100644
--- a/services/proxy/pkg/config/config.go
+++ b/services/proxy/pkg/config/config.go
@@ -18,7 +18,8 @@ type Config struct {
 
 	HTTP HTTP `yaml:"http"`
 
-	Reva *shared.Reva `yaml:"reva"`
+	Reva          *shared.Reva          `yaml:"reva"`
+	GRPCClientTLS *shared.GRPCClientTLS `yaml:"grpc_client_tls"`
 
 	Policies              []Policy        `yaml:"policies"`
 	OIDC                  OIDC            `yaml:"oidc"`
diff --git a/services/proxy/pkg/config/defaults/defaultconfig.go b/services/proxy/pkg/config/defaults/defaultconfig.go
index 414d742270a..3f605bcb7b7 100644
--- a/services/proxy/pkg/config/defaults/defaultconfig.go
+++ b/services/proxy/pkg/config/defaults/defaultconfig.go
@@ -242,13 +242,20 @@ func EnsureDefaults(cfg *config.Config) {
 
 	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
 		cfg.Reva = &shared.Reva{
-			Address:   cfg.Commons.Reva.Address,
-			TLSMode:   cfg.Commons.Reva.TLSMode,
-			TLSCACert: cfg.Commons.Reva.TLSCACert,
+			Address: cfg.Commons.Reva.Address,
+			TLS:     cfg.Commons.Reva.TLS,
 		}
 	} else if cfg.Reva == nil {
 		cfg.Reva = &shared.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
+		}
+	}
 }
 
 // Sanitize sanitizes the configuration
diff --git a/services/search/pkg/command/server.go b/services/search/pkg/command/server.go
index e1bfac3a3e9..789964bd0f2 100644
--- a/services/search/pkg/command/server.go
+++ b/services/search/pkg/command/server.go
@@ -6,6 +6,7 @@ import (
 
 	"github.com/oklog/run"
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/configlog"
+	ogrpc "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
 	"github.com/owncloud/ocis/v2/services/search/pkg/config"
 	"github.com/owncloud/ocis/v2/services/search/pkg/config/parser"
@@ -32,6 +33,10 @@ func Server(cfg *config.Config) *cli.Command {
 			if err != nil {
 				return err
 			}
+			err = ogrpc.Configure(ogrpc.GetClientOptions(cfg.GRPCClientTLS)...)
+			if err != nil {
+				return err
+			}
 
 			gr := run.Group{}
 			ctx, cancel := func() (context.Context, context.CancelFunc) {
diff --git a/services/search/pkg/config/config.go b/services/search/pkg/config/config.go
index b69832cd35f..f9cee19da9f 100644
--- a/services/search/pkg/config/config.go
+++ b/services/search/pkg/config/config.go
@@ -16,11 +16,12 @@ type Config struct {
 	Log     *Log     `yaml:"log"`
 	Debug   Debug    `yaml:"debug"`
 
-	GRPC GRPC `yaml:"grpc"`
+	GRPC GRPCConfig `yaml:"grpc"`
 
-	Datapath string       `yaml:"data_path" env:"SEARCH_DATA_PATH" desc:"The directory where the filesystem storage will store search data. If not definied, the root directory derives from $OCIS_BASE_DATA_PATH:/search."`
-	Reva     *shared.Reva `yaml:"reva"`
-	Events   Events       `yaml:"events"`
+	Datapath      string                `yaml:"data_path" env:"SEARCH_DATA_PATH" desc:"The directory where the filesystem storage will store search data. If not definied, the root directory derives from $OCIS_BASE_DATA_PATH:/search."`
+	Reva          *shared.Reva          `yaml:"reva"`
+	GRPCClientTLS *shared.GRPCClientTLS `yaml:"grpc_client_tls"`
+	Events        Events                `yaml:"events"`
 
 	MachineAuthAPIKey string `yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;SEARCH_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used to validate internal requests necessary for the access to resources from other services."`
 
diff --git a/services/search/pkg/config/defaults/defaultconfig.go b/services/search/pkg/config/defaults/defaultconfig.go
index 3670bb3b41d..cfc9eb7014d 100644
--- a/services/search/pkg/config/defaults/defaultconfig.go
+++ b/services/search/pkg/config/defaults/defaultconfig.go
@@ -22,7 +22,7 @@ func DefaultConfig() *config.Config {
 			Addr:  "127.0.0.1:9224",
 			Token: "",
 		},
-		GRPC: config.GRPC{
+		GRPC: config.GRPCConfig{
 			Addr:      "127.0.0.1:9220",
 			Namespace: "com.owncloud.api",
 		},
@@ -72,13 +72,27 @@ func EnsureDefaults(cfg *config.Config) {
 
 	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
 		cfg.Reva = &shared.Reva{
-			Address:   cfg.Commons.Reva.Address,
-			TLSMode:   cfg.Commons.Reva.TLSMode,
-			TLSCACert: cfg.Commons.Reva.TLSCACert,
+			Address: cfg.Commons.Reva.Address,
+			TLS:     cfg.Commons.Reva.TLS,
 		}
 	} else if cfg.Reva == nil {
 		cfg.Reva = &shared.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.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
+		}
+	}
 }
 
 // Sanitize sanitizes the configuration
diff --git a/services/search/pkg/config/grpc.go b/services/search/pkg/config/grpc.go
index 51fd97212f3..5240c6d0018 100644
--- a/services/search/pkg/config/grpc.go
+++ b/services/search/pkg/config/grpc.go
@@ -1,7 +1,10 @@
 package config
 
-// GRPC defines the available grpc configuration.
-type GRPC struct {
-	Addr      string `ocisConfig:"addr" env:"SEARCH_GRPC_ADDR" desc:"The bind address of the GRPC service."`
-	Namespace string `ocisConfig:"-" yaml:"-"`
+import "github.com/owncloud/ocis/v2/ocis-pkg/shared"
+
+// GRPCConfig defines the available grpc configuration.
+type GRPCConfig struct {
+	Addr      string                 `ocisConfig:"addr" env:"SEARCH_GRPC_ADDR" desc:"The bind address of the GRPC service."`
+	Namespace string                 `ocisConfig:"-" yaml:"-"`
+	TLS       *shared.GRPCServiceTLS `yaml:"tls"`
 }
diff --git a/services/search/pkg/server/grpc/server.go b/services/search/pkg/server/grpc/server.go
index 28bad68a3ce..c152d47ef28 100644
--- a/services/search/pkg/server/grpc/server.go
+++ b/services/search/pkg/server/grpc/server.go
@@ -11,7 +11,12 @@ import (
 func Server(opts ...Option) grpc.Service {
 	options := newOptions(opts...)
 
-	service := grpc.NewService(
+	service, err := grpc.NewService(
+		grpc.TLSEnabled(options.Config.GRPC.TLS.Enabled),
+		grpc.TLSCert(
+			options.Config.GRPC.TLS.Cert,
+			options.Config.GRPC.TLS.Key,
+		),
 		grpc.Name(options.Config.Service.Name),
 		grpc.Context(options.Context),
 		grpc.Address(options.Config.GRPC.Addr),
@@ -20,6 +25,10 @@ func Server(opts ...Option) grpc.Service {
 		grpc.Flags(options.Flags...),
 		grpc.Version(version.GetString()),
 	)
+	if err != nil {
+		options.Logger.Fatal().Err(err).Msg("Error creating search service")
+		return grpc.Service{}
+	}
 
 	handle, err := svc.NewHandler(
 		svc.Config(options.Config),
diff --git a/services/settings/pkg/command/server.go b/services/settings/pkg/command/server.go
index 6e9571495ca..0d989314eba 100644
--- a/services/settings/pkg/command/server.go
+++ b/services/settings/pkg/command/server.go
@@ -6,6 +6,7 @@ import (
 
 	"github.com/oklog/run"
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/configlog"
+	ogrpc "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
 	"github.com/owncloud/ocis/v2/services/settings/pkg/config"
 	"github.com/owncloud/ocis/v2/services/settings/pkg/config/parser"
@@ -33,6 +34,10 @@ func Server(cfg *config.Config) *cli.Command {
 			if err != nil {
 				return err
 			}
+			err = ogrpc.Configure(ogrpc.GetClientOptions(cfg.GRPCClientTLS)...)
+			if err != nil {
+				return err
+			}
 
 			servers := run.Group{}
 			ctx, cancel := func() (context.Context, context.CancelFunc) {
diff --git a/services/settings/pkg/config/config.go b/services/settings/pkg/config/config.go
index 39069543410..c777d3b4571 100644
--- a/services/settings/pkg/config/config.go
+++ b/services/settings/pkg/config/config.go
@@ -16,8 +16,10 @@ type Config struct {
 	Log     *Log     `yaml:"log"`
 	Debug   Debug    `yaml:"debug"`
 
-	HTTP HTTP `yaml:"http"`
-	GRPC GRPC `yaml:"grpc"`
+	HTTP HTTP       `yaml:"http"`
+	GRPC GRPCConfig `yaml:"grpc"`
+
+	GRPCClientTLS *shared.GRPCClientTLS `yaml:"grpc_client_tls"`
 
 	StoreType string   `yaml:"store_type" env:"SETTINGS_STORE_TYPE" desc:"Store type configures the persistency driver. Supported values are \"metadata\" and \"filesystem\"."`
 	DataPath  string   `yaml:"data_path" env:"SETTINGS_DATA_PATH" desc:"The directory where the filesystem storage will store ocis settings. If not definied, the root directory derives from $OCIS_BASE_DATA_PATH:/settings."`
diff --git a/services/settings/pkg/config/defaults/defaultconfig.go b/services/settings/pkg/config/defaults/defaultconfig.go
index b318c06b58c..18a6ba4ad47 100644
--- a/services/settings/pkg/config/defaults/defaultconfig.go
+++ b/services/settings/pkg/config/defaults/defaultconfig.go
@@ -5,6 +5,7 @@ import (
 	"strings"
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/defaults"
+	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
 	"github.com/owncloud/ocis/v2/services/settings/pkg/config"
 )
 
@@ -39,7 +40,7 @@ func DefaultConfig() *config.Config {
 				AllowCredentials: true,
 			},
 		},
-		GRPC: config.GRPC{
+		GRPC: config.GRPCConfig{
 			Addr:      "127.0.0.1:9191",
 			Namespace: "com.owncloud.api",
 		},
@@ -100,6 +101,22 @@ func EnsureDefaults(cfg *config.Config) {
 	if cfg.AdminUserID == "" && cfg.Commons != nil {
 		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.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
+		}
+	}
 }
 
 func Sanitize(cfg *config.Config) {
diff --git a/services/settings/pkg/config/grpc.go b/services/settings/pkg/config/grpc.go
index 1acae9e3004..37ce9714c2e 100644
--- a/services/settings/pkg/config/grpc.go
+++ b/services/settings/pkg/config/grpc.go
@@ -1,7 +1,10 @@
 package config
 
-// GRPC defines the available grpc configuration.
-type GRPC struct {
-	Addr      string `yaml:"addr" env:"SETTINGS_GRPC_ADDR" desc:"The bind address of the GRPC service."`
-	Namespace string `yaml:"-"`
+import "github.com/owncloud/ocis/v2/ocis-pkg/shared"
+
+// GRPCConfig defines the available grpc configuration.
+type GRPCConfig struct {
+	Addr      string                 `yaml:"addr" env:"SETTINGS_GRPC_ADDR" desc:"The bind address of the GRPC service."`
+	Namespace string                 `yaml:"-"`
+	TLS       *shared.GRPCServiceTLS `yaml:"tls"`
 }
diff --git a/services/settings/pkg/server/grpc/server.go b/services/settings/pkg/server/grpc/server.go
index 937f8d2e2cf..7e448ee62dc 100644
--- a/services/settings/pkg/server/grpc/server.go
+++ b/services/settings/pkg/server/grpc/server.go
@@ -16,7 +16,12 @@ import (
 func Server(opts ...Option) grpc.Service {
 	options := newOptions(opts...)
 
-	service := grpc.NewService(
+	service, err := grpc.NewService(
+		grpc.TLSEnabled(options.Config.GRPC.TLS.Enabled),
+		grpc.TLSCert(
+			options.Config.GRPC.TLS.Cert,
+			options.Config.GRPC.TLS.Key,
+		),
 		grpc.Logger(options.Logger),
 		grpc.Name(options.Name),
 		grpc.Version(version.GetString()),
@@ -25,6 +30,9 @@ func Server(opts ...Option) grpc.Service {
 		grpc.Context(options.Context),
 		grpc.Flags(options.Flags...),
 	)
+	if err != nil {
+		options.Logger.Fatal().Err(err).Msg("Error creating settings service")
+	}
 
 	handle := svc.NewService(options.Config, options.Logger)
 	if err := settingssvc.RegisterBundleServiceHandler(service.Server(), handle); err != nil {
diff --git a/services/sharing/pkg/config/config.go b/services/sharing/pkg/config/config.go
index 83e11bb048e..475ad0f09d8 100644
--- a/services/sharing/pkg/config/config.go
+++ b/services/sharing/pkg/config/config.go
@@ -55,12 +55,10 @@ type Debug struct {
 }
 
 type GRPCConfig struct {
-	Addr       string `yaml:"addr" env:"SHARING_GRPC_ADDR" desc:"The bind address of the GRPC service."`
-	TLSEnabled bool   `yaml:"tls_enabled" env:"OCIS_GRPC_TLS_ENABLED"`
-	TLSCert    string `yaml:"tls_cert" env:"OCIS_GRPC_TLS_CERTIFICATE" desc:"Path/File name of the TLS server certificate (in PEM format) for the reva grpc services."`
-	TLSKey     string `yaml:"tls_key" env:"OCIS_GRPC_TLS_KEY" desc:"Path/File name for the TLS certificate key (in PEM format) for the server certificate."`
-	Namespace  string `yaml:"-"`
-	Protocol   string `yaml:"protocol" env:"SHARING_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
+	Addr      string                 `yaml:"addr" env:"SHARING_GRPC_ADDR" desc:"The bind address of the GRPC service."`
+	TLS       *shared.GRPCServiceTLS `yaml:"tls"`
+	Namespace string                 `yaml:"-"`
+	Protocol  string                 `yaml:"protocol" env:"SHARING_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
 }
 
 type UserSharingDrivers struct {
diff --git a/services/sharing/pkg/config/defaults/defaultconfig.go b/services/sharing/pkg/config/defaults/defaultconfig.go
index cbf0cd12201..5049e1d8eae 100644
--- a/services/sharing/pkg/config/defaults/defaultconfig.go
+++ b/services/sharing/pkg/config/defaults/defaultconfig.go
@@ -101,9 +101,8 @@ func EnsureDefaults(cfg *config.Config) {
 
 	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
 		cfg.Reva = &shared.Reva{
-			Address:   cfg.Commons.Reva.Address,
-			TLSMode:   cfg.Commons.Reva.TLSMode,
-			TLSCACert: cfg.Commons.Reva.TLSCACert,
+			Address: cfg.Commons.Reva.Address,
+			TLS:     cfg.Commons.Reva.TLS,
 		}
 	} else if cfg.Reva == nil {
 		cfg.Reva = &shared.Reva{}
@@ -117,6 +116,15 @@ 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.UserSharingDrivers.CS3.SystemUserAPIKey == "" && cfg.Commons != nil && cfg.Commons.SystemUserAPIKey != "" {
 		cfg.UserSharingDrivers.CS3.SystemUserAPIKey = cfg.Commons.SystemUserAPIKey
 	}
diff --git a/services/sharing/pkg/revaconfig/config.go b/services/sharing/pkg/revaconfig/config.go
index cfef6b52040..eb24939c873 100644
--- a/services/sharing/pkg/revaconfig/config.go
+++ b/services/sharing/pkg/revaconfig/config.go
@@ -23,9 +23,9 @@ func SharingConfigFromStruct(cfg *config.Config) map[string]interface{} {
 			"network": cfg.GRPC.Protocol,
 			"address": cfg.GRPC.Addr,
 			"tls_settings": map[string]interface{}{
-				"enabled":     cfg.GRPC.TLSEnabled,
-				"certificate": cfg.GRPC.TLSCert,
-				"key":         cfg.GRPC.TLSKey,
+				"enabled":     cfg.GRPC.TLS.Enabled,
+				"certificate": cfg.GRPC.TLS.Cert,
+				"key":         cfg.GRPC.TLS.Key,
 			},
 			// TODO build services dynamically
 			"services": map[string]interface{}{
diff --git a/services/storage-publiclink/pkg/config/config.go b/services/storage-publiclink/pkg/config/config.go
index 34d9620c56d..7a01fc0b7ea 100644
--- a/services/storage-publiclink/pkg/config/config.go
+++ b/services/storage-publiclink/pkg/config/config.go
@@ -51,12 +51,10 @@ type Debug struct {
 }
 
 type GRPCConfig struct {
-	Addr       string `yaml:"addr" env:"STORAGE_PUBLICLINK_GRPC_ADDR" desc:"The bind address of the GRPC service."`
-	TLSEnabled bool   `yaml:"tls_enabled" env:"OCIS_GRPC_TLS_ENABLED"`
-	TLSCert    string `yaml:"tls_cert" env:"OCIS_GRPC_TLS_CERTIFICATE" desc:"Path/File name of the TLS server certificate (in PEM format) for the reva grpc services."`
-	TLSKey     string `yaml:"tls_key" env:"OCIS_GRPC_TLS_KEY" desc:"Path/File name for the TLS certificate key (in PEM format) for the server certificate."`
-	Namespace  string `yaml:"-"`
-	Protocol   string `yaml:"protocol" env:"STORAGE_PUBLICLINK_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
+	Addr      string                 `yaml:"addr" env:"STORAGE_PUBLICLINK_GRPC_ADDR" desc:"The bind address of the GRPC service."`
+	TLS       *shared.GRPCServiceTLS `yaml:"tls"`
+	Namespace string                 `yaml:"-"`
+	Protocol  string                 `yaml:"protocol" env:"STORAGE_PUBLICLINK_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
 }
 
 type StorageProvider struct {
diff --git a/services/storage-publiclink/pkg/config/defaults/defaultconfig.go b/services/storage-publiclink/pkg/config/defaults/defaultconfig.go
index cdd955b3945..9497a28ed0c 100644
--- a/services/storage-publiclink/pkg/config/defaults/defaultconfig.go
+++ b/services/storage-publiclink/pkg/config/defaults/defaultconfig.go
@@ -61,9 +61,8 @@ func EnsureDefaults(cfg *config.Config) {
 
 	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
 		cfg.Reva = &shared.Reva{
-			Address:   cfg.Commons.Reva.Address,
-			TLSMode:   cfg.Commons.Reva.TLSMode,
-			TLSCACert: cfg.Commons.Reva.TLSCACert,
+			Address: cfg.Commons.Reva.Address,
+			TLS:     cfg.Commons.Reva.TLS,
 		}
 	} else if cfg.Reva == nil {
 		cfg.Reva = &shared.Reva{}
@@ -76,6 +75,15 @@ func EnsureDefaults(cfg *config.Config) {
 	} else if cfg.TokenManager == nil {
 		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
+		}
+	}
 }
 
 func Sanitize(cfg *config.Config) {
diff --git a/services/storage-publiclink/pkg/revaconfig/config.go b/services/storage-publiclink/pkg/revaconfig/config.go
index af366d76301..084195426b3 100644
--- a/services/storage-publiclink/pkg/revaconfig/config.go
+++ b/services/storage-publiclink/pkg/revaconfig/config.go
@@ -23,9 +23,9 @@ func StoragePublicLinkConfigFromStruct(cfg *config.Config) map[string]interface{
 			"network": cfg.GRPC.Protocol,
 			"address": cfg.GRPC.Addr,
 			"tls_settings": map[string]interface{}{
-				"enabled":     cfg.GRPC.TLSEnabled,
-				"certificate": cfg.GRPC.TLSCert,
-				"key":         cfg.GRPC.TLSKey,
+				"enabled":     cfg.GRPC.TLS.Enabled,
+				"certificate": cfg.GRPC.TLS.Cert,
+				"key":         cfg.GRPC.TLS.Key,
 			},
 			"interceptors": map[string]interface{}{
 				"log": map[string]interface{}{},
diff --git a/services/storage-shares/pkg/config/config.go b/services/storage-shares/pkg/config/config.go
index 5e5c7d23e6c..cd73f6241e8 100644
--- a/services/storage-shares/pkg/config/config.go
+++ b/services/storage-shares/pkg/config/config.go
@@ -53,10 +53,8 @@ type Debug struct {
 }
 
 type GRPCConfig struct {
-	Addr       string `yaml:"addr" env:"STORAGE_SHARES_GRPC_ADDR" desc:"The bind address of the GRPC service."`
-	TLSEnabled bool   `yaml:"tls_enabled" env:"OCIS_GRPC_TLS_ENABLED"`
-	TLSCert    string `yaml:"tls_cert" env:"OCIS_GRPC_TLS_CERTIFICATE" desc:"Path/File name of the TLS server certificate (in PEM format) for the reva grpc services."`
-	TLSKey     string `yaml:"tls_key" env:"OCIS_GRPC_TLS_KEY" desc:"Path/File name for the TLS certificate key (in PEM format) for the server certificate."`
-	Namespace  string `yaml:"-"`
-	Protocol   string `yaml:"protocol" env:"STORAGE_SHARES_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
+	Addr      string                 `yaml:"addr" env:"STORAGE_SHARES_GRPC_ADDR" desc:"The bind address of the GRPC service."`
+	TLS       *shared.GRPCServiceTLS `yaml:"tls"`
+	Namespace string                 `yaml:"-"`
+	Protocol  string                 `yaml:"protocol" env:"STORAGE_SHARES_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
 }
diff --git a/services/storage-shares/pkg/config/defaults/defaultconfig.go b/services/storage-shares/pkg/config/defaults/defaultconfig.go
index 0b8836200d1..dcc1d3c4f57 100644
--- a/services/storage-shares/pkg/config/defaults/defaultconfig.go
+++ b/services/storage-shares/pkg/config/defaults/defaultconfig.go
@@ -61,9 +61,8 @@ func EnsureDefaults(cfg *config.Config) {
 
 	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
 		cfg.Reva = &shared.Reva{
-			Address:   cfg.Commons.Reva.Address,
-			TLSMode:   cfg.Commons.Reva.TLSMode,
-			TLSCACert: cfg.Commons.Reva.TLSCACert,
+			Address: cfg.Commons.Reva.Address,
+			TLS:     cfg.Commons.Reva.TLS,
 		}
 	} else if cfg.Reva == nil {
 		cfg.Reva = &shared.Reva{}
@@ -76,6 +75,15 @@ func EnsureDefaults(cfg *config.Config) {
 	} else if cfg.TokenManager == nil {
 		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
+		}
+	}
 }
 
 func Sanitize(cfg *config.Config) {
diff --git a/services/storage-shares/pkg/revaconfig/config.go b/services/storage-shares/pkg/revaconfig/config.go
index cb9f9dd5c72..e230e6bc7b2 100644
--- a/services/storage-shares/pkg/revaconfig/config.go
+++ b/services/storage-shares/pkg/revaconfig/config.go
@@ -23,9 +23,9 @@ func StorageSharesConfigFromStruct(cfg *config.Config) map[string]interface{} {
 			"network": cfg.GRPC.Protocol,
 			"address": cfg.GRPC.Addr,
 			"tls_settings": map[string]interface{}{
-				"enabled":     cfg.GRPC.TLSEnabled,
-				"certificate": cfg.GRPC.TLSCert,
-				"key":         cfg.GRPC.TLSKey,
+				"enabled":     cfg.GRPC.TLS.Enabled,
+				"certificate": cfg.GRPC.TLS.Cert,
+				"key":         cfg.GRPC.TLS.Key,
 			},
 			"services": map[string]interface{}{
 				"sharesstorageprovider": map[string]interface{}{
diff --git a/services/storage-system/pkg/config/config.go b/services/storage-system/pkg/config/config.go
index eae54daec5f..65366cdc8ab 100644
--- a/services/storage-system/pkg/config/config.go
+++ b/services/storage-system/pkg/config/config.go
@@ -56,12 +56,10 @@ type Debug struct {
 }
 
 type GRPCConfig struct {
-	Addr       string `yaml:"addr" env:"STORAGE_SYSTEM_GRPC_ADDR" desc:"The bind address of the GRPC service."`
-	TLSEnabled bool   `yaml:"tls_enabled" env:"OCIS_GRPC_TLS_ENABLED"`
-	TLSCert    string `yaml:"tls_cert" env:"OCIS_GRPC_TLS_CERTIFICATE" desc:"Path/File name of the TLS server certificate (in PEM format) for the reva grpc services."`
-	TLSKey     string `yaml:"tls_key" env:"OCIS_GRPC_TLS_KEY" desc:"Path/File name for the TLS certificate key (in PEM format) for the server certificate."`
-	Namespace  string `yaml:"-"`
-	Protocol   string `yaml:"protocol" env:"STORAGE_SYSTEM_GRPC_PROTOCOL" desc:"The transport protocol of the GPRC service."`
+	Addr      string                 `yaml:"addr" env:"STORAGE_SYSTEM_GRPC_ADDR" desc:"The bind address of the GRPC service."`
+	TLS       *shared.GRPCServiceTLS `yaml:"tls"`
+	Namespace string                 `yaml:"-"`
+	Protocol  string                 `yaml:"protocol" env:"STORAGE_SYSTEM_GRPC_PROTOCOL" desc:"The transport protocol of the GPRC service."`
 }
 
 type HTTPConfig struct {
diff --git a/services/storage-system/pkg/config/defaults/defaultconfig.go b/services/storage-system/pkg/config/defaults/defaultconfig.go
index c8738826160..9b420bdbfc1 100644
--- a/services/storage-system/pkg/config/defaults/defaultconfig.go
+++ b/services/storage-system/pkg/config/defaults/defaultconfig.go
@@ -73,9 +73,8 @@ func EnsureDefaults(cfg *config.Config) {
 
 	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
 		cfg.Reva = &shared.Reva{
-			Address:   cfg.Commons.Reva.Address,
-			TLSMode:   cfg.Commons.Reva.TLSMode,
-			TLSCACert: cfg.Commons.Reva.TLSCACert,
+			Address: cfg.Commons.Reva.Address,
+			TLS:     cfg.Commons.Reva.TLS,
 		}
 	} else if cfg.Reva == nil {
 		cfg.Reva = &shared.Reva{}
@@ -97,6 +96,15 @@ 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
+		}
+	}
+
 }
 
 func Sanitize(cfg *config.Config) {
diff --git a/services/storage-system/pkg/revaconfig/config.go b/services/storage-system/pkg/revaconfig/config.go
index 56534c54263..82b6a0ad3a9 100644
--- a/services/storage-system/pkg/revaconfig/config.go
+++ b/services/storage-system/pkg/revaconfig/config.go
@@ -24,9 +24,9 @@ func StorageSystemFromStruct(cfg *config.Config) map[string]interface{} {
 			"network": cfg.GRPC.Protocol,
 			"address": cfg.GRPC.Addr,
 			"tls_settings": map[string]interface{}{
-				"enabled":     cfg.GRPC.TLSEnabled,
-				"certificate": cfg.GRPC.TLSCert,
-				"key":         cfg.GRPC.TLSKey,
+				"enabled":     cfg.GRPC.TLS.Enabled,
+				"certificate": cfg.GRPC.TLS.Cert,
+				"key":         cfg.GRPC.TLS.Key,
 			},
 			"services": map[string]interface{}{
 				"gateway": map[string]interface{}{
diff --git a/services/storage-users/pkg/config/config.go b/services/storage-users/pkg/config/config.go
index e348a76351e..c98c4b0944f 100644
--- a/services/storage-users/pkg/config/config.go
+++ b/services/storage-users/pkg/config/config.go
@@ -60,12 +60,10 @@ type Debug struct {
 }
 
 type GRPCConfig struct {
-	Addr       string `yaml:"addr" env:"STORAGE_USERS_GRPC_ADDR" desc:"The bind address of the GRPC service."`
-	TLSEnabled bool   `yaml:"tls_enabled" env:"OCIS_GRPC_TLS_ENABLED"`
-	TLSCert    string `yaml:"tls_cert" env:"OCIS_GRPC_TLS_CERTIFICATE" desc:"Path/File name of the TLS server certificate (in PEM format) for the reva grpc services."`
-	TLSKey     string `yaml:"tls_key" env:"OCIS_GRPC_TLS_KEY" desc:"Path/File name for the TLS certificate key (in PEM format) for the server certificate."`
-	Namespace  string `yaml:"-"`
-	Protocol   string `yaml:"protocol" env:"STORAGE_USERS_GRPC_PROTOCOL" desc:"The transport protocol of the GPRC service."`
+	Addr      string                 `yaml:"addr" env:"STORAGE_USERS_GRPC_ADDR" desc:"The bind address of the GRPC service."`
+	TLS       *shared.GRPCServiceTLS `yaml:"tls"`
+	Namespace string                 `yaml:"-"`
+	Protocol  string                 `yaml:"protocol" env:"STORAGE_USERS_GRPC_PROTOCOL" desc:"The transport protocol of the GPRC service."`
 }
 
 type HTTPConfig struct {
diff --git a/services/storage-users/pkg/config/defaults/defaultconfig.go b/services/storage-users/pkg/config/defaults/defaultconfig.go
index fa0796d288f..9fbd3e0fa14 100644
--- a/services/storage-users/pkg/config/defaults/defaultconfig.go
+++ b/services/storage-users/pkg/config/defaults/defaultconfig.go
@@ -111,9 +111,8 @@ func EnsureDefaults(cfg *config.Config) {
 
 	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
 		cfg.Reva = &shared.Reva{
-			Address:   cfg.Commons.Reva.Address,
-			TLSMode:   cfg.Commons.Reva.TLSMode,
-			TLSCACert: cfg.Commons.Reva.TLSCACert,
+			Address: cfg.Commons.Reva.Address,
+			TLS:     cfg.Commons.Reva.TLS,
 		}
 	} else if cfg.Reva == nil {
 		cfg.Reva = &shared.Reva{}
@@ -126,6 +125,15 @@ func EnsureDefaults(cfg *config.Config) {
 	} else if cfg.TokenManager == nil {
 		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
+		}
+	}
 }
 
 func Sanitize(cfg *config.Config) {
diff --git a/services/storage-users/pkg/revaconfig/config.go b/services/storage-users/pkg/revaconfig/config.go
index 81d542fd180..fa225fd7d6f 100644
--- a/services/storage-users/pkg/revaconfig/config.go
+++ b/services/storage-users/pkg/revaconfig/config.go
@@ -23,9 +23,9 @@ func StorageUsersConfigFromStruct(cfg *config.Config) map[string]interface{} {
 			"network": cfg.GRPC.Protocol,
 			"address": cfg.GRPC.Addr,
 			"tls_settings": map[string]interface{}{
-				"enabled":     cfg.GRPC.TLSEnabled,
-				"certificate": cfg.GRPC.TLSCert,
-				"key":         cfg.GRPC.TLSKey,
+				"enabled":     cfg.GRPC.TLS.Enabled,
+				"certificate": cfg.GRPC.TLS.Cert,
+				"key":         cfg.GRPC.TLS.Key,
 			},
 			// TODO build services dynamically
 			"services": map[string]interface{}{
diff --git a/services/storage-users/pkg/revaconfig/user.go b/services/storage-users/pkg/revaconfig/user.go
index f3dd247f35d..1d1899f3050 100644
--- a/services/storage-users/pkg/revaconfig/user.go
+++ b/services/storage-users/pkg/revaconfig/user.go
@@ -95,7 +95,7 @@ func UserDrivers(cfg *config.Config) map[string]interface{} {
 			"treetime_accounting":         true,
 			"treesize_accounting":         true,
 			"permissionssvc":              cfg.Drivers.OCIS.PermissionsEndpoint,
-			"permissionssvc_tls_mode":     "off",
+			"permissionssvc_tls_mode":     cfg.Commons.GRPCClientTLS.Mode,
 		},
 		"s3": map[string]interface{}{
 			"enable_home": false,
@@ -115,7 +115,7 @@ func UserDrivers(cfg *config.Config) map[string]interface{} {
 			"treetime_accounting":         true,
 			"treesize_accounting":         true,
 			"permissionssvc":              cfg.Drivers.S3NG.PermissionsEndpoint,
-			"permissionssvc_tls_mode":     "off",
+			"permissionssvc_tls_mode":     cfg.Commons.GRPCClientTLS.Mode,
 			"s3.region":                   cfg.Drivers.S3NG.Region,
 			"s3.access_key":               cfg.Drivers.S3NG.AccessKey,
 			"s3.secret_key":               cfg.Drivers.S3NG.SecretKey,
diff --git a/services/store/pkg/command/server.go b/services/store/pkg/command/server.go
index 76534809bb3..bf8da8f4634 100644
--- a/services/store/pkg/command/server.go
+++ b/services/store/pkg/command/server.go
@@ -7,6 +7,7 @@ import (
 	"github.com/oklog/run"
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/configlog"
+	ogrpc "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
 	"github.com/owncloud/ocis/v2/services/store/pkg/config"
 	"github.com/owncloud/ocis/v2/services/store/pkg/config/parser"
@@ -33,6 +34,10 @@ func Server(cfg *config.Config) *cli.Command {
 			if err != nil {
 				return err
 			}
+			err = ogrpc.Configure(ogrpc.GetClientOptions(cfg.GRPCClientTLS)...)
+			if err != nil {
+				return err
+			}
 
 			var (
 				gr          = run.Group{}
diff --git a/services/store/pkg/config/config.go b/services/store/pkg/config/config.go
index 2e2556ef0c6..740e3b23e51 100644
--- a/services/store/pkg/config/config.go
+++ b/services/store/pkg/config/config.go
@@ -16,7 +16,9 @@ type Config struct {
 	Log     *Log     `yaml:"log"`
 	Debug   Debug    `yaml:"debug"`
 
-	GRPC GRPC `yaml:"grpc"`
+	GRPC GRPCConfig `yaml:"grpc"`
+
+	GRPCClientTLS *shared.GRPCClientTLS `yaml:"grpc_client_tls"`
 
 	Datapath string `yaml:"data_path" env:"STORE_DATA_PATH" desc:"The directory where the filesystem storage will store ocis settings. If not definied, the root directory derives from $OCIS_BASE_DATA_PATH:/store."`
 
diff --git a/services/store/pkg/config/defaults/defaultconfig.go b/services/store/pkg/config/defaults/defaultconfig.go
index 69abdc07c87..ffd1dc0ad3c 100644
--- a/services/store/pkg/config/defaults/defaultconfig.go
+++ b/services/store/pkg/config/defaults/defaultconfig.go
@@ -4,6 +4,7 @@ import (
 	"path"
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/defaults"
+	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
 	"github.com/owncloud/ocis/v2/services/store/pkg/config"
 )
 
@@ -22,7 +23,7 @@ func DefaultConfig() *config.Config {
 			Pprof:  false,
 			Zpages: false,
 		},
-		GRPC: config.GRPC{
+		GRPC: config.GRPCConfig{
 			Addr:      "127.0.0.1:9460",
 			Namespace: "com.owncloud.api",
 		},
@@ -56,6 +57,22 @@ func EnsureDefaults(cfg *config.Config) {
 	} else if cfg.Tracing == nil {
 		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.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
+		}
+	}
 }
 
 func Sanitize(cfg *config.Config) {
diff --git a/services/store/pkg/config/grpc.go b/services/store/pkg/config/grpc.go
index 1d145619fc8..db708919349 100644
--- a/services/store/pkg/config/grpc.go
+++ b/services/store/pkg/config/grpc.go
@@ -1,7 +1,10 @@
 package config
 
-// GRPC defines the available grpc configuration.
-type GRPC struct {
-	Addr      string `yaml:"addr" env:"STORE_GRPC_ADDR" desc:"The bind address of the GRPC service."`
-	Namespace string `yaml:"-"`
+import "github.com/owncloud/ocis/v2/ocis-pkg/shared"
+
+// GRPCConfig defines the available grpc configuration.
+type GRPCConfig struct {
+	Addr      string                 `yaml:"addr" env:"STORE_GRPC_ADDR" desc:"The bind address of the GRPC service."`
+	Namespace string                 `yaml:"-"`
+	TLS       *shared.GRPCServiceTLS `yaml:"tls"`
 }
diff --git a/services/store/pkg/server/grpc/server.go b/services/store/pkg/server/grpc/server.go
index 0a3de8549d8..73783385e2d 100644
--- a/services/store/pkg/server/grpc/server.go
+++ b/services/store/pkg/server/grpc/server.go
@@ -11,7 +11,12 @@ import (
 func Server(opts ...Option) grpc.Service {
 	options := newOptions(opts...)
 
-	service := grpc.NewService(
+	service, err := grpc.NewService(
+		grpc.TLSEnabled(options.Config.GRPC.TLS.Enabled),
+		grpc.TLSCert(
+			options.Config.GRPC.TLS.Cert,
+			options.Config.GRPC.TLS.Key,
+		),
 		grpc.Namespace(options.Config.GRPC.Namespace),
 		grpc.Name(options.Config.Service.Name),
 		grpc.Version(version.GetString()),
@@ -20,6 +25,10 @@ func Server(opts ...Option) grpc.Service {
 		grpc.Logger(options.Logger),
 		grpc.Flags(options.Flags...),
 	)
+	if err != nil {
+		options.Logger.Fatal().Err(err).Msg("Error creating store service")
+		return grpc.Service{}
+	}
 
 	hdlr, err := svc.New(
 		svc.Logger(options.Logger),
diff --git a/services/thumbnails/pkg/command/server.go b/services/thumbnails/pkg/command/server.go
index c79b882ddcb..b61d351c8ad 100644
--- a/services/thumbnails/pkg/command/server.go
+++ b/services/thumbnails/pkg/command/server.go
@@ -6,6 +6,7 @@ import (
 
 	"github.com/oklog/run"
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/configlog"
+	ogrpc "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
 	"github.com/owncloud/ocis/v2/services/thumbnails/pkg/config"
 	"github.com/owncloud/ocis/v2/services/thumbnails/pkg/config/parser"
@@ -33,6 +34,10 @@ func Server(cfg *config.Config) *cli.Command {
 			if err != nil {
 				return err
 			}
+			err = ogrpc.Configure(ogrpc.GetClientOptions(cfg.GRPCClientTLS)...)
+			if err != nil {
+				return err
+			}
 
 			var (
 				gr          = run.Group{}
diff --git a/services/thumbnails/pkg/config/config.go b/services/thumbnails/pkg/config/config.go
index 24b6440b55b..76d038236d7 100644
--- a/services/thumbnails/pkg/config/config.go
+++ b/services/thumbnails/pkg/config/config.go
@@ -16,8 +16,10 @@ type Config struct {
 	Log     *Log     `yaml:"log"`
 	Debug   Debug    `yaml:"debug"`
 
-	GRPC GRPC `yaml:"grpc"`
-	HTTP HTTP `yaml:"http"`
+	GRPC GRPCConfig `yaml:"grpc"`
+	HTTP HTTP       `yaml:"http"`
+
+	GRPCClientTLS *shared.GRPCClientTLS `yaml:"grpc_client_tls"`
 
 	Thumbnail Thumbnail `yaml:"thumbnail"`
 
@@ -31,14 +33,12 @@ type FileSystemStorage struct {
 
 // Thumbnail defines the available thumbnail related configuration.
 type Thumbnail struct {
-	Resolutions          []string          `yaml:"resolutions" env:"THUMBNAILS_RESOLUTIONS" desc:"The supported target resolutions in the format WidthxHeight e.g. 32x32. You can define any resolution as required and separate multiple resolutions by blank or comma."`
-	FileSystemStorage    FileSystemStorage `yaml:"filesystem_storage"`
-	WebdavAllowInsecure  bool              `yaml:"webdav_allow_insecure" env:"OCIS_INSECURE;THUMBNAILS_WEBDAVSOURCE_INSECURE" desc:"Ignore untrusted SSL certificates when connecting to the webdav source."`
-	CS3AllowInsecure     bool              `yaml:"cs3_allow_insecure" env:"OCIS_INSECURE;THUMBNAILS_CS3SOURCE_INSECURE" desc:"Ignore untrusted SSL certificates when connecting to the CS3 source."`
-	RevaGateway          string            `yaml:"reva_gateway" env:"REVA_GATEWAY" desc:"CS3 gateway used to look up user metadata"`
-	RevaGatewayTLSMode   string            `yaml:"reva_gateway_tls_mode" env:"REVA_GATEWAY_TLS_MODE"`
-	RevaGatewayTLSCACert string            `yaml:"reva_gateway_tls_cacert" env:"REVA_GATEWAY_TLS_CACERT"`
-	FontMapFile          string            `yaml:"font_map_file" env:"THUMBNAILS_TXT_FONTMAP_FILE" desc:"The path to a font file for txt thumbnails."`
-	TransferSecret       string            `yaml:"transfer_secret" env:"THUMBNAILS_TRANSFER_TOKEN" desc:"The secret to sign JWT to download the actual thumbnail file."`
-	DataEndpoint         string            `yaml:"data_endpoint" env:"THUMBNAILS_DATA_ENDPOINT" desc:"The HTTP endpoint where the actual thumbnail file can be downloaded."`
+	Resolutions         []string          `yaml:"resolutions" env:"THUMBNAILS_RESOLUTIONS" desc:"The supported target resolutions in the format WidthxHeight e.g. 32x32. You can define any resolution as required and separate multiple resolutions by blank or comma."`
+	FileSystemStorage   FileSystemStorage `yaml:"filesystem_storage"`
+	WebdavAllowInsecure bool              `yaml:"webdav_allow_insecure" env:"OCIS_INSECURE;THUMBNAILS_WEBDAVSOURCE_INSECURE" desc:"Ignore untrusted SSL certificates when connecting to the webdav source."`
+	CS3AllowInsecure    bool              `yaml:"cs3_allow_insecure" env:"OCIS_INSECURE;THUMBNAILS_CS3SOURCE_INSECURE" desc:"Ignore untrusted SSL certificates when connecting to the CS3 source."`
+	RevaGateway         string            `yaml:"reva_gateway" env:"REVA_GATEWAY" desc:"CS3 gateway used to look up user metadata"`
+	FontMapFile         string            `yaml:"font_map_file" env:"THUMBNAILS_TXT_FONTMAP_FILE" desc:"The path to a font file for txt thumbnails."`
+	TransferSecret      string            `yaml:"transfer_secret" env:"THUMBNAILS_TRANSFER_TOKEN" desc:"The secret to sign JWT to download the actual thumbnail file."`
+	DataEndpoint        string            `yaml:"data_endpoint" env:"THUMBNAILS_DATA_ENDPOINT" desc:"The HTTP endpoint where the actual thumbnail file can be downloaded."`
 }
diff --git a/services/thumbnails/pkg/config/defaults/defaultconfig.go b/services/thumbnails/pkg/config/defaults/defaultconfig.go
index d0b2c341ef6..5ec4ed848fe 100644
--- a/services/thumbnails/pkg/config/defaults/defaultconfig.go
+++ b/services/thumbnails/pkg/config/defaults/defaultconfig.go
@@ -24,7 +24,7 @@ func DefaultConfig() *config.Config {
 			Pprof:  false,
 			Zpages: false,
 		},
-		GRPC: config.GRPC{
+		GRPC: config.GRPCConfig{
 			Addr:      "127.0.0.1:9185",
 			Namespace: "com.owncloud.api",
 		},
@@ -41,12 +41,10 @@ func DefaultConfig() *config.Config {
 			FileSystemStorage: config.FileSystemStorage{
 				RootDirectory: path.Join(defaults.BaseDataPath(), "thumbnails"),
 			},
-			WebdavAllowInsecure:  false,
-			RevaGateway:          shared.DefaultRevaConfig().Address,
-			RevaGatewayTLSMode:   shared.DefaultRevaConfig().TLSMode,
-			RevaGatewayTLSCACert: shared.DefaultRevaConfig().TLSCACert,
-			CS3AllowInsecure:     false,
-			DataEndpoint:         "http://127.0.0.1:9186/thumbnails/data",
+			WebdavAllowInsecure: false,
+			RevaGateway:         shared.DefaultRevaConfig().Address,
+			CS3AllowInsecure:    false,
+			DataEndpoint:        "http://127.0.0.1:9186/thumbnails/data",
 		},
 	}
 }
@@ -74,6 +72,22 @@ func EnsureDefaults(cfg *config.Config) {
 	} else if cfg.Tracing == nil {
 		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.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
+		}
+	}
 }
 
 func Sanitize(cfg *config.Config) {
diff --git a/services/thumbnails/pkg/config/grpc.go b/services/thumbnails/pkg/config/grpc.go
index 6852c0eb8c7..636a838e9e3 100644
--- a/services/thumbnails/pkg/config/grpc.go
+++ b/services/thumbnails/pkg/config/grpc.go
@@ -1,7 +1,10 @@
 package config
 
-// GRPC defines the available grpc configuration.
-type GRPC struct {
-	Addr      string `yaml:"addr" env:"THUMBNAILS_GRPC_ADDR" desc:"The address off the grpc service."`
-	Namespace string `yaml:"-"`
+import "github.com/owncloud/ocis/v2/ocis-pkg/shared"
+
+// GRPCConfig defines the available grpc configuration.
+type GRPCConfig struct {
+	Addr      string                 `yaml:"addr" env:"THUMBNAILS_GRPC_ADDR" desc:"The bind address of the GRPC service."`
+	Namespace string                 `yaml:"-"`
+	TLS       *shared.GRPCServiceTLS `yaml:"tls"`
 }
diff --git a/services/thumbnails/pkg/server/grpc/server.go b/services/thumbnails/pkg/server/grpc/server.go
index 0ad60848a12..a783d18fa67 100644
--- a/services/thumbnails/pkg/server/grpc/server.go
+++ b/services/thumbnails/pkg/server/grpc/server.go
@@ -15,7 +15,12 @@ import (
 func NewService(opts ...Option) grpc.Service {
 	options := newOptions(opts...)
 
-	service := grpc.NewService(
+	service, err := grpc.NewService(
+		grpc.TLSEnabled(options.Config.GRPC.TLS.Enabled),
+		grpc.TLSCert(
+			options.Config.GRPC.TLS.Cert,
+			options.Config.GRPC.TLS.Key,
+		),
 		grpc.Logger(options.Logger),
 		grpc.Namespace(options.Namespace),
 		grpc.Name(options.Name),
@@ -25,14 +30,19 @@ func NewService(opts ...Option) grpc.Service {
 		grpc.Flags(options.Flags...),
 		grpc.Version(version.GetString()),
 	)
+	if err != nil {
+		options.Logger.Fatal().Err(err).Msg("Error creating thumbnail service")
+		return grpc.Service{}
+	}
+
 	tconf := options.Config.Thumbnail
-	tm, err := pool.StringToTLSMode(tconf.RevaGatewayTLSMode)
+	tm, err := pool.StringToTLSMode(options.Config.GRPCClientTLS.Mode)
 	if err != nil {
 		options.Logger.Error().Err(err).Msg("could not get gateway client tls mode")
 		return grpc.Service{}
 	}
 	gc, err := pool.GetGatewayServiceClient(tconf.RevaGateway,
-		pool.WithTLSCACert(tconf.RevaGatewayTLSCACert),
+		pool.WithTLSCACert(options.Config.GRPCClientTLS.CACert),
 		pool.WithTLSMode(tm),
 	)
 	if err != nil {
diff --git a/services/users/pkg/config/config.go b/services/users/pkg/config/config.go
index 829b82c39e8..f109c43737d 100644
--- a/services/users/pkg/config/config.go
+++ b/services/users/pkg/config/config.go
@@ -52,12 +52,10 @@ type Debug struct {
 }
 
 type GRPCConfig struct {
-	Addr       string `yaml:"addr" env:"USERS_GRPC_ADDR" desc:"The bind address of the GRPC service."`
-	TLSEnabled bool   `yaml:"tls_enabled" env:"OCIS_GRPC_TLS_ENABLED"`
-	TLSCert    string `yaml:"tls_cert" env:"OCIS_GRPC_TLS_CERTIFICATE" desc:"Path/File name of the TLS server certificate (in PEM format) for the reva grpc services."`
-	TLSKey     string `yaml:"tls_key" env:"OCIS_GRPC_TLS_KEY" desc:"Path/File name for the TLS certificate key (in PEM format) for the server certificate."`
-	Namespace  string `yaml:"-"`
-	Protocol   string `yaml:"protocol" env:"USERS_GRPC_PROTOCOL" desc:"The transport protocol of the GPRC service."`
+	Addr      string                 `yaml:"addr" env:"USERS_GRPC_ADDR" desc:"The bind address of the GRPC service."`
+	TLS       *shared.GRPCServiceTLS `yaml:"tls"`
+	Namespace string                 `yaml:"-"`
+	Protocol  string                 `yaml:"protocol" env:"USERS_GRPC_PROTOCOL" desc:"The transport protocol of the GPRC service."`
 }
 
 type Drivers struct {
diff --git a/services/users/pkg/config/defaults/defaultconfig.go b/services/users/pkg/config/defaults/defaultconfig.go
index 615e3091312..1fe0ee094c3 100644
--- a/services/users/pkg/config/defaults/defaultconfig.go
+++ b/services/users/pkg/config/defaults/defaultconfig.go
@@ -106,9 +106,8 @@ func EnsureDefaults(cfg *config.Config) {
 
 	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
 		cfg.Reva = &shared.Reva{
-			Address:   cfg.Commons.Reva.Address,
-			TLSMode:   cfg.Commons.Reva.TLSMode,
-			TLSCACert: cfg.Commons.Reva.TLSCACert,
+			Address: cfg.Commons.Reva.Address,
+			TLS:     cfg.Commons.Reva.TLS,
 		}
 	} else if cfg.Reva == nil {
 		cfg.Reva = &shared.Reva{}
@@ -121,6 +120,15 @@ func EnsureDefaults(cfg *config.Config) {
 	} else if cfg.TokenManager == nil {
 		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
+		}
+	}
 }
 
 func Sanitize(cfg *config.Config) {
diff --git a/services/users/pkg/revaconfig/config.go b/services/users/pkg/revaconfig/config.go
index 27c7af7bd0c..aefa92432ef 100644
--- a/services/users/pkg/revaconfig/config.go
+++ b/services/users/pkg/revaconfig/config.go
@@ -23,9 +23,9 @@ func UsersConfigFromStruct(cfg *config.Config) map[string]interface{} {
 			"network": cfg.GRPC.Protocol,
 			"address": cfg.GRPC.Addr,
 			"tls_settings": map[string]interface{}{
-				"enabled":     cfg.GRPC.TLSEnabled,
-				"certificate": cfg.GRPC.TLSCert,
-				"key":         cfg.GRPC.TLSKey,
+				"enabled":     cfg.GRPC.TLS.Enabled,
+				"certificate": cfg.GRPC.TLS.Cert,
+				"key":         cfg.GRPC.TLS.Key,
 			},
 			// TODO build services dynamically
 			"services": map[string]interface{}{
diff --git a/services/webdav/pkg/command/server.go b/services/webdav/pkg/command/server.go
index 5393a453f9a..dcd4d99cec1 100644
--- a/services/webdav/pkg/command/server.go
+++ b/services/webdav/pkg/command/server.go
@@ -6,6 +6,7 @@ import (
 
 	"github.com/oklog/run"
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/configlog"
+	ogrpc "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
 	"github.com/owncloud/ocis/v2/services/webdav/pkg/config"
 	"github.com/owncloud/ocis/v2/services/webdav/pkg/config/parser"
@@ -32,6 +33,10 @@ func Server(cfg *config.Config) *cli.Command {
 			if err != nil {
 				return err
 			}
+			err = ogrpc.Configure(ogrpc.GetClientOptions(cfg.GRPCClientTLS)...)
+			if err != nil {
+				return err
+			}
 
 			var (
 				gr          = run.Group{}
diff --git a/services/webdav/pkg/config/config.go b/services/webdav/pkg/config/config.go
index 0803a1174c4..e002f9dcec2 100644
--- a/services/webdav/pkg/config/config.go
+++ b/services/webdav/pkg/config/config.go
@@ -16,6 +16,8 @@ type Config struct {
 	Log     *Log     `yaml:"log"`
 	Debug   Debug    `yaml:"debug"`
 
+	GRPCClientTLS *shared.GRPCClientTLS `yaml:"grpc_client_tls"`
+
 	HTTP HTTP `yaml:"http"`
 
 	OcisPublicURL        string          `yaml:"ocis_public_url" env:"OCIS_URL;OCIS_PUBLIC_URL" desc:"URL, where oCIS is reachable for users."`
diff --git a/services/webdav/pkg/config/defaults/defaultconfig.go b/services/webdav/pkg/config/defaults/defaultconfig.go
index ae6adb85a5d..5c6c46742a8 100644
--- a/services/webdav/pkg/config/defaults/defaultconfig.go
+++ b/services/webdav/pkg/config/defaults/defaultconfig.go
@@ -36,11 +36,9 @@ func DefaultConfig() *config.Config {
 		Service: config.Service{
 			Name: "webdav",
 		},
-		OcisPublicURL:        "https://127.0.0.1:9200",
-		WebdavNamespace:      "/users/{{.Id.OpaqueId}}",
-		RevaGateway:          shared.DefaultRevaConfig().Address,
-		RevaGatewayTLSMode:   shared.DefaultRevaConfig().TLSMode,
-		RevaGatewayTLSCACert: shared.DefaultRevaConfig().TLSCACert,
+		OcisPublicURL:   "https://127.0.0.1:9200",
+		WebdavNamespace: "/users/{{.Id.OpaqueId}}",
+		RevaGateway:     shared.DefaultRevaConfig().Address,
 	}
 }
 
@@ -67,6 +65,14 @@ func EnsureDefaults(cfg *config.Config) {
 	} else if cfg.Tracing == nil {
 		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
+		}
+	}
 }
 
 func Sanitize(cfg *config.Config) {
diff --git a/services/webdav/pkg/service/v0/service.go b/services/webdav/pkg/service/v0/service.go
index ccd5bfe960d..1d51ad1ea6d 100644
--- a/services/webdav/pkg/service/v0/service.go
+++ b/services/webdav/pkg/service/v0/service.go
@@ -60,12 +60,12 @@ func NewService(opts ...Option) (Service, error) {
 	// chi.RegisterMethod("REPORT")
 	m.Use(options.Middleware...)
 
-	tm, err := pool.StringToTLSMode(conf.RevaGatewayTLSMode)
+	tm, err := pool.StringToTLSMode(conf.GRPCClientTLS.Mode)
 	if err != nil {
 		return nil, err
 	}
 	gwc, err := pool.GetGatewayServiceClient(conf.RevaGateway,
-		pool.WithTLSCACert(conf.RevaGatewayTLSCACert),
+		pool.WithTLSCACert(conf.GRPCClientTLS.CACert),
 		pool.WithTLSMode(tm),
 	)
 	if err != nil {


Test patch:
diff --git a/services/graph/pkg/service/v0/drives_test.go b/services/graph/pkg/service/v0/drives_test.go
index 954b24c4ccc..ac18991b473 100644
--- a/services/graph/pkg/service/v0/drives_test.go
+++ b/services/graph/pkg/service/v0/drives_test.go
@@ -7,6 +7,7 @@ import (
 	"github.com/CiscoM31/godata"
 	libregraph "github.com/owncloud/libre-graph-api-go"
 	"github.com/stretchr/testify/assert"
+	"github.com/test-go/testify/require"
 )
 
 type sortTest struct {
@@ -121,3 +122,35 @@ func TestSort(t *testing.T) {
 		assert.Equal(t, test.DrivesSorted, sorted)
 	}
 }
+
+func TestSpaceNameValidation(t *testing.T) {
+	// set max length
+	_maxSpaceNameLength = 10
+
+	testCases := []struct {
+		Alias         string
+		SpaceName     string
+		ExpectedError error
+	}{
+		{"Happy Path", "Space", nil},
+		{"Just not too Long", "abcdefghij", nil},
+		{"Too Long", "abcdefghijk", ErrNameTooLong},
+		{"Empty", "", ErrNameEmpty},
+		{"Contains /", "Space/", ErrForbiddenCharacter},
+		{`Contains \`, `Space\`, ErrForbiddenCharacter},
+		{`Contains \\`, `Space\\`, ErrForbiddenCharacter},
+		{"Contains .", "Space.", ErrForbiddenCharacter},
+		{"Contains :", "Space:", ErrForbiddenCharacter},
+		{"Contains ?", "Sp?ace", ErrForbiddenCharacter},
+		{"Contains *", "Spa*ce", ErrForbiddenCharacter},
+		{`Contains "`, `"Space"`, ErrForbiddenCharacter},
+		{`Contains >`, `Sp>ce`, ErrForbiddenCharacter},
+		{`Contains <`, `S<pce`, ErrForbiddenCharacter},
+		{`Contains |`, `S|p|e`, ErrForbiddenCharacter},
+	}
+
+	for _, tc := range testCases {
+		err := validateSpaceName(tc.SpaceName)
+		require.Equal(t, tc.ExpectedError, err, tc.Alias)
+	}
+}
diff --git a/services/graph/pkg/service/v0/graph_test.go b/services/graph/pkg/service/v0/graph_test.go
index ca7e0087f89..6eff1f2da10 100644
--- a/services/graph/pkg/service/v0/graph_test.go
+++ b/services/graph/pkg/service/v0/graph_test.go
@@ -17,6 +17,7 @@ import (
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
 	libregraph "github.com/owncloud/libre-graph-api-go"
+	ogrpc "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
 	"github.com/owncloud/ocis/v2/services/graph/mocks"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/config"
@@ -41,7 +42,9 @@ var _ = Describe("Graph", func() {
 		cfg.Identity.LDAP.CACert = "" // skip the startup checks, we don't use LDAP at all in this tests
 		cfg.TokenManager.JWTSecret = "loremipsum"
 		cfg.Commons = &shared.Commons{}
+		cfg.GRPCClientTLS = &shared.GRPCClientTLS{}
 
+		_ = ogrpc.Configure(ogrpc.GetClientOptions(cfg.GRPCClientTLS)...)
 		gatewayClient = &mocks.GatewayClient{}
 		eventsPublisher = mocks.Publisher{}
 		svc = service.NewService(