Repository: owncloud/ocis
Pull request #4962 (2022-11-03 06:03:57)

Bump github.com/go-micro/plugins/v4/wrapper/breaker/gobreaker from 1.1.0 to 1.2.0
Bumps [github.com/go-micro/plugins/v4/wrapper/breaker/gobreaker](https://github.com/go-micro/plugins) from 1.1.0 to 1.2.0.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a href="https://github.com/go-micro/plugins/compare/v3/auth/jwt/v1.1.0...v4/auth/jwt/v1.2.0">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/go-micro/plugins/v4/wrapper/breaker/gobreaker&package-manager=go_modules&previous-version=1.1.0&new-version=1.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>

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

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=4962)

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

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=4962&metric=coverage&view=list) No Coverage information  
[![No Duplication information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/NoDuplicationInfo-16px.png 'No Duplication information')](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=4962&metric=duplicated_lines_density&view=list) No Duplication information



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 77cfdeebc91..d4af401f406 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)
@@ -44,6 +44,7 @@ The following sections list the changes for unreleased.
 * Enhancement - Add thumbnails support for tiff and bmp files: [#4634](https://github.com/owncloud/ocis/pull/4634)
 * Enhancement - Update reva: [#4588](https://github.com/owncloud/ocis/pull/4588)
 * Enhancement - Update ownCloud Web to v6.0.0-rc.2: [#4786](https://github.com/owncloud/ocis/pull/4786)
+* Enhancement - Validate space names: [#4955](https://github.com/owncloud/ocis/pull/4955)
 * Enhancement - Make it possible to configure a WOPI folderurl: [#4716](https://github.com/owncloud/ocis/pull/4716)
 
 ## Details
@@ -277,11 +278,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)
 
@@ -414,6 +417,15 @@ The following sections list the changes for unreleased.
    https://github.com/owncloud/ocis/pull/4786
    https://github.com/owncloud/web/releases/tag/v6.0.0-rc.2
 
+* Enhancement - Validate space names: [#4955](https://github.com/owncloud/ocis/pull/4955)
+
+   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
+
 * Enhancement - Make it possible to configure a WOPI folderurl: [#4716](https://github.com/owncloud/ocis/pull/4716)
 
    The wopi folder URL is used to jump back from an application to the containing folder in the files
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/go.mod b/go.mod
index cedba04c94a..14fe395f112 100644
--- a/go.mod
+++ b/go.mod
@@ -29,7 +29,7 @@ require (
 	github.com/go-micro/plugins/v4/registry/nats v1.1.0
 	github.com/go-micro/plugins/v4/server/grpc v1.1.1
 	github.com/go-micro/plugins/v4/server/http v1.1.1
-	github.com/go-micro/plugins/v4/wrapper/breaker/gobreaker v1.1.0
+	github.com/go-micro/plugins/v4/wrapper/breaker/gobreaker v1.2.0
 	github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus v1.2.0
 	github.com/go-micro/plugins/v4/wrapper/trace/opencensus v1.1.0
 	github.com/go-ozzo/ozzo-validation/v4 v4.3.0
diff --git a/go.sum b/go.sum
index 4a39872bbfb..e48219ed27d 100644
--- a/go.sum
+++ b/go.sum
@@ -499,8 +499,8 @@ github.com/go-micro/plugins/v4/store/nats-js v1.1.0/go.mod h1:jJf7Gm39OafZlT3s3U
 github.com/go-micro/plugins/v4/store/redis v1.1.0 h1:QWl5FAfMaekppZGNcj0mSyi8vCkjZGvHoGdaBNeKNm4=
 github.com/go-micro/plugins/v4/store/redis v1.1.0/go.mod h1:yXFv4vhmr1ccxRfHxvuSetIBZDOJvRA404PZk5z6/bc=
 github.com/go-micro/plugins/v4/transport/grpc v1.1.0 h1:mXfDYfFQLnVDzjGY3o84oe4prfux9h8txsnA19dKsj8=
-github.com/go-micro/plugins/v4/wrapper/breaker/gobreaker v1.1.0 h1:X+j/pAJV9sfOYzMrjMDYdtAKiJ1vozw8p98ZsBDmVAc=
-github.com/go-micro/plugins/v4/wrapper/breaker/gobreaker v1.1.0/go.mod h1:+Z5TSrTYBaoruuGsgqpzjK/Jc2pnRF5nV5sMwmjqTM4=
+github.com/go-micro/plugins/v4/wrapper/breaker/gobreaker v1.2.0 h1:EQj4l7fuOSz8ueUYhFlpZPp9+tN4JeONL32ARRKXW/U=
+github.com/go-micro/plugins/v4/wrapper/breaker/gobreaker v1.2.0/go.mod h1:JR9Ox/iJIrcXm8nCWdAEBsyG7Q7lyMLzsTZPfXrqvwo=
 github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus v1.2.0 h1:UWBUYtMXCxQ9bIGOYcbLOjtPv8ovvCRjWWM6tHhB4S8=
 github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus v1.2.0/go.mod h1:8BYxs/wEE4ZJayHZQffw4A8s9rcPumyoNms0hYoNocM=
 github.com/go-micro/plugins/v4/wrapper/trace/opencensus v1.1.0 h1:ITm1vEP8BPEccWFAu6/tMFHrxHfwYzE4GdkCy6PlF6A=
diff --git a/ocis-pkg/config/config.go b/ocis-pkg/config/config.go
index 6f03ade4466..968019372a7 100644
--- a/ocis-pkg/config/config.go
+++ b/ocis-pkg/config/config.go
@@ -56,9 +56,12 @@ 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"`
+	HTTPServiceTLS shared.HTTPServiceTLS  `yaml:"http_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..aa25038dd87 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,16 @@ 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
+	}
+
+	cfg.Commons.HTTPServiceTLS = cfg.HTTPServiceTLS
+
 	// copy token manager to the commons part if set
 	if cfg.TokenManager != nil {
 		cfg.Commons.TokenManager = cfg.TokenManager
diff --git a/ocis-pkg/crypto/gencert.go b/ocis-pkg/crypto/gencert.go
index 581f14e68e0..6787f9890bf 100644
--- a/ocis-pkg/crypto/gencert.go
+++ b/ocis-pkg/crypto/gencert.go
@@ -4,6 +4,7 @@ import (
 	"crypto/ecdsa"
 	"crypto/rand"
 	"crypto/rsa"
+	"crypto/tls"
 	"crypto/x509"
 	"encoding/pem"
 	"fmt"
@@ -12,6 +13,7 @@ import (
 	"path/filepath"
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/log"
+	mtls "go-micro.dev/v4/util/tls"
 )
 
 var (
@@ -50,6 +52,16 @@ func GenCert(certName string, keyName string, l log.Logger) error {
 	return nil
 }
 
+// GenTempCertForAddr generates temporary TLS-Certificates in memory.
+func GenTempCertForAddr(addr string) (tls.Certificate, error) {
+	subjects := defaultHosts
+
+	if host, _, err := net.SplitHostPort(addr); err == nil && host != "" {
+		subjects = []string{host}
+	}
+	return mtls.Certificate(subjects...)
+}
+
 // persistCertificate generates a certificate using pk as private key and proceeds to store it into a file named certName.
 func persistCertificate(certName string, l log.Logger, pk interface{}) error {
 	if err := ensureExistsDir(certName); err != nil {
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..823ad5430ac 100644
--- a/ocis-pkg/service/grpc/service.go
+++ b/ocis-pkg/service/grpc/service.go
@@ -1,54 +1,56 @@
 package grpc
 
 import (
+	"crypto/tls"
+	"fmt"
 	"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"
+	ociscrypto "github.com/owncloud/ocis/v2/ocis-pkg/crypto"
 	"github.com/owncloud/ocis/v2/ocis-pkg/registry"
 	"go-micro.dev/v4"
-	"go-micro.dev/v4/client"
+	"go-micro.dev/v4/server"
 )
 
-// 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.
+			cert, err = ociscrypto.GenTempCertForAddr(sopts.Address)
+			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 +67,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/service/http/option.go b/ocis-pkg/service/http/option.go
index 8176187205e..6f533c00dcb 100644
--- a/ocis-pkg/service/http/option.go
+++ b/ocis-pkg/service/http/option.go
@@ -2,10 +2,10 @@ package http
 
 import (
 	"context"
-	"crypto/tls"
 	"net/http"
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/log"
+	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
 	"github.com/urfave/cli/v2"
 )
 
@@ -15,7 +15,7 @@ type Option func(o *Options)
 // Options defines the available options for this package.
 type Options struct {
 	Logger    log.Logger
-	TLSConfig *tls.Config
+	TLSConfig shared.HTTPServiceTLS
 	Namespace string
 	Name      string
 	Version   string
@@ -88,7 +88,7 @@ func Flags(flags ...cli.Flag) Option {
 }
 
 // TLSConfig provides a function to set the TLSConfig option.
-func TLSConfig(config *tls.Config) Option {
+func TLSConfig(config shared.HTTPServiceTLS) Option {
 	return func(o *Options) {
 		o.TLSConfig = config
 	}
diff --git a/ocis-pkg/service/http/service.go b/ocis-pkg/service/http/service.go
index dfeeaee5542..cc7516ed176 100644
--- a/ocis-pkg/service/http/service.go
+++ b/ocis-pkg/service/http/service.go
@@ -1,6 +1,8 @@
 package http
 
 import (
+	"crypto/tls"
+	"fmt"
 	"strings"
 	"time"
 
@@ -8,6 +10,7 @@ import (
 	"github.com/owncloud/ocis/v2/ocis-pkg/registry"
 
 	mhttps "github.com/go-micro/plugins/v4/server/http"
+	ociscrypto "github.com/owncloud/ocis/v2/ocis-pkg/crypto"
 	"go-micro.dev/v4"
 	"go-micro.dev/v4/server"
 )
@@ -18,11 +21,42 @@ type Service struct {
 }
 
 // NewService initializes a new http service.
-func NewService(opts ...Option) Service {
+func NewService(opts ...Option) (Service, error) {
 	noopBroker := broker.NoOp{}
 	sopts := newOptions(opts...)
+	var mServer server.Server
+	if sopts.TLSConfig.Enabled {
+		var cert tls.Certificate
+		var err error
+		if sopts.TLSConfig.Cert != "" {
+			cert, err = tls.LoadX509KeyPair(sopts.TLSConfig.Cert, sopts.TLSConfig.Key)
+			if err != nil {
+				sopts.Logger.Error().Err(err).
+					Str("cert", sopts.TLSConfig.Cert).
+					Str("key", sopts.TLSConfig.Key).
+					Msg("error loading server certifcate and key")
+				return Service{}, fmt.Errorf("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.
+			sopts.Logger.Warn().Str("address", sopts.Address).
+				Msg("No server certificate configured. Generating a temporary self-signed certificate")
+			cert, err = ociscrypto.GenTempCertForAddr(sopts.Address)
+			if err != nil {
+				return Service{}, fmt.Errorf("error creating temporary self-signed certificate: %w", err)
+			}
+		}
+		tlsConfig := &tls.Config{
+			Certificates: []tls.Certificate{cert},
+		}
+		mServer = mhttps.NewServer(server.TLSConfig(tlsConfig))
+	} else {
+		mServer = mhttps.NewServer()
+	}
+
 	wopts := []micro.Option{
-		micro.Server(mhttps.NewServer(server.TLSConfig(sopts.TLSConfig))),
+		micro.Server(mServer),
 		micro.Broker(noopBroker),
 		micro.Address(sopts.Address),
 		micro.Name(strings.Join([]string{sopts.Namespace, sopts.Name}, ".")),
@@ -33,6 +67,9 @@ func NewService(opts ...Option) Service {
 		micro.RegisterTTL(time.Second * 30),
 		micro.RegisterInterval(time.Second * 10),
 	}
+	if sopts.TLSConfig.Enabled {
+		wopts = append(wopts, micro.Metadata(map[string]string{"use_tls": "true"}))
+	}
 
-	return Service{micro.NewService(wopts...)}
+	return Service{micro.NewService(wopts...)}, 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..9796caca573 100644
--- a/ocis-pkg/shared/shared_types.go
+++ b/ocis-pkg/shared/shared_types.go
@@ -31,9 +31,25 @@ 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 HTTPServiceTLS struct {
+	Enabled bool   `yaml:"enabled" env:"OCIS_HTTP_TLS_ENABLED"`
+	Cert    string `yaml:"cert" env:"OCIS_HTTP_TLS_CERTIFICATE" desc:"Path/File name of the TLS server certificate (in PEM format) for the http services."`
+	Key     string `yaml:"key" env:"OCIS_HTTP_TLS_KEY" desc:"Path/File name for the TLS certificate key (in PEM format) for the server certificate to use for the http services."`
 }
 
 type CacheStore struct {
@@ -45,15 +61,18 @@ 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"`
+	HTTPServiceTLS    HTTPServiceTLS  `yaml:"http_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..f238f21b212 100644
--- a/services/graph/pkg/config/defaults/defaultconfig.go
+++ b/services/graph/pkg/config/defaults/defaultconfig.go
@@ -113,6 +113,18 @@ 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
+		}
+	}
+
+	if cfg.Commons != nil {
+		cfg.HTTP.TLS = cfg.Commons.HTTPServiceTLS
+	}
 }
 
 func Sanitize(cfg *config.Config) {
diff --git a/services/graph/pkg/config/http.go b/services/graph/pkg/config/http.go
index 86784b67f99..ec521094c89 100644
--- a/services/graph/pkg/config/http.go
+++ b/services/graph/pkg/config/http.go
@@ -1,8 +1,11 @@
 package config
 
+import "github.com/owncloud/ocis/v2/ocis-pkg/shared"
+
 // HTTP defines the available http configuration.
 type HTTP struct {
-	Addr      string `yaml:"addr" env:"GRAPH_HTTP_ADDR" desc:"The bind address of the HTTP service."`
-	Namespace string `yaml:"-"`
-	Root      string `yaml:"root" env:"GRAPH_HTTP_ROOT" desc:"Subdirectory that serves as the root for this HTTP service."`
+	Addr      string                `yaml:"addr" env:"GRAPH_HTTP_ADDR" desc:"The bind address of the HTTP service."`
+	Namespace string                `yaml:"-"`
+	Root      string                `yaml:"root" env:"GRAPH_HTTP_ROOT" desc:"Subdirectory that serves as the root for this HTTP service."`
+	TLS       shared.HTTPServiceTLS `yaml:"tls"`
 }
diff --git a/services/graph/pkg/server/http/server.go b/services/graph/pkg/server/http/server.go
index 489e6ed8660..15851c2fe3e 100644
--- a/services/graph/pkg/server/http/server.go
+++ b/services/graph/pkg/server/http/server.go
@@ -3,6 +3,7 @@ package http
 import (
 	"crypto/tls"
 	"crypto/x509"
+	"fmt"
 	"os"
 
 	"github.com/cs3org/reva/v2/pkg/events/server"
@@ -24,7 +25,8 @@ import (
 func Server(opts ...Option) (http.Service, error) {
 	options := newOptions(opts...)
 
-	service := http.NewService(
+	service, err := http.NewService(
+		http.TLSConfig(options.Config.HTTP.TLS),
 		http.Logger(options.Logger),
 		http.Namespace(options.Config.HTTP.Namespace),
 		http.Name("graph"),
@@ -33,6 +35,12 @@ func Server(opts ...Option) (http.Service, error) {
 		http.Context(options.Context),
 		http.Flags(options.Flags...),
 	)
+	if err != nil {
+		options.Logger.Error().
+			Err(err).
+			Msg("Error initializing http service")
+		return http.Service{}, fmt.Errorf("could not initialize http service: %w", err)
+	}
 
 	var publisher events.Stream
 
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/idp/pkg/server/http/server.go b/services/idp/pkg/server/http/server.go
index 6e03aa2ab2d..68c424f4e5f 100644
--- a/services/idp/pkg/server/http/server.go
+++ b/services/idp/pkg/server/http/server.go
@@ -1,13 +1,14 @@
 package http
 
 import (
-	"crypto/tls"
+	"fmt"
 	"os"
 
 	chimiddleware "github.com/go-chi/chi/v5/middleware"
 	pkgcrypto "github.com/owncloud/ocis/v2/ocis-pkg/crypto"
 	"github.com/owncloud/ocis/v2/ocis-pkg/middleware"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/http"
+	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
 	svc "github.com/owncloud/ocis/v2/services/idp/pkg/service/v0"
 	"go-micro.dev/v4"
@@ -17,7 +18,6 @@ import (
 func Server(opts ...Option) (http.Service, error) {
 	options := newOptions(opts...)
 
-	var tlsConfig *tls.Config
 	if options.Config.HTTP.TLS {
 		_, certErr := os.Stat(options.Config.HTTP.TLSCert)
 		_, keyErr := os.Stat(options.Config.HTTP.TLSKey)
@@ -29,17 +29,9 @@ func Server(opts ...Option) (http.Service, error) {
 				os.Exit(1)
 			}
 		}
-
-		cer, err := tls.LoadX509KeyPair(options.Config.HTTP.TLSCert, options.Config.HTTP.TLSKey)
-		if err != nil {
-			options.Logger.Fatal().Err(err).Msg("Could not setup TLS")
-			os.Exit(1)
-		}
-
-		tlsConfig = &tls.Config{MinVersion: tls.VersionTLS12, Certificates: []tls.Certificate{cer}}
 	}
 
-	service := http.NewService(
+	service, err := http.NewService(
 		http.Logger(options.Logger),
 		http.Namespace(options.Config.HTTP.Namespace),
 		http.Name(options.Config.Service.Name),
@@ -47,8 +39,18 @@ func Server(opts ...Option) (http.Service, error) {
 		http.Address(options.Config.HTTP.Addr),
 		http.Context(options.Context),
 		http.Flags(options.Flags...),
-		http.TLSConfig(tlsConfig),
+		http.TLSConfig(shared.HTTPServiceTLS{
+			Enabled: options.Config.HTTP.TLS,
+			Cert:    options.Config.HTTP.TLSCert,
+			Key:     options.Config.HTTP.TLSKey,
+		}),
 	)
+	if err != nil {
+		options.Logger.Error().
+			Err(err).
+			Msg("Error initializing http service")
+		return http.Service{}, fmt.Errorf("could not initialize http service: %w", err)
+	}
 
 	handle := svc.NewService(
 		svc.Logger(options.Logger),
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..30dc68871b0 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,17 @@ 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
+		}
+	}
+	if cfg.Commons != nil {
+		cfg.HTTP.TLS = cfg.Commons.HTTPServiceTLS
+	}
 }
 
 func Sanitize(cfg *config.Config) {
diff --git a/services/ocs/pkg/config/http.go b/services/ocs/pkg/config/http.go
index a89e6180e58..4062e219523 100644
--- a/services/ocs/pkg/config/http.go
+++ b/services/ocs/pkg/config/http.go
@@ -1,11 +1,14 @@
 package config
 
+import "github.com/owncloud/ocis/v2/ocis-pkg/shared"
+
 // HTTP defines the available http configuration.
 type HTTP struct {
-	Addr      string `yaml:"addr" env:"OCS_HTTP_ADDR" desc:"The bind address of the HTTP service."`
-	Root      string `yaml:"root" env:"OCS_HTTP_ROOT" desc:"Subdirectory that serves as the root for this HTTP service."`
-	Namespace string `yaml:"-"`
-	CORS      CORS   `yaml:"cors"`
+	Addr      string                `yaml:"addr" env:"OCS_HTTP_ADDR" desc:"The bind address of the HTTP service."`
+	Root      string                `yaml:"root" env:"OCS_HTTP_ROOT" desc:"Subdirectory that serves as the root for this HTTP service."`
+	Namespace string                `yaml:"-"`
+	CORS      CORS                  `yaml:"cors"`
+	TLS       shared.HTTPServiceTLS `yaml:"tls"`
 }
 
 // CORS defines the available cors configuration.
diff --git a/services/ocs/pkg/server/http/server.go b/services/ocs/pkg/server/http/server.go
index 1f3a4b608d5..58d9525a04c 100644
--- a/services/ocs/pkg/server/http/server.go
+++ b/services/ocs/pkg/server/http/server.go
@@ -1,6 +1,8 @@
 package http
 
 import (
+	"fmt"
+
 	chimiddleware "github.com/go-chi/chi/v5/middleware"
 	"github.com/owncloud/ocis/v2/ocis-pkg/cors"
 	"github.com/owncloud/ocis/v2/ocis-pkg/middleware"
@@ -15,7 +17,8 @@ import (
 func Server(opts ...Option) (http.Service, error) {
 	options := newOptions(opts...)
 
-	service := http.NewService(
+	service, err := http.NewService(
+		http.TLSConfig(options.Config.HTTP.TLS),
 		http.Logger(options.Logger),
 		http.Name(options.Config.Service.Name),
 		http.Version(version.GetString()),
@@ -24,6 +27,12 @@ func Server(opts ...Option) (http.Service, error) {
 		http.Context(options.Context),
 		http.Flags(options.Flags...),
 	)
+	if err != nil {
+		options.Logger.Error().
+			Err(err).
+			Msg("Error initializing http service")
+		return http.Service{}, fmt.Errorf("could not initialize http service: %w", err)
+	}
 
 	handle := svc.NewService(
 		svc.Logger(options.Logger),
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..5c8823d37f9 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()
@@ -67,10 +72,13 @@ func Server(cfg *config.Config) *cli.Command {
 
 			m.BuildInfo.WithLabelValues(version.GetString()).Set(1)
 
-			rp := proxy.NewMultiHostReverseProxy(
+			rp, err := proxy.NewMultiHostReverseProxy(
 				proxy.Logger(logger),
 				proxy.Config(cfg),
 			)
+			if err != nil {
+				return fmt.Errorf("Failed to initialize reverse proxy: %w", err)
+			}
 
 			{
 				server, err := proxyHTTP.Server(
diff --git a/services/proxy/pkg/config/config.go b/services/proxy/pkg/config/config.go
index c9bce96e74d..26d3618e2d9 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"`
@@ -32,6 +33,7 @@ type Config struct {
 	AutoprovisionAccounts bool            `yaml:"auto_provision_accounts" env:"PROXY_AUTOPROVISION_ACCOUNTS" desc:"Set this to 'true' to automatically provision users that do not yet exist in the users service on-demand upon first sign-in. To use this a write-enabled libregraph user backend needs to be setup an running."`
 	EnableBasicAuth       bool            `yaml:"enable_basic_auth" env:"PROXY_ENABLE_BASIC_AUTH" desc:"Set this to true to enable 'basic authentication' (username/password)."`
 	InsecureBackends      bool            `yaml:"insecure_backends" env:"PROXY_INSECURE_BACKENDS" desc:"Disable TLS certificate validation for all HTTP backend connections."`
+	BackendHTTPSCACert    string          `yaml:"backend_https_cacert" env:"PROXY_HTTPS_CACERT" desc:"The root CA certificate used to validate TLS server certificates of https enabled backend services."`
 	AuthMiddleware        AuthMiddleware  `yaml:"auth_middleware"`
 
 	Context context.Context `yaml:"-" json:"-"`
diff --git a/services/proxy/pkg/config/defaults/defaultconfig.go b/services/proxy/pkg/config/defaults/defaultconfig.go
index 414d742270a..19585cb9d05 100644
--- a/services/proxy/pkg/config/defaults/defaultconfig.go
+++ b/services/proxy/pkg/config/defaults/defaultconfig.go
@@ -70,47 +70,47 @@ func DefaultPolicies() []config.Policy {
 			Routes: []config.Route{
 				{
 					Endpoint:    "/",
-					Backend:     "http://localhost:9100",
+					Service:     "com.owncloud.web.web",
 					Unprotected: true,
 				},
 				{
 					Endpoint:    "/.well-known/",
-					Backend:     "http://localhost:9130",
+					Service:     "com.owncloud.web.idp",
 					Unprotected: true,
 				},
 				{
 					Endpoint:    "/konnect/",
-					Backend:     "http://localhost:9130",
+					Service:     "com.owncloud.web.idp",
 					Unprotected: true,
 				},
 				{
 					Endpoint:    "/signin/",
-					Backend:     "http://localhost:9130",
+					Service:     "com.owncloud.web.idp",
 					Unprotected: true,
 				},
 				{
 					Endpoint: "/archiver",
-					Backend:  "http://localhost:9140",
+					Service:  "com.owncloud.web.frontend",
 				},
 				{
 					Type:     config.RegexRoute,
 					Endpoint: "/ocs/v[12].php/cloud/user/signing-key", // only `user/signing-key` is left in ocis-ocs
-					Backend:  "http://localhost:9110",
+					Service:  "com.owncloud.web.ocs",
 				},
 				{
 					Type:        config.RegexRoute,
 					Endpoint:    "/ocs/v[12].php/config",
-					Backend:     "http://localhost:9140",
+					Service:     "com.owncloud.web.frontend",
 					Unprotected: true,
 				},
 				{
 					Endpoint: "/ocs/",
-					Backend:  "http://localhost:9140",
+					Service:  "com.owncloud.web.frontend",
 				},
 				{
 					Type:     config.QueryRoute,
 					Endpoint: "/remote.php/?preview=1",
-					Backend:  "http://localhost:9115",
+					Service:  "com.owncloud.web.webdav",
 				},
 				// TODO the actual REPORT goes to /dav/files/{username}, which is user specific ... how would this work in a spaces world?
 				// TODO what paths are returned? the href contains the full path so it should be possible to return urls from other spaces?
@@ -119,27 +119,27 @@ func DefaultPolicies() []config.Policy {
 				{
 					Method:   "REPORT",
 					Endpoint: "/remote.php/dav/",
-					Backend:  "http://localhost:9115", // TODO use registry?
+					Service:  "com.owncloud.web.webdav",
 				},
 				{
 					Method:   "REPORT",
 					Endpoint: "/remote.php/webdav",
-					Backend:  "http://localhost:9115", // TODO use registry?
+					Service:  "com.owncloud.web.webdav",
 				},
 				{
 					Method:   "REPORT",
 					Endpoint: "/dav/spaces",
-					Backend:  "http://localhost:9115",
+					Service:  "com.owncloud.web.webdav",
 				},
 				{
 					Type:     config.QueryRoute,
 					Endpoint: "/dav/?preview=1",
-					Backend:  "http://localhost:9115",
+					Service:  "com.owncloud.web.webdav",
 				},
 				{
 					Type:     config.QueryRoute,
 					Endpoint: "/webdav/?preview=1",
-					Backend:  "http://localhost:9115",
+					Service:  "com.owncloud.web.webdav",
 				},
 				{
 					Endpoint: "/remote.php/",
@@ -173,29 +173,29 @@ func DefaultPolicies() []config.Policy {
 				},
 				{
 					Endpoint:    "/data",
-					Backend:     "http://localhost:9140",
+					Service:     "com.owncloud.web.frontend",
 					Unprotected: true,
 				},
 				{
 					Endpoint:    "/app/list",
-					Backend:     "http://localhost:9140",
+					Service:     "com.owncloud.web.frontend",
 					Unprotected: true,
 				},
 				{
 					Endpoint: "/app/", // /app or /apps? ocdav only handles /apps
-					Backend:  "http://localhost:9140",
+					Service:  "com.owncloud.web.frontend",
 				},
 				{
 					Endpoint: "/graph/",
-					Backend:  "http://localhost:9120",
+					Service:  "com.owncloud.graph.graph",
 				},
 				{
 					Endpoint: "/api/v0/settings",
-					Backend:  "http://localhost:9190",
+					Service:  "com.owncloud.web.settings",
 				},
 				{
 					Endpoint:    "/settings.js",
-					Backend:     "http://localhost:9190",
+					Service:     "com.owncloud.web.settings",
 					Unprotected: true,
 				},
 			},
@@ -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/proxy/pkg/proxy/proxy.go b/services/proxy/pkg/proxy/proxy.go
index 12b49cdb664..1642484aeb9 100644
--- a/services/proxy/pkg/proxy/proxy.go
+++ b/services/proxy/pkg/proxy/proxy.go
@@ -2,7 +2,10 @@ package proxy
 
 import (
 	"crypto/tls"
+	"crypto/x509"
+	"errors"
 	"fmt"
+	"io/ioutil"
 	"net"
 	"net/http"
 	"net/http/httputil"
@@ -33,7 +36,7 @@ type MultiHostReverseProxy struct {
 }
 
 // NewMultiHostReverseProxy creates a new MultiHostReverseProxy
-func NewMultiHostReverseProxy(opts ...Option) *MultiHostReverseProxy {
+func NewMultiHostReverseProxy(opts ...Option) (*MultiHostReverseProxy, error) {
 	options := newOptions(opts...)
 
 	rp := &MultiHostReverseProxy{
@@ -47,6 +50,20 @@ func NewMultiHostReverseProxy(opts ...Option) *MultiHostReverseProxy {
 		ri.Director()(r)
 	}
 
+	tlsConf := &tls.Config{
+		InsecureSkipVerify: options.Config.InsecureBackends, //nolint:gosec
+	}
+	if options.Config.BackendHTTPSCACert != "" {
+		certs := x509.NewCertPool()
+		pemData, err := ioutil.ReadFile(options.Config.BackendHTTPSCACert)
+		if err != nil {
+			return nil, err
+		}
+		if !certs.AppendCertsFromPEM(pemData) {
+			return nil, errors.New("Error initializing LDAP Backend. Adding CA cert failed")
+		}
+		tlsConf.RootCAs = certs
+	}
 	// equals http.DefaultTransport except TLSClientConfig
 	rp.Transport = &http.Transport{
 		Proxy: http.ProxyFromEnvironment,
@@ -60,11 +77,9 @@ func NewMultiHostReverseProxy(opts ...Option) *MultiHostReverseProxy {
 		IdleConnTimeout:       90 * time.Second,
 		TLSHandshakeTimeout:   10 * time.Second,
 		ExpectContinueTimeout: 1 * time.Second,
-		TLSClientConfig: &tls.Config{
-			InsecureSkipVerify: options.Config.InsecureBackends, //nolint:gosec
-		},
+		TLSClientConfig:       tlsConf,
 	}
-	return rp
+	return rp, nil
 }
 
 func (p *MultiHostReverseProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
diff --git a/services/proxy/pkg/router/router.go b/services/proxy/pkg/router/router.go
index d0a5959cadb..d61e99a720b 100644
--- a/services/proxy/pkg/router/router.go
+++ b/services/proxy/pkg/router/router.go
@@ -148,7 +148,9 @@ func (rt Router) addHost(policy string, target *url.URL, route config.Route) {
 				}
 				req.URL.Host = node.Address
 				req.URL.Scheme = node.Metadata["protocol"] // TODO check property exists?
-
+				if node.Metadata["use_tls"] == "true" {
+					req.URL.Scheme = "https"
+				}
 			} else {
 				req.URL.Host = target.Host
 				req.URL.Scheme = target.Scheme
diff --git a/services/proxy/pkg/server/http/server.go b/services/proxy/pkg/server/http/server.go
index 8eb8f1ba050..ce41fa33892 100644
--- a/services/proxy/pkg/server/http/server.go
+++ b/services/proxy/pkg/server/http/server.go
@@ -1,11 +1,13 @@
 package http
 
 import (
-	"crypto/tls"
+	"fmt"
 	"os"
 
 	pkgcrypto "github.com/owncloud/ocis/v2/ocis-pkg/crypto"
+	"github.com/owncloud/ocis/v2/ocis-pkg/service/http"
 	svc "github.com/owncloud/ocis/v2/ocis-pkg/service/http"
+	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
 	"github.com/owncloud/ocis/v2/ocis-pkg/version"
 	"go-micro.dev/v4"
 )
@@ -16,9 +18,6 @@ func Server(opts ...Option) (svc.Service, error) {
 	l := options.Logger
 	httpCfg := options.Config.HTTP
 
-	var cer tls.Certificate
-
-	var tlsConfig *tls.Config
 	if options.Config.HTTP.TLS {
 		l.Warn().Msgf("No tls certificate provided, using a generated one")
 		_, certErr := os.Stat(httpCfg.TLSCert)
@@ -31,27 +30,29 @@ func Server(opts ...Option) (svc.Service, error) {
 				os.Exit(1)
 			}
 		}
-
-		cer, certErr = tls.LoadX509KeyPair(httpCfg.TLSCert, httpCfg.TLSKey)
-		if certErr != nil {
-			options.Logger.Fatal().Err(certErr).Msg("Could not setup TLS")
-			os.Exit(1)
-		}
-
-		tlsConfig = &tls.Config{MinVersion: tls.VersionTLS12, Certificates: []tls.Certificate{cer}}
 	}
 	chain := options.Middlewares.Then(options.Handler)
 
-	service := svc.NewService(
+	service, err := svc.NewService(
 		svc.Name(options.Config.Service.Name),
 		svc.Version(version.GetString()),
-		svc.TLSConfig(tlsConfig),
+		http.TLSConfig(shared.HTTPServiceTLS{
+			Enabled: options.Config.HTTP.TLS,
+			Cert:    options.Config.HTTP.TLSCert,
+			Key:     options.Config.HTTP.TLSKey,
+		}),
 		svc.Logger(options.Logger),
 		svc.Address(options.Config.HTTP.Addr),
 		svc.Namespace(options.Config.HTTP.Namespace),
 		svc.Context(options.Context),
 		svc.Flags(options.Flags...),
 	)
+	if err != nil {
+		options.Logger.Error().
+			Err(err).
+			Msg("Error initializing http service")
+		return http.Service{}, fmt.Errorf("could not initialize http service: %w", err)
+	}
 
 	if err := micro.RegisterHandler(service.Server(), chain); err != nil {
 		return svc.Service{}, err
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..98f55f3f6bc 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) {
@@ -47,13 +52,19 @@ func Server(cfg *config.Config) *cli.Command {
 			mtrcs.BuildInfo.WithLabelValues(version.GetString()).Set(1)
 
 			// prepare an HTTP server and add it to the group run.
-			httpServer := http.Server(
+			httpServer, err := http.Server(
 				http.Name(cfg.Service.Name),
 				http.Logger(logger),
 				http.Context(ctx),
 				http.Config(cfg),
 				http.Metrics(mtrcs),
 			)
+			if err != nil {
+				logger.Error().
+					Err(err).
+					Msg("Error initializing http service")
+				return fmt.Errorf("could not initialize http service: %w", err)
+			}
 			servers.Add(httpServer.Run, func(_ error) {
 				logger.Info().Str("server", "http").Msg("Shutting down server")
 				cancel()
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..02c7b0bf7ff 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,26 @@ 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
+		}
+	}
+
+	if cfg.Commons != nil {
+		cfg.HTTP.TLS = cfg.Commons.HTTPServiceTLS
+	}
 }
 
 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/config/http.go b/services/settings/pkg/config/http.go
index 5749e8550f6..e43daa0cad9 100644
--- a/services/settings/pkg/config/http.go
+++ b/services/settings/pkg/config/http.go
@@ -1,12 +1,15 @@
 package config
 
+import "github.com/owncloud/ocis/v2/ocis-pkg/shared"
+
 // HTTP defines the available http configuration.
 type HTTP struct {
-	Addr      string `yaml:"addr" env:"SETTINGS_HTTP_ADDR" desc:"The bind address of the HTTP service."`
-	Namespace string `yaml:"-"`
-	Root      string `yaml:"root" env:"SETTINGS_HTTP_ROOT" desc:"Subdirectory that serves as the root for this HTTP service."`
-	CacheTTL  int    `yaml:"cache_ttl" env:"SETTINGS_CACHE_TTL" desc:"Browser cache control max-age value in seconds for settings Web UI assets."`
-	CORS      CORS   `yaml:"cors"`
+	Addr      string                `yaml:"addr" env:"SETTINGS_HTTP_ADDR" desc:"The bind address of the HTTP service."`
+	TLS       shared.HTTPServiceTLS `yaml:"tls"`
+	Namespace string                `yaml:"-"`
+	Root      string                `yaml:"root" env:"SETTINGS_HTTP_ROOT" desc:"Subdirectory that serves as the root for this HTTP service."`
+	CacheTTL  int                   `yaml:"cache_ttl" env:"SETTINGS_CACHE_TTL" desc:"Browser cache control max-age value in seconds for settings Web UI assets."`
+	CORS      CORS                  `yaml:"cors"`
 }
 
 // CORS defines the available cors configuration.
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/settings/pkg/server/http/server.go b/services/settings/pkg/server/http/server.go
index ec96b0f4d4b..fd92344ad17 100644
--- a/services/settings/pkg/server/http/server.go
+++ b/services/settings/pkg/server/http/server.go
@@ -1,6 +1,8 @@
 package http
 
 import (
+	"fmt"
+
 	"github.com/go-chi/chi/v5"
 	chimiddleware "github.com/go-chi/chi/v5/middleware"
 	"github.com/owncloud/ocis/v2/ocis-pkg/account"
@@ -15,10 +17,11 @@ import (
 )
 
 // Server initializes the http service and server.
-func Server(opts ...Option) http.Service {
+func Server(opts ...Option) (http.Service, error) {
 	options := newOptions(opts...)
 
-	service := http.NewService(
+	service, err := http.NewService(
+		http.TLSConfig(options.Config.HTTP.TLS),
 		http.Logger(options.Logger),
 		http.Name(options.Name),
 		http.Version(version.GetString()),
@@ -27,6 +30,12 @@ func Server(opts ...Option) http.Service {
 		http.Context(options.Context),
 		http.Flags(options.Flags...),
 	)
+	if err != nil {
+		options.Logger.Error().
+			Err(err).
+			Msg("Error initializing http service")
+		return http.Service{}, fmt.Errorf("could not initialize http service: %w", err)
+	}
 
 	handle := svc.NewService(options.Config, options.Logger)
 
@@ -81,5 +90,5 @@ func Server(opts ...Option) http.Service {
 
 	micro.RegisterHandler(service.Server(), mux)
 
-	return service
+	return service, 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..cc59f6affaa 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,26 @@ 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
+		}
+	}
+
+	if cfg.Commons != nil {
+		cfg.HTTP.TLS = cfg.Commons.HTTPServiceTLS
+	}
 }
 
 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/config/http.go b/services/thumbnails/pkg/config/http.go
index d01215550d4..4133b1df441 100644
--- a/services/thumbnails/pkg/config/http.go
+++ b/services/thumbnails/pkg/config/http.go
@@ -1,8 +1,11 @@
 package config
 
+import "github.com/owncloud/ocis/v2/ocis-pkg/shared"
+
 // HTTP defines the available http configuration.
 type HTTP struct {
-	Addr      string `yaml:"addr" env:"THUMBNAILS_HTTP_ADDR" desc:"The bind address of the HTTP service."`
-	Root      string `yaml:"root" env:"THUMBNAILS_HTTP_ROOT" desc:"Subdirectory that serves as the root for this HTTP service."`
-	Namespace string `yaml:"-"`
+	Addr      string                `yaml:"addr" env:"THUMBNAILS_HTTP_ADDR" desc:"The bind address of the HTTP service."`
+	TLS       shared.HTTPServiceTLS `yaml:"tls"`
+	Root      string                `yaml:"root" env:"THUMBNAILS_HTTP_ROOT" desc:"Subdirectory that serves as the root for this HTTP service."`
+	Namespace string                `yaml:"-"`
 }
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/thumbnails/pkg/server/http/server.go b/services/thumbnails/pkg/server/http/server.go
index 7f03f4080e5..4401ac681c8 100644
--- a/services/thumbnails/pkg/server/http/server.go
+++ b/services/thumbnails/pkg/server/http/server.go
@@ -1,6 +1,8 @@
 package http
 
 import (
+	"fmt"
+
 	"github.com/go-chi/chi/v5/middleware"
 	ocismiddleware "github.com/owncloud/ocis/v2/ocis-pkg/middleware"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/http"
@@ -14,7 +16,8 @@ import (
 func Server(opts ...Option) (http.Service, error) {
 	options := newOptions(opts...)
 
-	service := http.NewService(
+	service, err := http.NewService(
+		http.TLSConfig(options.Config.HTTP.TLS),
 		http.Logger(options.Logger),
 		http.Name(options.Config.Service.Name),
 		http.Version(version.GetString()),
@@ -22,6 +25,12 @@ func Server(opts ...Option) (http.Service, error) {
 		http.Address(options.Config.HTTP.Addr),
 		http.Context(options.Context),
 	)
+	if err != nil {
+		options.Logger.Error().
+			Err(err).
+			Msg("Error initializing http service")
+		return http.Service{}, fmt.Errorf("could not initialize http service: %w", err)
+	}
 
 	handle := svc.NewService(
 		svc.Logger(options.Logger),
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/web/pkg/config/defaults/defaultconfig.go b/services/web/pkg/config/defaults/defaultconfig.go
index 2ed1d41bf42..42bc08af123 100644
--- a/services/web/pkg/config/defaults/defaultconfig.go
+++ b/services/web/pkg/config/defaults/defaultconfig.go
@@ -96,6 +96,10 @@ func EnsureDefaults(cfg *config.Config) {
 	} else if cfg.Tracing == nil {
 		cfg.Tracing = &config.Tracing{}
 	}
+
+	if cfg.Commons != nil {
+		cfg.HTTP.TLS = cfg.Commons.HTTPServiceTLS
+	}
 }
 
 func Sanitize(cfg *config.Config) {
diff --git a/services/web/pkg/config/http.go b/services/web/pkg/config/http.go
index addb0fce0c1..a827ba5be27 100644
--- a/services/web/pkg/config/http.go
+++ b/services/web/pkg/config/http.go
@@ -1,9 +1,12 @@
 package config
 
+import "github.com/owncloud/ocis/v2/ocis-pkg/shared"
+
 // HTTP defines the available http configuration.
 type HTTP struct {
-	Addr      string `yaml:"addr" env:"WEB_HTTP_ADDR" desc:"The bind address of the HTTP service."`
-	Namespace string `yaml:"-"`
-	Root      string `yaml:"root" env:"WEB_HTTP_ROOT" desc:"Subdirectory that serves as the root for this HTTP service."`
-	CacheTTL  int    `yaml:"cache_ttl" env:"WEB_CACHE_TTL" desc:"Cache policy in seconds for ownCloud Web assets."`
+	Addr      string                `yaml:"addr" env:"WEB_HTTP_ADDR" desc:"The bind address of the HTTP service."`
+	TLS       shared.HTTPServiceTLS `yaml:"tls"`
+	Namespace string                `yaml:"-"`
+	Root      string                `yaml:"root" env:"WEB_HTTP_ROOT" desc:"Subdirectory that serves as the root for this HTTP service."`
+	CacheTTL  int                   `yaml:"cache_ttl" env:"WEB_CACHE_TTL" desc:"Cache policy in seconds for ownCloud Web assets."`
 }
diff --git a/services/web/pkg/server/http/server.go b/services/web/pkg/server/http/server.go
index 6984c65b44a..c36406407b6 100644
--- a/services/web/pkg/server/http/server.go
+++ b/services/web/pkg/server/http/server.go
@@ -1,6 +1,8 @@
 package http
 
 import (
+	"fmt"
+
 	chimiddleware "github.com/go-chi/chi/v5/middleware"
 	"github.com/owncloud/ocis/v2/ocis-pkg/middleware"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/http"
@@ -14,7 +16,8 @@ import (
 func Server(opts ...Option) (http.Service, error) {
 	options := newOptions(opts...)
 
-	service := http.NewService(
+	service, err := http.NewService(
+		http.TLSConfig(options.Config.HTTP.TLS),
 		http.Logger(options.Logger),
 		http.Namespace(options.Namespace),
 		http.Name("web"),
@@ -23,6 +26,12 @@ func Server(opts ...Option) (http.Service, error) {
 		http.Context(options.Context),
 		http.Flags(options.Flags...),
 	)
+	if err != nil {
+		options.Logger.Error().
+			Err(err).
+			Msg("Error initializing http service")
+		return http.Service{}, fmt.Errorf("could not initialize http service: %w", err)
+	}
 
 	handle := svc.NewService(
 		svc.Logger(options.Logger),
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..083d0a1a325 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,18 @@ 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.Commons != nil {
+		cfg.HTTP.TLS = cfg.Commons.HTTPServiceTLS
+	}
 }
 
 func Sanitize(cfg *config.Config) {
diff --git a/services/webdav/pkg/config/http.go b/services/webdav/pkg/config/http.go
index 26ba1ed1cfd..7b44da9e0de 100644
--- a/services/webdav/pkg/config/http.go
+++ b/services/webdav/pkg/config/http.go
@@ -1,5 +1,7 @@
 package config
 
+import "github.com/owncloud/ocis/v2/ocis-pkg/shared"
+
 // CORS defines the available cors configuration.
 type CORS struct {
 	AllowedOrigins   []string `yaml:"allow_origins" env:"OCIS_CORS_ALLOW_ORIGINS;WEBDAV_CORS_ALLOW_ORIGINS" desc:"A comma-separated list of allowed CORS origins. See following chapter for more details: *Access-Control-Allow-Origin* at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin"`
@@ -10,8 +12,9 @@ type CORS struct {
 
 // HTTP defines the available http configuration.
 type HTTP struct {
-	Addr      string `yaml:"addr" env:"WEBDAV_HTTP_ADDR" desc:"The bind address of the HTTP service."`
-	Namespace string `yaml:"-"`
-	Root      string `yaml:"root" env:"WEBDAV_HTTP_ROOT" desc:"Subdirectory that serves as the root for this HTTP service."`
-	CORS      CORS   `yaml:"cors"`
+	Addr      string                `yaml:"addr" env:"WEBDAV_HTTP_ADDR" desc:"The bind address of the HTTP service."`
+	Namespace string                `yaml:"-"`
+	Root      string                `yaml:"root" env:"WEBDAV_HTTP_ROOT" desc:"Subdirectory that serves as the root for this HTTP service."`
+	CORS      CORS                  `yaml:"cors"`
+	TLS       shared.HTTPServiceTLS `yaml:"tls"`
 }
diff --git a/services/webdav/pkg/server/http/server.go b/services/webdav/pkg/server/http/server.go
index f5b782507fc..02e87486679 100644
--- a/services/webdav/pkg/server/http/server.go
+++ b/services/webdav/pkg/server/http/server.go
@@ -1,6 +1,8 @@
 package http
 
 import (
+	"fmt"
+
 	chimiddleware "github.com/go-chi/chi/v5/middleware"
 	"github.com/owncloud/ocis/v2/ocis-pkg/cors"
 	"github.com/owncloud/ocis/v2/ocis-pkg/middleware"
@@ -14,7 +16,8 @@ import (
 func Server(opts ...Option) (http.Service, error) {
 	options := newOptions(opts...)
 
-	service := http.NewService(
+	service, err := http.NewService(
+		http.TLSConfig(options.Config.HTTP.TLS),
 		http.Logger(options.Logger),
 		http.Namespace(options.Config.HTTP.Namespace),
 		http.Name(options.Config.Service.Name),
@@ -23,6 +26,12 @@ func Server(opts ...Option) (http.Service, error) {
 		http.Context(options.Context),
 		http.Flags(options.Flags...),
 	)
+	if err != nil {
+		options.Logger.Error().
+			Err(err).
+			Msg("Error initializing http service")
+		return http.Service{}, fmt.Errorf("could not initialize http service: %w", err)
+	}
 
 	handle, err := svc.NewService(
 		svc.Logger(options.Logger),
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(
diff --git a/services/proxy/pkg/proxy/proxy_integration_test.go b/services/proxy/pkg/proxy/proxy_integration_test.go
index 65a8c037b8c..0f19c3a4a94 100644
--- a/services/proxy/pkg/proxy/proxy_integration_test.go
+++ b/services/proxy/pkg/proxy/proxy_integration_test.go
@@ -164,7 +164,7 @@ func TestProxyIntegration(t *testing.T) {
 }
 
 func newTestProxy(cfg *config.Config, fn RoundTripFunc) *MultiHostReverseProxy {
-	rp := NewMultiHostReverseProxy(Config(cfg))
+	rp, _ := NewMultiHostReverseProxy(Config(cfg))
 	rp.Transport = fn
 	return rp
 }