Repository: owncloud/ocis
Pull request #4121 (2022-07-06 21:31:46)

ApiTests. refactoring apiSpace suite
- "creating project space" moved to background
- many scenarios are combined into one
- added test re-sharing to the group


Patch:
diff --git a/.drone.env b/.drone.env
index 9e5e56a077e..339d19491bb 100644
--- a/.drone.env
+++ b/.drone.env
@@ -1,5 +1,5 @@
 # The test runner source for API tests
-CORE_COMMITID=15758a077c65fed9a72ed4238a8912a9e39f4547
+CORE_COMMITID=f1e0bf08b898c7300d4b294c8371f4025d9d99b8
 CORE_BRANCH=master
 
 # The test runner source for UI tests
diff --git a/.drone.star b/.drone.star
index c6c42b88602..d80e42c1c4e 100644
--- a/.drone.star
+++ b/.drone.star
@@ -17,7 +17,7 @@ OC_CI_GOLANG = "owncloudci/golang:1.18"
 OC_CI_NODEJS = "owncloudci/nodejs:%s"
 OC_CI_PHP = "owncloudci/php:%s"
 OC_CI_WAIT_FOR = "owncloudci/wait-for:latest"
-OC_CS3_API_VALIDATOR = "owncloud/cs3api-validator:latest"
+OC_CS3_API_VALIDATOR = "owncloud/cs3api-validator:0.1.0"
 OC_LITMUS = "owncloud/litmus:latest"
 OC_OC_TEST_MIDDLEWARE = "owncloud/owncloud-test-middleware:1.6.0"
 OC_SERVER = "owncloud/server:10"
@@ -620,7 +620,7 @@ def cs3ApiTests(ctx, storage, accounts_hash_difficulty = 4):
 
 def coreApiTests(ctx, part_number = 1, number_of_parts = 1, storage = "ocis", accounts_hash_difficulty = 4):
     early_fail = config["apiTests"]["earlyFail"] if "earlyFail" in config["apiTests"] else False
-    filterTags = "~@skipOnGraph&&~@skipOnOcis&&~@notToImplementOnOCIS&&~@toImplementOnOCIS&&~comments-app-required&&~@federation-app-required&&~@notifications-app-required&&~systemtags-app-required&&~@local_storage&&~@skipOnOcis-%s-Storage&&~@issue-ocis-3023" % ("OC" if storage == "owncloud" else "OCIS")
+    filterTags = "~@skipOnGraph&&~@skipOnOcis&&~@notToImplementOnOCIS&&~@toImplementOnOCIS&&~comments-app-required&&~@federation-app-required&&~@notifications-app-required&&~systemtags-app-required&&~@local_storage&&~@skipOnOcis-%s-Storage" % ("OC" if storage == "owncloud" else "OCIS")
     expectedFailuresFile = "/drone/src/tests/acceptance/expected-failures-API-on-%s-storage.md" % (storage.upper())
 
     return {
diff --git a/.github/stale.yml b/.github/stale.yml
index b42404aaad6..fc5821130e0 100644
--- a/.github/stale.yml
+++ b/.github/stale.yml
@@ -7,6 +7,7 @@ daysUntilClose: 10
 exemptLabels:
   - "Type:Bug"
   - "Type:Technical-Debt"
+  - "Category:Enhancement"
   - "Category:Research"
   - "QA:team"
 # Label to use when marking an issue as stale
diff --git a/CHANGELOG.md b/CHANGELOG.md
index de9a920e081..eaa57f900cf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,15 +7,20 @@ The following sections list the changes for unreleased.
 ## Summary
 
 * Bugfix - CSP rules for silent token refresh in iframe: [#4031](https://github.com/owncloud/ocis/pull/4031)
+* Bugfix - Fix `OCIS_RUN_SERVICES`: [#4133](https://github.com/owncloud/ocis/pull/4133)
+* Bugfix - Fix unused config option `GRAPH_SPACES_INSECURE`: [#55555](https://github.com/owncloud/ocis/pull/55555)
 * Bugfix - Remove unused configuration options: [#3973](https://github.com/owncloud/ocis/pull/3973)
 * Bugfix - Remove static ocs user backend config: [#4077](https://github.com/owncloud/ocis/pull/4077)
 * Bugfix - Fix make sensitive config values in the proxy's debug server: [#4086](https://github.com/owncloud/ocis/pull/4086)
 * Bugfix - Fix startup error logging: [#4093](https://github.com/owncloud/ocis/pull/4093)
+* Bugfix - Escape DN attribute value: [#4117](https://github.com/owncloud/ocis/pull/4117)
 * Bugfix - Polish search: [#4094](https://github.com/owncloud/ocis/pull/4094)
 * Bugfix - Store user passwords hashed in idm: [#3778](https://github.com/owncloud/ocis/issues/3778)
 * Enhancement - Add capability for alias links: [#3983](https://github.com/owncloud/ocis/issues/3983)
 * Enhancement - Update IdP UI: [#3493](https://github.com/owncloud/ocis/issues/3493)
 * Enhancement - Refactor extensions to services: [#3980](https://github.com/owncloud/ocis/pull/3980)
+* Enhancement - Update reva: [#4115](https://github.com/owncloud/ocis/pull/4115)
+* Enhancement - Search service at the old webdav endpoint: [#4118](https://github.com/owncloud/ocis/pull/4118)
 
 ## Details
 
@@ -28,6 +33,26 @@ The following sections list the changes for unreleased.
    https://github.com/owncloud/web/issues/7030
    https://github.com/owncloud/ocis/pull/4031
 
+* Bugfix - Fix `OCIS_RUN_SERVICES`: [#4133](https://github.com/owncloud/ocis/pull/4133)
+
+   `OCIS_RUN_SERVICES` was introduced as successor to `OCIS_RUN_EXTENSIONS` because we
+   wanted to call oCIS "core" extensions services. We kept `OCIS_RUN_EXTENSIONS` for backwards
+   compatibility reasons.
+
+   It turned out, that setting `OCIS_RUN_SERVICES` has no effect since introduced.
+   `OCIS_RUN_EXTENSIONS`. `OCIS_RUN_EXTENSIONS` was working fine all the time.
+
+   We now fixed `OCIS_RUN_SERVICES`, so that you can use it as a equivalent replacement for
+   `OCIS_RUN_EXTENSIONS`
+
+   https://github.com/owncloud/ocis/pull/4133
+
+* Bugfix - Fix unused config option `GRAPH_SPACES_INSECURE`: [#55555](https://github.com/owncloud/ocis/pull/55555)
+
+   We've removed the unused config option `GRAPH_SPACES_INSECURE` from the GRAPH service.
+
+   https://github.com/owncloud/ocis/pull/55555
+
 * Bugfix - Remove unused configuration options: [#3973](https://github.com/owncloud/ocis/pull/3973)
 
    We've removed multiple unused configuration options:
@@ -64,6 +89,12 @@ The following sections list the changes for unreleased.
 
    https://github.com/owncloud/ocis/pull/4093
 
+* Bugfix - Escape DN attribute value: [#4117](https://github.com/owncloud/ocis/pull/4117)
+
+   Escaped the DN attribute value on creating users and groups.
+
+   https://github.com/owncloud/ocis/pull/4117
+
 * Bugfix - Polish search: [#4094](https://github.com/owncloud/ocis/pull/4094)
 
    We improved the feedback when providing invalid search queries and added support for limiting
@@ -102,6 +133,16 @@ The following sections list the changes for unreleased.
    to avoid confusion between external extensions and code we provide and maintain.
 
    https://github.com/owncloud/ocis/pull/3980
+
+* Enhancement - Update reva: [#4115](https://github.com/owncloud/ocis/pull/4115)
+
+   https://github.com/owncloud/ocis/pull/4115
+
+* Enhancement - Search service at the old webdav endpoint: [#4118](https://github.com/owncloud/ocis/pull/4118)
+
+   We made the search service available for legacy clients at the old webdav endpoint.
+
+   https://github.com/owncloud/ocis/pull/4118
 # Changelog for [2.0.0-beta.4] (2022-06-28)
 
 The following sections list the changes for 2.0.0-beta.4.
diff --git a/changelog/unreleased/fix-ocis-run-services.md b/changelog/unreleased/fix-ocis-run-services.md
new file mode 100644
index 00000000000..6b6f07d7e4d
--- /dev/null
+++ b/changelog/unreleased/fix-ocis-run-services.md
@@ -0,0 +1,12 @@
+Bugfix: Fix `OCIS_RUN_SERVICES`
+
+`OCIS_RUN_SERVICES` was introduced as successor to `OCIS_RUN_EXTENSIONS` because
+we wanted to call oCIS "core" extensions services. We kept `OCIS_RUN_EXTENSIONS` for
+backwards compatibility reasons.
+
+It turned out, that setting `OCIS_RUN_SERVICES` has no effect since introduced. `OCIS_RUN_EXTENSIONS`.
+`OCIS_RUN_EXTENSIONS` was working fine all the time.
+
+We now fixed `OCIS_RUN_SERVICES`, so that you can use it as a equivalent replacement for `OCIS_RUN_EXTENSIONS`
+
+https://github.com/owncloud/ocis/pull/4133
diff --git a/changelog/unreleased/fix-remove-unused-GRAPH_SPACES_INSECURE.md b/changelog/unreleased/fix-remove-unused-GRAPH_SPACES_INSECURE.md
new file mode 100644
index 00000000000..6b442414abf
--- /dev/null
+++ b/changelog/unreleased/fix-remove-unused-GRAPH_SPACES_INSECURE.md
@@ -0,0 +1,5 @@
+Bugfix: Fix unused config option `GRAPH_SPACES_INSECURE`
+
+We've removed the unused config option `GRAPH_SPACES_INSECURE` from the GRAPH service.
+
+https://github.com/owncloud/ocis/pull/55555
diff --git a/changelog/unreleased/ldap-escape-dn.md b/changelog/unreleased/ldap-escape-dn.md
new file mode 100644
index 00000000000..78e38cd5fde
--- /dev/null
+++ b/changelog/unreleased/ldap-escape-dn.md
@@ -0,0 +1,6 @@
+Bugfix: Escape DN attribute value
+
+Escaped the DN attribute value on creating users and groups.
+
+
+https://github.com/owncloud/ocis/pull/4117
diff --git a/changelog/unreleased/update-reva-beta.5.md b/changelog/unreleased/update-reva-beta.5.md
new file mode 100644
index 00000000000..eb8a103dc78
--- /dev/null
+++ b/changelog/unreleased/update-reva-beta.5.md
@@ -0,0 +1,3 @@
+Enhancement: Update reva
+
+https://github.com/owncloud/ocis/pull/4115
diff --git a/changelog/unreleased/webdav-search.md b/changelog/unreleased/webdav-search.md
new file mode 100644
index 00000000000..af8f69e117e
--- /dev/null
+++ b/changelog/unreleased/webdav-search.md
@@ -0,0 +1,5 @@
+Enhancement: Search service at the old webdav endpoint
+
+We made the search service available for legacy clients at the old webdav endpoint.
+
+https://github.com/owncloud/ocis/pull/4118
diff --git a/go.mod b/go.mod
index 6322e825369..c20b7b7b0b1 100644
--- a/go.mod
+++ b/go.mod
@@ -10,7 +10,7 @@ require (
 	github.com/blevesearch/bleve_index_api v1.0.2
 	github.com/coreos/go-oidc/v3 v3.2.0
 	github.com/cs3org/go-cs3apis v0.0.0-20220512100524-551800f020d8
-	github.com/cs3org/reva/v2 v2.6.2-0.20220705085406-20c332e3da17
+	github.com/cs3org/reva/v2 v2.6.2-0.20220706093852-e2232b5a63df
 	github.com/disintegration/imaging v1.6.2
 	github.com/ggwhite/go-masker v1.0.9
 	github.com/go-chi/chi/v5 v5.0.7
diff --git a/go.sum b/go.sum
index b2eb46bb949..d61370128cc 100644
--- a/go.sum
+++ b/go.sum
@@ -299,6 +299,8 @@ github.com/cs3org/reva/v2 v2.6.1 h1:iVJlbKwUbjeTq17zZ8XGtD86yM+L64oHQ24r1HjzsQM=
 github.com/cs3org/reva/v2 v2.6.1/go.mod h1:zAHqzr36X4lIalonDQeNbwrIXjn66C38lp5A+MTRS1c=
 github.com/cs3org/reva/v2 v2.6.2-0.20220705085406-20c332e3da17 h1:xSAhpna63GSOs5NYue83xVYh5PR9um1LQgTv3eBGz08=
 github.com/cs3org/reva/v2 v2.6.2-0.20220705085406-20c332e3da17/go.mod h1:zAHqzr36X4lIalonDQeNbwrIXjn66C38lp5A+MTRS1c=
+github.com/cs3org/reva/v2 v2.6.2-0.20220706093852-e2232b5a63df h1:qbfO+xipOcpPsKbzoRAzgq3+JvKkc0JjQR6ov/rE2+I=
+github.com/cs3org/reva/v2 v2.6.2-0.20220706093852-e2232b5a63df/go.mod h1:zAHqzr36X4lIalonDQeNbwrIXjn66C38lp5A+MTRS1c=
 github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8 h1:Z9lwXumT5ACSmJ7WGnFl+OMLLjpz5uR2fyz7dC255FI=
 github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8/go.mod h1:4abs/jPXcmJzYoYGF91JF9Uq9s/KL5n1jvFDix8KcqY=
 github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
diff --git a/ocis-pkg/config/config.go b/ocis-pkg/config/config.go
index 8e9319a44de..2aa26107cf2 100644
--- a/ocis-pkg/config/config.go
+++ b/ocis-pkg/config/config.go
@@ -49,7 +49,7 @@ type Mode int
 type Runtime struct {
 	Port       string `yaml:"port" env:"OCIS_RUNTIME_PORT"`
 	Host       string `yaml:"host" env:"OCIS_RUNTIME_HOST"`
-	Extensions string `yaml:"services" env:"OCIS_RUN_EXTENSIONS,OCIS_RUN_SERVICES"`
+	Extensions string `yaml:"services" env:"OCIS_RUN_EXTENSIONS;OCIS_RUN_SERVICES"`
 }
 
 // Config combines all available configuration parts.
diff --git a/ocis-pkg/ldap/ldap.go b/ocis-pkg/ldap/ldap.go
index 8eceaf3cb94..cfa452f1a5d 100644
--- a/ocis-pkg/ldap/ldap.go
+++ b/ocis-pkg/ldap/ldap.go
@@ -5,6 +5,7 @@ import (
 	"errors"
 	"io/ioutil"
 	"os"
+	"strings"
 	"time"
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/log"
@@ -15,6 +16,20 @@ const (
 	caCheckSleep   = 2
 )
 
+var (
+	dnEscaper = strings.NewReplacer(
+		"\\", "\\\\",
+		",", "\\,",
+		"+", "\\+",
+		`"`, `\\"`,
+		"<", "\\<",
+		">", "\\>",
+		";", "\\;",
+		"=", "\\=",
+		"\000", "\\00",
+	)
+)
+
 func WaitForCA(log log.Logger, insecure bool, caCert string) error {
 	if !insecure && caCert != "" {
 		for i := 0; i < caCheckRetries; i++ {
@@ -38,3 +53,20 @@ func WaitForCA(log log.Logger, insecure bool, caCert string) error {
 	}
 	return nil
 }
+
+// EscapeDNAttributeValue escapes special characters in an attribute value as [described in RFC4514](https://datatracker.ietf.org/doc/html/rfc4514).
+func EscapeDNAttributeValue(v string) string {
+	if v == "" {
+		return v
+	}
+
+	v = dnEscaper.Replace(v)
+
+	if strings.HasSuffix(v, " ") {
+		v = v[:len(v)-1] + "\\ "
+	}
+	if strings.HasPrefix(v, "#") || strings.HasPrefix(v, " ") {
+		v = "\\" + v
+	}
+	return v
+}
diff --git a/services/app-provider/pkg/config/config.go b/services/app-provider/pkg/config/config.go
index 454bffb4371..da4a4b53c71 100644
--- a/services/app-provider/pkg/config/config.go
+++ b/services/app-provider/pkg/config/config.go
@@ -18,8 +18,8 @@ type Config struct {
 	TokenManager *TokenManager `yaml:"token_manager"`
 	Reva         *Reva         `yaml:"reva"`
 
-	ExternalAddr string  `yaml:"external_addr" env:"APP_PROVIDER_EXTERNAL_ADDR" desc:"Address of the app provider, where the gateway service can reach it."`
-	Driver       string  `yaml:"driver" env:"APP_PROVIDER_DRIVER" desc:"Driver, which the app provider uses. Only \"wopi\" is supported as of now."`
+	ExternalAddr string  `yaml:"external_addr" env:"APP_PROVIDER_EXTERNAL_ADDR" desc:"Address of the app provider, where the GATEWAY service can reach it."`
+	Driver       string  `yaml:"driver" env:"APP_PROVIDER_DRIVER" desc:"Driver, the APP PROVIDER services uses. Only \"wopi\" is supported as of now."`
 	Drivers      Drivers `yaml:"drivers"`
 
 	Supervised bool            `yaml:"-"`
@@ -54,7 +54,7 @@ type Debug struct {
 type GRPCConfig struct {
 	Addr      string `yaml:"addr" env:"APP_PROVIDER_GRPC_ADDR" desc:"The bind address of the GRPC service."`
 	Namespace string `yaml:"-"`
-	Protocol  string `yaml:"protocol" env:"APP_PROVIDER_GRPC_PROTOCOL" desc:"The transport protocol of the grpc service."`
+	Protocol  string `yaml:"protocol" env:"APP_PROVIDER_GRPC_PROTOCOL" desc:"The transport protocol of the GPRC service."`
 }
 
 type Drivers struct {
@@ -65,7 +65,7 @@ type WOPIDriver struct {
 	AppAPIKey      string `yaml:"app_api_key" env:"APP_PROVIDER_WOPI_APP_API_KEY" desc:"API key for the wopi app."`
 	AppDesktopOnly bool   `yaml:"app_desktop_only" env:"APP_PROVIDER_WOPI_APP_DESKTOP_ONLY" desc:"Offer this app only on desktop."`
 	AppIconURI     string `yaml:"app_icon_uri" env:"APP_PROVIDER_WOPI_APP_ICON_URI" desc:"URI to an app icon to be used by clients."`
-	AppInternalURL string `yaml:"app_internal_url" env:"APP_PROVIDER_WOPI_APP_INTERNAL_URL" desc:"Internal URL to the app, eg in your DMZ."`
+	AppInternalURL string `yaml:"app_internal_url" env:"APP_PROVIDER_WOPI_APP_INTERNAL_URL" desc:"Internal URL to the app, like in your DMZ."`
 	AppName        string `yaml:"app_name" env:"APP_PROVIDER_WOPI_APP_NAME" desc:"Human readable app name."`
 	AppURL         string `yaml:"app_url" env:"APP_PROVIDER_WOPI_APP_URL" desc:"URL for end users to access the app."`
 	Insecure       bool   `yaml:"insecure" env:"APP_PROVIDER_WOPI_INSECURE" desc:"Allow insecure connections to the app."`
diff --git a/services/app-registry/pkg/config/config.go b/services/app-registry/pkg/config/config.go
index 3c13b65ea38..817d0b91b79 100644
--- a/services/app-registry/pkg/config/config.go
+++ b/services/app-registry/pkg/config/config.go
@@ -44,15 +44,15 @@ type Service struct {
 
 type Debug struct {
 	Addr   string `yaml:"addr" env:"APP_REGISTRY_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"APP_REGISTRY_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"APP_REGISTRY_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"APP_REGISTRY_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"APP_REGISTRY_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"APP_REGISTRY_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
 
 type GRPCConfig struct {
 	Addr      string `yaml:"addr" env:"APP_REGISTRY_GRPC_ADDR" desc:"The bind address of the GRPC service."`
 	Namespace string `yaml:"-"`
-	Protocol  string `yaml:"protocol" env:"APP_REGISTRY_GRPC_PROTOCOL" desc:"The transport protocol of the grpc service."`
+	Protocol  string `yaml:"protocol" env:"APP_REGISTRY_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
 }
 
 type AppRegistry struct {
diff --git a/services/audit/pkg/config/config.go b/services/audit/pkg/config/config.go
index 0e904ff0a80..a6d2ac26b27 100644
--- a/services/audit/pkg/config/config.go
+++ b/services/audit/pkg/config/config.go
@@ -33,5 +33,5 @@ type Auditlog struct {
 	LogToConsole bool   `yaml:"log_to_console" env:"AUDIT_LOG_TO_CONSOLE" desc:"Logs to Stdout if true. Independent of the log to file option."`
 	LogToFile    bool   `yaml:"log_to_file" env:"AUDIT_LOG_TO_FILE" desc:"Logs to file if true. Independent of the log to Stdout file option."`
 	FilePath     string `yaml:"filepath" env:"AUDIT_FILEPATH" desc:"Filepath to the logfile. Mandatory if LogToFile is true."`
-	Format       string `yaml:"format" env:"AUDIT_FORMAT" desc:"Log format. using json is advised."`
+	Format       string `yaml:"format" env:"AUDIT_FORMAT" desc:"Log format. Using json is advised."`
 }
diff --git a/services/audit/pkg/config/debug.go b/services/audit/pkg/config/debug.go
index c9ff3e9fda7..16d40bae6ab 100644
--- a/services/audit/pkg/config/debug.go
+++ b/services/audit/pkg/config/debug.go
@@ -3,7 +3,7 @@ package config
 // Debug defines the available debug configuration.
 type Debug struct {
 	Addr   string `yaml:"addr" env:"AUDIT_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"AUDIT_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"AUDIT_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"AUDIT_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"AUDIT_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"AUDIT_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
diff --git a/services/auth-basic/pkg/config/config.go b/services/auth-basic/pkg/config/config.go
index c168c61bd78..1458ca1078f 100644
--- a/services/auth-basic/pkg/config/config.go
+++ b/services/auth-basic/pkg/config/config.go
@@ -19,7 +19,7 @@ type Config struct {
 	Reva         *Reva         `yaml:"reva"`
 
 	SkipUserGroupsInToken bool          `yaml:"skip_user_groups_in_token" env:"AUTH_BASIC_SKIP_USER_GROUPS_IN_TOKEN" desc:"Disables the encoding of the user's group memberships in the reva access token. This reduces the token size, especially when users are members of a large number of groups."`
-	AuthProvider          string        `yaml:"auth_provider" env:"AUTH_BASIC_AUTH_PROVIDER" desc:"The auth provider which should be used by the service (e.g. 'ldap')."`
+	AuthProvider          string        `yaml:"auth_provider" env:"AUTH_BASIC_AUTH_PROVIDER" desc:"The auth provider which should be used by the service like 'ldap'."`
 	AuthProviders         AuthProviders `yaml:"auth_providers"`
 
 	Supervised bool            `yaml:"-"`
@@ -45,15 +45,15 @@ type Service struct {
 
 type Debug struct {
 	Addr   string `yaml:"addr" env:"AUTH_BASIC_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"AUTH_BASIC_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"AUTH_BASIC_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"AUTH_BASIC_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"AUTH_BASIC_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"AUTH_BASIC_DEBUG_ZPAGES" desc:"Enables zpages, which can  be used for collecting and viewing traces in-memory."`
 }
 
 type GRPCConfig struct {
 	Addr      string `yaml:"addr" env:"AUTH_BASIC_GRPC_ADDR" desc:"The bind address of the GRPC service."`
 	Namespace string `yaml:"-"`
-	Protocol  string `yaml:"protocol" env:"AUTH_BASIC_GRPC_PROTOCOL" desc:"The transport protocol of the grpc service."`
+	Protocol  string `yaml:"protocol" env:"AUTH_BASIC_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
 }
 
 type AuthProviders struct {
@@ -74,9 +74,9 @@ type LDAPProvider struct {
 	BindPassword     string          `yaml:"bind_password" env:"LDAP_BIND_PASSWORD;AUTH_BASIC_LDAP_BIND_PASSWORD" desc:"Password to use for authenticating the 'bind_dn'."`
 	UserBaseDN       string          `yaml:"user_base_dn" env:"LDAP_USER_BASE_DN;AUTH_BASIC_LDAP_USER_BASE_DN" desc:"Search base DN for looking up LDAP users."`
 	GroupBaseDN      string          `yaml:"group_base_dn" env:"LDAP_GROUP_BASE_DN;AUTH_BASIC_LDAP_GROUP_BASE_DN" desc:"Search base DN for looking up LDAP groups."`
-	UserScope        string          `yaml:"user_scope" env:"LDAP_USER_SCOPE;AUTH_BASIC_LDAP_USER_SCOPE" desc:"LDAP search scope to use when looking up users ('base', 'one', 'sub')."`
-	GroupScope       string          `yaml:"group_scope" env:"LDAP_GROUP_SCOPE;AUTH_BASIC_LDAP_GROUP_SCOPE" desc:"LDAP search scope to use when looking up gruops ('base', 'one', 'sub')."`
-	UserFilter       string          `yaml:"user_filter" env:"LDAP_USER_FILTER;AUTH_BASIC_LDAP_USER_FILTER" desc:"LDAP filter to add to the default filters for user search (e.g. '(objectclass=ownCloud)')."`
+	UserScope        string          `yaml:"user_scope" env:"LDAP_USER_SCOPE;AUTH_BASIC_LDAP_USER_SCOPE" desc:"LDAP search scope to use when looking up users. Supported values are 'base', 'one' and 'sub'."`
+	GroupScope       string          `yaml:"group_scope" env:"LDAP_GROUP_SCOPE;AUTH_BASIC_LDAP_GROUP_SCOPE" desc:"LDAP search scope to use when looking up groups. Supported values are 'base', 'one' and 'sub'."`
+	UserFilter       string          `yaml:"user_filter" env:"LDAP_USER_FILTER;AUTH_BASIC_LDAP_USER_FILTER" desc:"LDAP filter to add to the default filters for user search like '(objectclass=ownCloud)'."`
 	GroupFilter      string          `yaml:"group_filter" env:"LDAP_GROUP_FILTER;AUTH_BASIC_LDAP_GROUP_FILTER" desc:"LDAP filter to add to the default filters for group searches."`
 	UserObjectClass  string          `yaml:"user_object_class" env:"LDAP_USER_OBJECTCLASS;AUTH_BASIC_LDAP_USER_OBJECTCLASS" desc:"The object class to use for users in the default user search filter ('inetOrgPerson')."`
 	GroupObjectClass string          `yaml:"group_object_class" env:"LDAP_GROUP_OBJECTCLASS;AUTH_BASIC_LDAP_GROUP_OBJECTCLASS" desc:"The object class to use for groups in the default group search filter ('groupOfNames'). "`
@@ -87,8 +87,8 @@ type LDAPProvider struct {
 }
 
 type LDAPUserSchema struct {
-	ID              string `yaml:"id" env:"LDAP_USER_SCHEMA_ID;AUTH_BASIC_LDAP_USER_SCHEMA_ID" desc:"LDAP Attribute to use as the unique id for users. This should be a stable globally unique id (e.g. a UUID)."`
-	IDIsOctetString bool   `yaml:"id_is_octet_string" env:"LDAP_USER_SCHEMA_ID_IS_OCTETSTRING;AUTH_BASIC_LDAP_USER_SCHEMA_ID_IS_OCTETSTRING" desc:"Set this to true if the defined 'id' attribute for users is of the 'OCTETSTRING' syntax. This is e.g. required when using the 'objectGUID' attribute of Active Directory for the user ids."`
+	ID              string `yaml:"id" env:"LDAP_USER_SCHEMA_ID;AUTH_BASIC_LDAP_USER_SCHEMA_ID" desc:"LDAP Attribute to use as the unique id for users. This should be a stable globally unique ID like a UUID."`
+	IDIsOctetString bool   `yaml:"id_is_octet_string" env:"LDAP_USER_SCHEMA_ID_IS_OCTETSTRING;AUTH_BASIC_LDAP_USER_SCHEMA_ID_IS_OCTETSTRING" desc:"Set this to true if the defined 'id' attribute for users is of the 'OCTETSTRING' syntax. This is e.g. required when using the 'objectGUID' attribute of Active Directory for the user IDs."`
 	Mail            string `yaml:"mail" env:"LDAP_USER_SCHEMA_MAIL;AUTH_BASIC_LDAP_USER_SCHEMA_MAIL" desc:"LDAP Attribute to use for the email address of users."`
 	DisplayName     string `yaml:"display_name" env:"LDAP_USER_SCHEMA_DISPLAYNAME;AUTH_BASIC_LDAP_USER_SCHEMA_DISPLAYNAME" desc:"LDAP Attribute to use for the displayname of users."`
 	Username        string `yaml:"user_name" env:"LDAP_USER_SCHEMA_USERNAME;AUTH_BASIC_LDAP_USER_SCHEMA_USERNAME" desc:"LDAP Attribute to use for username of users."`
@@ -96,10 +96,10 @@ type LDAPUserSchema struct {
 
 type LDAPGroupSchema struct {
 	ID              string `yaml:"id" env:"LDAP_GROUP_SCHEMA_ID;AUTH_BASIC_LDAP_GROUP_SCHEMA_ID" desc:"LDAP Attribute to use as the unique id for groups. This should be a stable globally unique id (e.g. a UUID)."`
-	IDIsOctetString bool   `yaml:"id_is_octet_string" env:"LDAP_GROUP_SCHEMA_ID_IS_OCTETSTRING;AUTH_BASIC_LDAP_GROUP_SCHEMA_ID_IS_OCTETSTRING" desc:"Set this to true if the defined 'id' attribute for groups is of the 'OCTETSTRING' syntax. This is e.g. required when using the 'objectGUID' attribute of Active Directory for the group ids."`
+	IDIsOctetString bool   `yaml:"id_is_octet_string" env:"LDAP_GROUP_SCHEMA_ID_IS_OCTETSTRING;AUTH_BASIC_LDAP_GROUP_SCHEMA_ID_IS_OCTETSTRING" desc:"Set this to true if the defined 'id' attribute for groups is of the 'OCTETSTRING' syntax. This is e.g. required when using the 'objectGUID' attribute of Active Directory for the group IDs."`
 	Mail            string `yaml:"mail" env:"LDAP_GROUP_SCHEMA_MAIL;AUTH_BASIC_LDAP_GROUP_SCHEMA_MAIL" desc:"LDAP Attribute to use for the email address of groups (can be empty)."`
-	DisplayName     string `yaml:"display_name" env:"LDAP_GROUP_SCHEMA_DISPLAYNAME;AUTH_BASIC_LDAP_GROUP_SCHEMA_DISPLAYNAME" desc:"LDAP Attribute to use for the displayname of groups (often the same as groupname attribute)"`
-	Groupname       string `yaml:"group_name" env:"LDAP_GROUP_SCHEMA_GROUPNAME;AUTH_BASIC_LDAP_GROUP_SCHEMA_GROUPNAME" desc:"LDAP Attribute to use for the name of groups"`
+	DisplayName     string `yaml:"display_name" env:"LDAP_GROUP_SCHEMA_DISPLAYNAME;AUTH_BASIC_LDAP_GROUP_SCHEMA_DISPLAYNAME" desc:"LDAP Attribute to use for the displayname of groups (often the same as groupname attribute)."`
+	Groupname       string `yaml:"group_name" env:"LDAP_GROUP_SCHEMA_GROUPNAME;AUTH_BASIC_LDAP_GROUP_SCHEMA_GROUPNAME" desc:"LDAP Attribute to use for the name of groups."`
 	Member          string `yaml:"member" env:"LDAP_GROUP_SCHEMA_MEMBER;AUTH_BASIC_LDAP_GROUP_SCHEMA_MEMBER" desc:"LDAP Attribute that is used for group members."`
 }
 
@@ -112,5 +112,5 @@ type OwnCloudSQLProvider struct {
 	IDP              string `yaml:"idp" env:"AUTH_BASIC_OWNCLOUDSQL_IDP" desc:"The identity provider value to set in the userids of the CS3 user objects for users returned by this user provider."`
 	Nobody           int64  `yaml:"nobody" env:"AUTH_BASIC_OWNCLOUDSQL_NOBODY" desc:"Fallback number if no numeric UID and GID properties are provided."`
 	JoinUsername     bool   `yaml:"join_username" env:"AUTH_BASIC_OWNCLOUDSQL_JOIN_USERNAME" desc:"Join the user properties table to read usernames"`
-	JoinOwnCloudUUID bool   `yaml:"join_owncloud_uuid" env:"AUTH_BASIC_OWNCLOUDSQL_JOIN_OWNCLOUD_UUID" desc:"Join the user properties table to read user ids (boolean)."`
+	JoinOwnCloudUUID bool   `yaml:"join_owncloud_uuid" env:"AUTH_BASIC_OWNCLOUDSQL_JOIN_OWNCLOUD_UUID" desc:"Join the user properties table to read user ID's."`
 }
diff --git a/services/auth-bearer/pkg/config/config.go b/services/auth-bearer/pkg/config/config.go
index 3e583696989..5503a2cefc1 100644
--- a/services/auth-bearer/pkg/config/config.go
+++ b/services/auth-bearer/pkg/config/config.go
@@ -45,15 +45,15 @@ type Service struct {
 
 type Debug struct {
 	Addr   string `yaml:"addr" env:"AUTH_BEARER_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"AUTH_BEARER_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"AUTH_BEARER_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"AUTH_BEARER_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"AUTH_BEARER_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"AUTH_BEARER_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
 
 type GRPCConfig struct {
 	Addr      string `yaml:"addr" env:"AUTH_BEARER_GRPC_ADDR" desc:"The bind address of the GRPC service."`
 	Namespace string `yaml:"-"`
-	Protocol  string `yaml:"protocol" env:"AUTH_BEARER_GRPC_PROTOCOL" desc:"The transport protocol of the grpc service."`
+	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-machine/pkg/config/config.go b/services/auth-machine/pkg/config/config.go
index ffb26a9fa71..d0b2c0b545f 100644
--- a/services/auth-machine/pkg/config/config.go
+++ b/services/auth-machine/pkg/config/config.go
@@ -45,13 +45,13 @@ type Service struct {
 
 type Debug struct {
 	Addr   string `yaml:"addr" env:"AUTH_MACHINE_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"AUTH_MACHINE_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"AUTH_MACHINE_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"AUTH_MACHINE_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"AUTH_MACHINE_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"AUTH_MACHINE_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
 
 type GRPCConfig struct {
 	Addr      string `yaml:"addr" env:"AUTH_MACHINE_GRPC_ADDR" desc:"The bind address of the GRPC service."`
 	Namespace string `yaml:"-"`
-	Protocol  string `yaml:"protocol" env:"AUTH_MACHINE_GRPC_PROTOCOL" desc:"The transport protocol of the grpc service."`
+	Protocol  string `yaml:"protocol" env:"AUTH_MACHINE_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
 }
diff --git a/services/frontend/pkg/config/config.go b/services/frontend/pkg/config/config.go
index a1f1fda5ab4..066c23b78fc 100644
--- a/services/frontend/pkg/config/config.go
+++ b/services/frontend/pkg/config/config.go
@@ -21,7 +21,7 @@ type Config struct {
 
 	TokenManager      *TokenManager `yaml:"token_manager"`
 	Reva              *Reva         `yaml:"reva"`
-	MachineAuthAPIKey string        `yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;FRONTEND_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used to validate internal requests necessary for the access to resources from other services."`
+	MachineAuthAPIKey string        `yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;FRONTEND_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used to validate internal requests necessary to access resources from other services."`
 
 	SkipUserGroupsInToken bool `yaml:"skip_user_groups_in_token" env:"FRONTEND_SKIP_USER_GROUPS_IN_TOKEN" desc:"Disables the loading of user's group memberships from the reva access token."`
 
@@ -33,7 +33,7 @@ type Config struct {
 	DefaultUploadProtocol    string `yaml:"default_upload_protocol" env:"FRONTEND_DEFAULT_UPLOAD_PROTOCOL" desc:"The default upload protocol to use in the frontend (e.g. tus)."`
 	EnableResharing          bool   `yaml:"enable_resharing" env:"FRONTEND_ENABLE_RESHARING" desc:"Enables the support for resharing in the frontend."`
 
-	PublicURL string `yaml:"public_url" env:"OCIS_URL;FRONTEND_PUBLIC_URL" desc:"The public facing url of the ocis frontend."`
+	PublicURL string `yaml:"public_url" env:"OCIS_URL;FRONTEND_PUBLIC_URL" desc:"The public facing URL of the oCIS frontend."`
 
 	AppHandler  AppHandler  `yaml:"app_handler"`
 	Archiver    Archiver    `yaml:"archiver"`
@@ -66,15 +66,15 @@ type Service struct {
 
 type Debug struct {
 	Addr   string `yaml:"addr" env:"FRONTEND_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"FRONTEND_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"FRONTEND_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"FRONTEND_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"FRONTEND_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"FRONTEND_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
 
 type HTTPConfig struct {
 	Addr      string `yaml:"addr" env:"FRONTEND_HTTP_ADDR" desc:"The bind address of the HTTP service."`
 	Namespace string `yaml:"-"`
-	Protocol  string `yaml:"protocol" env:"FRONTEND_HTTP_PROTOCOL" desc:"The transport protocol of the http service."`
+	Protocol  string `yaml:"protocol" env:"FRONTEND_HTTP_PROTOCOL" desc:"The transport protocol of the HTTP service."`
 	Prefix    string `yaml:"prefix" env:"FRONTEND_HTTP_PREFIX" desc:"The Path prefix where the frontend can be accessed (defaults to /)."`
 }
 
@@ -105,11 +105,11 @@ type DataGateway struct {
 }
 
 type OCS struct {
-	Prefix                  string             `yaml:"prefix" env:"FRONTEND_OCS_PREFIX" desc:"Path prefix for the ocs service"`
+	Prefix                  string             `yaml:"prefix" env:"FRONTEND_OCS_PREFIX" desc:"Path prefix for the OCS service"`
 	SharePrefix             string             `yaml:"share_prefix" env:"FRONTEND_OCS_SHARE_PREFIX" desc:"Path prefix for shares."`
 	HomeNamespace           string             `yaml:"home_namespace" env:"FRONTEND_OCS_HOME_NAMESPACE" desc:"Homespace namespace identifier."`
-	AdditionalInfoAttribute string             `yaml:"additional_info_attribute" env:"FRONTEND_OCS_ADDITIONAL_INFO_ATTRIBUTE" desc:"Additional information attribute for the user (e.g. {{.Mail}}"`
-	ResourceInfoCacheTTL    int                `yaml:"resource_info_cache_ttl" env:"FRONTEND_OCS_RESOURCE_INFO_CACHE_TTL" desc:"Max TTL for the resource info cache"`
+	AdditionalInfoAttribute string             `yaml:"additional_info_attribute" env:"FRONTEND_OCS_ADDITIONAL_INFO_ATTRIBUTE" desc:"Additional information attribute for the user like {{.Mail}}."`
+	ResourceInfoCacheTTL    int                `yaml:"resource_info_cache_ttl" env:"FRONTEND_OCS_RESOURCE_INFO_CACHE_TTL" desc:"Max TTL for the resource info cache."`
 	CacheWarmupDriver       string             `yaml:"cache_warmup_driver,omitempty"`  // not supported by the oCIS product, therefore not part of docs
 	CacheWarmupDrivers      CacheWarmupDrivers `yaml:"cache_warmup_drivers,omitempty"` // not supported by the oCIS product, therefore not part of docs
 }
diff --git a/services/gateway/pkg/config/config.go b/services/gateway/pkg/config/config.go
index bb2c023ca9e..b9ac6b537c8 100644
--- a/services/gateway/pkg/config/config.go
+++ b/services/gateway/pkg/config/config.go
@@ -24,23 +24,23 @@ type Config struct {
 	CommitShareToStorageGrant  bool   `yaml:"commit_share_to_storage_grant" env:"GATEWAY_COMMIT_SHARE_TO_STORAGE_GRANT" desc:"Commit shares to storage grants. This grants access to shared resources for the share receiver directly on the storage."`
 	ShareFolder                string `yaml:"share_folder_name" env:"GATEWAY_SHARE_FOLDER_NAME" desc:"Name of the share folder in users' home space."`
 	DisableHomeCreationOnLogin bool   `yaml:"disable_home_creation_on_login" env:"GATEWAY_DISABLE_HOME_CREATION_ON_LOGIN" desc:"Disable creation of the home space on login."`
-	TransferSecret             string `yaml:"transfer_secret" env:"STORAGE_TRANSFER_SECRET" desc:"The storage transfer secret"` // TODO: how to name the env
-	TransferExpires            int    `yaml:"transfer_expires" env:"GATEWAY_TRANSFER_EXPIRES" desc:"Expiry for the gateway tokens"`
+	TransferSecret             string `yaml:"transfer_secret" env:"STORAGE_TRANSFER_SECRET" desc:"The storage transfer secret."` // TODO: how to name the env
+	TransferExpires            int    `yaml:"transfer_expires" env:"GATEWAY_TRANSFER_EXPIRES" desc:"Expiry for the gateway tokens."`
 	EtagCacheTTL               int    `yaml:"etag_cache_ttl" env:"GATEWAY_ETAG_CACHE_TTL" desc:"Max TTL in seconds for the gateway's ETAG cache."`
 
-	FrontendPublicURL string `yaml:"frontend_public_url" env:"OCIS_URL;GATEWAY_FRONTEND_PUBLIC_URL" desc:"The public facing url of the ocis frontend."`
+	FrontendPublicURL string `yaml:"frontend_public_url" env:"OCIS_URL;GATEWAY_FRONTEND_PUBLIC_URL" desc:"The public facing URL of the oCIS frontend."`
 
-	UsersEndpoint             string `yaml:"users_endpoint" env:"GATEWAY_USERS_ENDPOINT" desc:"The users api endpoint."`
-	GroupsEndpoint            string `yaml:"groups_endpoint" env:"GATEWAY_GROUPS_ENDPOINT" desc:"The groups api endpoint."`
-	PermissionsEndpoint       string `yaml:"permissions_endpoint" env:"GATEWAY_PERMISSIONS_ENDPOINT" desc:"The permission api endpoint."`
-	SharingEndpoint           string `yaml:"sharing_endpoint" env:"GATEWAY_SHARING_ENDPOINT" desc:"The share api endpoint."`
-	AuthBasicEndpoint         string `yaml:"auth_basic_endpoint" env:"GATEWAY_AUTH_BASIC_ENDPOINT" desc:"The auth basic api endpoint."`
-	AuthBearerEndpoint        string `yaml:"auth_bearer_endpoint" env:"GATEWAY_AUTH_BEARER_ENDPOINT" desc:"The auth bearer api endpoint."`
-	AuthMachineEndpoint       string `yaml:"auth_machine_endpoint" env:"GATEWAY_AUTH_MACHINE_ENDPOINT" desc:"The auth machine api endpoint."`
-	StoragePublicLinkEndpoint string `yaml:"storage_public_link_endpoint" env:"GATEWAY_STORAGE_PUBLIC_LINK_ENDPOINT" desc:"The storage puliclink api endpoint."`
-	StorageUsersEndpoint      string `yaml:"storage_users_endpoint" env:"GATEWAY_STORAGE_USERS_ENDPOINT" desc:"The storage users api endpoint."`
-	StorageSharesEndpoint     string `yaml:"storage_shares_endpoint" env:"GATEWAY_STORAGE_SHARES_ENDPOINT" desc:"The storage shares api endpoint."`
-	AppRegistryEndpoint       string `yaml:"app_registry_endpoint" env:"GATEWAY_APP_REGISTRY_ENDPOINT" desc:"The app registry api endpoint."`
+	UsersEndpoint             string `yaml:"users_endpoint" env:"GATEWAY_USERS_ENDPOINT" desc:"The USERS API endpoint."`
+	GroupsEndpoint            string `yaml:"groups_endpoint" env:"GATEWAY_GROUPS_ENDPOINT" desc:"The GROUPS API endpoint."`
+	PermissionsEndpoint       string `yaml:"permissions_endpoint" env:"GATEWAY_PERMISSIONS_ENDPOINT" desc:"The SETTINGS API endpoint."`
+	SharingEndpoint           string `yaml:"sharing_endpoint" env:"GATEWAY_SHARING_ENDPOINT" desc:"The SHARE API endpoint."`
+	AuthBasicEndpoint         string `yaml:"auth_basic_endpoint" env:"GATEWAY_AUTH_BASIC_ENDPOINT" desc:"The AUTH BASIC API endpoint."`
+	AuthBearerEndpoint        string `yaml:"auth_bearer_endpoint" env:"GATEWAY_AUTH_BEARER_ENDPOINT" desc:"The AUTH BEARER API endpoint."`
+	AuthMachineEndpoint       string `yaml:"auth_machine_endpoint" env:"GATEWAY_AUTH_MACHINE_ENDPOINT" desc:"The AUTH MACHINE API endpoint."`
+	StoragePublicLinkEndpoint string `yaml:"storage_public_link_endpoint" env:"GATEWAY_STORAGE_PUBLIC_LINK_ENDPOINT" desc:"The STORAGE PUBLICLINK API endpoint."`
+	StorageUsersEndpoint      string `yaml:"storage_users_endpoint" env:"GATEWAY_STORAGE_USERS_ENDPOINT" desc:"The STORAGE USERS API endpoint."`
+	StorageSharesEndpoint     string `yaml:"storage_shares_endpoint" env:"GATEWAY_STORAGE_SHARES_ENDPOINT" desc:"The STORAGE SHARES API endpoint."`
+	AppRegistryEndpoint       string `yaml:"app_registry_endpoint" env:"GATEWAY_APP_REGISTRY_ENDPOINT" desc:"The APP REGISTRY API endpoint."`
 
 	StorageRegistry StorageRegistry `yaml:"storage_registry"` //TODO: should we even support switching this?
 
@@ -67,15 +67,15 @@ type Service struct {
 
 type Debug struct {
 	Addr   string `yaml:"addr" env:"GATEWAY_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"GATEWAY_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"GATEWAY_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"GATEWAY_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"GATEWAY_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"GATEWAY_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
 
 type GRPCConfig struct {
 	Addr      string `yaml:"addr" env:"GATEWAY_GRPC_ADDR" desc:"The bind address of the GRPC service."`
 	Namespace string `yaml:"-"`
-	Protocol  string `yaml:"protocol" env:"GATEWAY_GRPC_PROTOCOL" desc:"The transport protocol of the grpc service."`
+	Protocol  string `yaml:"protocol" env:"GATEWAY_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
 }
 
 type StorageRegistry struct {
diff --git a/services/graph-explorer/pkg/config/config.go b/services/graph-explorer/pkg/config/config.go
index 34efc43bf07..cccfe691b87 100644
--- a/services/graph-explorer/pkg/config/config.go
+++ b/services/graph-explorer/pkg/config/config.go
@@ -25,8 +25,8 @@ type Config struct {
 
 // GraphExplorer defines the available graph-explorer configuration.
 type GraphExplorer struct {
-	ClientID     string `yaml:"client_id" env:"GRAPH_EXPLORER_CLIENT_ID" desc:"OIDC client id, the graph explorer uses. This client needs to be set up in your IDP."`
+	ClientID     string `yaml:"client_id" env:"GRAPH_EXPLORER_CLIENT_ID" desc:"OIDC client ID the graph explorer uses. This client needs to be set up in your IDP."`
 	Issuer       string `yaml:"issuer" env:"OCIS_URL;OCIS_OIDC_ISSUER;GRAPH_EXPLORER_ISSUER" desc:"URL of the OIDC issuer. It defaults to URL of the builtin IDP."`
-	GraphURLBase string `yaml:"graph_url_base" env:"OCIS_URL;GRAPH_EXPLORER_GRAPH_URL_BASE" desc:"Base URL, where the graph explorer is reachable for users."`
-	GraphURLPath string `yaml:"graph_url_path" env:"GRAPH_EXPLORER_GRAPH_URL_PATH" desc:"URL path, where the graph explorer is reachable for users."`
+	GraphURLBase string `yaml:"graph_url_base" env:"OCIS_URL;GRAPH_EXPLORER_GRAPH_URL_BASE" desc:"Base URL where the graph explorer is reachable for users."`
+	GraphURLPath string `yaml:"graph_url_path" env:"GRAPH_EXPLORER_GRAPH_URL_PATH" desc:"URL path where the graph explorer is reachable for users."`
 }
diff --git a/services/graph-explorer/pkg/config/debug.go b/services/graph-explorer/pkg/config/debug.go
index f6092992019..ebdfe5b3eb7 100644
--- a/services/graph-explorer/pkg/config/debug.go
+++ b/services/graph-explorer/pkg/config/debug.go
@@ -3,7 +3,7 @@ package config
 // Debug defines the available debug configuration.
 type Debug struct {
 	Addr   string `yaml:"addr" env:"GRAPH_EXPLORER_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"GRAPH_EXPLORER_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"GRAPH_EXPLORER_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"GRAPH_EXPLORER_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"GRAPH_EXPLORER_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"GRAPH_EXPLORER_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
diff --git a/services/graph/pkg/config/config.go b/services/graph/pkg/config/config.go
index 73b2fe9a125..67b38229c79 100644
--- a/services/graph/pkg/config/config.go
+++ b/services/graph/pkg/config/config.go
@@ -32,44 +32,43 @@ type Spaces struct {
 	WebDavBase                      string `yaml:"webdav_base" env:"OCIS_URL;GRAPH_SPACES_WEBDAV_BASE" desc:"The public facing URL of WebDAV."`
 	WebDavPath                      string `yaml:"webdav_path" env:"GRAPH_SPACES_WEBDAV_PATH" desc:"The WebDAV subpath for spaces."`
 	DefaultQuota                    string `yaml:"default_quota" env:"GRAPH_SPACES_DEFAULT_QUOTA" desc:"The default quota in bytes."`
-	Insecure                        bool   `yaml:"insecure" env:"OCIS_INSECURE;GRAPH_SPACES_INSECURE" desc:"Allow insecure connetctions to the spaces."`
-	ExtendedSpacePropertiesCacheTTL int    `yaml:"extended_space_properties_cache_ttl" env:"GRAPH_SPACES_EXTENDED_SPACE_PROPERTIES_CACHE_TTL" desc:"Max TTL for the spaces property cache."`
+	ExtendedSpacePropertiesCacheTTL int    `yaml:"extended_space_properties_cache_ttl" env:"GRAPH_SPACES_EXTENDED_SPACE_PROPERTIES_CACHE_TTL" desc:"Max TTL in seconds for the spaces property cache."`
 }
 
 type LDAP struct {
 	URI                string `yaml:"uri" env:"LDAP_URI;GRAPH_LDAP_URI" desc:"URI of the LDAP Server to connect to. Supported URI schemes are 'ldaps://' and 'ldap://'"`
-	CACert             string `yaml:"cacert" env:"LDAP_CACERT;GRAPH_LDAP_CACERT" desc:"The certificate to verify TLS connections"`
+	CACert             string `yaml:"cacert" env:"LDAP_CACERT;GRAPH_LDAP_CACERT" desc:"The certificate to verify TLS connections."`
 	Insecure           bool   `yaml:"insecure" env:"LDAP_INSECURE;GRAPH_LDAP_INSECURE" desc:"Disable TLS certificate validation for the LDAP connections. Do not set this in production environments."`
 	BindDN             string `yaml:"bind_dn" env:"LDAP_BIND_DN;GRAPH_LDAP_BIND_DN" desc:"LDAP DN to use for simple bind authentication with the target LDAP server."`
 	BindPassword       string `yaml:"bind_password" env:"LDAP_BIND_PASSWORD;GRAPH_LDAP_BIND_PASSWORD" desc:"Password to use for authenticating the 'bind_dn'."`
-	UseServerUUID      bool   `yaml:"use_server_uuid" env:"GRAPH_LDAP_SERVER_UUID" desc:"If set to true, rely on the LDAP Server to generate a unique ID for users and groups, e.g. when using 'entryUUID' as the user id attribute."`
-	UsePasswordModExOp bool   `yaml:"use_password_modify_exop" env:"GRAPH_LDAP_SERVER_USE_PASSWORD_MODIFY_EXOP" desc:"User the Password Modify Extended Operation for updating user passwords"`
-	WriteEnabled       bool   `yaml:"write_enabled" env:"GRAPH_LDAP_SERVER_WRITE_ENABLED" desc:"Allow to create, modify and delete LDAP users via graph API. This is only works when the default Schema is used."`
+	UseServerUUID      bool   `yaml:"use_server_uuid" env:"GRAPH_LDAP_SERVER_UUID" desc:"If set to true, rely on the LDAP Server to generate a unique ID for users and groups, like when using 'entryUUID' as the user ID attribute."`
+	UsePasswordModExOp bool   `yaml:"use_password_modify_exop" env:"GRAPH_LDAP_SERVER_USE_PASSWORD_MODIFY_EXOP" desc:"User the Password Modify Extended Operation for updating user passwords."`
+	WriteEnabled       bool   `yaml:"write_enabled" env:"GRAPH_LDAP_SERVER_WRITE_ENABLED" desc:"Allow to create, modify and delete LDAP users via GRAPH API. This is only works when the default Schema is used."`
 
 	UserBaseDN               string `yaml:"user_base_dn" env:"LDAP_USER_BASE_DN;GRAPH_LDAP_USER_BASE_DN" desc:"Search base DN for looking up LDAP users."`
-	UserSearchScope          string `yaml:"user_search_scope" env:"LDAP_USER_SCOPE;GRAPH_LDAP_USER_SCOPE" desc:"LDAP search scope to use when looking up users ('base', 'one', 'sub')."`
-	UserFilter               string `yaml:"user_filter" env:"LDAP_USER_FILTER;GRAPH_LDAP_USER_FILTER" desc:"LDAP filter to add to the default filters for user search (e.g. '(objectclass=ownCloud)')."`
+	UserSearchScope          string `yaml:"user_search_scope" env:"LDAP_USER_SCOPE;GRAPH_LDAP_USER_SCOPE" desc:"LDAP search scope to use when looking up users. Supported scopes are 'base', 'one' and 'sub'."`
+	UserFilter               string `yaml:"user_filter" env:"LDAP_USER_FILTER;GRAPH_LDAP_USER_FILTER" desc:"LDAP filter to add to the default filters for user search like '(objectclass=ownCloud)'."`
 	UserObjectClass          string `yaml:"user_objectclass" env:"LDAP_USER_OBJECTCLASS;GRAPH_LDAP_USER_OBJECTCLASS" desc:"The object class to use for users in the default user search filter ('inetOrgPerson')."`
 	UserEmailAttribute       string `yaml:"user_mail_attribute" env:"LDAP_USER_SCHEMA_MAIL;GRAPH_LDAP_USER_EMAIL_ATTRIBUTE" desc:"LDAP Attribute to use for the email address of users."`
 	UserDisplayNameAttribute string `yaml:"user_displayname_attribute" env:"LDAP_USER_SCHEMA_DISPLAY_NAME;GRAPH_LDAP_USER_DISPLAYNAME_ATTRIBUTE" desc:"LDAP Attribute to use for the displayname of users."`
 	UserNameAttribute        string `yaml:"user_name_attribute" env:"LDAP_USER_SCHEMA_USERNAME;GRAPH_LDAP_USER_NAME_ATTRIBUTE" desc:"LDAP Attribute to use for username of users."`
-	UserIDAttribute          string `yaml:"user_id_attribute" env:"LDAP_USER_SCHEMA_ID;GRAPH_LDAP_USER_UID_ATTRIBUTE" desc:"LDAP Attribute to use as the unique id for users. This should be a stable globally unique id (e.g. a UUID)."`
+	UserIDAttribute          string `yaml:"user_id_attribute" env:"LDAP_USER_SCHEMA_ID;GRAPH_LDAP_USER_UID_ATTRIBUTE" desc:"LDAP Attribute to use as the unique ID for users. This should be a stable globally unique ID like a UUID."`
 
 	GroupBaseDN        string `yaml:"group_base_dn" env:"LDAP_GROUP_BASE_DN;GRAPH_LDAP_GROUP_BASE_DN" desc:"Search base DN for looking up LDAP groups."`
-	GroupSearchScope   string `yaml:"group_search_scope" env:"LDAP_GROUP_SCOPE;GRAPH_LDAP_GROUP_SEARCH_SCOPE" desc:"LDAP search scope to use when looking up gruops ('base', 'one', 'sub')."`
+	GroupSearchScope   string `yaml:"group_search_scope" env:"LDAP_GROUP_SCOPE;GRAPH_LDAP_GROUP_SEARCH_SCOPE" desc:"LDAP search scope to use when looking up groups. Supported scopes are 'base', 'one' and 'sub'."`
 	GroupFilter        string `yaml:"group_filter" env:"LDAP_GROUP_FILTER;GRAPH_LDAP_GROUP_FILTER" desc:"LDAP filter to add to the default filters for group searches."`
 	GroupObjectClass   string `yaml:"group_objectclass" env:"LDAP_GROUP_OBJECTCLASS;GRAPH_LDAP_GROUP_OBJECTCLASS" desc:"The object class to use for groups in the default group search filter ('groupOfNames'). "`
-	GroupNameAttribute string `yaml:"group_name_attribute" env:"LDAP_GROUP_SCHEMA_GROUPNAME;GRAPH_LDAP_GROUP_NAME_ATTRIBUTE" desc:"LDAP Attribute to use for the name of groups"`
-	GroupIDAttribute   string `yaml:"group_id_attribute" env:"LDAP_GROUP_SCHEMA_ID;GRAPH_LDAP_GROUP_ID_ATTRIBUTE" desc:"LDAP Attribute to use as the unique id for groups. This should be a stable globally unique id (e.g. a UUID)."`
+	GroupNameAttribute string `yaml:"group_name_attribute" env:"LDAP_GROUP_SCHEMA_GROUPNAME;GRAPH_LDAP_GROUP_NAME_ATTRIBUTE" desc:"LDAP Attribute to use for the name of groups."`
+	GroupIDAttribute   string `yaml:"group_id_attribute" env:"LDAP_GROUP_SCHEMA_ID;GRAPH_LDAP_GROUP_ID_ATTRIBUTE" desc:"LDAP Attribute to use as the unique id for groups. This should be a stable globally unique ID like a UUID."`
 }
 
 type Identity struct {
-	Backend string `yaml:"backend" env:"GRAPH_IDENTITY_BACKEND" desc:"The user identity backend to use, defaults to 'ldap', can be 'cs3'."`
+	Backend string `yaml:"backend" env:"GRAPH_IDENTITY_BACKEND" desc:"The user identity backend to use. Supported backend types are 'ldap' and 'cs3'."`
 	LDAP    LDAP   `yaml:"ldap"`
 }
 
 // Events combines the configuration options for the event bus.
 type Events struct {
-	Endpoint string `yaml:"endpoint" env:"GRAPH_EVENTS_ENDPOINT" desc:"the address of the streaming service"`
-	Cluster  string `yaml:"cluster" env:"GRAPH_EVENTS_CLUSTER" desc:"the clusterID of the streaming service. Mandatory when using nats"`
+	Endpoint string `yaml:"endpoint" env:"GRAPH_EVENTS_ENDPOINT" desc:"The address of the streaming service."`
+	Cluster  string `yaml:"cluster" env:"GRAPH_EVENTS_CLUSTER" desc:"The clusterID of the streaming service. Mandatory when using the NATS service."`
 }
diff --git a/services/graph/pkg/config/debug.go b/services/graph/pkg/config/debug.go
index bf139205d8a..86376aa3098 100644
--- a/services/graph/pkg/config/debug.go
+++ b/services/graph/pkg/config/debug.go
@@ -3,7 +3,7 @@ package config
 // Debug defines the available debug configuration.
 type Debug struct {
 	Addr   string `yaml:"addr" env:"GRAPH_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"GRAPH_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"GRAPH_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"GRAPH_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"GRAPH_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"GRAPH_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
diff --git a/services/graph/pkg/config/defaults/defaultconfig.go b/services/graph/pkg/config/defaults/defaultconfig.go
index 47379b777bd..da9ef0ede89 100644
--- a/services/graph/pkg/config/defaults/defaultconfig.go
+++ b/services/graph/pkg/config/defaults/defaultconfig.go
@@ -36,7 +36,6 @@ func DefaultConfig() *config.Config {
 			WebDavBase:   "https://localhost:9200",
 			WebDavPath:   "/dav/spaces/",
 			DefaultQuota: "1000000000",
-			Insecure:     false,
 		},
 		Identity: config.Identity{
 			Backend: "ldap",
diff --git a/services/graph/pkg/identity/ldap.go b/services/graph/pkg/identity/ldap.go
index a801c9510b4..398fabaca63 100644
--- a/services/graph/pkg/identity/ldap.go
+++ b/services/graph/pkg/identity/ldap.go
@@ -11,6 +11,7 @@ import (
 	"github.com/gofrs/uuid"
 	ldapdn "github.com/libregraph/idm/pkg/ldapdn"
 	libregraph "github.com/owncloud/libre-graph-api-go"
+	oldap "github.com/owncloud/ocis/v2/ocis-pkg/ldap"
 	"github.com/owncloud/ocis/v2/ocis-pkg/log"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/config"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/service/v0/errorcode"
@@ -116,7 +117,7 @@ func (i *LDAP) CreateUser(ctx context.Context, user libregraph.User) (*libregrap
 		return nil, errReadOnly
 	}
 	ar := ldap.AddRequest{
-		DN: fmt.Sprintf("uid=%s,%s", *user.OnPremisesSamAccountName, i.userBaseDN),
+		DN: fmt.Sprintf("uid=%s,%s", oldap.EscapeDNAttributeValue(*user.OnPremisesSamAccountName), i.userBaseDN),
 		Attributes: []ldap.Attribute{
 			// inetOrgPerson requires "cn"
 			{
@@ -691,7 +692,7 @@ func (i *LDAP) CreateGroup(ctx context.Context, group libregraph.Group) (*libreg
 		return nil, errorcode.New(errorcode.NotAllowed, "server is configured read-only")
 	}
 	ar := ldap.AddRequest{
-		DN: fmt.Sprintf("cn=%s,%s", *group.DisplayName, i.groupBaseDN),
+		DN: fmt.Sprintf("cn=%s,%s", oldap.EscapeDNAttributeValue(*group.DisplayName), i.groupBaseDN),
 		Attributes: []ldap.Attribute{
 			{
 				Type: i.groupAttributeMap.name,
diff --git a/services/graph/pkg/service/v0/graph.go b/services/graph/pkg/service/v0/graph.go
index 9117b56b1c1..6853754a5cc 100644
--- a/services/graph/pkg/service/v0/graph.go
+++ b/services/graph/pkg/service/v0/graph.go
@@ -75,7 +75,6 @@ type Graph struct {
 	logger               *log.Logger
 	identityBackend      identity.Backend
 	gatewayClient        GatewayClient
-	httpClient           HTTPClient
 	roleService          settingssvc.RoleService
 	spacePropertiesCache *ttlcache.Cache
 	eventsPublisher      events.Publisher
@@ -91,11 +90,6 @@ func (g Graph) GetGatewayClient() GatewayClient {
 	return g.gatewayClient
 }
 
-// GetClient returns a gateway client to talk to reva
-func (g Graph) GetHTTPClient() HTTPClient {
-	return g.httpClient
-}
-
 func (g Graph) publishEvent(ev interface{}) {
 	if err := events.Publish(g.eventsPublisher, ev); err != nil {
 		g.logger.Error().
diff --git a/services/graph/pkg/service/v0/option.go b/services/graph/pkg/service/v0/option.go
index 90a2b1b72df..752c7de3c75 100644
--- a/services/graph/pkg/service/v0/option.go
+++ b/services/graph/pkg/service/v0/option.go
@@ -21,7 +21,6 @@ type Options struct {
 	Middleware      []func(http.Handler) http.Handler
 	GatewayClient   GatewayClient
 	IdentityBackend identity.Backend
-	HTTPClient      HTTPClient
 	RoleService     settingssvc.RoleService
 	RoleManager     *roles.Manager
 	EventsPublisher events.Publisher
@@ -73,13 +72,6 @@ func WithIdentityBackend(val identity.Backend) Option {
 	}
 }
 
-// WithHTTPClient provides a function to set the http client option.
-func WithHTTPClient(val HTTPClient) Option {
-	return func(o *Options) {
-		o.HTTPClient = val
-	}
-}
-
 // RoleService provides a function to set the RoleService option.
 func RoleService(val settingssvc.RoleService) Option {
 	return func(o *Options) {
diff --git a/services/graph/pkg/service/v0/service.go b/services/graph/pkg/service/v0/service.go
index 75066e61d87..4f6799339af 100644
--- a/services/graph/pkg/service/v0/service.go
+++ b/services/graph/pkg/service/v0/service.go
@@ -136,15 +136,6 @@ func NewService(opts ...Option) Service {
 		svc.identityBackend = options.IdentityBackend
 	}
 
-	if options.HTTPClient == nil {
-		http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{
-			InsecureSkipVerify: options.Config.Spaces.Insecure, //nolint:gosec
-		}
-		svc.httpClient = &http.Client{}
-	} else {
-		svc.httpClient = options.HTTPClient
-	}
-
 	if options.RoleService == nil {
 		svc.roleService = settingssvc.NewRoleService("com.owncloud.api.settings", grpc.DefaultClient)
 	} else {
diff --git a/services/groups/pkg/config/config.go b/services/groups/pkg/config/config.go
index 569aa46406d..e792a17f2b8 100644
--- a/services/groups/pkg/config/config.go
+++ b/services/groups/pkg/config/config.go
@@ -20,7 +20,7 @@ type Config struct {
 
 	SkipUserGroupsInToken bool `yaml:"skip_user_groups_in_token" env:"GROUPS_SKIP_USER_GROUPS_IN_TOKEN" desc:"Disables the loading of user's group memberships from the reva access token."`
 
-	Driver  string  `yaml:"driver" desc:"The driver which should be used by the groups service (e.g. ldap)."`
+	Driver  string  `yaml:"driver" desc:"The driver which should be used by the groups service like 'ldap'."`
 	Drivers Drivers `yaml:"drivers"`
 
 	Supervised bool            `yaml:"-"`
@@ -46,15 +46,15 @@ type Service struct {
 
 type Debug struct {
 	Addr   string `yaml:"addr" env:"GROUPS_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"GROUPS_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"GROUPS_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"GROUPS_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"GROUPS_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"GROUPS_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
 
 type GRPCConfig struct {
 	Addr      string `yaml:"addr" env:"GROUPS_GRPC_ADDR" desc:"The bind address of the GRPC service."`
 	Namespace string `yaml:"-"`
-	Protocol  string `yaml:"protocol" env:"GROUPS_GRPC_PROTOCOL" desc:"The transport protocol of the grpc service."`
+	Protocol  string `yaml:"protocol" env:"GROUPS_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
 }
 
 type Drivers struct {
@@ -73,31 +73,31 @@ type LDAPDriver struct {
 	BindPassword     string          `yaml:"bind_password" env:"LDAP_BIND_PASSWORD;GROUPS_LDAP_BIND_PASSWORD" desc:"Password to use for authenticating the 'bind_dn'."`
 	UserBaseDN       string          `yaml:"user_base_dn" env:"LDAP_USER_BASE_DN;GROUPS_LDAP_USER_BASE_DN" desc:"Search base DN for looking up LDAP users."`
 	GroupBaseDN      string          `yaml:"group_base_dn" env:"LDAP_GROUP_BASE_DN;GROUPS_LDAP_GROUP_BASE_DN" desc:"Search base DN for looking up LDAP groups."`
-	UserScope        string          `yaml:"user_scope" env:"LDAP_USER_SCOPE;GROUPS_LDAP_USER_SCOPE" desc:"LDAP search scope to use when looking up users ('base', 'one', 'sub')."`
-	GroupScope       string          `yaml:"group_scope" env:"LDAP_GROUP_SCOPE;GROUPS_LDAP_GROUP_SCOPE" desc:"LDAP search scope to use when looking up gruops ('base', 'one', 'sub')."`
-	UserFilter       string          `yaml:"user_filter" env:"LDAP_USER_FILTER;GROUPS_LDAP_USER_FILTER" desc:"LDAP filter to add to the default filters for user search (e.g. '(objectclass=ownCloud)')."`
+	UserScope        string          `yaml:"user_scope" env:"LDAP_USER_SCOPE;GROUPS_LDAP_USER_SCOPE" desc:"LDAP search scope to use when looking up users. Supported scopes are 'base', 'one' and 'sub'."`
+	GroupScope       string          `yaml:"group_scope" env:"LDAP_GROUP_SCOPE;GROUPS_LDAP_GROUP_SCOPE" desc:"LDAP search scope to use when looking up groups. Supported scopes are 'base', 'one' and 'sub'."`
+	UserFilter       string          `yaml:"user_filter" env:"LDAP_USER_FILTER;GROUPS_LDAP_USER_FILTER" desc:"LDAP filter to add to the default filters for user search like '(objectclass=ownCloud)'."`
 	GroupFilter      string          `yaml:"group_filter" env:"LDAP_GROUP_FILTER;GROUPS_LDAP_GROUP_FILTER" desc:"LDAP filter to add to the default filters for group searches."`
 	UserObjectClass  string          `yaml:"user_object_class" env:"LDAP_USER_OBJECTCLASS;GROUPS_LDAP_USER_OBJECTCLASS" desc:"The object class to use for users in the default user search filter ('inetOrgPerson')."`
 	GroupObjectClass string          `yaml:"group_object_class" env:"LDAP_GROUP_OBJECTCLASS;GROUPS_LDAP_GROUP_OBJECTCLASS" desc:"The object class to use for groups in the default group search filter ('groupOfNames')."`
-	IDP              string          `yaml:"idp" env:"OCIS_URL;OCIS_OIDC_ISSUER;GROUPS_IDP_URL" desc:"The identity provider value to set in the groupids of the CS3 group objects for groups returned by this group provider."`
+	IDP              string          `yaml:"idp" env:"OCIS_URL;OCIS_OIDC_ISSUER;GROUPS_IDP_URL" desc:"The identity provider value to set in the group IDs of the CS3 group objects for groups returned by this group provider."`
 	UserSchema       LDAPUserSchema  `yaml:"user_schema"`
 	GroupSchema      LDAPGroupSchema `yaml:"group_schema"`
 }
 
 type LDAPUserSchema struct {
-	ID              string `yaml:"id" env:"LDAP_USER_SCHEMA_ID;GROUPS_LDAP_USER_SCHEMA_ID" desc:"LDAP Attribute to use as the unique id for users. This should be a stable globally unique id (e.g. a UUID)."`
-	IDIsOctetString bool   `yaml:"id_is_octet_string" env:"LDAP_USER_SCHEMA_ID_IS_OCTETSTRING;GROUPS_LDAP_USER_SCHEMA_ID_IS_OCTETSTRING" desc:"Set this to true if the defined 'id' attribute for users is of the 'OCTETSTRING' syntax. This is e.g. required when using the 'objectGUID' attribute of Active Directory for the user ids."`
+	ID              string `yaml:"id" env:"LDAP_USER_SCHEMA_ID;GROUPS_LDAP_USER_SCHEMA_ID" desc:"LDAP Attribute to use as the unique id for users. This should be a stable globally unique id like a UUID."`
+	IDIsOctetString bool   `yaml:"id_is_octet_string" env:"LDAP_USER_SCHEMA_ID_IS_OCTETSTRING;GROUPS_LDAP_USER_SCHEMA_ID_IS_OCTETSTRING" desc:"Set this to true if the defined 'id' attribute for users is of the 'OCTETSTRING' syntax. This is e.g. required when using the 'objectGUID' attribute of Active Directory for the user id's."`
 	Mail            string `yaml:"mail" env:"LDAP_USER_SCHEMA_MAIL;GROUPS_LDAP_USER_SCHEMA_MAIL" desc:"LDAP Attribute to use for the email address of users."`
 	DisplayName     string `yaml:"display_name" env:"LDAP_USER_SCHEMA_DISPLAYNAME;GROUPS_LDAP_USER_SCHEMA_DISPLAYNAME" desc:"LDAP Attribute to use for the displayname of users."`
 	Username        string `yaml:"user_name" env:"LDAP_USER_SCHEMA_USERNAME;GROUPS_LDAP_USER_SCHEMA_USERNAME" desc:"LDAP Attribute to use for username of users."`
 }
 
 type LDAPGroupSchema struct {
-	ID              string `yaml:"id" env:"LDAP_GROUP_SCHEMA_ID;GROUPS_LDAP_GROUP_SCHEMA_ID" desc:"LDAP Attribute to use as the unique id for groups. This should be a stable globally unique id (e.g. a UUID)."`
-	IDIsOctetString bool   `yaml:"id_is_octet_string" env:"LDAP_GROUP_SCHEMA_ID_IS_OCTETSTRING;GROUPS_LDAP_GROUP_SCHEMA_ID_IS_OCTETSTRING" desc:"Set this to true if the defined 'id' attribute for groups is of the 'OCTETSTRING' syntax. This is e.g. required when using the 'objectGUID' attribute of Active Directory for the group ids."`
+	ID              string `yaml:"id" env:"LDAP_GROUP_SCHEMA_ID;GROUPS_LDAP_GROUP_SCHEMA_ID" desc:"LDAP Attribute to use as the unique id for groups. This should be a stable globally unique ID like a UUID."`
+	IDIsOctetString bool   `yaml:"id_is_octet_string" env:"LDAP_GROUP_SCHEMA_ID_IS_OCTETSTRING;GROUPS_LDAP_GROUP_SCHEMA_ID_IS_OCTETSTRING" desc:"Set this to true if the defined 'id' attribute for groups is of the 'OCTETSTRING' syntax. This is e.g. required when using the 'objectGUID' attribute of Active Directory for the group ID's."`
 	Mail            string `yaml:"mail" env:"LDAP_GROUP_SCHEMA_MAIL;GROUPS_LDAP_GROUP_SCHEMA_MAIL" desc:"LDAP Attribute to use for the email address of groups (can be empty)."`
-	DisplayName     string `yaml:"display_name" env:"LDAP_GROUP_SCHEMA_DISPLAYNAME;GROUPS_LDAP_GROUP_SCHEMA_DISPLAYNAME" desc:"LDAP Attribute to use for the displayname of groups (often the same as groupname attribute)"`
-	Groupname       string `yaml:"group_name" env:"LDAP_GROUP_SCHEMA_GROUPNAME;GROUPS_LDAP_GROUP_SCHEMA_GROUPNAME" desc:"LDAP Attribute to use for the name of groups"`
+	DisplayName     string `yaml:"display_name" env:"LDAP_GROUP_SCHEMA_DISPLAYNAME;GROUPS_LDAP_GROUP_SCHEMA_DISPLAYNAME" desc:"LDAP Attribute to use for the displayname of groups (often the same as groupname attribute)."`
+	Groupname       string `yaml:"group_name" env:"LDAP_GROUP_SCHEMA_GROUPNAME;GROUPS_LDAP_GROUP_SCHEMA_GROUPNAME" desc:"LDAP Attribute to use for the name of groups."`
 	Member          string `yaml:"member" env:"LDAP_GROUP_SCHEMA_MEMBER;GROUPS_LDAP_GROUP_SCHEMA_MEMBER" desc:"LDAP Attribute that is used for group members."`
 }
 
@@ -109,9 +109,9 @@ type OwnCloudSQLDriver struct {
 	DBName             string `yaml:"db_name" env:"GROUPS_OWNCLOUDSQL_DB_NAME" desc:"Name of the owncloud database."`
 	IDP                string `yaml:"idp" env:"GROUPS_OWNCLOUDSQL_IDP" desc:"The identity provider value to set in the userids of the CS3 user objects for users returned by this user provider."`
 	Nobody             int64  `yaml:"nobody" env:"GROUPS_OWNCLOUDSQL_NOBODY" desc:"Fallback number if no numeric UID and GID properties are provided."`
-	JoinUsername       bool   `yaml:"join_username" env:"GROUPS_OWNCLOUDSQL_JOIN_USERNAME" desc:"Join the user properties table to read usernames (boolean)"`
-	JoinOwnCloudUUID   bool   `yaml:"join_owncloud_uuid" env:"GROUPS_OWNCLOUDSQL_JOIN_OWNCLOUD_UUID" desc:"Join the user properties table to read user ids (boolean)."`
-	EnableMedialSearch bool   `yaml:"enable_medial_search" env:"GROUPS_OWNCLOUDSQL_ENABLE_MEDIAL_SEARCH" desc:"Allow 'medial search' when searching for users instead of just doing a prefix search. (Allows finding 'Alice' when searching for 'lic'.)"`
+	JoinUsername       bool   `yaml:"join_username" env:"GROUPS_OWNCLOUDSQL_JOIN_USERNAME" desc:"Join the user properties table to read usernames."`
+	JoinOwnCloudUUID   bool   `yaml:"join_owncloud_uuid" env:"GROUPS_OWNCLOUDSQL_JOIN_OWNCLOUD_UUID" desc:"Join the user properties table to read user IDs."`
+	EnableMedialSearch bool   `yaml:"enable_medial_search" env:"GROUPS_OWNCLOUDSQL_ENABLE_MEDIAL_SEARCH" desc:"Allow 'medial search' when searching for users instead of just doing a prefix search. This allows finding 'Alice' when searching for 'lic'."`
 }
 
 type JSONDriver struct {
diff --git a/services/idm/pkg/config/config.go b/services/idm/pkg/config/config.go
index 567765b3011..f9c62063946 100644
--- a/services/idm/pkg/config/config.go
+++ b/services/idm/pkg/config/config.go
@@ -17,24 +17,24 @@ type Config struct {
 	Debug   Debug    `yaml:"debug"`
 
 	IDM             Settings `yaml:"idm"`
-	CreateDemoUsers bool     `yaml:"create_demo_users" env:"IDM_CREATE_DEMO_USERS;ACCOUNTS_DEMO_USERS_AND_GROUPS" desc:"Flag to enabe/disable the creation of the demo users"`
+	CreateDemoUsers bool     `yaml:"create_demo_users" env:"IDM_CREATE_DEMO_USERS;ACCOUNTS_DEMO_USERS_AND_GROUPS" desc:"Flag to enable or disable the creation of the demo users."`
 
 	ServiceUserPasswords ServiceUserPasswords `yaml:"service_user_passwords"`
-	AdminUserID          string               `yaml:"admin_user_id" env:"OCIS_ADMIN_USER_ID;IDM_ADMIN_USER_ID" desc:"ID of a user, that should receive admin privileges."`
+	AdminUserID          string               `yaml:"admin_user_id" env:"OCIS_ADMIN_USER_ID;IDM_ADMIN_USER_ID" desc:"ID of the user that should receive admin privileges."`
 
 	Context context.Context `yaml:"-"`
 }
 
 type Settings struct {
-	LDAPSAddr    string `yaml:"ldaps_addr" env:"IDM_LDAPS_ADDR" desc:"Listen address for the ldaps listener (ip-addr:port)"`
-	Cert         string `yaml:"cert" env:"IDM_LDAPS_CERT" desc:"File name of the TLS server certificate for the ldaps listener"`
-	Key          string `yaml:"key" env:"IDM_LDAPS_KEY" desc:"File name for the TLS certificate key for the server certificate"`
-	DatabasePath string `yaml:"database" env:"IDM_DATABASE_PATH" desc:"Full path to the idm backend database"`
+	LDAPSAddr    string `yaml:"ldaps_addr" env:"IDM_LDAPS_ADDR" desc:"Listen address for the LDAPS listener (ip-addr:port)."`
+	Cert         string `yaml:"cert" env:"IDM_LDAPS_CERT" desc:"File name of the TLS server certificate for the LDAPS listener."`
+	Key          string `yaml:"key" env:"IDM_LDAPS_KEY" desc:"File name for the TLS certificate key for the server certificate."`
+	DatabasePath string `yaml:"database" env:"IDM_DATABASE_PATH" desc:"Full path to the IDM backend database."`
 }
 
 type ServiceUserPasswords struct {
-	OcisAdmin string `yaml:"admin_password" env:"IDM_ADMIN_PASSWORD" desc:"Password to set for the ocis \"admin\" user. Either cleartext or an argon2id hash"`
-	Idm       string `yaml:"idm_password" env:"IDM_SVC_PASSWORD" desc:"Password to set for the \"idm\" service user. Either cleartext or an argon2id hash"`
-	Reva      string `yaml:"reva_password" env:"IDM_REVASVC_PASSWORD" desc:"Password to set for the \"reva\" service user. Either cleartext or an argon2id hash"`
-	Idp       string `yaml:"idp_password" env:"IDM_IDPSVC_PASSWORD" desc:"Password to set for the \"idp\" service user. Either cleartext or an argon2id hash"`
+	OcisAdmin string `yaml:"admin_password" env:"IDM_ADMIN_PASSWORD" desc:"Password to set for the oCIS \"admin\" user. Either cleartext or an argon2id hash."`
+	Idm       string `yaml:"idm_password" env:"IDM_SVC_PASSWORD" desc:"Password to set for the \"idm\" service user. Either cleartext or an argon2id hash."`
+	Reva      string `yaml:"reva_password" env:"IDM_REVASVC_PASSWORD" desc:"Password to set for the \"reva\" service user. Either cleartext or an argon2id hash."`
+	Idp       string `yaml:"idp_password" env:"IDM_IDPSVC_PASSWORD" desc:"Password to set for the \"idp\" service user. Either cleartext or an argon2id hash."`
 }
diff --git a/services/idm/pkg/config/debug.go b/services/idm/pkg/config/debug.go
index 2f3218e5ed0..a5814cbe51f 100644
--- a/services/idm/pkg/config/debug.go
+++ b/services/idm/pkg/config/debug.go
@@ -3,7 +3,7 @@ package config
 // Debug defines the available debug configuration.
 type Debug struct {
 	Addr   string `yaml:"addr" env:"IDM_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"IDM_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"IDM_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"IDM_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"IDM_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"IDM_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
diff --git a/services/idp/pkg/config/config.go b/services/idp/pkg/config/config.go
index 1623f6062b2..385ff180d33 100644
--- a/services/idp/pkg/config/config.go
+++ b/services/idp/pkg/config/config.go
@@ -32,23 +32,23 @@ type Config struct {
 
 // Ldap defines the available LDAP configuration.
 type Ldap struct {
-	URI       string `yaml:"uri" env:"LDAP_URI;IDP_LDAP_URI" desc:"Url of the LDAP service to use as idp."`
-	TLSCACert string `yaml:"cacert" env:"LDAP_CACERT;IDP_LDAP_TLS_CACERT" desc:"Path to the tls cert for the ldap service."`
+	URI       string `yaml:"uri" env:"LDAP_URI;IDP_LDAP_URI" desc:"Url of the LDAP service to use as IDP."`
+	TLSCACert string `yaml:"cacert" env:"LDAP_CACERT;IDP_LDAP_TLS_CACERT" desc:"Path to the TLS cert for the LDAP service."`
 
 	BindDN       string `yaml:"bind_dn" env:"LDAP_BIND_DN;IDP_LDAP_BIND_DN" desc:"LDAP DN to use for simple bind authentication with the target LDAP server."`
 	BindPassword string `yaml:"bind_password" env:"LDAP_BIND_PASSWORD;IDP_LDAP_BIND_PASSWORD" desc:"Password to use for authenticating the 'bind_dn'."`
 
 	BaseDN string `yaml:"base_dn" env:"LDAP_USER_BASE_DN;IDP_LDAP_BASE_DN" desc:"Search base DN for looking up LDAP users."`
-	Scope  string `yaml:"scope" env:"LDAP_USER_SCOPE;IDP_LDAP_SCOPE" desc:"LDAP search scope to use when looking up users ('base', 'one', 'sub')."`
+	Scope  string `yaml:"scope" env:"LDAP_USER_SCOPE;IDP_LDAP_SCOPE" desc:"LDAP search scope to use when looking up users. Supported scopes are 'base', 'one' and 'sub'."`
 
-	LoginAttribute    string `yaml:"login_attribute" env:"IDP_LDAP_LOGIN_ATTRIBUTE" desc:"LDAP User attribute to use for login (e.g. uid)."`
-	EmailAttribute    string `yaml:"email_attribute" env:"LDAP_USER_SCHEMA_MAIL;IDP_LDAP_EMAIL_ATTRIBUTE" desc:"LDAP User email attribute (e.g. mail)."`
-	NameAttribute     string `yaml:"name_attribute" env:"LDAP_USER_SCHEMA_USERNAME;IDP_LDAP_NAME_ATTRIBUTE" desc:"LDAP User name attribute (e.g. displayName)."`
-	UUIDAttribute     string `yaml:"uuid_attribute" env:"LDAP_USER_SCHEMA_ID;IDP_LDAP_UUID_ATTRIBUTE" desc:"LDAP User uuid attribute (e.g. uid)."`
-	UUIDAttributeType string `yaml:"uuid_attribute_type" env:"IDP_LDAP_UUID_ATTRIBUTE_TYPE" desc:"LDAP User uuid attribute type (e.g. text)."`
+	LoginAttribute    string `yaml:"login_attribute" env:"IDP_LDAP_LOGIN_ATTRIBUTE" desc:"LDAP User attribute to use for login like 'uid'."`
+	EmailAttribute    string `yaml:"email_attribute" env:"LDAP_USER_SCHEMA_MAIL;IDP_LDAP_EMAIL_ATTRIBUTE" desc:"LDAP User email attribute like 'mail'."`
+	NameAttribute     string `yaml:"name_attribute" env:"LDAP_USER_SCHEMA_USERNAME;IDP_LDAP_NAME_ATTRIBUTE" desc:"LDAP User name attribute like 'displayName'."`
+	UUIDAttribute     string `yaml:"uuid_attribute" env:"LDAP_USER_SCHEMA_ID;IDP_LDAP_UUID_ATTRIBUTE" desc:"LDAP User uuid attribute like 'uid'."`
+	UUIDAttributeType string `yaml:"uuid_attribute_type" env:"IDP_LDAP_UUID_ATTRIBUTE_TYPE" desc:"LDAP User uuid attribute type like 'text'."`
 
-	Filter      string `yaml:"filter" env:"LDAP_USER_FILTER;IDP_LDAP_FILTER" desc:"LDAP filter to add to the default filters for user search (e.g. '(objectclass=ownCloud)')."`
-	ObjectClass string `yaml:"objectclass" env:"LDAP_USER_OBJECTCLASS;IDP_LDAP_OBJECTCLASS" desc:"LDAP User ObjectClass (e.g. inetOrgPerson)."`
+	Filter      string `yaml:"filter" env:"LDAP_USER_FILTER;IDP_LDAP_FILTER" desc:"LDAP filter to add to the default filters for user search like '(objectclass=ownCloud)'."`
+	ObjectClass string `yaml:"objectclass" env:"LDAP_USER_OBJECTCLASS;IDP_LDAP_OBJECTCLASS" desc:"LDAP User ObjectClass like 'inetOrgPerson'."`
 }
 
 // Asset defines the available asset configuration.
@@ -72,22 +72,22 @@ type Settings struct {
 
 	Iss string `yaml:"iss" env:"OCIS_URL;OCIS_OIDC_ISSUER;IDP_ISS" desc:"The OIDC issuer URL to use."`
 
-	IdentityManager string `yaml:"identity_manager" env:"IDP_IDENTITY_MANAGER" desc:"The identity manager implementation to use, defaults to 'ldap', can be changed to 'cs3', 'kc', 'libregraph', 'cookie' or 'guest'."`
+	IdentityManager string `yaml:"identity_manager" env:"IDP_IDENTITY_MANAGER" desc:"The identity manager implementation to use. Supported identity managers are 'ldap', 'cs3', 'kc', 'libregraph', 'cookie' and 'guest'."`
 
-	URIBasePath string `yaml:"uri_base_path" env:"IDP_URI_BASE_PATH" desc:"Idp uri base path (defaults to \"\")."`
+	URIBasePath string `yaml:"uri_base_path" env:"IDP_URI_BASE_PATH" desc:"IDP uri base path (defaults to \"\")."`
 
-	SignInURI    string `yaml:"sign_in_uri" env:"IDP_SIGN_IN_URI" desc:"Idp sign-in url."`
-	SignedOutURI string `yaml:"signed_out_uri" env:"IDP_SIGN_OUT_URI" desc:"Idp sign-out url."`
+	SignInURI    string `yaml:"sign_in_uri" env:"IDP_SIGN_IN_URI" desc:"IDP sign-in url."`
+	SignedOutURI string `yaml:"signed_out_uri" env:"IDP_SIGN_OUT_URI" desc:"IDP sign-out url."`
 
-	AuthorizationEndpointURI string `yaml:"authorization_endpoint_uri" env:"IDP_ENDPOINT_URI" desc:"Url of IDP endpoint."`
+	AuthorizationEndpointURI string `yaml:"authorization_endpoint_uri" env:"IDP_ENDPOINT_URI" desc:"URL of the IDP endpoint."`
 	EndsessionEndpointURI    string `yaml:"-"` // unused, not supported by lico-idp
 
-	Insecure bool `yaml:"insecure" env:"LDAP_INSECURE;IDP_INSECURE" desc:"Allow insecure connections to the user backend (eg. LDAP, CS3 api, ...)."`
+	Insecure bool `yaml:"insecure" env:"LDAP_INSECURE;IDP_INSECURE" desc:"Allow insecure connections to the user backend like LDAP, CS3 api, ..."`
 
 	TrustedProxy []string `yaml:"trusted_proxy"` //TODO: how to configure this via env?
 
 	AllowScope                     []string `yaml:"allow_scope"` // TODO: is this even needed?
-	AllowClientGuests              bool     `yaml:"allow_client_guests" env:"IDP_ALLOW_CLIENT_GUESTS" desc:"Allow guest clients to access ocis."`
+	AllowClientGuests              bool     `yaml:"allow_client_guests" env:"IDP_ALLOW_CLIENT_GUESTS" desc:"Allow guest clients to access oCIS."`
 	AllowDynamicClientRegistration bool     `yaml:"allow_dynamic_client_registration" env:"IDP_ALLOW_DYNAMIC_CLIENT_REGISTRATION" desc:"Allow dynamic client registration."`
 
 	EncryptionSecretFile string `yaml:"encrypt_secret_file" env:"IDP_ENCRYPTION_SECRET_FILE" desc:"Path to the encryption secret file, if unset, a new certificate will be autogenerated upon each restart, thus invalidating all existing sessions."`
@@ -104,15 +104,15 @@ type Settings struct {
 	IdentifierUILocales               []string
 
 	SigningKid             string   `yaml:"signing_kid" env:"IDP_SIGNING_KID" desc:"Value of the KID (Key ID) field which is used in created tokens to uniquely identify the signing-private-key."`
-	SigningMethod          string   `yaml:"signing_method" env:"IDP_SIGNING_METHOD" desc:"Signing method of idp requests (e.g. PS256)"`
-	SigningPrivateKeyFiles []string `yaml:"signing_private_key_files" env:"IDP_SIGNING_PRIVATE_KEY_FILES" desc:"Private key files for signing idp requests."`
-	ValidationKeysPath     string   `yaml:"validation_keys_path" env:"IDP_VALIDATION_KEYS_PATH" desc:"Path to validation keys for idp requests."`
+	SigningMethod          string   `yaml:"signing_method" env:"IDP_SIGNING_METHOD" desc:"Signing method of IDP requests like 'PS256'"`
+	SigningPrivateKeyFiles []string `yaml:"signing_private_key_files" env:"IDP_SIGNING_PRIVATE_KEY_FILES" desc:"Private key files for signing IDP requests."`
+	ValidationKeysPath     string   `yaml:"validation_keys_path" env:"IDP_VALIDATION_KEYS_PATH" desc:"Path to validation keys for IDP requests."`
 
 	CookieBackendURI string
 	CookieNames      []string
 
-	AccessTokenDurationSeconds        uint64 `yaml:"access_token_duration_seconds" env:"IDP_ACCESS_TOKEN_EXPIRATION" desc:"Expiration time for idp access token (in seconds)."`
-	IDTokenDurationSeconds            uint64 `yaml:"id_token_duration_seconds" env:"IDP_ID_TOKEN_EXPIRATION" desc:"Expiration time for idp id tokens (in seconds)."`
-	RefreshTokenDurationSeconds       uint64 `yaml:"refresh_token_duration_seconds" env:"IDP_REFRESH_TOKEN_EXPIRATION" desc:"Expiration time for refresh tokens (in seconds)."`
-	DyamicClientSecretDurationSeconds uint64 `yaml:"dynamic_client_secret_duration_seconds" env:"IDP_DYNAMIC_CLIENT_SECRET_DURATION" desc:"Expiration time for dynamic clients (in seconds)."`
+	AccessTokenDurationSeconds        uint64 `yaml:"access_token_duration_seconds" env:"IDP_ACCESS_TOKEN_EXPIRATION" desc:"Expiration time in seconds for IDP access token."`
+	IDTokenDurationSeconds            uint64 `yaml:"id_token_duration_seconds" env:"IDP_ID_TOKEN_EXPIRATION" desc:"Expiration time in seconds for IDP ID tokens."`
+	RefreshTokenDurationSeconds       uint64 `yaml:"refresh_token_duration_seconds" env:"IDP_REFRESH_TOKEN_EXPIRATION" desc:"Expiration time in seconds for refresh tokens."`
+	DyamicClientSecretDurationSeconds uint64 `yaml:"dynamic_client_secret_duration_seconds" env:"IDP_DYNAMIC_CLIENT_SECRET_DURATION" desc:"Expiration time in seconds for dynamic clients."`
 }
diff --git a/services/idp/pkg/config/debug.go b/services/idp/pkg/config/debug.go
index 25004b69005..7a3a6671d92 100644
--- a/services/idp/pkg/config/debug.go
+++ b/services/idp/pkg/config/debug.go
@@ -3,7 +3,7 @@ package config
 // Debug defines the available debug configuration.
 type Debug struct {
 	Addr   string `yaml:"addr" env:"IDP_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"IDP_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"IDP_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"IDP_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"IDP_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"IDP_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
diff --git a/services/nats/pkg/config/config.go b/services/nats/pkg/config/config.go
index 3c63b11a759..9e969cc9968 100644
--- a/services/nats/pkg/config/config.go
+++ b/services/nats/pkg/config/config.go
@@ -23,7 +23,7 @@ type Config struct {
 // Nats is the nats config
 type Nats struct {
 	Host      string `yaml:"host" env:"NATS_NATS_HOST" desc:"Bind address."`
-	Port      int    `yaml:"port" env:"NATS_NATS_PORT" desc:"Bind port:"`
+	Port      int    `yaml:"port" env:"NATS_NATS_PORT" desc:"Bind port."`
 	ClusterID string `yaml:"clusterid" env:"NATS_NATS_CLUSTER_ID" desc:"ID of the NATS cluster."`
 	StoreDir  string `yaml:"store_dir" env:"NATS_NATS_STORE_DIR" desc:"Path for the NATS JetStream persistence directory."`
 }
diff --git a/services/nats/pkg/config/debug.go b/services/nats/pkg/config/debug.go
index da1ed930241..b7f61e1e420 100644
--- a/services/nats/pkg/config/debug.go
+++ b/services/nats/pkg/config/debug.go
@@ -3,7 +3,7 @@ package config
 // Debug defines the available debug configuration.
 type Debug struct {
 	Addr   string `yaml:"addr" env:"NATS_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"NATS_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"NATS_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"NATS_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"NATS_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"NATS_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
diff --git a/services/notifications/pkg/config/config.go b/services/notifications/pkg/config/config.go
index 3345b566afc..7c605ca8469 100644
--- a/services/notifications/pkg/config/config.go
+++ b/services/notifications/pkg/config/config.go
@@ -25,15 +25,15 @@ type Notifications struct {
 	SMTP              SMTP   `yaml:"SMTP"`
 	Events            Events `yaml:"events"`
 	RevaGateway       string `yaml:"reva_gateway" env:"REVA_GATEWAY;NOTIFICATIONS_REVA_GATEWAY" desc:"CS3 gateway used to look up user metadata"`
-	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 for the access to resources from other services."`
+	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."`
 }
 
 // SMTP combines the smtp configuration options.
 type SMTP struct {
-	Host     string `yaml:"smtp_host" env:"NOTIFICATIONS_SMTP_HOST" desc:"SMTP host, to connect to."`
-	Port     string `yaml:"smtp_port" env:"NOTIFICATIONS_SMTP_PORT" desc:"Port of the SMTP host, to connect to."`
-	Sender   string `yaml:"smtp_sender" env:"NOTIFICATIONS_SMTP_SENDER" desc:"Sender of emails, that will be sent."`
-	Password string `yaml:"smtp_password" env:"NOTIFICATIONS_SMTP_PASSWORD" desc:"Password of the SMTP host, to connect to."`
+	Host     string `yaml:"smtp_host" env:"NOTIFICATIONS_SMTP_HOST" desc:"SMTP host to connect to."`
+	Port     string `yaml:"smtp_port" env:"NOTIFICATIONS_SMTP_PORT" desc:"Port of the SMTP host to connect to."`
+	Sender   string `yaml:"smtp_sender" env:"NOTIFICATIONS_SMTP_SENDER" desc:"Sender of emails that will be sent."`
+	Password string `yaml:"smtp_password" env:"NOTIFICATIONS_SMTP_PASSWORD" desc:"Password of the SMTP host to connect to."`
 }
 
 // Events combines the configuration options for the event bus.
diff --git a/services/notifications/pkg/config/debug.go b/services/notifications/pkg/config/debug.go
index 8eac6d526e6..b8d3609fb9d 100644
--- a/services/notifications/pkg/config/debug.go
+++ b/services/notifications/pkg/config/debug.go
@@ -3,7 +3,7 @@ package config
 // Debug defines the available debug configuration.
 type Debug struct {
 	Addr   string `yaml:"addr" env:"NOTIFICATIONS_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"NOTIFICATIONS_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"NOTIFICATIONS_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"NOTIFICATIONS_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"NOTIFICATIONS_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"NOTIFICATIONS_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
diff --git a/services/ocdav/pkg/config/config.go b/services/ocdav/pkg/config/config.go
index ce3b4e1c958..1735ebff420 100644
--- a/services/ocdav/pkg/config/config.go
+++ b/services/ocdav/pkg/config/config.go
@@ -24,12 +24,12 @@ type Config struct {
 	FilesNamespace  string `yaml:"files_namespace" env:"OCDAV_FILES_NAMESPACE" desc:"Jail requests to /dav/files/{username} into this CS3 namespace. Supports template layouting with CS3 User properties."`
 	SharesNamespace string `yaml:"shares_namespace" env:"OCDAV_SHARES_NAMESPACE" desc:"The human readable path for the share jail. Relative to a users personal space root. Upcased intentionally."`
 	// PublicURL used to redirect /s/{token} URLs to
-	PublicURL string `yaml:"public_url" env:"OCIS_URL;OCDAV_PUBLIC_URL" desc:"URL, where oCIS is reachable for users."`
+	PublicURL string `yaml:"public_url" env:"OCIS_URL;OCDAV_PUBLIC_URL" desc:"URL where oCIS is reachable for users."`
 
 	// Insecure certificates allowed when making requests to the gateway
 	Insecure bool `yaml:"insecure" env:"OCIS_INSECURE;OCDAV_INSECURE"`
 	// Timeout in seconds when making requests to the gateway
-	Timeout    int64      `yaml:"gateway_request_timeout" env:"OCDAV_GATEWAY_REQUEST_TIMEOUT" desc:"Request timeout in seconds for requests from the oCDAV service to the gateway service."`
+	Timeout    int64      `yaml:"gateway_request_timeout" env:"OCDAV_GATEWAY_REQUEST_TIMEOUT" desc:"Request timeout in seconds for requests from the oCDAV service to the GATEWAY service."`
 	Middleware Middleware `yaml:"middleware"`
 
 	MachineAuthAPIKey string `yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;OCDAV_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used to validate internal requests necessary for the access to resources from other services."`
@@ -57,15 +57,15 @@ type Service struct {
 
 type Debug struct {
 	Addr   string `yaml:"addr" env:"OCDAV_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"OCDAV_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"OCDAV_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"OCDAV_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"OCDAV_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"OCDAV_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
 
 type HTTPConfig struct {
 	Addr      string `yaml:"addr" env:"OCDAV_HTTP_ADDR" desc:"The bind address of the HTTP service."`
 	Namespace string `yaml:"-"`
-	Protocol  string `yaml:"protocol" env:"OCDAV_HTTP_PROTOCOL" desc:"The transport protocol of the http service."`
+	Protocol  string `yaml:"protocol" env:"OCDAV_HTTP_PROTOCOL" desc:"The transport protocol of the HTTP service."`
 	Prefix    string `yaml:"prefix" env:"OCDAV_HTTP_PREFIX" desc:"A URL path prefix for the handler."`
 }
 
diff --git a/services/ocs/pkg/config/config.go b/services/ocs/pkg/config/config.go
index 2e550cca5e5..5ec5d1f0c85 100644
--- a/services/ocs/pkg/config/config.go
+++ b/services/ocs/pkg/config/config.go
@@ -24,7 +24,7 @@ type Config struct {
 	IdentityManagement IdentityManagement `yaml:"identity_management"`
 
 	AccountBackend    string `yaml:"-"` // we only support cs3 backend, no need to have this configurable
-	MachineAuthAPIKey string `yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;OCS_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used to validate internal requests necessary for the access to resources from other services."`
+	MachineAuthAPIKey string `yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;OCS_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used to validate internal requests necessary to access resources from other services."`
 
 	Context context.Context `yaml:"-"`
 }
diff --git a/services/ocs/pkg/config/debug.go b/services/ocs/pkg/config/debug.go
index ab80432210f..df5035a3f22 100644
--- a/services/ocs/pkg/config/debug.go
+++ b/services/ocs/pkg/config/debug.go
@@ -3,7 +3,7 @@ package config
 // Debug defines the available debug configuration.
 type Debug struct {
 	Addr   string `yaml:"addr" env:"OCS_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"OCS_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"OCS_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"OCS_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"OCS_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"OCS_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
diff --git a/services/proxy/pkg/config/config.go b/services/proxy/pkg/config/config.go
index 236d407dfde..60a881657a3 100644
--- a/services/proxy/pkg/config/config.go
+++ b/services/proxy/pkg/config/config.go
@@ -25,13 +25,13 @@ type Config struct {
 	TokenManager          *TokenManager   `mask:"struct" yaml:"token_manager"`
 	PolicySelector        *PolicySelector `yaml:"policy_selector"`
 	PreSignedURL          PreSignedURL    `yaml:"pre_signed_url"`
-	AccountBackend        string          `yaml:"account_backend" env:"PROXY_ACCOUNT_BACKEND_TYPE" desc:"Account backend the proxy should use, currenly only 'cs3' is possible here."`
+	AccountBackend        string          `yaml:"account_backend" env:"PROXY_ACCOUNT_BACKEND_TYPE" desc:"Account backend the PROXY service should use. Currently only 'cs3' is possible here."`
 	UserOIDCClaim         string          `yaml:"user_oidc_claim" env:"PROXY_USER_OIDC_CLAIM" desc:"The name of an OpenID Connect claim that should be used for resolving users with the account backend. Currently defaults to 'email'."`
-	UserCS3Claim          string          `yaml:"user_cs3_claim" env:"PROXY_USER_CS3_CLAIM" desc:"The name of a CS3 user attribute (claim) that should be mapped to the 'user_oidc_claim'. Currently defaults to 'mail' (other possible values are: 'username', 'displayname')"`
-	MachineAuthAPIKey     string          `mask:"password" yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;PROXY_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used to validate internal requests necessary for the access to resources from other services."`
+	UserCS3Claim          string          `yaml:"user_cs3_claim" env:"PROXY_USER_CS3_CLAIM" desc:"The name of a CS3 user attribute (claim) that should be mapped to the 'user_oidc_claim'. Currently defaults to 'mail'. Supported values are 'username' and 'displayname'."`
+	MachineAuthAPIKey     string          `mask:"password" yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;PROXY_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used to validate internal requests necessary to access resources from other services."`
 	AutoprovisionAccounts bool            `yaml:"auto_provision_accounts" env:"PROXY_AUTOPROVISION_ACCOUNTS" desc:"Set this to 'true' to automatically provsion users that do not yet exist in the users service on-demand upon first signin. 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' (username/password) authentication."`
-	InsecureBackends      bool            `yaml:"insecure_backends" env:"PROXY_INSECURE_BACKENDS" desc:"Disable TLS certificate validation for all http backend connections."`
+	InsecureBackends      bool            `yaml:"insecure_backends" env:"PROXY_INSECURE_BACKENDS" desc:"Disable TLS certificate validation for all HTTP backend connections."`
 	AuthMiddleware        AuthMiddleware  `yaml:"auth_middleware"`
 
 	Context context.Context `yaml:"-" json:"-"`
@@ -84,14 +84,14 @@ type AuthMiddleware struct {
 // with the configured oidc-provider
 type OIDC struct {
 	Issuer        string        `yaml:"issuer" env:"OCIS_URL;OCIS_OIDC_ISSUER;PROXY_OIDC_ISSUER" desc:"URL of the OIDC issuer. It defaults to URL of the builtin IDP."`
-	Insecure      bool          `yaml:"insecure" env:"OCIS_INSECURE;PROXY_OIDC_INSECURE" desc:"Disable TLS certificate validation for connections to the IDP. (not recommended for production environments."`
+	Insecure      bool          `yaml:"insecure" env:"OCIS_INSECURE;PROXY_OIDC_INSECURE" desc:"Disable TLS certificate validation for connections to the IDP. Note that this is not recommended for production environments."`
 	UserinfoCache UserinfoCache `yaml:"user_info_cache"`
 }
 
 // UserinfoCache is a TTL cache configuration.
 type UserinfoCache struct {
-	Size int `yaml:"size" env:"PROXY_OIDC_USERINFO_CACHE_SIZE" desc:"Cache size for oidc user info."`
-	TTL  int `yaml:"ttl" env:"PROXY_OIDC_USERINFO_CACHE_TTL" desc:"Max TTL for the oidc user info cache."`
+	Size int `yaml:"size" env:"PROXY_OIDC_USERINFO_CACHE_SIZE" desc:"Cache size for OIDC user info."`
+	TTL  int `yaml:"ttl" env:"PROXY_OIDC_USERINFO_CACHE_TTL" desc:"Max TTL in seconds for the OIDC user info cache."`
 }
 
 // PolicySelector is the toplevel-configuration for different selectors
@@ -108,13 +108,13 @@ type StaticSelectorConf struct {
 
 // TokenManager is the config for using the reva token manager
 type TokenManager struct {
-	JWTSecret string `mask:"password" yaml:"jwt_secret" env:"OCIS_JWT_SECRET;PROXY_JWT_SECRET" desc:"The secret to mint and validate jwt tokens."`
+	JWTSecret string `mask:"password" yaml:"jwt_secret" env:"OCIS_JWT_SECRET;PROXY_JWT_SECRET" desc:"The secret to mint and validate JWT tokens."`
 }
 
 // PreSignedURL is the config for the presigned url middleware
 type PreSignedURL struct {
 	AllowedHTTPMethods []string `yaml:"allowed_http_methods"`
-	Enabled            bool     `yaml:"enabled" env:"PROXY_ENABLE_PRESIGNEDURLS" desc:"Allow ocs to get a signing key to sign requests."`
+	Enabled            bool     `yaml:"enabled" env:"PROXY_ENABLE_PRESIGNEDURLS" desc:"Allow OCS to get a signing key to sign requests."`
 }
 
 // ClaimsSelectorConf is the config for the claims-selector
diff --git a/services/proxy/pkg/config/debug.go b/services/proxy/pkg/config/debug.go
index 3a3c491266b..b63e74b9a10 100644
--- a/services/proxy/pkg/config/debug.go
+++ b/services/proxy/pkg/config/debug.go
@@ -3,7 +3,7 @@ package config
 // Debug defines the available debug configuration.
 type Debug struct {
 	Addr   string `yaml:"addr" env:"PROXY_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `mask:"password" yaml:"token" env:"PROXY_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"PROXY_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `mask:"password" yaml:"token" env:"PROXY_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"PROXY_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"PROXY_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
diff --git a/services/proxy/pkg/config/defaults/defaultconfig.go b/services/proxy/pkg/config/defaults/defaultconfig.go
index 566373002ad..962f1853521 100644
--- a/services/proxy/pkg/config/defaults/defaultconfig.go
+++ b/services/proxy/pkg/config/defaults/defaultconfig.go
@@ -97,15 +97,20 @@ func DefaultPolicies() []config.Policy {
 					Endpoint: "/remote.php/?preview=1",
 					Backend:  "http://localhost:9115",
 				},
+				// 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?
+				// TODO or we allow a REPORT on /dav/spaces to search all spaces and /dav/space/{spaceid} to search a specific space
+				// send webdav REPORT requests to search service
 				{
-					// 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?
-					// TODO or we allow a REPORT on /dav/spaces to search all spaces and /dav/space/{spaceid} to search a specific space
-					// send webdav REPORT requests to search service
 					Method:   "REPORT",
 					Endpoint: "/remote.php/dav/",
 					Backend:  "http://localhost:9115", // TODO use registry?
 				},
+				{
+					Method:   "REPORT",
+					Endpoint: "/remote.php/webdav",
+					Backend:  "http://localhost:9115", // TODO use registry?
+				},
 				{
 					Type:     config.QueryRoute,
 					Endpoint: "/dav/?preview=1",
diff --git a/services/proxy/pkg/middleware/oidc_auth.go b/services/proxy/pkg/middleware/oidc_auth.go
index 332b5eb6e3c..8fedb3c2f4f 100644
--- a/services/proxy/pkg/middleware/oidc_auth.go
+++ b/services/proxy/pkg/middleware/oidc_auth.go
@@ -6,13 +6,10 @@ import (
 	"strings"
 	"time"
 
-	"github.com/golang-jwt/jwt/v4"
-
 	gOidc "github.com/coreos/go-oidc/v3/oidc"
 	"github.com/owncloud/ocis/v2/ocis-pkg/log"
 	"github.com/owncloud/ocis/v2/ocis-pkg/oidc"
 	"github.com/owncloud/ocis/v2/ocis-pkg/sync"
-	"github.com/owncloud/ocis/v2/services/proxy/pkg/config"
 	"golang.org/x/oauth2"
 )
 
@@ -27,13 +24,12 @@ func OIDCAuth(optionSetters ...Option) func(next http.Handler) http.Handler {
 	tokenCache := sync.NewCache(options.UserinfoCacheSize)
 
 	h := oidcAuth{
-		logger:             options.Logger,
-		providerFunc:       options.OIDCProviderFunc,
-		httpClient:         options.HTTPClient,
-		oidcIss:            options.OIDCIss,
-		TokenManagerConfig: options.TokenManagerConfig,
-		tokenCache:         &tokenCache,
-		tokenCacheTTL:      options.UserinfoCacheTTL,
+		logger:        options.Logger,
+		providerFunc:  options.OIDCProviderFunc,
+		httpClient:    options.HTTPClient,
+		oidcIss:       options.OIDCIss,
+		tokenCache:    &tokenCache,
+		tokenCacheTTL: options.UserinfoCacheTTL,
 	}
 
 	return func(next http.Handler) http.Handler {
@@ -59,25 +55,20 @@ func OIDCAuth(optionSetters ...Option) func(next http.Handler) http.Handler {
 				return
 			}
 
-			// inject claims to the request context for the account_uuid middleware.
-			req = req.WithContext(oidc.NewContext(req.Context(), claims))
-
-			// store claims in context
-			// uses the original context, not the one with probably reduced security
+			// inject claims to the request context for the account_resolver middleware.
 			next.ServeHTTP(w, req.WithContext(oidc.NewContext(req.Context(), claims)))
 		})
 	}
 }
 
 type oidcAuth struct {
-	logger             log.Logger
-	provider           OIDCProvider
-	providerFunc       func() (OIDCProvider, error)
-	httpClient         *http.Client
-	oidcIss            string
-	tokenCache         *sync.Cache
-	tokenCacheTTL      time.Duration
-	TokenManagerConfig config.TokenManager
+	logger        log.Logger
+	provider      OIDCProvider
+	providerFunc  func() (OIDCProvider, error)
+	httpClient    *http.Client
+	oidcIss       string
+	tokenCache    *sync.Cache
+	tokenCacheTTL time.Duration
 }
 
 func (m oidcAuth) getClaims(token string, req *http.Request) (claims map[string]interface{}, status int) {
@@ -120,25 +111,21 @@ func (m oidcAuth) getClaims(token string, req *http.Request) (claims map[string]
 	return
 }
 
-// extractExpiration tries to parse and extract the expiration from the provided token. It might not even be a jwt.
-// defaults to the configured fallback TTL.
-// TODO: use introspection endpoint if available in the oidc configuration. Still needs a fallback to configured TTL.
+// extractExpiration currently just returns a hardcoded default for now. It was
+// supposed to parse and extract the expiration time from the provided
+// access_token.
+// As the access_token is defined as an opaque string. Validating and parsing it
+// can be tricky:
+// 1. Try to treat it as a JWT:
+//    - Verifying the validity of the token requires downloading the propoer public
+//      key from the IDP (uri in "jwks_uri" in ".well-known/openid-configuration"
+// 2. Verify and extract it via the introspection endpoint of the IDP (RFC7662) for
+//    IDPs that provide that feature
+// 3. Other IDP implementation specific methods.
+// 4. Fallback to default value
 func (m oidcAuth) extractExpiration(token string) time.Time {
 	defaultExpiration := time.Now().Add(m.tokenCacheTTL)
-
-	t, err := jwt.Parse(token, func(t *jwt.Token) (interface{}, error) {
-		return []byte(m.TokenManagerConfig.JWTSecret), nil
-	})
-	if err != nil {
-		return defaultExpiration
-	}
-
-	at, ok := t.Claims.(jwt.StandardClaims)
-	if !ok || at.ExpiresAt == 0 {
-		return defaultExpiration
-	}
-
-	return time.Unix(at.ExpiresAt, 0)
+	return defaultExpiration
 }
 
 func (m oidcAuth) shouldServe(req *http.Request) bool {
diff --git a/services/search/pkg/config/config.go b/services/search/pkg/config/config.go
index ad851051f1f..a1475a89540 100644
--- a/services/search/pkg/config/config.go
+++ b/services/search/pkg/config/config.go
@@ -29,7 +29,7 @@ type Config struct {
 
 // Events combines the configuration options for the event bus.
 type Events struct {
-	Endpoint      string `yaml:"endpoint" env:"SEARCH_EVENTS_ENDPOINT" desc:"the address of the streaming service"`
-	Cluster       string `yaml:"cluster" env:"SEARCH_EVENTS_CLUSTER" desc:"the clusterID of the streaming service. Mandatory when using nats"`
-	ConsumerGroup string `yaml:"group" env:"SEARCH_EVENTS_GROUP" desc:"the customergroup of the service. One group will only get one copy of an event"`
+	Endpoint      string `yaml:"endpoint" env:"SEARCH_EVENTS_ENDPOINT" desc:"The address of the streaming service"`
+	Cluster       string `yaml:"cluster" env:"SEARCH_EVENTS_CLUSTER" desc:"The clusterID of the streaming service. Mandatory when using NATS"`
+	ConsumerGroup string `yaml:"group" env:"SEARCH_EVENTS_GROUP" desc:"The customer group of the service. One group will only get one copy of an event"`
 }
diff --git a/services/search/pkg/config/debug.go b/services/search/pkg/config/debug.go
index 7eee7847073..bd783a00f29 100644
--- a/services/search/pkg/config/debug.go
+++ b/services/search/pkg/config/debug.go
@@ -3,7 +3,7 @@ package config
 // Debug defines the available debug configuration.
 type Debug struct {
 	Addr   string `ocisConfig:"addr" env:"SEARCH_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `ocisConfig:"token" env:"SEARCH_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `ocisConfig:"pprof" env:"SEARCH_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `ocisConfig:"token" env:"SEARCH_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `ocisConfig:"pprof" env:"SEARCH_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `ocisConfig:"zpages" env:"SEARCH_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
diff --git a/services/settings/pkg/config/config.go b/services/settings/pkg/config/config.go
index 9e0c42d465e..141e7a82c23 100644
--- a/services/settings/pkg/config/config.go
+++ b/services/settings/pkg/config/config.go
@@ -19,16 +19,16 @@ type Config struct {
 	HTTP HTTP `yaml:"http"`
 	GRPC GRPC `yaml:"grpc"`
 
-	StoreType string   `yaml:"store_type" env:"SETTINGS_STORE_TYPE" desc:"Store type configures the persistency driver. Possible values are \"metadata\" and \"filesystem\"."`
+	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:"Path for the persistence directory."`
 	Metadata  Metadata `yaml:"metadata_config"`
 
-	AdminUserID string `yaml:"admin_user_id" env:"OCIS_ADMIN_USER_ID;SETTINGS_ADMIN_USER_ID" desc:"ID of a user, that should receive admin privileges."`
+	AdminUserID string `yaml:"admin_user_id" env:"OCIS_ADMIN_USER_ID;SETTINGS_ADMIN_USER_ID" desc:"ID of the user that should receive admin privileges."`
 
 	Asset        Asset         `yaml:"asset"`
 	TokenManager *TokenManager `yaml:"token_manager"`
 
-	SetupDefaultAssignments bool `yaml:"set_default_assignments" env:"SETTINGS_SETUP_DEFAULT_ASSIGNMENTS;ACCOUNTS_DEMO_USERS_AND_GROUPS" desc:"If the default role assignments for the demo users should be setup."`
+	SetupDefaultAssignments bool `yaml:"set_default_assignments" env:"SETTINGS_SETUP_DEFAULT_ASSIGNMENTS;ACCOUNTS_DEMO_USERS_AND_GROUPS" desc:"The default role assignments the demo users should be setup."`
 
 	Context context.Context `yaml:"-"`
 }
@@ -40,10 +40,10 @@ type Asset struct {
 
 // Metadata configures the metadata store to use
 type Metadata struct {
-	GatewayAddress string `yaml:"gateway_addr" env:"STORAGE_GATEWAY_GRPC_ADDR" desc:"GRPC address of the storage-system service."`
-	StorageAddress string `yaml:"storage_addr" env:"STORAGE_GRPC_ADDR" desc:"GRPC address of the storage-system service."`
+	GatewayAddress string `yaml:"gateway_addr" env:"STORAGE_GATEWAY_GRPC_ADDR" desc:"GRPC address of the STORAGE-SYSTEM service."`
+	StorageAddress string `yaml:"storage_addr" env:"STORAGE_GRPC_ADDR" desc:"GRPC address of the STORAGE-SYSTEM service."`
 
-	SystemUserID     string `yaml:"system_user_id" env:"OCIS_SYSTEM_USER_ID;SETTINGS_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."`
-	SystemUserIDP    string `yaml:"system_user_idp" env:"OCIS_SYSTEM_USER_IDP;SETTINGS_SYSTEM_USER_IDP" desc:"IDP of the oCIS storage-system system user."`
-	SystemUserAPIKey string `yaml:"system_user_api_key" env:"OCIS_SYSTEM_USER_API_KEY" desc:"API key for the storage-system system user."`
+	SystemUserID     string `yaml:"system_user_id" env:"OCIS_SYSTEM_USER_ID;SETTINGS_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."`
+	SystemUserIDP    string `yaml:"system_user_idp" env:"OCIS_SYSTEM_USER_IDP;SETTINGS_SYSTEM_USER_IDP" desc:"IDP of the oCIS STORAGE-SYSTEM system user."`
+	SystemUserAPIKey string `yaml:"system_user_api_key" env:"OCIS_SYSTEM_USER_API_KEY" desc:"API key for the STORAGE-SYSTEM system user."`
 }
diff --git a/services/settings/pkg/config/debug.go b/services/settings/pkg/config/debug.go
index 21c45a4e81f..126643fc03a 100644
--- a/services/settings/pkg/config/debug.go
+++ b/services/settings/pkg/config/debug.go
@@ -3,7 +3,7 @@ package config
 // Debug defines the available debug configuration.
 type Debug struct {
 	Addr   string `yaml:"addr" env:"SETTINGS_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"SETTINGS_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"SETTINGS_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"SETTINGS_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"SETTINGS_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"SETTINGS_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
diff --git a/services/sharing/pkg/config/config.go b/services/sharing/pkg/config/config.go
index dcb801239f1..3abeea6f5b6 100644
--- a/services/sharing/pkg/config/config.go
+++ b/services/sharing/pkg/config/config.go
@@ -21,9 +21,9 @@ type Config struct {
 
 	SkipUserGroupsInToken bool `yaml:"skip_user_groups_in_token" env:"SHARING_SKIP_USER_GROUPS_IN_TOKEN" desc:"Disables the loading of user's group memberships from the reva access token."`
 
-	UserSharingDriver    string               `yaml:"user_sharing_driver" env:"SHARING_USER_DRIVER" desc:"Driver to be used to persist shares. Possible values: \"json\", \"cs3\", \"owncloudsql\""`
+	UserSharingDriver    string               `yaml:"user_sharing_driver" env:"SHARING_USER_DRIVER" desc:"Driver to be used to persist shares. Supported values are 'json', 'cs3' and 'owncloudsql'."`
 	UserSharingDrivers   UserSharingDrivers   `yaml:"user_sharing_drivers"`
-	PublicSharingDriver  string               `yaml:"public_sharing_driver" env:"SHARING_PUBLIC_DRIVER" desc:"Driver to be used to persist public shares. Possible values: \"json\", \"cs3\""`
+	PublicSharingDriver  string               `yaml:"public_sharing_driver" env:"SHARING_PUBLIC_DRIVER" desc:"Driver to be used to persist public shares. Supported values are 'json' and 'cs3'."`
 	PublicSharingDrivers PublicSharingDrivers `yaml:"public_sharing_drivers"`
 
 	Supervised bool            `yaml:"-"`
@@ -49,15 +49,15 @@ type Service struct {
 
 type Debug struct {
 	Addr   string `yaml:"addr" env:"SHARING_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"SHARING_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"SHARING_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"SHARING_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"SHARING_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"SHARING_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
 
 type GRPCConfig struct {
 	Addr      string `yaml:"addr" env:"SHARING_GRPC_ADDR" desc:"The bind address of the GRPC service."`
 	Namespace string `yaml:"-"`
-	Protocol  string `yaml:"protocol" env:"SHARING_GRPC_PROTOCOL" desc:"The transport protocol of the grpc service."`
+	Protocol  string `yaml:"protocol" env:"SHARING_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
 }
 
 type UserSharingDrivers struct {
@@ -69,7 +69,7 @@ type UserSharingDrivers struct {
 }
 
 type UserSharingJSONDriver struct {
-	File string `yaml:"file" env:"SHARING_USER_JSON_FILE" desc:"Path to the json file where shares will be persisted."`
+	File string `yaml:"file" env:"SHARING_USER_JSON_FILE" desc:"Path to the JSON file where shares will be persisted."`
 }
 
 type UserSharingSQLDriver struct {
@@ -94,10 +94,10 @@ type UserSharingOwnCloudSQLDriver struct {
 }
 
 type UserSharingCS3Driver struct {
-	ProviderAddr     string `yaml:"provider_addr" env:"SHARING_USER_CS3_PROVIDER_ADDR" desc:"GRPC address of the storage-system extension."`
-	SystemUserID     string `yaml:"system_user_id" env:"OCIS_SYSTEM_USER_ID;SHARING_USER_CS3_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."`
-	SystemUserIDP    string `yaml:"system_user_idp" env:"OCIS_SYSTEM_USER_IDP;SHARING_USER_CS3_SYSTEM_USER_IDP" desc:"IDP of the oCIS storage-system system user."`
-	SystemUserAPIKey string `yaml:"system_user_api_key" env:"OCIS_SYSTEM_USER_API_KEY;SHARING_USER_CS3_SYSTEM_USER_API_KEY" desc:"API key for the storage-system system user."`
+	ProviderAddr     string `yaml:"provider_addr" env:"SHARING_USER_CS3_PROVIDER_ADDR" desc:"GRPC address of the STORAGE-SYSTEM service."`
+	SystemUserID     string `yaml:"system_user_id" env:"OCIS_SYSTEM_USER_ID;SHARING_USER_CS3_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."`
+	SystemUserIDP    string `yaml:"system_user_idp" env:"OCIS_SYSTEM_USER_IDP;SHARING_USER_CS3_SYSTEM_USER_IDP" desc:"IDP of the oCIS STORAGE-SYSTEM system user."`
+	SystemUserAPIKey string `yaml:"system_user_api_key" env:"OCIS_SYSTEM_USER_API_KEY;SHARING_USER_CS3_SYSTEM_USER_API_KEY" desc:"API key for the STORAGE-SYSTEM system user."`
 }
 
 type PublicSharingDrivers struct {
@@ -124,13 +124,13 @@ type PublicSharingSQLDriver struct {
 }
 
 type PublicSharingCS3Driver struct {
-	ProviderAddr     string `yaml:"provider_addr" env:"SHARING_PUBLIC_CS3_PROVIDER_ADDR" desc:"GRPC address of the storage-system extension."`
-	SystemUserID     string `yaml:"system_user_id" env:"OCIS_SYSTEM_USER_ID;SHARING_PUBLIC_CS3_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."`
-	SystemUserIDP    string `yaml:"system_user_idp" env:"OCIS_SYSTEM_USER_IDP;SHARING_PUBLIC_CS3_SYSTEM_USER_IDP" desc:"IDP of the oCIS storage-system system user."`
-	SystemUserAPIKey string `yaml:"system_user_api_key" env:"OCIS_SYSTEM_USER_API_KEY;SHARING_USER_CS3_SYSTEM_USER_API_KEY" desc:"API key for the storage-system system user."`
+	ProviderAddr     string `yaml:"provider_addr" env:"SHARING_PUBLIC_CS3_PROVIDER_ADDR" desc:"GRPC address of the STORAGE-SYSTEM extension."`
+	SystemUserID     string `yaml:"system_user_id" env:"OCIS_SYSTEM_USER_ID;SHARING_PUBLIC_CS3_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."`
+	SystemUserIDP    string `yaml:"system_user_idp" env:"OCIS_SYSTEM_USER_IDP;SHARING_PUBLIC_CS3_SYSTEM_USER_IDP" desc:"IDP of the oCIS STORAGE-SYSTEM system user."`
+	SystemUserAPIKey string `yaml:"system_user_api_key" env:"OCIS_SYSTEM_USER_API_KEY;SHARING_USER_CS3_SYSTEM_USER_API_KEY" desc:"API key for the STORAGE-SYSTEM system user."`
 }
 
 type Events struct {
-	Addr      string `yaml:"endpoint" env:"SHARING_EVENTS_ENDPOINT" desc:"the address of the streaming service"`
-	ClusterID string `yaml:"cluster" env:"SHARING_EVENTS_CLUSTER" desc:"the clusterID of the streaming service. Mandatory when using nats"`
+	Addr      string `yaml:"endpoint" env:"SHARING_EVENTS_ENDPOINT" desc:"The address of the streaming service"`
+	ClusterID string `yaml:"cluster" env:"SHARING_EVENTS_CLUSTER" desc:"The clusterID of the streaming service. Mandatory when using the NATS service"`
 }
diff --git a/services/storage-publiclink/pkg/config/config.go b/services/storage-publiclink/pkg/config/config.go
index 9faf48a934d..c2569e51965 100644
--- a/services/storage-publiclink/pkg/config/config.go
+++ b/services/storage-publiclink/pkg/config/config.go
@@ -45,15 +45,15 @@ type Service struct {
 
 type Debug struct {
 	Addr   string `yaml:"addr" env:"STORAGE_PUBLICLINK_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"STORAGE_PUBLICLINK_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"STORAGE_PUBLICLINK_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"STORAGE_PUBLICLINK_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"STORAGE_PUBLICLINK_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"STORAGE_PUBLICLINK_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
 
 type GRPCConfig struct {
 	Addr      string `yaml:"addr" env:"STORAGE_PUBLICLINK_GRPC_ADDR" desc:"The bind address of the GRPC service."`
 	Namespace string `yaml:"-"`
-	Protocol  string `yaml:"protocol" env:"STORAGE_PUBLICLINK_GRPC_PROTOCOL" desc:"The transport protocol of the grpc service."`
+	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-shares/pkg/config/config.go b/services/storage-shares/pkg/config/config.go
index 3e8da9996d6..33a46d2ecb3 100644
--- a/services/storage-shares/pkg/config/config.go
+++ b/services/storage-shares/pkg/config/config.go
@@ -22,7 +22,7 @@ type Config struct {
 
 	MountID                string `yaml:"mount_id" env:"STORAGE_SHARES_MOUNT_ID" desc:"Mount ID of this storage. Admins can set the ID for the storage in this config option manually which is then used to reference the storage. Any reasonable long string is possible, preferably this would be an UUIDv4 format."`
 	ReadOnly               bool   `yaml:"readonly" env:"STORAGE_SHARES_READ_ONLY" desc:"Set this storage to be read-only."`
-	SharesProviderEndpoint string `yaml:"user_share_provider_endpoint" env:"STORAGE_SHARES_USER_SHARE_PROVIDER_ENDPOINT" desc:"GRPC endpoint of the sharing extension."`
+	SharesProviderEndpoint string `yaml:"user_share_provider_endpoint" env:"STORAGE_SHARES_USER_SHARE_PROVIDER_ENDPOINT" desc:"GRPC endpoint of the SHARING service."`
 
 	Supervised bool            `yaml:"-"`
 	Context    context.Context `yaml:"-"`
@@ -47,13 +47,13 @@ type Service struct {
 
 type Debug struct {
 	Addr   string `yaml:"addr" env:"STORAGE_SHARES_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"STORAGE_SHARES_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"STORAGE_SHARES_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"STORAGE_SHARES_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"STORAGE_SHARES_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"STORAGE_SHARES_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
 
 type GRPCConfig struct {
 	Addr      string `yaml:"addr" env:"STORAGE_SHARES_GRPC_ADDR" desc:"The bind address of the GRPC service."`
 	Namespace string `yaml:"-"`
-	Protocol  string `yaml:"protocol" env:"STORAGE_SHARES_GRPC_PROTOCOL" desc:"The transport protocol of the grpc service."`
+	Protocol  string `yaml:"protocol" env:"STORAGE_SHARES_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service."`
 }
diff --git a/services/storage-system/pkg/config/config.go b/services/storage-system/pkg/config/config.go
index 77804959e87..95a01e38864 100644
--- a/services/storage-system/pkg/config/config.go
+++ b/services/storage-system/pkg/config/config.go
@@ -19,14 +19,14 @@ type Config struct {
 
 	TokenManager     *TokenManager `yaml:"token_manager"`
 	Reva             *Reva         `yaml:"reva"`
-	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        `yaml:"system_user_api_key" env:"OCIS_SYSTEM_USER_API_KEY" desc:"API key for the storage-system system user."`
+	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        `yaml:"system_user_api_key" env:"OCIS_SYSTEM_USER_API_KEY" desc:"API key for the STORAGE-SYSTEM system user."`
 
 	SkipUserGroupsInToken bool `yaml:"skip_user_groups_in_token" env:"STORAGE_SYSTEM_SKIP_USER_GROUPS_IN_TOKEN" desc:"Disables the loading of user's group memberships from the reva access token."`
 
-	Driver        string  `yaml:"driver" env:"STORAGE_SYSTEM_DRIVER" desc:"The driver which should be used by the service"`
+	Driver        string  `yaml:"driver" env:"STORAGE_SYSTEM_DRIVER" desc:"The driver which should be used by the service."`
 	Drivers       Drivers `yaml:"drivers"`
-	DataServerURL string  `yaml:"data_server_url" env:"STORAGE_SYSTEM_DATA_SERVER_URL" desc:"URL of the data server, needs to be reachable by services using this service."`
+	DataServerURL string  `yaml:"data_server_url" env:"STORAGE_SYSTEM_DATA_SERVER_URL" desc:"URL of the data server, needs to be reachable by other services using this service."`
 
 	Supervised bool            `yaml:"-"`
 	Context    context.Context `yaml:"-"`
@@ -59,13 +59,13 @@ type Debug struct {
 type GRPCConfig struct {
 	Addr      string `yaml:"addr" env:"STORAGE_SYSTEM_GRPC_ADDR" desc:"The bind address of the GRPC service."`
 	Namespace string `yaml:"-"`
-	Protocol  string `yaml:"protocol" env:"STORAGE_SYSTEM_GRPC_PROTOCOL" desc:"The transport protocol of the grpc service."`
+	Protocol  string `yaml:"protocol" env:"STORAGE_SYSTEM_GRPC_PROTOCOL" desc:"The transport protocol of the GPRC service."`
 }
 
 type HTTPConfig struct {
 	Addr      string `yaml:"addr" env:"STORAGE_SYSTEM_HTTP_ADDR" desc:"The bind address of the HTTP service."`
 	Namespace string `yaml:"-"`
-	Protocol  string `yaml:"protocol" env:"STORAGE_SYSTEM_HTTP_PROTOCOL" desc:"The transport protocol of the http service."`
+	Protocol  string `yaml:"protocol" env:"STORAGE_SYSTEM_HTTP_PROTOCOL" desc:"The transport protocol of the HTTP service."`
 }
 
 type Drivers struct {
@@ -74,10 +74,10 @@ type Drivers struct {
 
 type OCISDriver struct {
 	// Root is the absolute path to the location of the data
-	Root string `yaml:"root" env:"STORAGE_SYSTEM_OCIS_ROOT" desc:"Path for the directory where the storage-system service stores it's persistent data."`
+	Root string `yaml:"root" env:"STORAGE_SYSTEM_OCIS_ROOT" desc:"Path for the directory where the STORAGE-SYSTEM service stores it's persistent data."`
 }
 
 type Events struct {
-	Addr      string `yaml:"endpoint" env:"STORAGE_SYSTEM_EVENTS_ENDPOINT" desc:"the address of the streaming service"`
-	ClusterID string `yaml:"cluster" env:"STORAGE_SYSTEM_EVENTS_CLUSTER" desc:"the clusterID of the streaming service. Mandatory when using nats"`
+	Addr      string `yaml:"endpoint" env:"STORAGE_SYSTEM_EVENTS_ENDPOINT" desc:"The address of the streaming service."`
+	ClusterID string `yaml:"cluster" env:"STORAGE_SYSTEM_EVENTS_CLUSTER" desc:"The clusterID of the streaming service. Mandatory when using the NATS service."`
 }
diff --git a/services/storage-users/pkg/config/config.go b/services/storage-users/pkg/config/config.go
index d29a1b96ce3..f13122af927 100644
--- a/services/storage-users/pkg/config/config.go
+++ b/services/storage-users/pkg/config/config.go
@@ -52,21 +52,21 @@ type Service struct {
 
 type Debug struct {
 	Addr   string `yaml:"addr" env:"STORAGE_USERS_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"STORAGE_USERS_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"STORAGE_USERS_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"STORAGE_USERS_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"STORAGE_USERS_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"STORAGE_USERS_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
 
 type GRPCConfig struct {
 	Addr      string `yaml:"addr" env:"STORAGE_USERS_GRPC_ADDR" desc:"The bind address of the GRPC service."`
 	Namespace string `yaml:"-"`
-	Protocol  string `yaml:"protocol" env:"STORAGE_USERS_GRPC_PROTOCOL" desc:"The transport protocol of the grpc service."`
+	Protocol  string `yaml:"protocol" env:"STORAGE_USERS_GRPC_PROTOCOL" desc:"The transport protocol of the GPRC service."`
 }
 
 type HTTPConfig struct {
 	Addr      string `yaml:"addr" env:"STORAGE_USERS_HTTP_ADDR" desc:"The bind address of the HTTP service."`
 	Namespace string `yaml:"-"`
-	Protocol  string `yaml:"protocol" env:"STORAGE_USERS_HTTP_PROTOCOL" desc:"The transport protocol of the http service."`
+	Protocol  string `yaml:"protocol" env:"STORAGE_USERS_HTTP_PROTOCOL" desc:"The transport protocol of the HTTP service."`
 	Prefix    string
 }
 
@@ -119,8 +119,8 @@ type OwnCloudSQLDriver struct {
 	// Root is the absolute path to the location of the data
 	Root string `yaml:"root" env:"STORAGE_USERS_OWNCLOUDSQL_DATADIR" desc:"Path for the persistence directory."`
 	//ShareFolder defines the name of the folder jailing all shares
-	ShareFolder           string `yaml:"share_folder" env:"STORAGE_USERS_OWNCLOUDSQL_SHARE_FOLDER" desc:"name of the folder jailing all shares."`
-	UserLayout            string `yaml:"user_layout" env:"STORAGE_USERS_OWNCLOUDSQL_LAYOUT" desc:"path layout to use to navigate into a users folder in an owncloud data dir"`
+	ShareFolder           string `yaml:"share_folder" env:"STORAGE_USERS_OWNCLOUDSQL_SHARE_FOLDER" desc:"Name of the folder jailing all shares."`
+	UserLayout            string `yaml:"user_layout" env:"STORAGE_USERS_OWNCLOUDSQL_LAYOUT" desc:"Path layout to use to navigate into a users folder in an owncloud data directory"`
 	UploadInfoDir         string `yaml:"upload_info_dir" env:"STORAGE_USERS_OWNCLOUDSQL_UPLOADINFO_DIR" desc:"Path to a directory, where uploads will be stored temporarily."`
 	DBUsername            string `yaml:"db_username" env:"STORAGE_USERS_OWNCLOUDSQL_DB_USERNAME" desc:"Username for the database."`
 	DBPassword            string `yaml:"db_password" env:"STORAGE_USERS_OWNCLOUDSQL_DB_PASSWORD" desc:"Password for the database."`
@@ -131,8 +131,8 @@ type OwnCloudSQLDriver struct {
 }
 
 type Events struct {
-	Addr      string `yaml:"endpoint" env:"STORAGE_USERS_EVENTS_ENDPOINT" desc:"the address of the streaming service"`
-	ClusterID string `yaml:"cluster" env:"STORAGE_USERS_EVENTS_CLUSTER" desc:"the clusterID of the streaming service. Mandatory when using nats"`
+	Addr      string `yaml:"endpoint" env:"STORAGE_USERS_EVENTS_ENDPOINT" desc:"The address of the streaming service"`
+	ClusterID string `yaml:"cluster" env:"STORAGE_USERS_EVENTS_CLUSTER" desc:"The clusterID of the streaming service. Mandatory when using the NATS service."`
 }
 type S3Driver struct {
 	// Root is the absolute path to the location of the data
diff --git a/services/store/pkg/config/debug.go b/services/store/pkg/config/debug.go
index 3b5e7123f00..29449d7ebfe 100644
--- a/services/store/pkg/config/debug.go
+++ b/services/store/pkg/config/debug.go
@@ -3,7 +3,7 @@ package config
 // Debug defines the available debug configuration.
 type Debug struct {
 	Addr   string `yaml:"addr" env:"STORE_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"STORE_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"STORE_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"STORE_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"STORE_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"STORE_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
diff --git a/services/thumbnails/pkg/config/debug.go b/services/thumbnails/pkg/config/debug.go
index 7570d15486f..b5217dc4c50 100644
--- a/services/thumbnails/pkg/config/debug.go
+++ b/services/thumbnails/pkg/config/debug.go
@@ -3,7 +3,7 @@ package config
 // Debug defines the available debug configuration.
 type Debug struct {
 	Addr   string `yaml:"addr" env:"THUMBNAILS_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"THUMBNAILS_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"THUMBNAILS_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"THUMBNAILS_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"THUMBNAILS_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"THUMBNAILS_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
diff --git a/services/users/pkg/config/config.go b/services/users/pkg/config/config.go
index 7668a5e798a..38da71eccd3 100644
--- a/services/users/pkg/config/config.go
+++ b/services/users/pkg/config/config.go
@@ -20,7 +20,7 @@ type Config struct {
 
 	SkipUserGroupsInToken bool `yaml:"skip_user_groups_in_token" env:"USERS_SKIP_USER_GROUPS_IN_TOKEN" desc:"Disables the loading of user's group memberships from the reva access token."`
 
-	Driver  string  `yaml:"driver" env:"USERS_DRIVER" desc:"The user driver which should be used by the users service. Defaults to 'ldap', can be 'owncloudsql', 'json' or 'rest'"`
+	Driver  string  `yaml:"driver" env:"USERS_DRIVER" desc:"The user driver which should be used by the users service. Supported values are 'ldap', 'owncloudsql', 'json' and 'rest'."`
 	Drivers Drivers `yaml:"drivers"`
 
 	Supervised bool            `yaml:"-"`
@@ -46,15 +46,15 @@ type Service struct {
 
 type Debug struct {
 	Addr   string `yaml:"addr" env:"USERS_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"USERS_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"USERS_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"USERS_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"USERS_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"USERS_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
 
 type GRPCConfig struct {
 	Addr      string `yaml:"addr" env:"USERS_GRPC_ADDR" desc:"The bind address of the GRPC service."`
 	Namespace string `yaml:"-"`
-	Protocol  string `yaml:"protocol" env:"USERS_GRPC_PROTOCOL" desc:"The transport protocol of the grpc service."`
+	Protocol  string `yaml:"protocol" env:"USERS_GRPC_PROTOCOL" desc:"The transport protocol of the GPRC service."`
 }
 
 type Drivers struct {
@@ -76,31 +76,31 @@ type LDAPDriver struct {
 	BindPassword     string          `yaml:"bind_password" env:"LDAP_BIND_PASSWORD;USERS_LDAP_BIND_PASSWORD" desc:"Password to use for authenticating the 'bind_dn'."`
 	UserBaseDN       string          `yaml:"user_base_dn" env:"LDAP_USER_BASE_DN;USERS_LDAP_USER_BASE_DN" desc:"Search base DN for looking up LDAP users."`
 	GroupBaseDN      string          `yaml:"group_base_dn" env:"LDAP_GROUP_BASE_DN;USERS_LDAP_GROUP_BASE_DN" desc:"Search base DN for looking up LDAP groups."`
-	UserScope        string          `yaml:"user_scope" env:"LDAP_USER_SCOPE;USERS_LDAP_USER_SCOPE" desc:"LDAP search scope to use when looking up users ('base', 'one', 'sub')."`
-	GroupScope       string          `yaml:"group_scope" env:"LDAP_GROUP_SCOPE;USERS_LDAP_GROUP_SCOPE" desc:"LDAP search scope to use when looking up gruops ('base', 'one', 'sub')."`
-	UserFilter       string          `yaml:"user_filter" env:"LDAP_USER_FILTER;USERS_LDAP_USER_FILTER" desc:"LDAP filter to add to the default filters for user search (e.g. '(objectclass=ownCloud)')."`
+	UserScope        string          `yaml:"user_scope" env:"LDAP_USER_SCOPE;USERS_LDAP_USER_SCOPE" desc:"LDAP search scope to use when looking up users. Supported values are 'base', 'one' and 'sub'."`
+	GroupScope       string          `yaml:"group_scope" env:"LDAP_GROUP_SCOPE;USERS_LDAP_GROUP_SCOPE" desc:"LDAP search scope to use when looking up groups. Supported values are 'base', 'one' and 'sub'."`
+	UserFilter       string          `yaml:"user_filter" env:"LDAP_USER_FILTER;USERS_LDAP_USER_FILTER" desc:"LDAP filter to add to the default filters for user search like '(objectclass=ownCloud)'."`
 	GroupFilter      string          `yaml:"group_filter" env:"LDAP_GROUP_FILTER;USERS_LDAP_GROUP_FILTER" desc:"LDAP filter to add to the default filters for group searches."`
-	UserObjectClass  string          `yaml:"user_object_class" env:"LDAP_USER_OBJECTCLASS;USERS_LDAP_USER_OBJECTCLASS" desc:"The object class to use for users in the default user search filter ('inetOrgPerson')."`
-	GroupObjectClass string          `yaml:"group_object_class" env:"LDAP_GROUP_OBJECTCLASS;USERS_LDAP_GROUP_OBJECTCLASS" desc:"The object class to use for groups in the default group search filter ('groupOfNames'). "`
+	UserObjectClass  string          `yaml:"user_object_class" env:"LDAP_USER_OBJECTCLASS;USERS_LDAP_USER_OBJECTCLASS" desc:"The object class to use for users in the default user search filter like 'inetOrgPerson'."`
+	GroupObjectClass string          `yaml:"group_object_class" env:"LDAP_GROUP_OBJECTCLASS;USERS_LDAP_GROUP_OBJECTCLASS" desc:"The object class to use for groups in the default group search filter like 'groupOfNames'. "`
 	IDP              string          `yaml:"idp" env:"OCIS_URL;OCIS_OIDC_ISSUER;USERS_IDP_URL" desc:"The identity provider value to set in the userids of the CS3 user objects for users returned by this user provider."`
 	UserSchema       LDAPUserSchema  `yaml:"user_schema"`
 	GroupSchema      LDAPGroupSchema `yaml:"group_schema"`
 }
 
 type LDAPUserSchema struct {
-	ID              string `yaml:"id" env:"LDAP_USER_SCHEMA_ID;USERS_LDAP_USER_SCHEMA_ID" desc:"LDAP Attribute to use as the unique id for users. This should be a stable globally unique id (e.g. a UUID)."`
-	IDIsOctetString bool   `yaml:"id_is_octet_string" env:"LDAP_USER_SCHEMA_ID_IS_OCTETSTRING;USERS_LDAP_USER_SCHEMA_ID_IS_OCTETSTRING" desc:"Set this to true if the defined 'id' attribute for users is of the 'OCTETSTRING' syntax. This is e.g. required when using the 'objectGUID' attribute of Active Directory for the user ids."`
+	ID              string `yaml:"id" env:"LDAP_USER_SCHEMA_ID;USERS_LDAP_USER_SCHEMA_ID" desc:"LDAP Attribute to use as the unique id for users. This should be a stable globally unique id like a UUID."`
+	IDIsOctetString bool   `yaml:"id_is_octet_string" env:"LDAP_USER_SCHEMA_ID_IS_OCTETSTRING;USERS_LDAP_USER_SCHEMA_ID_IS_OCTETSTRING" desc:"Set this to true if the defined 'id' attribute for users is of the 'OCTETSTRING' syntax. This is e.g. required when using the 'objectGUID' attribute of Active Directory for the user ID's."`
 	Mail            string `yaml:"mail" env:"LDAP_USER_SCHEMA_MAIL;USERS_LDAP_USER_SCHEMA_MAIL" desc:"LDAP Attribute to use for the email address of users."`
 	DisplayName     string `yaml:"display_name" env:"LDAP_USER_SCHEMA_DISPLAYNAME;USERS_LDAP_USER_SCHEMA_DISPLAYNAME" desc:"LDAP Attribute to use for the displayname of users."`
 	Username        string `yaml:"user_name" env:"LDAP_USER_SCHEMA_USERNAME;USERS_LDAP_USER_SCHEMA_USERNAME" desc:"LDAP Attribute to use for username of users."`
 }
 
 type LDAPGroupSchema struct {
-	ID              string `yaml:"id" env:"LDAP_GROUP_SCHEMA_ID;USERS_LDAP_GROUP_SCHEMA_ID" desc:"LDAP Attribute to use as the unique id for groups. This should be a stable globally unique id (e.g. a UUID)."`
-	IDIsOctetString bool   `yaml:"id_is_octet_string" env:"LDAP_GROUP_SCHEMA_ID_IS_OCTETSTRING;USERS_LDAP_GROUP_SCHEMA_ID_IS_OCTETSTRING" desc:"Set this to true if the defined 'id' attribute for groups is of the 'OCTETSTRING' syntax. This is e.g. required when using the 'objectGUID' attribute of Active Directory for the group ids."`
+	ID              string `yaml:"id" env:"LDAP_GROUP_SCHEMA_ID;USERS_LDAP_GROUP_SCHEMA_ID" desc:"LDAP Attribute to use as the unique ID for groups. This should be a stable globally unique ID like a UUID."`
+	IDIsOctetString bool   `yaml:"id_is_octet_string" env:"LDAP_GROUP_SCHEMA_ID_IS_OCTETSTRING;USERS_LDAP_GROUP_SCHEMA_ID_IS_OCTETSTRING" desc:"Set this to true if the defined 'id' attribute for groups is of the 'OCTETSTRING' syntax. This is e.g. required when using the 'objectGUID' attribute of Active Directory for the group ID's."`
 	Mail            string `yaml:"mail" env:"LDAP_GROUP_SCHEMA_MAIL;USERS_LDAP_GROUP_SCHEMA_MAIL" desc:"LDAP Attribute to use for the email address of groups (can be empty)."`
-	DisplayName     string `yaml:"display_name" env:"LDAP_GROUP_SCHEMA_DISPLAYNAME;USERS_LDAP_GROUP_SCHEMA_DISPLAYNAME" desc:"LDAP Attribute to use for the displayname of groups (often the same as groupname attribute)"`
-	Groupname       string `yaml:"group_name" env:"LDAP_GROUP_SCHEMA_GROUPNAME;USERS_LDAP_GROUP_SCHEMA_GROUPNAME" desc:"LDAP Attribute to use for the name of groups"`
+	DisplayName     string `yaml:"display_name" env:"LDAP_GROUP_SCHEMA_DISPLAYNAME;USERS_LDAP_GROUP_SCHEMA_DISPLAYNAME" desc:"LDAP Attribute to use for the displayname of groups (often the same as groupname attribute)."`
+	Groupname       string `yaml:"group_name" env:"LDAP_GROUP_SCHEMA_GROUPNAME;USERS_LDAP_GROUP_SCHEMA_GROUPNAME" desc:"LDAP Attribute to use for the name of groups."`
 	Member          string `yaml:"member" env:"LDAP_GROUP_SCHEMA_MEMBER;USERS_LDAP_GROUP_SCHEMA_MEMBER" desc:"LDAP Attribute that is used for group members."`
 }
 
@@ -113,8 +113,8 @@ type OwnCloudSQLDriver struct {
 	IDP                string `yaml:"idp" env:"USERS_OWNCLOUDSQL_IDP" desc:"The identity provider value to set in the userids of the CS3 user objects for users returned by this user provider."`
 	Nobody             int64  `yaml:"nobody" env:"USERS_OWNCLOUDSQL_NOBODY" desc:"Fallback number if no numeric UID and GID properties are provided."`
 	JoinUsername       bool   `yaml:"join_username" env:"USERS_OWNCLOUDSQL_JOIN_USERNAME" desc:"Join the user properties table to read usernames"`
-	JoinOwnCloudUUID   bool   `yaml:"join_owncloud_uuid" env:"USERS_OWNCLOUDSQL_JOIN_OWNCLOUD_UUID" desc:"Join the user properties table to read user ids (boolean)."`
-	EnableMedialSearch bool   `yaml:"enable_medial_search" env:"USERS_OWNCLOUDSQL_ENABLE_MEDIAL_SEARCH" desc:"Allow 'medial search' when searching for users instead of just doing a prefix search. (Allows finding 'Alice' when searching for 'lic'.)"`
+	JoinOwnCloudUUID   bool   `yaml:"join_owncloud_uuid" env:"USERS_OWNCLOUDSQL_JOIN_OWNCLOUD_UUID" desc:"Join the user properties table to read user IDs."`
+	EnableMedialSearch bool   `yaml:"enable_medial_search" env:"USERS_OWNCLOUDSQL_ENABLE_MEDIAL_SEARCH" desc:"Allow 'medial search' when searching for users instead of just doing a prefix search. This allows finding 'Alice' when searching for 'lic'."`
 }
 type RESTProvider struct {
 	ClientID          string
diff --git a/services/web/pkg/config/debug.go b/services/web/pkg/config/debug.go
index 7301aa9ce0d..96d03d91c47 100644
--- a/services/web/pkg/config/debug.go
+++ b/services/web/pkg/config/debug.go
@@ -3,7 +3,7 @@ package config
 // Debug defines the available debug configuration.
 type Debug struct {
 	Addr   string `yaml:"addr" env:"WEB_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"WEB_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"WEB_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"WEB_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"WEB_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"WEB_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
diff --git a/services/webdav/pkg/config/debug.go b/services/webdav/pkg/config/debug.go
index e75fcc588a3..68b7153d0db 100644
--- a/services/webdav/pkg/config/debug.go
+++ b/services/webdav/pkg/config/debug.go
@@ -3,7 +3,7 @@ package config
 // Debug defines the available debug configuration.
 type Debug struct {
 	Addr   string `yaml:"addr" env:"WEBDAV_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"WEBDAV_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"`
-	Pprof  bool   `yaml:"pprof" env:"WEBDAV_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"`
+	Token  string `yaml:"token" env:"WEBDAV_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"WEBDAV_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
 	Zpages bool   `yaml:"zpages" env:"WEBDAV_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
 }
diff --git a/services/webdav/pkg/service/v0/service.go b/services/webdav/pkg/service/v0/service.go
index 89f60fe5837..52190901fb9 100644
--- a/services/webdav/pkg/service/v0/service.go
+++ b/services/webdav/pkg/service/v0/service.go
@@ -113,7 +113,8 @@ func NewService(opts ...Option) (Service, error) {
 		// back to using `chi.RegisterMethod`.
 		m.MethodNotAllowed(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
 			routePrefix := path.Join(options.Config.HTTP.Root, "/remote.php/dav/files/")
-			if req.Method == "REPORT" && strings.HasPrefix(req.URL.Path, routePrefix) {
+			legacyRoutePrefix := path.Join(options.Config.HTTP.Root, "/remote.php/webdav")
+			if req.Method == "REPORT" && (strings.HasPrefix(req.URL.Path, routePrefix) || strings.HasPrefix(req.URL.Path, legacyRoutePrefix)) {
 				// The URLParam will not be available here. If it is needed it
 				// needs to be passed manually or chi needs to be fixed
 				// To use it properly.


Test patch:
diff --git a/ocis-pkg/ldap/ldap_suite_test.go b/ocis-pkg/ldap/ldap_suite_test.go
new file mode 100644
index 00000000000..3eee47856d2
--- /dev/null
+++ b/ocis-pkg/ldap/ldap_suite_test.go
@@ -0,0 +1,13 @@
+package ldap_test
+
+import (
+	"testing"
+
+	. "github.com/onsi/ginkgo/v2"
+	. "github.com/onsi/gomega"
+)
+
+func TestLdap(t *testing.T) {
+	RegisterFailHandler(Fail)
+	RunSpecs(t, "Ldap Suite")
+}
diff --git a/ocis-pkg/ldap/ldap_test.go b/ocis-pkg/ldap/ldap_test.go
new file mode 100644
index 00000000000..d3ee3152cfb
--- /dev/null
+++ b/ocis-pkg/ldap/ldap_test.go
@@ -0,0 +1,25 @@
+package ldap_test
+
+import (
+	. "github.com/onsi/ginkgo/v2"
+	. "github.com/onsi/gomega"
+	"github.com/owncloud/ocis/v2/ocis-pkg/ldap"
+)
+
+var _ = Describe("ldap", func() {
+	DescribeTable("EscapeDNAttributeValue should escape special characters",
+		func(input, expected string) {
+			escaped := ldap.EscapeDNAttributeValue(input)
+			Expect(escaped).To(Equal(expected))
+		},
+		Entry("normal dn", "foobar", "foobar"),
+		Entry("including comma", "foo,bar", "foo\\,bar"),
+		Entry("including equals", "foo=bar", "foo\\=bar"),
+		Entry("beginning with number sign", "#foobar", "\\#foobar"),
+		Entry("beginning with space", " foobar", "\\ foobar"),
+		Entry("only one space", " ", "\\ "),
+		Entry("two spaces", "  ", "\\ \\ "),
+		Entry("ending with space", "foobar ", "foobar\\ "),
+		Entry("containing multiple special chars", "f+o>o,b<a;r=\"\000", `f\+o\>o\,b\<a\;r\=\\"\00`),
+	)
+})
diff --git a/services/graph/pkg/service/v0/graph_test.go b/services/graph/pkg/service/v0/graph_test.go
index a119713c38f..9354449d7b5 100644
--- a/services/graph/pkg/service/v0/graph_test.go
+++ b/services/graph/pkg/service/v0/graph_test.go
@@ -29,7 +29,6 @@ var _ = Describe("Graph", func() {
 	var (
 		svc             service.Service
 		gatewayClient   *mocks.GatewayClient
-		httpClient      *mocks.HTTPClient
 		eventsPublisher mocks.Publisher
 		ctx             context.Context
 		cfg             *config.Config
@@ -42,12 +41,10 @@ var _ = Describe("Graph", func() {
 		cfg.TokenManager.JWTSecret = "loremipsum"
 
 		gatewayClient = &mocks.GatewayClient{}
-		httpClient = &mocks.HTTPClient{}
 		eventsPublisher = mocks.Publisher{}
 		svc = service.NewService(
 			service.Config(cfg),
 			service.WithGatewayClient(gatewayClient),
-			service.WithHTTPClient(httpClient),
 			service.EventsPublisher(&eventsPublisher),
 		)
 	})
diff --git a/services/graph/pkg/service/v0/password_test.go b/services/graph/pkg/service/v0/password_test.go
index e26242ca7aa..a31f7775ec1 100644
--- a/services/graph/pkg/service/v0/password_test.go
+++ b/services/graph/pkg/service/v0/password_test.go
@@ -36,7 +36,6 @@ var _ = Describe("Users changing their own password", func() {
 	var (
 		svc             service.Service
 		gatewayClient   *mocks.GatewayClient
-		httpClient      *mocks.HTTPClient
 		ldapClient      *mocks.Client
 		ldapConfig      config.LDAP
 		identityBackend identity.Backend
@@ -70,13 +69,11 @@ var _ = Describe("Users changing their own password", func() {
 		identityBackend, err = identity.NewLDAPBackend(ldapClient, ldapConfig, &loggger)
 		Expect(err).To(BeNil())
 
-		httpClient = &mocks.HTTPClient{}
 		eventsPublisher = mocks.Publisher{}
 		svc = service.NewService(
 			service.Config(cfg),
 			service.WithGatewayClient(gatewayClient),
 			service.WithIdentityBackend(identityBackend),
-			service.WithHTTPClient(httpClient),
 			service.EventsPublisher(&eventsPublisher),
 		)
 		user = &userv1beta1.User{
diff --git a/tests/acceptance/expected-failures-API-on-OCIS-storage.md b/tests/acceptance/expected-failures-API-on-OCIS-storage.md
index cc9d42b9688..c213afa4f7f 100644
--- a/tests/acceptance/expected-failures-API-on-OCIS-storage.md
+++ b/tests/acceptance/expected-failures-API-on-OCIS-storage.md
@@ -944,25 +944,19 @@ _ocdav: api compatibility, return correct status code_
 
 #### [/webdav and spaces endpoint does not alloow REPORT requests](https://github.com/owncloud/ocis/issues/4034)
 
-- [apiWebdavOperations/search.feature:42](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/search.feature#L42)
 - [apiWebdavOperations/search.feature:48](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/search.feature#L48)
-- [apiWebdavOperations/search.feature:64](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/search.feature#L64)
 - [apiWebdavOperations/search.feature:70](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/search.feature#L70)
-- [apiWebdavOperations/search.feature:87](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/search.feature#L87)
 - [apiWebdavOperations/search.feature:93](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/search.feature#L93)
-- [apiWebdavOperations/search.feature:102](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/search.feature#L102)
 - [apiWebdavOperations/search.feature:108](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/search.feature#L108)
 - [apiWebdavOperations/search.feature:126](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/search.feature#L126)
 - [apiWebdavOperations/search.feature:132](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/search.feature#L132)
 - [apiWebdavOperations/search.feature:150](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/search.feature#L150)
 - [apiWebdavOperations/search.feature:156](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/search.feature#L156)
-- [apiWebdavOperations/search.feature:174](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/search.feature#L174)
 - [apiWebdavOperations/search.feature:180](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/search.feature#L180)
 - [apiWebdavOperations/search.feature:207](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/search.feature#L207)
 - [apiWebdavOperations/search.feature:213](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/search.feature#L213)
 - [apiWebdavOperations/search.feature:239](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/search.feature#L239)
 - [apiWebdavOperations/search.feature:245](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/search.feature#L245)
-- [apiWebdavOperations/search.feature:264](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/search.feature#L264)
 - [apiWebdavOperations/search.feature:270](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/search.feature#L270)
 
 ### [No permisions propertry in response while searching for files and folders on ocis with new webdav](https://github.com/owncloud/ocis/issues/4009)
@@ -1346,17 +1340,6 @@ And other missing implementation of favorites
 - [apiShareOperationsToShares2/shareAccessByID.feature:162](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareOperationsToShares2/shareAccessByID.feature#L162)
 - [apiShareOperationsToShares2/shareAccessByID.feature:163](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareOperationsToShares2/shareAccessByID.feature#L163)
 
-#### [[OC-storage] share-types field empty for shared file folder in webdav response](https://github.com/owncloud/ocis/issues/2144)
-
-- [apiWebdavProperties2/getFileProperties.feature:215](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties2/getFileProperties.feature#L215)
-- [apiWebdavProperties2/getFileProperties.feature:216](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties2/getFileProperties.feature#L216)
-- [apiWebdavProperties2/getFileProperties.feature:221](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties2/getFileProperties.feature#L221)
-
-### [Different share permissions provides varying roles in oc10 and ocis](https://github.com/owncloud/ocis/issues/1277)
-
-- [apiWebdavProperties2/getFileProperties.feature:275](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties2/getFileProperties.feature#L275)
-- [apiWebdavProperties2/getFileProperties.feature:276](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties2/getFileProperties.feature#L276)
-- [apiWebdavProperties2/getFileProperties.feature:281](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties2/getFileProperties.feature#L281)
 
 #### [Shares to deleted group listed in the response](https://github.com/owncloud/ocis/issues/2441)
 
@@ -1535,10 +1518,6 @@ Not everything needs to be implemented for ocis. While the oc10 testsuite covers
 - [apiWebdavOperations/search.feature:289](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/search.feature#L289)
 - [apiWebdavOperations/search.feature:314](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/search.feature#L314)
 
-#### [Incorrect response while listing resources of a folder with depth infinity](https://github.com/owncloud/ocis/issues/3073)
-
-- [apiWebdavOperations/listFiles.feature:182](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/listFiles.feature#L182)
-
 #### [Cannot disable the dav propfind depth infinity for resources](https://github.com/owncloud/ocis/issues/3720)
 - [apiWebdavOperations/listFiles.feature:398](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/listFiles.feature#L398)
 - [apiWebdavOperations/listFiles.feature:399](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/listFiles.feature#L399)
diff --git a/tests/acceptance/expected-failures-webUI-on-OCIS-storage.md b/tests/acceptance/expected-failures-webUI-on-OCIS-storage.md
index c7b97f6fdef..cc7a5c48e66 100644
--- a/tests/acceptance/expected-failures-webUI-on-OCIS-storage.md
+++ b/tests/acceptance/expected-failures-webUI-on-OCIS-storage.md
@@ -66,7 +66,6 @@ Other free text and markdown formatting can be used elsewhere in the document if
 - [webUISharingPublicManagement/publicLinkIndicator.feature:81](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingPublicManagement/publicLinkIndicator.feature#L81)
 - [webUISharingPublicManagement/publicLinkIndicator.feature:98](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingPublicManagement/publicLinkIndicator.feature#L98)
 - [webUISharingInternalGroupsSharingIndicator/shareWithGroups.feature:61](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingInternalGroupsSharingIndicator/shareWithGroups.feature#L61)
-- [webUISharingInternalGroupsSharingIndicator/shareWithGroups.feature:20](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingInternalGroupsSharingIndicator/shareWithGroups.feature#L20)
 - [webUISharingInternalGroupsSharingIndicator/shareWithGroups.feature:80](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingInternalGroupsSharingIndicator/shareWithGroups.feature#L80)
 - [webUISharingInternalGroupsSharingIndicator/shareWithGroups.feature:42](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingInternalGroupsSharingIndicator/shareWithGroups.feature#L42)
 - [webUISharingInternalUsersSharingIndicator/shareWithUsers.feature:80](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingInternalUsersSharingIndicator/shareWithUsers.feature#L80)
@@ -378,7 +377,7 @@ Other free text and markdown formatting can be used elsewhere in the document if
 - [webUIFilesDetails/fileDetails.feature:57](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFilesDetails/fileDetails.feature#L57)
 - [webUIRenameFiles/renameFiles.feature:257](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIRenameFiles/renameFiles.feature#L257)
 
-### [Copy/move not possible from and into shares in oCIS](https://github.com/owncloud/web/issues/6892) 
+### [Copy/move not possible from and into shares in oCIS](https://github.com/owncloud/web/issues/6892)
 - [webUIFilesCopy/copy.feature:89](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFilesCopy/copy.feature#L89)
 - [webUIFilesCopy/copy.feature:101](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFilesCopy/copy.feature#L101)
 
diff --git a/tests/acceptance/features/apiSpaces/changeSpaces.feature b/tests/acceptance/features/apiSpaces/changeSpaces.feature
index a3937755524..73535e12629 100644
--- a/tests/acceptance/features/apiSpaces/changeSpaces.feature
+++ b/tests/acceptance/features/apiSpaces/changeSpaces.feature
@@ -1,139 +1,198 @@
 @api @skipOnOcV10
 Feature: Change data of space
-  As a user with admin rights
+  As a user with space admin rights
   I want to be able to change the data of a created space (increase the quota, change name, etc.)
 
   Note - this feature is run in CI with ACCOUNTS_HASH_DIFFICULTY set to the default for production
   See https://github.com/owncloud/ocis/issues/1542 and https://github.com/owncloud/ocis/pull/839
 
   Background:
-    Given user "Alice" has been created with default attributes and without skeleton files
-    And the administrator has given "Alice" the role "Admin" using the settings api
+    Given these users have been created with default attributes and without skeleton files:
+      | username |
+      | Alice    |
+      | Brian    |
+      | Bob      |
+    And the administrator has given "Alice" the role "Space Admin" using the settings api
+    And user "Alice" has created a space "Project Jupiter" of type "project" with quota "20"
+    And user "Alice" has shared a space "Project Jupiter" to user "Brian" with role "editor"
+    And user "Alice" has shared a space "Project Jupiter" to user "Bob" with role "viewer"
 
-  Scenario: An admin user can change the name and description of a Space via the Graph API
-    Given user "Alice" has created a space "Project Jupiter" of type "project" with quota "20"
-    When user "Alice" changes the name of the "Project Jupiter" space to "Project Death Star"
-    And user "Alice" changes the description of the "Project Death Star" space to "The Death Star is a fictional mobile space station"
+
+  Scenario Outline: Only space admin user can change the name of a Space via the Graph API
+    When user "<user>" changes the name of the "Project Jupiter" space to "Project Death Star"
+    Then the HTTP status code should be "<code>"
+    And the user "<user>" should have a space called "<expectedName>" with these key and value pairs:
+      | key       | value          |
+      | driveType | project        |
+      | name      | <expectedName> |
+    Examples:
+      | user  | code | expectedName       |
+      | Alice | 200  | Project Death Star |
+      | Brian | 403  | Project Jupiter    |
+      | Bob   | 403  | Project Jupiter    |
+
+
+  Scenario: Only space admin user can change the description(subtitle) of a Space via the Graph API
+    When user "Alice" changes the description of the "Project Jupiter" space to "The Death Star is a fictional mobile space station"
     Then the HTTP status code should be "200"
-    When user "Alice" lists all available spaces via the GraphApi
-    Then the json responded should contain a space "Project Death Star" with these key and value pairs:
-      | key              | value                                              |
-      | driveType        | project                                            |
-      | name             | Project Death Star                                 |
-      | description      | The Death Star is a fictional mobile space station |
-      | quota@@@total    | 20                                                 |
-      | root@@@webDavUrl | %base_url%/dav/spaces/%space_id%                   |
-
-  Scenario: An admin user can increase the quota of a Space via the Graph API
-    Given user "Alice" has created a space "Project Earth" of type "project" with quota "20"
-    When user "Alice" changes the quota of the "Project Earth" space to "100"
+    And the user "Alice" should have a space called "Project Jupiter" with these key and value pairs:
+      | key         | value                                              |
+      | driveType   | project                                            |
+      | name        | Project Jupiter                                    |
+      | description | The Death Star is a fictional mobile space station |
+
+
+  Scenario Outline: Viewer and editor cannot change the description(subtitle) of a Space via the Graph API
+    When user "<user>" changes the description of the "Project Jupiter" space to "The Death Star is a fictional mobile space station"
+    Then the HTTP status code should be "<code>"
+    Examples:
+      | user  | code |
+      | Brian | 403  |
+      | Bob   | 403  |
+
+
+  Scenario Outline: An user tries to increase the quota of a Space via the Graph API
+    When user "<user>" changes the quota of the "Project Jupiter" space to "100"
+    Then the HTTP status code should be "<code>"
+    And the user "<user>" should have a space called "Project Jupiter" with these key and value pairs:
+      | key           | value                |
+      | name          | Project Jupiter      |
+      | quota@@@total | <expectedQuataValue> |
+    Examples:
+      | user  | code | expectedQuataValue |
+      | Alice | 200  | 100                |
+      | Brian | 401  | 20                 |
+      | Bob   | 401  | 20                 |
+
+
+  Scenario Outline: An space admin user set no restriction quota of a Space via the Graph API
+    When user "Alice" changes the quota of the "Project Jupiter" space to "<quotaValue>"
     Then the HTTP status code should be "200"
-    When user "Alice" lists all available spaces via the GraphApi
-    Then the json responded should contain a space "Project Earth" with these key and value pairs:
-      | key           | value         |
-      | name          | Project Earth |
-      | quota@@@total | 100           |
-
-
-  Scenario: An user set readme file as description of the space via the Graph API
-    Given user "Alice" has created a space "add special section" with the default quota using the GraphApi
-    And user "Alice" has created a folder ".space" in space "add special section"
-    And user "Alice" has uploaded a file inside space "add special section" with content "space description" to ".space/readme.md"
-    When user "Alice" sets the file ".space/readme.md" as a description in a special section of the "add special section" space
+    When user "Alice" uploads a file inside space "Project Jupiter" with content "some content" to "file.txt" using the WebDAV API
+    Then the HTTP status code should be "201"
+    And the user "Alice" should have a space called "Project Jupiter" with these key and value pairs:
+      | key          | value           |
+      | name         | Project Jupiter |
+      | quota@@@used | 12              |
+    Examples:
+      | quotaValue |
+      | 0          |
+      | -1         |
+
+
+  Scenario: An user space admin set readme file as description of the space via the Graph API
+    Given user "Alice" has created a folder ".space" in space "Project Jupiter"
+    And user "Alice" has uploaded a file inside space "Project Jupiter" with content "space description" to ".space/readme.md"
+    When user "Alice" sets the file ".space/readme.md" as a description in a special section of the "Project Jupiter" space
     Then the HTTP status code should be "200"
-    When user "Alice" lists all available spaces via the GraphApi
-    Then the json responded should contain a space "add special section" owned by "Alice" with description file ".space/readme.md" with these key and value pairs:
-      | key                                | value               |
-      | name                               | add special section |
-      | special@@@0@@@size                 | 17                  |
-      | special@@@0@@@name                 | readme.md           |
-      | special@@@0@@@specialFolder@@@name | readme              |
-      | special@@@0@@@file@@@mimeType      | text/markdown       |
-      | special@@@0@@@id                   | %file_id%           |
-      | special@@@0@@@eTag                 | %eTag%              |
-    And for user "Alice" folder ".space/" of the space "add special section" should contain these entries:
+    And the user "Alice" should have a space called "Project Jupiter" owned by "Alice" with description file ".space/readme.md" with these key and value pairs:
+      | key                                | value           |
+      | name                               | Project Jupiter |
+      | special@@@0@@@size                 | 17              |
+      | special@@@0@@@name                 | readme.md       |
+      | special@@@0@@@specialFolder@@@name | readme          |
+      | special@@@0@@@file@@@mimeType      | text/markdown   |
+      | special@@@0@@@id                   | %file_id%       |
+      | special@@@0@@@eTag                 | %eTag%          |
+    And for user "Alice" folder ".space/" of the space "Project Jupiter" should contain these entries:
       | readme.md |
-    And for user "Alice" the content of the file ".space/readme.md" of the space "add special section" should be "space description"
+    And for user "Alice" the content of the file ".space/readme.md" of the space "Project Jupiter" should be "space description"
+
+
+  Scenario Outline: An user member of the space changes readme file
+    Given user "Alice" has created a folder ".space" in space "Project Jupiter"
+    And user "Alice" has uploaded a file inside space "Project Jupiter" with content "space description" to ".space/readme.md"
+    And user "Alice" has set the file ".space/readme.md" as a description in a special section of the "Project Jupiter" space
+    When user "<user>" uploads a file inside space "Project Jupiter" with content "new description" to ".space/readme.md" using the WebDAV API
+    Then the HTTP status code should be "<code>"
+    And the user "<user>" should have a space called "Project Jupiter" owned by "Alice" with description file ".space/readme.md" with these key and value pairs:
+      | key                                | value           |
+      | name                               | Project Jupiter |
+      | special@@@0@@@size                 | <size>          |
+      | special@@@0@@@name                 | readme.md       |
+      | special@@@0@@@specialFolder@@@name | readme          |
+      | special@@@0@@@file@@@mimeType      | text/markdown   |
+      | special@@@0@@@id                   | %file_id%       |
+      | special@@@0@@@eTag                 | %eTag%          |
+    And for user "<user>" folder ".space/" of the space "Project Jupiter" should contain these entries:
+      | readme.md |
+    And for user "<user>" the content of the file ".space/readme.md" of the space "Project Jupiter" should be "<content>"
+    Examples:
+      | user  | code | size | content           |
+      | Brian | 204  | 15   | new description   |
+      | Bob   | 403  | 17   | space description |
 
 
-  Scenario Outline: An user set image file as space image of the space via the Graph API
-    Given user "Alice" has created a space "add special section" with the default quota using the GraphApi
-    And user "Alice" has created a folder ".space" in space "add special section"
-    And user "Alice" has uploaded a file inside space "add special section" with content "" to ".space/<fileName>"
-    When user "Alice" sets the file ".space/<fileName>" as a space image in a special section of the "add special section" space
+  Scenario Outline: An user space admin and editor set image file as space image of the space via the Graph API
+    Given user "Alice" has created a folder ".space" in space "Project Jupiter"
+    And user "<user>" has uploaded a file inside space "Project Jupiter" with content "" to ".space/<fileName>"
+    When user "<user>" sets the file ".space/<fileName>" as a space image in a special section of the "Project Jupiter" space
     Then the HTTP status code should be "200"
-    When user "Alice" lists all available spaces via the GraphApi
-    Then the json responded should contain a space "add special section" owned by "Alice" with description file ".space/<fileName>" with these key and value pairs:
-      | key                                | value               |
-      | name                               | add special section |
-      | special@@@0@@@size                 | 0                   |
-      | special@@@0@@@name                 | <nameInResponse>    |
-      | special@@@0@@@specialFolder@@@name | image               |
-      | special@@@0@@@file@@@mimeType      | <mimeType>          |
-      | special@@@0@@@id                   | %file_id%           |
-      | special@@@0@@@eTag                 | %eTag%              |
-    And for user "Alice" folder ".space/" of the space "add special section" should contain these entries:
+    And the user "Alice" should have a space called "Project Jupiter" owned by "Alice" with description file ".space/<fileName>" with these key and value pairs:
+      | key                                | value            |
+      | name                               | Project Jupiter  |
+      | special@@@0@@@size                 | 0                |
+      | special@@@0@@@name                 | <nameInResponse> |
+      | special@@@0@@@specialFolder@@@name | image            |
+      | special@@@0@@@file@@@mimeType      | <mimeType>       |
+      | special@@@0@@@id                   | %file_id%        |
+      | special@@@0@@@eTag                 | %eTag%           |
+    And for user "<user>" folder ".space/" of the space "Project Jupiter" should contain these entries:
       | <fileName> |
     Examples:
-      | fileName        | nameInResponse  | mimeType   |
-      | spaceImage.jpeg | spaceImage.jpeg | image/jpeg |
-      | spaceImage.png  | spaceImage.png  | image/png  |
-      | spaceImage.gif  | spaceImage.gif  | image/gif  |
-
-
-  Scenario: An user set new readme file as description of the space via the Graph API
-    Given user "Alice" has created a space "add special section" with the default quota using the GraphApi
-    And user "Alice" has created a folder ".space" in space "add special section"
-    And user "Alice" has uploaded a file inside space "add special section" with content "space description" to ".space/readme.md"
-    And user "Alice" has set the file ".space/readme.md" as a description in a special section of the "add special section" space
-    When user "Alice" has uploaded a file inside space "add special section" with content "new space description" to ".space/newReadme.md"
-    And user "Alice" sets the file ".space/newReadme.md" as a description in a special section of the "add special section" space
-    Then the HTTP status code should be "200"
-    And for user "Alice" the content of the file ".space/newReadme.md" of the space "add special section" should be "new space description"
-    When user "Alice" lists all available spaces via the GraphApi
-    Then the json responded should contain a space "add special section" owned by "Alice" with description file ".space/newReadme.md" with these key and value pairs:
-      | key                                | value               |
-      | name                               | add special section |
-      | special@@@0@@@size                 | 21                  |
-      | special@@@0@@@name                 | newReadme.md        |
-      | special@@@0@@@specialFolder@@@name | readme              |
-      | special@@@0@@@file@@@mimeType      | text/markdown       |
-      | special@@@0@@@id                   | %file_id%           |
-      | special@@@0@@@eTag                 | %eTag%              |
-
-
-  Scenario: An user set new image file as space image of the space via the Graph API
-    Given user "Alice" has created a space "add special section" with the default quota using the GraphApi
-    And user "Alice" has created a folder ".space" in space "add special section"
-    And user "Alice" has uploaded a file inside space "add special section" with content "" to ".space/spaceImage.jpeg"
-    And user "Alice" has set the file ".space/spaceImage.jpeg" as a space image in a special section of the "add special section" space
-    When user "Alice" has uploaded a file inside space "add special section" with content "" to ".space/newSpaceImage.png"
-    And user "Alice" sets the file ".space/newSpaceImage.png" as a space image in a special section of the "add special section" space
-    Then the HTTP status code should be "200"
-    When user "Alice" lists all available spaces via the GraphApi
-    Then the json responded should contain a space "add special section" owned by "Alice" with description file ".space/newSpaceImage.png" with these key and value pairs:
-      | key                                | value               |
-      | name                               | add special section |
-      | special@@@0@@@size                 | 0                   |
-      | special@@@0@@@name                 | newSpaceImage.png   |
-      | special@@@0@@@specialFolder@@@name | image               |
-      | special@@@0@@@file@@@mimeType      | image/png           |
-      | special@@@0@@@id                   | %file_id%           |
-      | special@@@0@@@eTag                 | %eTag%              |
-
-
-  Scenario Outline: An admin user set no restriction quota of a Space via the Graph API
-    Given user "Alice" has created a space "Project Earth" of type "project" with quota "20"
-    When user "Alice" changes the quota of the "Project Earth" space to "<quotaValue>"
+      | user  | fileName        | nameInResponse  | mimeType   |
+      | Alice | spaceImage.jpeg | spaceImage.jpeg | image/jpeg |
+      | Brian | spaceImage.png  | spaceImage.png  | image/png  |
+      | Alice | spaceImage.gif  | spaceImage.gif  | image/gif  |
+
+
+  Scenario: An user viewer cannot set image file as space image of the space via the Graph API
+    Given user "Alice" has created a folder ".space" in space "Project Jupiter"
+    And user "Alice" has uploaded a file inside space "Project Jupiter" with content "" to ".space/someImageFile.jpg"
+    When user "Bob" sets the file ".space/someImageFile.jpg" as a space image in a special section of the "Project Jupiter" space
+    Then the HTTP status code should be "403"
+
+
+  Scenario Outline: An user set new readme file as description of the space via the Graph API
+    Given user "Alice" has created a folder ".space" in space "Project Jupiter"
+    And user "Alice" has uploaded a file inside space "Project Jupiter" with content "space description" to ".space/readme.md"
+    And user "Alice" has set the file ".space/readme.md" as a description in a special section of the "Project Jupiter" space
+    When user "<user>" uploads a file inside space "Project Jupiter" owned by the user "Alice" with content "new content" to ".space/readme.md" using the WebDAV API
+    Then the HTTP status code should be "<code>"
+    And for user "<user>" the content of the file ".space/readme.md" of the space "Project Jupiter" should be "<expectedContent>"
+    And the user "<user>" should have a space called "Project Jupiter" owned by "Alice" with description file ".space/readme.md" with these key and value pairs:
+      | key                                | value           |
+      | name                               | Project Jupiter |
+      | special@@@0@@@size                 | <expectedSize>  |
+      | special@@@0@@@name                 | readme.md       |
+      | special@@@0@@@specialFolder@@@name | readme          |
+      | special@@@0@@@file@@@mimeType      | text/markdown   |
+      | special@@@0@@@id                   | %file_id%       |
+      | special@@@0@@@eTag                 | %eTag%          |
+    Examples:
+      | user  | code | expectedSize | expectedContent   |
+      | Alice | 204  | 11           | new content       |
+      | Brian | 204  | 11           | new content       |
+      | Bob   | 403  | 17           | space description |
+
+
+  Scenario Outline: An user set new image file as space image of the space via the Graph API
+    Given user "Alice" has created a folder ".space" in space "Project Jupiter"
+    And user "Alice" has uploaded a file inside space "Project Jupiter" with content "" to ".space/spaceImage.jpeg"
+    And user "Alice" has set the file ".space/spaceImage.jpeg" as a space image in a special section of the "Project Jupiter" space
+    When user "<user>" has uploaded a file inside space "Project Jupiter" with content "" to ".space/newSpaceImage.png"
+    And user "<user>" sets the file ".space/newSpaceImage.png" as a space image in a special section of the "Project Jupiter" space
     Then the HTTP status code should be "200"
-    When user "Alice" uploads a file inside space "Project Earth" with content "some content" to "file.txt" using the WebDAV API
-    Then the HTTP status code should be "201"
-    When user "Alice" lists all available spaces via the GraphApi
-    Then the json responded should contain a space "Project Earth" with these key and value pairs:
-      | key          | value         |
-      | name         | Project Earth |
-      | quota@@@used | 12            |
+     And the user "<user>" should have a space called "Project Jupiter" owned by "Alice" with space image ".space/newSpaceImage.png" with these key and value pairs:
+      | key                                | value             |
+      | name                               | Project Jupiter   |
+      | special@@@0@@@size                 | 0                 |
+      | special@@@0@@@name                 | newSpaceImage.png |
+      | special@@@0@@@specialFolder@@@name | image             |
+      | special@@@0@@@file@@@mimeType      | image/png         |
+      | special@@@0@@@id                   | %file_id%         |
+      | special@@@0@@@eTag                 | %eTag%            |
     Examples:
-      | quotaValue |
-      | 0          |
-      | -1         |
+      | user  |
+      | Alice |
+      | Brian |
\ No newline at end of file
diff --git a/tests/acceptance/features/apiSpaces/deleteSpaces.feature b/tests/acceptance/features/apiSpaces/deleteSpaces.feature
index e34b1af191d..4c387a468ba 100644
--- a/tests/acceptance/features/apiSpaces/deleteSpaces.feature
+++ b/tests/acceptance/features/apiSpaces/deleteSpaces.feature
@@ -2,7 +2,7 @@
 Feature: Disabling and deleting space
   As a manager of space
   I want to be able to disable the space first, then delete it.
-  I want to make sure that a disabled spaces isn't accessible by shared users. 
+  I want to make sure that a disabled spaces isn't accessible by shared users.
 
   Note - this feature is run in CI with ACCOUNTS_HASH_DIFFICULTY set to the default for production
   See https://github.com/owncloud/ocis/issues/1542 and https://github.com/owncloud/ocis/pull/839
@@ -13,80 +13,58 @@ Feature: Disabling and deleting space
       | Alice    |
       | Brian    |
       | Bob      |
-    And the administrator has given "Alice" the role "Admin" using the settings api
+    And the administrator has given "Alice" the role "Space Admin" using the settings api
+    And user "Alice" has created a space "Project Moon" with the default quota using the GraphApi
+    And user "Alice" has shared a space "Project Moon" to user "Brian" with role "editor"
+    And user "Alice" has shared a space "Project Moon" to user "Bob" with role "viewer"
 
 
-  Scenario: An owner can disable a Space via the Graph API
-    Given user "Alice" has created a space "disable a space" of type "project" with quota "10"
-    And user "Alice" has shared a space "disable a space" to user "Brian" with role "editor"
-    When user "Alice" disables a space "disable a space"
+  Scenario Outline: A space admin user can disable a Space via the Graph API
+    When user "Alice" disables a space "Project Moon"
     Then the HTTP status code should be "204"
-    When user "Alice" lists all available spaces via the GraphApi
-    Then the json responded should contain a space "disable a space" with these key and value pairs:
-      | key                    | value           |
-      | name                   | disable a space |
-      | root@@@deleted@@@state | trashed         |
-    
+    And the user "Alice" should have a space called "Project Moon" with these key and value pairs:
+      | key                    | value        |
+      | name                   | Project Moon |
+      | root@@@deleted@@@state | trashed      |
+    And the user "<user>" should not have a space called "Project Moon"
+    Examples:
+      | user  |
+      | Brian |
+      | Bob   |
 
-   Scenario: Participants without a manager role cannot see the disabled space
-    Given user "Alice" has created a space "cannot see space" of type "project" with quota "10"
-    And user "Alice" has shared a space "cannot see space" to user "Brian" with role "editor"
-    And user "Alice" has shared a space "cannot see space" to user "Bob" with role "viewer"
-    And user "Alice" has disabled a space "cannot see space"  
-    When user "Brian" lists all available spaces via the GraphApi
-    Then the json responded should not contain a space with name "cannot see space"
-    When user "Bob" lists all available spaces via the GraphApi
-    Then the json responded should not contain a space with name "cannot see space"
+
+  Scenario Outline: An user without space admin role cannot disable a Space via the Graph API
+    When user "<user>" disables a space "Project Moon"
+    Then the HTTP status code should be "403"
+    And the user "<user>" should have a space called "Project Moon" with these key and value pairs:
+      | key  | value        |
+      | name | Project Moon |
+    Examples:
+      | user  |
+      | Brian |
+      | Bob   |
 
 
-  Scenario: An owner can delete a disabled Space via the webDav API
-    Given user "Alice" has created a space "delete a space" of type "project" with quota "10"
-    And user "Alice" has disabled a space "delete a space"
-    When user "Alice" deletes a space "delete a space"
+  Scenario: A space manager can delete a disabled Space via the webDav API
+    Given user "Alice" has disabled a space "Project Moon"
+    When user "Alice" deletes a space "Project Moon"
     Then the HTTP status code should be "204"
-    When user "Alice" lists all available spaces via the GraphApi
-    Then the json responded should not contain a space with name "delete a space"
-    
+    And the user "Alice" should not have a space called "Project Moon"
 
-  Scenario: An owner can disable and delete Space in which files and folders exist via the webDav API
-    Given user "Alice" has created a space "delete a space with content" of type "project" with quota "10"
-    And user "Alice" has uploaded a file inside space "delete a space with content" with content "test" to "test.txt"
-    And user "Alice" has created a folder "MainFolder" in space "delete a space with content"
-    When user "Alice" disables a space "delete a space with content"
+
+  Scenario: An space manager can disable and delete Space in which files and folders exist via the webDav API
+    Given user "Alice" has uploaded a file inside space "Project Moon" with content "test" to "test.txt"
+    And user "Alice" has created a folder "MainFolder" in space "Project Moon"
+    When user "Alice" disables a space "Project Moon"
     Then the HTTP status code should be "204"
-    When user "Alice" deletes a space "delete a space with content"
+    When user "Alice" deletes a space "Project Moon"
     Then the HTTP status code should be "204"
-    When user "Alice" lists all available spaces via the GraphApi
-    Then the json responded should not contain a space with name "delete a space with content"
+    And the user "Alice" should not have a space called "Project Moon"
 
 
-  Scenario: An owner cannot delete a space via the webDav API without first disabling it
-    Given user "Alice" has created a space "delete without disabling" of type "project" with quota "10"
-    When user "Alice" deletes a space "delete without disabling"
+  Scenario: An space manager cannot delete a space via the webDav API without first disabling it
+    When user "Alice" deletes a space "Project Moon"
     Then the HTTP status code should be "400"
-    When user "Alice" lists all available spaces via the GraphApi
-    Then the json responded should contain a space "delete without disabling" with these key and value pairs:
-      | key  | value                    |
-      | name | delete without disabling |
-
-
-  Scenario: An user with editor role cannot disable a Space via the Graph API
-    Given user "Alice" has created a space "editor tries to disable a space" of type "project" with quota "10"
-    And user "Alice" has shared a space "editor tries to disable a space" to user "Brian" with role "editor"
-    When user "Brian" disables a space "editor tries to disable a space"
-    Then the HTTP status code should be "403"
-    When user "Brian" lists all available spaces via the GraphApi
-    Then the json responded should contain a space "editor tries to disable a space" with these key and value pairs:
-      | key  | value                           |
-      | name | editor tries to disable a space |
-    
-
-  Scenario: An user with viewer role cannot disable a Space via the Graph API
-    Given user "Alice" has created a space "viewer tries to disable a space" of type "project" with quota "10"
-    And user "Alice" has shared a space "viewer tries to disable a space" to user "Brian" with role "viewer"
-    When user "Brian" disables a space "viewer tries to disable a space"
-    Then the HTTP status code should be "403"
-    When user "Brian" lists all available spaces via the GraphApi
-    Then the json responded should contain a space "viewer tries to disable a space" with these key and value pairs:
-      | key  | value                           |
-      | name | viewer tries to disable a space |
+    And the user "Alice" should have a space called "Project Moon" with these key and value pairs:
+      | key  | value        |
+      | name | Project Moon |
diff --git a/tests/acceptance/features/apiSpaces/download.feature b/tests/acceptance/features/apiSpaces/download.feature
index 5dd610344d2..983c8b58afe 100644
--- a/tests/acceptance/features/apiSpaces/download.feature
+++ b/tests/acceptance/features/apiSpaces/download.feature
@@ -1,6 +1,6 @@
 @api @skipOnOcV10
 Feature: Download file in project space
-    As a user, I want to be able to download files
+    As a user with different role, I want to be able to download files
 
     Note - this feature is run in CI with ACCOUNTS_HASH_DIFFICULTY set to the default for production
     See https://github.com/owncloud/ocis/issues/1542 and https://github.com/owncloud/ocis/pull/839
@@ -10,29 +10,42 @@ Feature: Download file in project space
             | username |
             | Alice    |
             | Brian    |
-        And the administrator has given "Alice" the role "Admin" using the settings api
+            | Bob    |
+        And the administrator has given "Alice" the role "Space Admin" using the settings api
         And user "Alice" has created a space "download file" with the default quota using the GraphApi
         And user "Alice" has uploaded a file inside space "download file" with content "some content" to "file.txt"
+        And user "Alice" has shared a space "download file" to user "Brian" with role "editor"
+        And user "Alice" has shared a space "download file" to user "Bob" with role "viewer"
 
 
-    Scenario: An user downloads a file in the project space
-        When user "Alice" downloads the file "file.txt" of the space "download file" using the WebDAV API
+    Scenario Outline: An user downloads a file in the project space
+        When user "<user>" downloads the file "file.txt" of the space "download file" using the WebDAV API
         Then the HTTP status code should be "200"
         And the following headers should be set
             | header         | value |
             | Content-Length | 12    |
+        Examples:
+            | user  |
+            | Alice |
+            | Brian |
+            | Bob   |
 
 
-    Scenario: An user downloads an old version of the file in the project space
+    Scenario Outline: An user downloads an old version of the file in the project space
         Given user "Alice" has uploaded a file inside space "download file" with content "new content" to "file.txt"
         And user "Alice" has uploaded a file inside space "download file" with content "newest content" to "file.txt"
-        When user "Alice" downloads version of the file "file.txt" with the index "1" of the space "download file" using the WebDAV API
+        When user "<user>" downloads version of the file "file.txt" with the index "1" of the space "download file" using the WebDAV API
         Then the HTTP status code should be "200"
         And the following headers should be set
             | header         | value |
             | Content-Length | 11    |
-        When user "Alice" downloads version of the file "file.txt" with the index "2" of the space "download file" using the WebDAV API
+        When user "<user>" downloads version of the file "file.txt" with the index "2" of the space "download file" using the WebDAV API
         Then the HTTP status code should be "200"
         And the following headers should be set
             | header         | value |
             | Content-Length | 12    |
+        Examples:
+            | user  |
+            | Alice |
+            | Brian |
+            | Bob   |
diff --git a/tests/acceptance/features/apiSpaces/filePreviews.feature b/tests/acceptance/features/apiSpaces/filePreviews.feature
index 6c1391a148c..2b7a0162d9d 100644
--- a/tests/acceptance/features/apiSpaces/filePreviews.feature
+++ b/tests/acceptance/features/apiSpaces/filePreviews.feature
@@ -9,8 +9,7 @@ Feature: Preview file in project space
     Given these users have been created with default attributes and without skeleton files:
       | username |
       | Alice    |
-      | Brian    |
-    And the administrator has given "Alice" the role "Admin" using the settings api
+    And the administrator has given "Alice" the role "Space Admin" using the settings api
     And user "Alice" has created a space "previews of the files" with the default quota using the GraphApi
 
 
diff --git a/tests/acceptance/features/apiSpaces/listSpaces.feature b/tests/acceptance/features/apiSpaces/listSpaces.feature
index 1c6d7623f99..f4f3e96a0a4 100644
--- a/tests/acceptance/features/apiSpaces/listSpaces.feature
+++ b/tests/acceptance/features/apiSpaces/listSpaces.feature
@@ -9,46 +9,67 @@ Feature: List and create spaces
   Background:
     Given user "Alice" has been created with default attributes and without skeleton files
 
+
   Scenario: An ordinary user can request information about their Space via the Graph API
     When user "Alice" lists all available spaces via the GraphApi
     Then the HTTP status code should be "200"
     And the json responded should contain a space "Alice Hansen" with these key and value pairs:
-      | key              | value        |
-      | driveType        | personal     |
-      | driveAlias       | personal/alice |
-      | id               | %space_id%   |
-      | name             | Alice Hansen |
-      | quota@@@state    | normal       |
+      | key              | value                            |
+      | driveType        | personal                         |
+      | driveAlias       | personal/alice                   |
+      | id               | %space_id%                       |
+      | name             | Alice Hansen                     |
+      | quota@@@state    | normal                           |
       | root@@@webDavUrl | %base_url%/dav/spaces/%space_id% |
 
+
   Scenario: An ordinary user can request information about their Space via the Graph API using a filter
+    Given user "Brian" has been created with default attributes and without skeleton files
+    And user "Brian" has created folder "folder"
+    And user "Brian" has shared folder "folder" with user "Alice" with permissions "31"
+    And user "Alice" has accepted share "/folder" offered by user "Brian"
+    Then the user "Alice" should have a space called "Shares Jail" with these key and value pairs:
+      | key       | value       |
+      | driveType | virtual     |
+      | id        | %space_id%  |
+      | name      | Shares Jail |
     When user "Alice" lists all available spaces via the GraphApi with query "$filter=driveType eq 'personal'"
     Then the HTTP status code should be "200"
     And the json responded should contain a space "Alice Hansen" with these key and value pairs:
-      | key              | value        |
-      | driveType        | personal     |
-      | id               | %space_id%   |
-      | name             | Alice Hansen |
-      | quota@@@state    | normal       |
+      | key              | value                            |
+      | driveType        | personal                         |
+      | id               | %space_id%                       |
+      | name             | Alice Hansen                     |
+      | quota@@@state    | normal                           |
       | root@@@webDavUrl | %base_url%/dav/spaces/%space_id% |
     And the json responded should not contain a space with name "Shares Jail"
     And the json responded should only contain spaces of type "personal"
 
+
   Scenario: An ordinary user will not see any space when using a filter for project
+    Given the administrator has given "Alice" the role "Space Admin" using the settings api
+    And user "Alice" has created a space "my project" of type "project" with quota "20"
     When user "Alice" lists all available spaces via the GraphApi with query "$filter=driveType eq 'project'"
     Then the HTTP status code should be "200"
+    And the json responded should contain a space "my project" with these key and value pairs:
+      | key       | value      |
+      | driveType | project    |
+      | id        | %space_id% |
+      | name      | my project |
     And the json responded should not contain a space with name "Alice Hansen"
-    And the json responded should not contain spaces of type "personal"
+
 
   Scenario: An ordinary user can access their Space via the webDav API
     When user "Alice" lists all available spaces via the GraphApi
     And user "Alice" lists the content of the space with the name "Alice Hansen" using the WebDav Api
     Then the HTTP status code should be "207"
 
+
   Scenario: An ordinary user cannot create a Space via Graph API
     When user "Alice" creates a space "Project Mars" of type "project" with the default quota using the GraphApi
     Then the HTTP status code should be "401"
 
+
   Scenario: An admin user can create a Space via the Graph API with default quota
     Given the administrator has given "Alice" the role "Admin" using the settings api
     When user "Alice" creates a space "Project Mars" of type "project" with the default quota using the GraphApi
@@ -61,6 +82,7 @@ Feature: List and create spaces
       | quota@@@total    | 1000000000                       |
       | root@@@webDavUrl | %base_url%/dav/spaces/%space_id% |
 
+
   Scenario: An admin user can create a Space via the Graph API with certain quota
     Given the administrator has given "Alice" the role "Admin" using the settings api
     When user "Alice" creates a space "Project Venus" of type "project" with quota "2000" using the GraphApi
@@ -72,6 +94,7 @@ Feature: List and create spaces
       | quota@@@total    | 2000                             |
       | root@@@webDavUrl | %base_url%/dav/spaces/%space_id% |
 
+
   Scenario: A user can list his personal space via multiple endpoints
     When user "Alice" lists all available spaces via the GraphApi with query "$filter=driveType eq 'personal'"
     Then the json responded should contain a space "Alice Hansen" owned by "Alice" with these key and value pairs:
@@ -87,6 +110,7 @@ Feature: List and create spaces
       | name             | Alice Hansen                     |
       | root@@@webDavUrl | %base_url%/dav/spaces/%space_id% |
 
+
   Scenario: A user can list his created spaces via multiple endpoints
     Given the administrator has given "Alice" the role "Admin" using the settings api
     When user "Alice" creates a space "Project Venus" of type "project" with quota "2000" using the GraphApi
diff --git a/tests/acceptance/features/apiSpaces/quota.feature b/tests/acceptance/features/apiSpaces/quota.feature
index c5b8c8cbf6f..781d6b1ce6b 100644
--- a/tests/acceptance/features/apiSpaces/quota.feature
+++ b/tests/acceptance/features/apiSpaces/quota.feature
@@ -13,14 +13,13 @@ Feature: State of the quota
 
   Background:
     Given user "Alice" has been created with default attributes and without skeleton files
-    And the administrator has given "Alice" the role "Admin" using the settings api
+    And the administrator has given "Alice" the role "Space Admin" using the settings api
 
 
   Scenario Outline: Quota information is returned in the list of spaces returned via the Graph API
     Given user "Alice" has created a space "<spaceName>" of type "project" with quota "<total>"
-    And user "Alice" has uploaded a file inside space "<spaceName>" with content "<fileContent>" to "test.txt"
-    When user "Alice" lists all available spaces via the GraphApi
-    Then the json responded should contain a space "<spaceName>" with these key and value pairs:
+    When user "Alice" uploads a file inside space "<spaceName>" with content "<fileContent>" to "test.txt" using the WebDAV API
+    Then the user "Alice" should have a space called "<spaceName>" with these key and value pairs:
       | key              | value       |
       | name             | <spaceName> |
       | quota@@@state    | <state>     |
diff --git a/tests/acceptance/features/apiSpaces/removeSpaceObjects.feature b/tests/acceptance/features/apiSpaces/removeSpaceObjects.feature
index 6e22ec10c05..e7650acb72b 100644
--- a/tests/acceptance/features/apiSpaces/removeSpaceObjects.feature
+++ b/tests/acceptance/features/apiSpaces/removeSpaceObjects.feature
@@ -13,7 +13,7 @@ Feature: Remove files, folder
       | username |
       | Alice    |
       | Brian    |
-    And the administrator has given "Alice" the role "Admin" using the settings api
+    And the administrator has given "Alice" the role "Space Admin" using the settings api
     And user "Alice" has created a space "delete objects" with the default quota using the GraphApi
     And user "Alice" has created a folder "folderForDeleting/sub1/sub2" in space "delete objects"
     And user "Alice" has uploaded a file inside space "delete objects" with content "some content" to "text.txt"
@@ -58,8 +58,7 @@ Feature: Remove files, folder
     And for user "<user>" the space "delete objects" <shouldOrNotBeInSpace> contain these entries:
       | text.txt |
     And as "<user>" file "text.txt" <shouldOrNotBeInTrash> exist in the trashbin of the space "delete objects"
-    When user "<user>" lists all available spaces via the GraphApi
-    Then the json responded should contain a space "delete objects" with these key and value pairs:
+    And the user "<user>" should have a space called "delete objects" with these key and value pairs:
       | key          | value          |
       | name         | delete objects |
       | quota@@@used | <quotaValue>   |
@@ -72,10 +71,8 @@ Feature: Remove files, folder
 
 
   Scenario: An user is unable to delete a Space via the webDav API
-    Given user "Alice" has created a space "user deletes a space" of type "project" with quota "20"
-    When user "Alice" removes the folder "" from space "user deletes a space"
+    When user "Alice" removes the folder "" from space "delete objects"
     Then the HTTP status code should be "400"
-    When user "Alice" lists all available spaces via the GraphApi
-    Then the json responded should contain a space "user deletes a space" with these key and value pairs:
-      | key  | value                |
-      | name | user deletes a space |
+    And the user "Alice" should have a space called "delete objects" with these key and value pairs:
+      | key  | value          |
+      | name | delete objects |
diff --git a/tests/acceptance/features/apiSpaces/resharing.feature b/tests/acceptance/features/apiSpaces/resharing.feature
index e4ff437f4f9..6a3eca755ff 100644
--- a/tests/acceptance/features/apiSpaces/resharing.feature
+++ b/tests/acceptance/features/apiSpaces/resharing.feature
@@ -23,6 +23,7 @@ Feature: Resharing
     And user "Carol" has shared folder "Shares/folder" with user "Damian" with permissions "17"
     And user "Damian" has accepted share "/folder" offered by user "Carol"
 
+
   Scenario Outline: You should only be able to see direct outgoing shares not all the chain:
     Given user "Brian" has shared folder "Shares/folder" with user "Fred" with permissions "17"
     And user "Fred" has accepted share "/folder" offered by user "Brian"
@@ -41,6 +42,7 @@ Feature: Resharing
       | Damian | 0                | should not be | should not be | should not be |
       | Fred   | 0                | should not be | should not be | should not be |
 
+
   Scenario: Owners can see all the chain:
     When user "Alice" gets all the shares inside the folder "folder" using the sharing API
     Then the OCS status code should be "100"
@@ -50,11 +52,13 @@ Feature: Resharing
     And user "Carol" should be included in the response
     And user "Damian" should be included in the response
 
+
   Scenario: You can't share with more permissions than you have
     When user "Damian" shares folder "Shares/folder" with user "Ember" with permissions "31" using the sharing API
     Then the OCS status code should be "404"
     And the OCS status message should be "Cannot set the requested share permissions"
 
+
   Scenario Outline: Editing reshares
     Given user "Carol" has shared folder "Shares/folder" with user "Fred" with permissions "17"
     And user "Fred" has accepted share "/folder" offered by user "Carol"
@@ -68,6 +72,7 @@ Feature: Resharing
       | Brian | 998  | should not be |
       | Carol | 100  | should be     |
 
+
   Scenario Outline: Deleting reshares
     Given user "Carol" has shared folder "Shares/folder" with user "Gina" with permissions "17"
     And user "Gina" has accepted share "/folder" offered by user "Carol"
@@ -81,6 +86,7 @@ Feature: Resharing
       | Brian | 400  | should exist     |
       | Carol | 100  | should not exist |
 
+
   Scenario Outline: Resharing with different permissions
     When user "<user>" shares folder "Shares/folder" with user "Ember" with permissions "<permissions>" using the sharing API
     Then the OCS status code should be "<code>"
@@ -92,6 +98,7 @@ Feature: Resharing
       | Damian | 27          | 404  |
       | Damian | 31          | 404  |
 
+
   Scenario Outline: Resharing files with different permissions
     Given user "Alice" has uploaded file with content "Random data" to "/file.txt"
     And user "Alice" has shared file "/file.txt" with user "Brian" with permissions "<shareepermissions>"
@@ -104,3 +111,18 @@ Feature: Resharing
       | 17                | 19                 | 404  |
       | 19                | 19                 | 100  |
 
+
+  Scenario Outline: Resharing with group with different permissions
+    Given group "security department" has been created
+    And the administrator has added a user "Ember" to the group "security department" using GraphApi
+    And the administrator has added a user "Fred" to the group "security department" using GraphApi
+    When user "Brian" shares folder "Shares/folder" with group "security department" with permissions "<permissions>" using the sharing API
+    Then the OCS status code should be "100"
+    When user "Ember" accepts share "/folder" offered by user "Brian" using the sharing API
+    Then user "Ember" <canUpload> able to upload file "filesForUpload/textfile.txt" to "/Shares/folder/textfile.txt"
+    When user "Fred" accepts share "/folder" offered by user "Brian" using the sharing API
+    Then user "Fred" <canUpload> able to upload file "filesForUpload/textfile.txt" to "/Shares/folder/textfile.txt"
+    Examples:
+      | permissions | canUpload     |
+      | 17          | should not be |
+      | 31          | should be     |
diff --git a/tests/acceptance/features/apiSpaces/restoreSpaceObjects.feature b/tests/acceptance/features/apiSpaces/restoreSpaceObjects.feature
index 05f71eec450..b1c970c6280 100644
--- a/tests/acceptance/features/apiSpaces/restoreSpaceObjects.feature
+++ b/tests/acceptance/features/apiSpaces/restoreSpaceObjects.feature
@@ -14,7 +14,7 @@ Feature: Restore files, folder
             | Brian    |
             | Bob      |
             | Carol    |
-        And the administrator has given "Alice" the role "Admin" using the settings api
+        And the administrator has given "Alice" the role "Space Admin" using the settings api
         And user "Alice" creates a space "restore objects" of type "project" with the default quota using the GraphApi
         And user "Alice" has created a folder "newFolder" in space "restore objects"
         And user "Alice" has uploaded a file inside space "restore objects" with content "test" to "newFolder/file.txt"
diff --git a/tests/acceptance/features/apiSpaces/restoreSpaces.feature b/tests/acceptance/features/apiSpaces/restoreSpaces.feature
index 0351fc2d20e..cc881478610 100644
--- a/tests/acceptance/features/apiSpaces/restoreSpaces.feature
+++ b/tests/acceptance/features/apiSpaces/restoreSpaces.feature
@@ -14,58 +14,51 @@ Feature: Restoring space
       | Alice    |
       | Brian    |
       | Bob      |
-    And the administrator has given "Alice" the role "Admin" using the settings api
+    And the administrator has given "Alice" the role "Space Admin" using the settings api
+    And user "Alice" has created a space "restore a space" of type "project" with quota "10"
 
 
   Scenario: An owner can restore a Space via the Graph API
-    Given user "Alice" has created a space "restore a space" of type "project" with quota "10"
-    And user "Alice" has disabled a space "restore a space"
+    Given user "Alice" has disabled a space "restore a space"
     When user "Alice" restores a disabled space "restore a space"
     Then the HTTP status code should be "200"
 
 
   Scenario: Participants can see the data after the space is restored
-    Given user "Alice" has created a space "data exists" of type "project" with quota "10"
-    And user "Alice" has created a folder "mainFolder" in space "data exists"
-    And user "Alice" has uploaded a file inside space "data exists" with content "example" to "test.txt"
-    And user "Alice" has shared a space "data exists" to user "Brian" with role "editor"
-    And user "Alice" has shared a space "data exists" to user "Bob" with role "viewer"
-    And user "Alice" has disabled a space "data exists"
-    When user "Alice" restores a disabled space "data exists"
-    Then for user "Alice" the space "data exists" should contain these entries:
-      | test.txt         |
-      | mainFolder       |
-    And for user "Brian" the space "data exists" should contain these entries:
-      | test.txt         |
-      | mainFolder       |
-    And for user "Bob" the space "data exists" should contain these entries:
-      | test.txt         |
-      | mainFolder       |
-
+    Given user "Alice" has created a folder "mainFolder" in space "restore a space"
+    And user "Alice" has uploaded a file inside space "restore a space" with content "example" to "test.txt"
+    And user "Alice" has shared a space "restore a space" to user "Brian" with role "editor"
+    And user "Alice" has shared a space "restore a space" to user "Bob" with role "viewer"
+    And user "Alice" has disabled a space "restore a space"
+    When user "Alice" restores a disabled space "restore a space"
+    Then for user "Alice" the space "restore a space" should contain these entries:
+      | test.txt   |
+      | mainFolder |
+    And for user "Brian" the space "restore a space" should contain these entries:
+      | test.txt   |
+      | mainFolder |
+    And for user "Bob" the space "restore a space" should contain these entries:
+      | test.txt   |
+      | mainFolder |
 
-  Scenario: Participants can create data in the space after restoring
-    Given user "Alice" has created a space "create data in restored space" of type "project" with quota "10"
-    And user "Alice" has shared a space "create data in restored space" to user "Brian" with role "editor"
-    And user "Alice" has disabled a space "create data in restored space"
-    And user "Alice" has restored a disabled space "create data in restored space"
-    When user "Brian" creates a folder "mainFolder" in space "create data in restored space" using the WebDav Api
-    And user "Brian" uploads a file inside space "create data in restored space" with content "test" to "test.txt" using the WebDAV API
-    Then for user "Brian" the space "create data in restored space" should contain these entries:
-      | test.txt         |
-      | mainFolder       |
-    
 
-  Scenario: User with viewer permissions cannot restore space
-    Given user "Alice" has created a space "viewer restores space" of type "project" with quota "10"
-    And user "Alice" has shared a space "viewer restores space" to user "Brian" with role "viewer"
-    And user "Alice" has disabled a space "viewer restores space"
-    When user "Brian" restores a disabled space "viewer restores space" without manager rights
-    Then the HTTP status code should be "404"
+  Scenario: Participant can create data in the space after restoring
+    Given user "Alice" has shared a space "restore a space" to user "Brian" with role "editor"
+    And user "Alice" has disabled a space "restore a space"
+    And user "Alice" has restored a disabled space "restore a space"
+    When user "Brian" creates a folder "mainFolder" in space "restore a space" using the WebDav Api
+    And user "Brian" uploads a file inside space "restore a space" with content "test" to "test.txt" using the WebDAV API
+    Then for user "Brian" the space "restore a space" should contain these entries:
+      | test.txt   |
+      | mainFolder |
 
 
-  Scenario: User with editor permissions cannot restore space
-    Given user "Alice" has created a space "editor restores space" of type "project" with quota "10"
-    And user "Alice" has shared a space "editor restores space" to user "Brian" with role "editor"
-    And user "Alice" has disabled a space "editor restores space"
-    When user "Brian" restores a disabled space "editor restores space" without manager rights
+  Scenario Outline: User without space manager role cannot restore space
+    Given user "Alice" has shared a space "restore a space" to user "Brian" with role "<role>"
+    And user "Alice" has disabled a space "restore a space"
+    When user "Brian" restores a disabled space "restore a space" without manager rights
     Then the HTTP status code should be "404"
+    Examples:
+      | role   |
+      | viewer |
+      | editor |
diff --git a/tests/acceptance/features/apiSpaces/search.feature b/tests/acceptance/features/apiSpaces/search.feature
index d41ff5eb740..dd1787df0b8 100644
--- a/tests/acceptance/features/apiSpaces/search.feature
+++ b/tests/acceptance/features/apiSpaces/search.feature
@@ -11,7 +11,7 @@ Feature: Search
       | Alice    |
       | Brian    |
     And using new DAV path
-    And the administrator has given "Alice" the role "Admin" using the settings api
+    And the administrator has given "Alice" the role "Space Admin" using the settings api
     And user "Alice" has created a space "find data" with the default quota using the GraphApi
     And user "Alice" has created a folder "folder/SubFolder1/subFOLDER2" in space "find data"
     And user "Alice" has uploaded a file inside space "find data" with content "some content" to "folder/SubFolder1/subFOLDER2/insideTheFolder.txt"
diff --git a/tests/acceptance/features/apiSpaces/shareSpaces.feature b/tests/acceptance/features/apiSpaces/shareSpaces.feature
index d534280744b..6393c61ace2 100644
--- a/tests/acceptance/features/apiSpaces/shareSpaces.feature
+++ b/tests/acceptance/features/apiSpaces/shareSpaces.feature
@@ -12,7 +12,7 @@ Feature: Share spaces
       | Alice    |
       | Brian    |
       | Bob      |
-    And the administrator has given "Alice" the role "Admin" using the settings api
+    And the administrator has given "Alice" the role "Space Admin" using the settings api
     And user "Alice" has created a space "share space" with the default quota using the GraphApi
 
 
@@ -21,8 +21,7 @@ Feature: Share spaces
     Then the HTTP status code should be "200"
     And the OCS status code should be "200"
     And the OCS status message should be "OK"
-    When user "Brian" lists all available spaces via the GraphApi
-    Then the json responded should contain a space "share space" with these key and value pairs:
+    And the user "Brian" should have a space called "share space" with these key and value pairs:
       | key       | value       |
       | driveType | project     |
       | id        | %space_id%  |
@@ -36,8 +35,7 @@ Feature: Share spaces
 
   Scenario: A user can see who has been granted access
     Given user "Alice" has shared a space "share space" to user "Brian" with role "viewer"
-    When user "Alice" lists all available spaces via the GraphApi
-    Then the json responded should contain a space "share space" granted to "Brian" with these key and value pairs:
+    And the user "Alice" should have a space called "share space" granted to "Brian" with these key and value pairs:
       | key                                                | value     |
       | root@@@permissions@@@1@@@grantedTo@@@0@@@user@@@id | %user_id% |
       | root@@@permissions@@@1@@@roles@@@0                 | viewer    |
@@ -54,25 +52,21 @@ Feature: Share spaces
 
   Scenario: When a user unshares a space, the space becomes unavailable to the receiver
     Given user "Alice" has shared a space "share space" to user "Brian" with role "viewer"
-    When user "Brian" lists all available spaces via the GraphApi
-    Then the json responded should contain a space "share space" with these key and value pairs:
+    And the user "Brian" should have a space called "share space" with these key and value pairs:
       | key       | value       |
       | driveType | project     |
       | id        | %space_id%  |
       | name      | share space |
     When user "Alice" unshares a space "share space" to user "Brian"
     Then the HTTP status code should be "200"
-    And user "Brian" lists all available spaces via the GraphApi
-    And the json responded should not contain a space with name "share space"
+    Then the user "Brian" should not have a space called "share space"
 
 
   Scenario: A user can add another user to the space managers to enable him
     Given user "Alice" has uploaded a file inside space "share space" with content "Test" to "test.txt"
-    And user "Alice" has shared a space "share space" to user "Brian" with role "manager"
-    When user "Brian" lists all available spaces via the GraphApi
-    Then the json responded should contain a space "share space" granted to "Brian" with role "manager"
-    When user "Brian" has shared a space "share space" to user "Bob" with role "viewer"
-    And user "Bob" lists all available spaces via the GraphApi
-    Then the json responded should contain a space "share space" granted to "Bob" with role "viewer"
+    When user "Alice" shares a space "share space" to user "Brian" with role "manager"
+    Then the user "Brian" should have a space called "share space" granted to "Brian" with role "manager"
+    When user "Brian" shares a space "share space" to user "Bob" with role "viewer"
+    Then the user "Bob" should have a space called "share space" granted to "Bob" with role "viewer"
     And for user "Bob" the space "share space" should contain these entries:
       | test.txt |
diff --git a/tests/acceptance/features/apiSpaces/shareSubItemOfSpace.feature b/tests/acceptance/features/apiSpaces/shareSubItemOfSpace.feature
index 6c5545feb05..4a22178e1ff 100644
--- a/tests/acceptance/features/apiSpaces/shareSubItemOfSpace.feature
+++ b/tests/acceptance/features/apiSpaces/shareSubItemOfSpace.feature
@@ -1,13 +1,8 @@
 @api @skipOnOcV10
 Feature: Share a file or folder that is inside a space
-      As an user with manager space role
-      I want to be able to share the data inside the space
+  As an user with manager space role
+  I want to be able to share the data inside the space
 
-      | role        | permissions |
-      | viewer      | 1           |
-      | uploader    | 4           |
-      | contributor | 5           |
-      | editor      | 15          |
 
   Note - this feature is run in CI with ACCOUNTS_HASH_DIFFICULTY set to the default for production
   See https://github.com/owncloud/ocis/issues/1542 and https://github.com/owncloud/ocis/pull/839
@@ -18,64 +13,41 @@ Feature: Share a file or folder that is inside a space
       | Alice    |
       | Brian    |
       | Bob      |
-    And the administrator has given "Alice" the role "Admin" using the settings api
+    And the administrator has given "Alice" the role "Space Admin" using the settings api
     And user "Alice" has created a space "share sub-item" with the default quota using the GraphApi
     And user "Alice" has created a folder "folder" in space "share sub-item"
-    And user "Alice" has uploaded a file inside space "share sub-item" with content "some content" to "folder/file.txt"
+    And user "Alice" has uploaded a file inside space "share sub-item" with content "some content" to "file.txt"
 
 
-  Scenario Outline: An user-owner can share a folder inside project space to another user with role:
-    When user "Alice" shares the following entity "folder" inside of space "share sub-item" with user "Brian" with role "<role>"
+  Scenario Outline: A manager of the space can share an entity inside project space to another user with role:
+    When user "Alice" shares the following entity "<entity>" inside of space "share sub-item" with user "Brian" with role "<role>"
     Then the HTTP status code should be "200"
     And the OCS status code should be "200"
     And the OCS status message should be "OK"
-    And user "Brian" accepts share "/folder" offered by user "Alice" using the sharing API
-    And as "Brian" folder "Shares/folder" should exist
+    When user "Brian" accepts share "/<entity>" offered by user "Alice" using the sharing API
+    And as "Brian" <type> "Shares/<entity>" should exist
     Examples:
-      | role   |
-      | viewer |
-      | editor |
+      | entity   | type   | role   |
+      | folder   | folder | viewer |
+      | folder   | folder | editor |
+      | file.txt | file   | viewer |
+      | file.txt | file   | editor |
 
 
-  Scenario Outline: An user-owner can share a file inside project space to another user with role:
-    When user "Alice" shares the following entity "folder/file.txt" inside of space "share sub-item" with user "Brian" with role "<role>"
-    Then the HTTP status code should be "200"
-    And the OCS status code should be "200"
-    And the OCS status message should be "OK"
-    And user "Brian" accepts share "/file.txt" offered by user "Alice" using the sharing API
-    Then as "Brian" file "Shares/file.txt" should exist
-    Examples:
-      | role   |
-      | viewer |
-      | editor |
-
-
-  Scenario Outline: An user participant of the project space with manager role can share a folder to another user
-    Given user "Alice" has shared a space "share sub-item" to user "Brian" with role "manager"
-    When user "Brian" shares the following entity "folder" inside of space "share sub-item" with user "Bob" with role "<role>"
-    Then the HTTP status code should be "200"
-    And the OCS status code should be "200"
-    And the OCS status message should be "OK"
-    And user "Bob" accepts share "/folder" offered by user "Brian" using the sharing API
-    And as "Bob" folder "Shares/folder" should exist
-    Examples:
-      | role   |
-      | viewer |
-      | editor |
-
-
-  Scenario Outline: An user participant of the project space with manager role can share a file to another user
+  Scenario Outline: An user participant of the project space with manager role can share an entity to another user
     Given user "Alice" has shared a space "share sub-item" to user "Brian" with role "manager"
-    When user "Brian" shares the following entity "folder/file.txt" inside of space "share sub-item" with user "Bob" with role "<role>"
+    When user "Brian" shares the following entity "<entity>" inside of space "share sub-item" with user "Bob" with role "<role>"
     Then the HTTP status code should be "200"
     And the OCS status code should be "200"
     And the OCS status message should be "OK"
-    And user "Bob" accepts share "/file.txt" offered by user "Brian" using the sharing API
-    Then as "Bob" file "Shares/file.txt" should exist
+    When user "Bob" accepts share "/<entity>" offered by user "Brian" using the sharing API
+    And as "Bob" <type> "Shares/<entity>" should exist
     Examples:
-      | role   |
-      | viewer |
-      | editor |
+      | entity   | type   | role   |
+      | folder   | folder | viewer |
+      | folder   | folder | editor |
+      | file.txt | file   | viewer |
+      | file.txt | file   | editor |
 
 
   Scenario Outline: An user participant of the project space without space manager role cannot share an entity to another user
@@ -85,8 +57,8 @@ Feature: Share a file or folder that is inside a space
     And the OCS status code should be "<statusCode>"
     And the OCS status message should be "<statusMessage>"
     Examples:
-      | entity          | spaceRole | statusCode | statusMessage       |
-      | folder          | editor    | 404        | No share permission |
-      | folder/file.txt | editor    | 404        | No share permission |
-      | folder/file.txt | viewer    | 404        | No share permission |
-      | folder          | viewer    | 404        | No share permission |
+      | entity   | spaceRole | statusCode | statusMessage       |
+      | folder   | editor    | 404        | No share permission |
+      | file.txt | editor    | 404        | No share permission |
+      | file.txt | viewer    | 404        | No share permission |
+      | folder   | viewer    | 404        | No share permission |
diff --git a/tests/acceptance/features/apiSpaces/shareSubItemOfSpaceViaPublicLink.feature b/tests/acceptance/features/apiSpaces/shareSubItemOfSpaceViaPublicLink.feature
index 75dc8fe238d..b38d3399f1a 100644
--- a/tests/acceptance/features/apiSpaces/shareSubItemOfSpaceViaPublicLink.feature
+++ b/tests/acceptance/features/apiSpaces/shareSubItemOfSpaceViaPublicLink.feature
@@ -23,13 +23,13 @@ Feature: Share a file or folder that is inside a space via public link
       | username |
       | Alice    |
       | Brian    |
-    And the administrator has given "Alice" the role "Admin" using the settings api
+    And the administrator has given "Alice" the role "Space Admin" using the settings api
     And user "Alice" has created a space "share sub-item" with the default quota using the GraphApi
     And user "Alice" has created a folder "folder" in space "share sub-item"
     And user "Alice" has uploaded a file inside space "share sub-item" with content "some content" to "folder/file.txt"
 
 
-  Scenario Outline: An user-owner can share an entity inside project space via public link
+  Scenario Outline: A manager of the space can share an entity inside project space via public link
     When user "Alice" creates a public link share inside of space "share sub-item" with settings:
       | path        | <entity>      |
       | shareType   | 3             |
diff --git a/tests/acceptance/features/apiSpaces/uploadSpaces.feature b/tests/acceptance/features/apiSpaces/uploadSpaces.feature
index 769da807dee..9b170787cf9 100644
--- a/tests/acceptance/features/apiSpaces/uploadSpaces.feature
+++ b/tests/acceptance/features/apiSpaces/uploadSpaces.feature
@@ -1,131 +1,75 @@
 @api @skipOnOcV10
 Feature: Upload files into a space
-  As a user
-  I want to be able to work with project spaces and quota
+  As an user
+  I want to be able to create folders and files in the space
 
   Note - this feature is run in CI with ACCOUNTS_HASH_DIFFICULTY set to the default for production
   See https://github.com/owncloud/ocis/issues/1542 and https://github.com/owncloud/ocis/pull/839
 
   Background:
-    Given user "Alice" has been created with default attributes and without skeleton files
-    And user "Bob" has been created with default attributes and without skeleton files
-    And the administrator has given "Alice" the role "Admin" using the settings api
-
-
-  Scenario: A user can create a folder in a Space via the Graph API
-    Given user "Alice" has created a space "Project Ceres" of type "project" with quota "2000"
-    When user "Alice" creates a folder "mainFolder" in space "Project Ceres" using the WebDav Api
+    Given these users have been created with default attributes and without skeleton files:
+      | username |
+      | Alice    |
+      | Brian    |
+      | Bob      |
+    And the administrator has given "Alice" the role "Space Admin" using the settings api
+    And user "Alice" has created a space "Project Ceres" of type "project" with quota "2000"
+
+
+  Scenario Outline: An user creates a folder in the Space via the Graph API
+    And user "Alice" has shared a space "Project Ceres" to user "Brian" with role "<role>"
+    When user "Brian" creates a folder "mainFolder" in space "Project Ceres" using the WebDav Api
+    Then the HTTP status code should be "<code>"
+    And for user "Brian" the space "Project Ceres" <shouldOrNot> contain these entries:
+      | mainFolder |
+    Examples:
+      | role    | code | shouldOrNot |
+      | manager | 201  | should      |
+      | editor  | 201  | should      |
+      | viewer  | 403  | should not  |
+
+
+  Scenario Outline: An user uploads a file in shared Space via the Graph API
+    And user "Alice" has shared a space "Project Ceres" to user "Brian" with role "<role>"
+    When user "Brian" uploads a file inside space "Project Ceres" with content "Test" to "test.txt" using the WebDAV API
+    Then the HTTP status code should be "<code>"
+    And for user "Brian" the space "Project Ceres" <shouldOrNot> contain these entries:
+      | test.txt |
+    And the user "Brian" should have a space called "Project Ceres" with these key and value pairs:
+      | key          | value         |
+      | name         | Project Ceres |
+      | quota@@@used | <usedQuota>   |
+    Examples:
+      | role    | code | shouldOrNot | usedQuota |
+      | manager | 201  | should      | 4         |
+      | editor  | 201  | should      | 4         |
+      | viewer  | 403  | should not  | 0         |
+
+
+  Scenario: An user can create subfolders in a Space via the Graph API
+    When user "Alice" creates a subfolder "mainFolder/subFolder1/subFolder2" in space "Project Ceres" using the WebDav Api
     Then the HTTP status code should be "201"
     And for user "Alice" the space "Project Ceres" should contain these entries:
-      | mainFolder        |
-
-
-  Scenario: A user can create subfolders in a Space via the Graph API
-    Given user "Alice" has created a space "Subfolders in Project" of type "project" with quota "2000"
-    When user "Alice" creates a subfolder "mainFolder/subFolder1/subFolder2" in space "Subfolders in Project" using the WebDav Api
-    Then the HTTP status code should be "201"
-    And for user "Alice" the space "Subfolders in Project" should contain these entries:
       | mainFolder |
-    And for user "Alice" folder "mainFolder/subFolder1/" of the space "Subfolders in Project" should contain these entries:
+    And for user "Alice" folder "mainFolder/subFolder1/" of the space "Project Ceres" should contain these entries:
       | subFolder2 |
 
 
-  Scenario: A user cannot create a folder in a Space if they do not have permission
-    Given user "Alice" has created a space "Project Merkur" of type "project" with quota "2000"
-    And user "Bob" creates a folder "forAlice" in space "Project Merkur" owned by the user "Alice" using the WebDav Api
-    Then the HTTP status code should be "404"
-    And for user "Alice" the space "Project Merkur" should not contain these entries:
-      | forAlice        |
-
-
-  Scenario: A user can create a folder and upload a file to a Space
-    Given user "Alice" has created a space "Project Moon" of type "project" with quota "2000"
-    When user "Alice" creates a folder "NewFolder" in space "Project Moon" using the WebDav Api
+  Scenario: An user can create a folder and upload a file to a Space
+    When user "Alice" creates a folder "NewFolder" in space "Project Ceres" using the WebDav Api
     Then the HTTP status code should be "201"
-    And user "Alice" uploads a file inside space "Project Moon" with content "Test" to "test.txt" using the WebDAV API
+    And user "Alice" uploads a file inside space "Project Ceres" with content "Test" to "test.txt" using the WebDAV API
     Then the HTTP status code should be "201"
-    And for user "Alice" the space "Project Moon" should contain these entries:
-      | NewFolder        |
-      | test.txt         |
+    And for user "Alice" the space "Project Ceres" should contain these entries:
+      | NewFolder |
+      | test.txt  |
 
 
-  Scenario: A user cannot upload a file in a Space if they do not have permission
-    Given user "Alice" has created a space "Project Pluto" of type "project" with quota "2000"
-    When user "Bob" uploads a file inside space "Project Pluto" owned by the user "Alice" with content "Test" to "test.txt" using the WebDAV API
+  Scenario: An user cannot create a folder or a file in a Space if they do not have permission
+    When user "Bob" creates a folder "forAlice" in space "Project Ceres" owned by the user "Alice" using the WebDav Api
     Then the HTTP status code should be "404"
-    And for user "Alice" the space "Project Pluto" should not contain these entries:
-      | test.txt        |
-
-
-  Scenario: A user can upload a file in a Space and see the remaining quota
-    When user "Alice" creates a space "Project Saturn" of type "project" with quota "2000" using the GraphApi
-    And the json responded should contain a space "Project Saturn" with these key and value pairs:
-      | key              | value         |
-      | driveType        | project       |
-      | id               | %space_id%    |
-      | name             | Project Saturn|
-      | quota@@@total    | 2000          |
-    And user "Alice" uploads a file inside space "Project Saturn" with content "Test" to "test.txt" using the WebDAV API
-    Then the HTTP status code should be "201"
-    And for user "Alice" the space "Project Saturn" should contain these entries:
-      | test.txt         |
-    When user "Alice" lists all available spaces via the GraphApi
-    Then the json responded should contain a space "Project Saturn" with these key and value pairs:
-      | key              | value         |
-      | driveType        | project       |
-      | id               | %space_id%    |
-      | name             | Project Saturn|
-      | quota@@@state    | normal        |
-      | quota@@@total    | 2000          |
-      | quota@@@remaining| 1996          |
-      | quota@@@used     | 4             |
-
-
-  Scenario: A user with role editor can create a folder in shared Space via the Graph API
-    Given user "Alice" has created a space "Editor can create folder" of type "project" with quota "2000"
-    And user "Alice" has shared a space "Editor can create folder" to user "Bob" with role "editor"
-    When user "Bob" creates a folder "mainFolder" in space "Editor can create folder" using the WebDav Api
-    Then the HTTP status code should be "201"
-    And for user "Bob" the space "Editor can create folder" should contain these entries:
-      | mainFolder        |
-    And for user "Alice" the space "Editor can create folder" should contain these entries:
-      | mainFolder        |
-
-
-  Scenario: A user with role viewer cannot create a folder in shared Space via the Graph API
-    Given user "Alice" has created a space "Viewer cannot create folder" of type "project" with quota "2000"
-    And user "Alice" has shared a space "Viewer cannot create folder" to user "Bob" with role "viewer"
-    When user "Bob" creates a folder "mainFolder" in space "Viewer cannot create folder" using the WebDav Api
-    Then the HTTP status code should be "403"
-    And for user "Bob" the space "Viewer cannot create folder" should not contain these entries:
-      | mainFolder        |
-    And for user "Alice" the space "Viewer cannot create folder" should not contain these entries:
-      | mainFolder        |
-
-
-  Scenario: A user with role editor can upload a file in shared Space via the Graph API
-    Given user "Alice" has created a space "Editor can upload file" of type "project" with quota "20"
-    And user "Alice" has shared a space "Editor can upload file" to user "Bob" with role "editor"
-    When user "Bob" uploads a file inside space "Editor can upload file" with content "Test" to "test.txt" using the WebDAV API
-    Then the HTTP status code should be "201"
-    And for user "Bob" the space "Editor can upload file" should contain these entries:
-      | test.txt         |
-    And for user "Alice" the space "Editor can upload file" should contain these entries:
-      | test.txt         |
-    When user "Bob" lists all available spaces via the GraphApi
-    Then the json responded should contain a space "Editor can upload file" with these key and value pairs:
-      | key              | value                 |
-      | name             | Editor can upload file |
-      | quota@@@used     | 4                     |
-
-
-  Scenario: A user with role viewer cannot upload a file in shared Space via the Graph API
-    Given user "Alice" has created a space "Viewer cannot upload file" of type "project" with quota "20"
-    And user "Alice" has shared a space "Viewer cannot upload file" to user "Bob" with role "viewer"
-    When user "Bob" uploads a file inside space "Viewer cannot upload file" with content "Test" to "test.txt" using the WebDAV API
-    Then the HTTP status code should be "403"
-    And for user "Bob" the space "Viewer cannot upload file" should not contain these entries:
-      | test.txt         |
-    And for user "Alice" the space "Viewer cannot upload file" should not contain these entries:
-      | test.txt         |
-      
\ No newline at end of file
+    When user "Bob" uploads a file inside space "Project Ceres" owned by the user "Alice" with content "Test" to "test.txt" using the WebDAV API
+    Then the HTTP status code should be "404"
+    And for user "Alice" the space "Project Ceres" should not contain these entries:
+      | forAlice |
+      | test.txt |
diff --git a/tests/acceptance/features/bootstrap/GraphContext.php b/tests/acceptance/features/bootstrap/GraphContext.php
index 2a27dbf1453..062975342d3 100644
--- a/tests/acceptance/features/bootstrap/GraphContext.php
+++ b/tests/acceptance/features/bootstrap/GraphContext.php
@@ -398,6 +398,8 @@ class GraphContext implements Context {
 	/**
 	 * adds a user to a group
 	 *
+	 * @Given /^the administrator has added a user "([^"]*)" to the group "([^"]*)" using GraphApi$/
+	 *
 	 * @param string $user
 	 * @param string $group
 	 * @param bool $checkResult
diff --git a/tests/acceptance/features/bootstrap/SpacesContext.php b/tests/acceptance/features/bootstrap/SpacesContext.php
index 93b5b608e1a..df291e845f1 100644
--- a/tests/acceptance/features/bootstrap/SpacesContext.php
+++ b/tests/acceptance/features/bootstrap/SpacesContext.php
@@ -389,13 +389,13 @@ class SpacesContext implements Context {
 		$userAdmin = $this->featureContext->getAdminUsername();
 
 		for ($i = 0; $i < 2; ++$i) {
-			$this->theUserListsAllHisAvailableSpacesUsingTheGraphApiWithFilter(
+			$this->theUserListsAllHisAvailableSpacesUsingTheGraphApi(
 				$userAdmin,
 				$query
 			);
 
 			$rawBody =  $this->featureContext->getResponse()->getBody()->getContents();
-			$drives = json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR);
+			$drives = json_decode($rawBody, true, 512);
 			if (isset($drives["value"])) {
 				$drives = $drives["value"];
 			}
@@ -569,19 +569,22 @@ class SpacesContext implements Context {
 
 	/**
 	 * @When /^user "([^"]*)" lists all available spaces via the GraphApi$/
+	 * @When /^user "([^"]*)" lists all available spaces via the GraphApi with query "([^"]*)"$/
 	 *
 	 * @param string $user
+	 * @param string $query
 	 *
 	 * @return void
 	 *
 	 * @throws GuzzleException
 	 * @throws Exception
 	 */
-	public function theUserListsAllHisAvailableSpacesUsingTheGraphApi(string $user): void {
+	public function theUserListsAllHisAvailableSpacesUsingTheGraphApi(string $user, string $query = ''): void {
 		$this->featureContext->setResponse(
 			$this->listMySpacesRequest(
 				$user,
-				$this->featureContext->getPasswordForUser($user)
+				$this->featureContext->getPasswordForUser($user),
+				"?" . $query
 			)
 		);
 		$this->rememberTheAvailableSpaces();
@@ -606,26 +609,6 @@ class SpacesContext implements Context {
 		$this->rememberTheAvailableSpaces();
 	}
 
-	/**
-	 * @When /^user "([^"]*)" lists all available spaces via the GraphApi with query "([^"]*)"$/
-	 *
-	 * @param string $user
-	 * @param string $query
-	 *
-	 * @return void
-	 *
-	 * @throws GuzzleException
-	 */
-	public function theUserListsAllHisAvailableSpacesUsingTheGraphApiWithFilter(string $user, string $query): void {
-		$this->featureContext->setResponse(
-			$this->listMySpacesRequest(
-				$user,
-				$this->featureContext->getPasswordForUser($user),
-				"?" . $query
-			)
-		);
-	}
-
 	/**
 	 * @When /^user "([^"]*)" looks up the single space "([^"]*)" via the GraphApi by using its id$/
 	 *
@@ -966,7 +949,6 @@ class SpacesContext implements Context {
 
 	/**
 	 * @Then /^the json responded should contain a space "([^"]*)" (?:|(?:owned by|granted to) "([^"]*)" )(?:|(?:with description file|with space image) "([^"]*)" )with these key and value pairs:$/
-	 *
 	 * @param string $spaceName
 	 * @param string $userName
 	 * @param string $fileName
@@ -1034,23 +1016,60 @@ class SpacesContext implements Context {
 	}
 
 	/**
-	 * @Then /^the json responded should contain a space "([^"]*)" granted to "([^"]*)" with role "([^"]*)"$/
+	 * @Then /^the user "([^"]*)" should have a space called "([^"]*)" with these key and value pairs:$/
+	 * @Then /^the user "([^"]*)" should have a space called "([^"]*)" (?:owned by|granted to) "([^"]*)" with these key and value pairs:$/
+	 * @Then /^the user "([^"]*)" should have a space called "([^"]*)" (?:with description file|with space image) "([^"]*)" with these key and value pairs:$/
+	 * @Then /^the user "([^"]*)" should have a space called "([^"]*)" (?:owned by|granted to) "([^"]*)" (?:with description file|with space image) "([^"]*)" with these key and value pairs:$/
 	 *
+	 * @param string $user
 	 * @param string $spaceName
-	 * @param string $userName
+	 * @param string $grantedUser
+	 * @param string $fileName
+	 * @param TableNode $table
+	 *
+	 * @return void
+	 * @throws Exception|GuzzleException
+	 */
+	public function userHasSpaceWith(
+		string $user,
+		string $spaceName,
+		string $grantedUser = '',
+		string $fileName = '',
+		TableNode $table
+	): void {
+		$this->theUserListsAllHisAvailableSpacesUsingTheGraphApi($user);
+		$this->featureContext->theHTTPStatusCodeShouldBe(
+			200,
+			"Expected response status code should be 200"
+		);
+		$this->jsonRespondedShouldContain($spaceName, $grantedUser, $fileName, $table);
+	}
+
+	/**
+	 * @Then /^the user "([^"]*)" should have a space called "([^"]*)" granted to "([^"]*)" with role "([^"]*)"$/
+	 *
+	 * @param string $user
+	 * @param string $spaceName
+	 * @param string $grantedUser
 	 * @param string $role
 	 *
 	 * @return void
 	 * @throws Exception|GuzzleException
 	 */
 	public function checkPermissionsInResponse(
+		string $user,
 		string $spaceName,
-		string $userName,
+		string $grantedUser,
 		string $role
 	): void {
+		$this->theUserListsAllHisAvailableSpacesUsingTheGraphApi($user);
+		$this->featureContext->theHTTPStatusCodeShouldBe(
+			200,
+			"Expected response status code should be 200"
+		);
 		Assert::assertIsArray($spaceAsArray = $this->getSpaceByNameFromResponse($spaceName), "No space with name $spaceName found");
 		$permissions = $spaceAsArray["root"]["permissions"];
-		$userId = $this->getUserIdByUserName($userName);
+		$userId = $this->getUserIdByUserName($grantedUser);
 
 		$userRole = "";
 		foreach ($permissions as $permission) {
@@ -1060,7 +1079,7 @@ class SpacesContext implements Context {
 				}
 			}
 		}
-		Assert::assertEquals($userRole, $role, "the user $userName with the role $role could not be found");
+		Assert::assertEquals($userRole, $role, "the user $grantedUser with the role $role could not be found");
 	}
 
 	/**
@@ -1077,6 +1096,27 @@ class SpacesContext implements Context {
 		Assert::assertEmpty($this->getSpaceByNameFromResponse($spaceName), "space $spaceName should not be available for a user");
 	}
 
+	/**
+	 * @Then /^the user "([^"]*)" should not have a space called "([^"]*)"$/
+	 *
+	 * @param string $user
+	 * @param string $spaceName
+	 *
+	 * @return void
+	 * @throws Exception
+	 */
+	public function usershouldNotHaveSpace(
+		string $user,
+		string $spaceName
+	): void {
+		$this->theUserListsAllHisAvailableSpacesUsingTheGraphApi($user);
+		$this->featureContext->theHTTPStatusCodeShouldBe(
+			200,
+			"Expected response status code should be 200"
+		);
+		$this->jsonRespondedShouldNotContain($spaceName);
+	}
+
 	/**
 	 * @Then /^the json responded should (not|only|)\s?contain spaces of type "([^"]*)"$/
 	 *
diff --git a/tests/parallelDeployAcceptance/expected-failures-API.md b/tests/parallelDeployAcceptance/expected-failures-API.md
index de3a7cdc76e..9c8c276e45c 100644
--- a/tests/parallelDeployAcceptance/expected-failures-API.md
+++ b/tests/parallelDeployAcceptance/expected-failures-API.md
@@ -1,1 +1,6 @@
 ## Scenarios that are expected to fail in parallel deployment
+
+The expected failures in this file are from features in the owncloud/ocis repo in the tests/parallelDeployAcceptance/features folder tree.
+
+### [Cannot PROPFIND file information using ocis selector](https://github.com/owncloud/ocis/issues/4112)
+- [apiWebdavOperations/downloadFile.feature:35](https://github.com/owncloud/ocis/blob/master/tests/parallelDeployAcceptance/features/apiWebdavOperations/downloadFile.feature#L35)