Repository: owncloud/ocis
Pull request #4815 (2022-10-13 13:59:47)

harden drives api and improve logging
<!--
Thanks for submitting a change to ownCloud!

This is the bug tracker for the oCIS component. Find other components at https://github.com/owncloud/core/blob/master/.github/CONTRIBUTING.md#guidelines

For fixing potential security issues please see https://owncloud.org/security/

To make it possible for us to get your change reviewed and merged please carefully fill out the requested information below.

Please note that any kind of change needs first be submitted to the master branch which holds the next version of oCIS.

Please set the following labels:

- Set label "Status:Needs-Review" for review or "Status:In-Progress" if the PR still has open tasks.
- Assignment: assign to self
- Reviewers: pick at least one
-->

## Description

We improved the logging of several http services. If possible and present, we now log the `X-Request-Id`.

## Logging Documentation

In ocis, we have the following log levels

### FATAL

FATAL means that the application is about to stop a serious problem or corruption from happening. This level of logging shows that the application’s situation is catastrophic, such that an important function is not working. For example the application is unable to connect to the data store due to config errors or not able to parse the config

### ERROR (default setting, OCIS_LOG_LEVEL=error)
This is the default log level, all errors on this level are important for admins because they need to fix them.  This log level is used when a severe issue is stopping functions within the application from operating correctly. Ocis logs all kind of inter service communication errors on this level because these needs to be addressed.

### WARN
The WARN log level is used when ocis detects an unexpected failure during an operation. It is also used if some operations might be incomplete. It  does not mean that the application has been harmed, the code should continue to work as usual. Admins should eventually check these warnings just in case the problem reoccurs.

### INFO
Messages  on this level are documenting the normal behavior of applications. They state what happened. These entries are purely informative to confirm that the application is working as desired. The info log level also enables the ocis Proxy to write a full access log.

### DEBUG
This log level provides diagnostic information in a detailed manner. It is verbose and has more information than you would need when using the application. This log level is used to understand problems in the application and during reproduction of problems. This log level could put a very high load on the output device and is not recommended in production environments. You should consider enabling this level only on a single service or very few services to pinpoint issues or bugs.


## To do

- [x] Drives API
- [x] User API
- [x] Groups API
- [x] Thumbnails API
- [x] Search API

## Motivation and Context

Increase the debuggability of the stack

## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran to -->
<!--- see how your change affects other areas of the code, etc. -->
- test environment:
- test case 1:
- test case 2:
- ...

## Screenshots (if appropriate):

## Types of changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Technical debt
- [ ] Tests only (no source changes)

## Checklist:
<!-- Tick the checkboxes when done. -->
<!-- Raise documentation ticket in owncloud.github.io/ -->
- [x] Code changes
- [ ] Unit tests added
- [ ] Acceptance tests added
- [x] Documentation ticket raised: [<link> ](https://github.com/owncloud/docs-ocis/issues/266)


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

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

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

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


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

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

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


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

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

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


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

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

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


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

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

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



Patch:
diff --git a/.drone.env b/.drone.env
index 418204b8392..3971384b8fd 100644
--- a/.drone.env
+++ b/.drone.env
@@ -1,5 +1,5 @@
 # The test runner source for API tests
-CORE_COMMITID=6a3c89e917330990f99feabef3b42d1c51c0df1d
+CORE_COMMITID=ddd3b90f4aea35a459a6fedf78a9bcf110dc3303
 CORE_BRANCH=master
 
 # The test runner source for UI tests
diff --git a/.drone.star b/.drone.star
index c2c2038ac1b..4e184314649 100644
--- a/.drone.star
+++ b/.drone.star
@@ -18,7 +18,7 @@ OC_CI_PHP = "owncloudci/php:%s"
 OC_CI_WAIT_FOR = "owncloudci/wait-for:latest"
 OC_CS3_API_VALIDATOR = "owncloud/cs3api-validator:0.2.0"
 OC_LITMUS = "owncloud/litmus:latest"
-OC_OC_TEST_MIDDLEWARE = "owncloud/owncloud-test-middleware:1.8.2"
+OC_OC_TEST_MIDDLEWARE = "owncloud/owncloud-test-middleware:1.8.1"
 OC_SERVER = "owncloud/server:10"
 OC_UBUNTU = "owncloud/ubuntu:20.04"
 OSIXIA_OPEN_LDAP = "osixia/openldap:latest"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f12d64682b3..a7e5c3b24dd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,16 +16,12 @@ The following sections list the changes for unreleased.
 * Bugfix - Fix the OIDC provider cache: [#4600](https://github.com/owncloud/ocis/pull/4600)
 * Bugfix - Render webdav permissions as string in search report: [#4575](https://github.com/owncloud/ocis/issues/4575)
 * Bugfix - Mail notifications for group shares: [#4714](https://github.com/owncloud/ocis/pull/4714)
-* Bugfix - Disable cache for selected static web assets: [#4809](https://github.com/owncloud/ocis/pull/4809)
 * Bugfix - Fix unfindable entities from shares/publicshares: [#4651](https://github.com/owncloud/ocis/pull/4651)
 * Bugfix - Graph service now forwards trace context: [#4582](https://github.com/owncloud/ocis/pull/4582)
-* Bugfix - Remove the storage-users event configuration: [#4825](https://github.com/owncloud/ocis/pull/4825)
-* Bugfix - Trigger a rescan of spaces in the search index when items have changed: [#4777](https://github.com/owncloud/ocis/pull/4777)
 * Bugfix - Make tokeninfo endpoint unprotected: [#4715](https://github.com/owncloud/ocis/pull/4715)
 * Bugfix - Fix wopi access to public shares: [#4631](https://github.com/owncloud/ocis/pull/4631)
 * Enhancement - Add curl to the oCIS OCI image: [#4751](https://github.com/owncloud/ocis/pull/4751)
 * Enhancement - Add Email templating: [#4564](https://github.com/owncloud/ocis/pull/4564)
-* Enhancement - We added e-mail subject templating: [#4799](https://github.com/owncloud/ocis/pull/4799)
 * Enhancement - Add webURL to space root: [#4588](https://github.com/owncloud/ocis/pull/4588)
 * Enhancement - Allow to configuring the reva cache store: [#4627](https://github.com/owncloud/ocis/pull/4627)
 * Enhancement - Add support for REPORT requests to /dav/spaces URLs: [#4661](https://github.com/owncloud/ocis/pull/4661)
@@ -123,14 +119,6 @@ The following sections list the changes for unreleased.
    https://github.com/owncloud/ocis/issues/4688
    https://github.com/owncloud/ocis/pull/4714
 
-* Bugfix - Disable cache for selected static web assets: [#4809](https://github.com/owncloud/ocis/pull/4809)
-
-   We've disabled caching for some static web assets. Files like the web index.html,
-   oidc-callback.html or similar contain paths to timestamped resources and should not be
-   cached.
-
-   https://github.com/owncloud/ocis/pull/4809
-
 * Bugfix - Fix unfindable entities from shares/publicshares: [#4651](https://github.com/owncloud/ocis/pull/4651)
 
    We fixed a problem where directories or empty files weren't findable because they were to the
@@ -143,21 +131,6 @@ The following sections list the changes for unreleased.
 
    https://github.com/owncloud/ocis/pull/4582
 
-* Bugfix - Remove the storage-users event configuration: [#4825](https://github.com/owncloud/ocis/pull/4825)
-
-   We've removed the events configuration from the storage-users section because it is not
-   needed.
-
-   https://github.com/owncloud/ocis/pull/4825
-
-* Bugfix - Trigger a rescan of spaces in the search index when items have changed: [#4777](https://github.com/owncloud/ocis/pull/4777)
-
-   The search service now scans spaces when items have been changed. This fixes the problem that
-   mtime and treesize propagation was not reflected in the search index properly.
-
-   https://github.com/owncloud/ocis/issues/4410
-   https://github.com/owncloud/ocis/pull/4777
-
 * Bugfix - Make tokeninfo endpoint unprotected: [#4715](https://github.com/owncloud/ocis/pull/4715)
 
    Make the tokeninfo endpoint unprotected as it is supposed to be available to the public.
@@ -188,12 +161,6 @@ The following sections list the changes for unreleased.
    https://github.com/owncloud/ocis/pull/4564
    https://github.com/cs3org/reva/pull/3252
 
-* Enhancement - We added e-mail subject templating: [#4799](https://github.com/owncloud/ocis/pull/4799)
-
-   We have added e-mail subject templating.
-
-   https://github.com/owncloud/ocis/pull/4799
-
 * Enhancement - Add webURL to space root: [#4588](https://github.com/owncloud/ocis/pull/4588)
 
    Add the web url to the space root on the graphAPI.
@@ -233,7 +200,6 @@ The following sections list the changes for unreleased.
    Encyrpted the connection to the event broker using TLS.
 
    https://github.com/owncloud/ocis/pull/4781
-   https://github.com/owncloud/ocis/pull/4800
 
 * Enhancement - Report parent id: [#4757](https://github.com/owncloud/ocis/pull/4757)
 
diff --git a/changelog/unreleased/add-subject-tempalting.md b/changelog/unreleased/add-subject-tempalting.md
deleted file mode 100644
index e33b34e9d26..00000000000
--- a/changelog/unreleased/add-subject-tempalting.md
+++ /dev/null
@@ -1,5 +0,0 @@
-Enhancement: We added e-mail subject templating
-
-We have added e-mail subject templating.
-
-https://github.com/owncloud/ocis/pull/4799
\ No newline at end of file
diff --git a/changelog/unreleased/fix-static-asset-caching.md b/changelog/unreleased/fix-static-asset-caching.md
deleted file mode 100644
index e27df2da06e..00000000000
--- a/changelog/unreleased/fix-static-asset-caching.md
+++ /dev/null
@@ -1,6 +0,0 @@
-Bugfix: Disable cache for selected static web assets
-
-We've disabled caching for some static web assets.
-Files like the web index.html, oidc-callback.html or similar contain paths to timestamped resources and should not be cached.
-
-https://github.com/owncloud/ocis/pull/4809
diff --git a/changelog/unreleased/logging-improvements.md b/changelog/unreleased/logging-improvements.md
new file mode 100644
index 00000000000..28dd126d541
--- /dev/null
+++ b/changelog/unreleased/logging-improvements.md
@@ -0,0 +1,5 @@
+Enhancement: Logging improvements
+
+We improved the logging of several http services. If possible and present, we now log the `X-Request-Id`.
+
+https://github.com/owncloud/ocis/pull/4815
diff --git a/changelog/unreleased/nats-tls.md b/changelog/unreleased/nats-tls.md
index 316c35b8141..f392f6778d8 100644
--- a/changelog/unreleased/nats-tls.md
+++ b/changelog/unreleased/nats-tls.md
@@ -3,4 +3,3 @@ Enhancement: Secure the nats connectin with TLS
 Encyrpted the connection to the event broker using TLS.
 
 https://github.com/owncloud/ocis/pull/4781
-https://github.com/owncloud/ocis/pull/4800
diff --git a/changelog/unreleased/remove-system-users-events-config.md b/changelog/unreleased/remove-system-users-events-config.md
deleted file mode 100644
index 496fba89e13..00000000000
--- a/changelog/unreleased/remove-system-users-events-config.md
+++ /dev/null
@@ -1,5 +0,0 @@
-Bugfix: Remove the storage-users event configuration
-
-We've removed the events configuration from the storage-users section because it is not needed.
-
-https://github.com/owncloud/ocis/pull/4825
diff --git a/changelog/unreleased/rescan-spaces.md b/changelog/unreleased/rescan-spaces.md
deleted file mode 100644
index 8afcabd4c6e..00000000000
--- a/changelog/unreleased/rescan-spaces.md
+++ /dev/null
@@ -1,7 +0,0 @@
-Bugfix: Trigger a rescan of spaces in the search index when items have changed
-
-The search service now scans spaces when items have been changed. This fixes the problem
-that mtime and treesize propagation was not reflected in the search index properly.
-
-https://github.com/owncloud/ocis/pull/4777
-https://github.com/owncloud/ocis/issues/4410
diff --git a/deployments/examples/ocis_wopi/config/wopiserver/wopiserver.conf.dist b/deployments/examples/ocis_wopi/config/wopiserver/wopiserver.conf.dist
index 07c37e6fd71..808d105292e 100644
--- a/deployments/examples/ocis_wopi/config/wopiserver/wopiserver.conf.dist
+++ b/deployments/examples/ocis_wopi/config/wopiserver/wopiserver.conf.dist
@@ -114,7 +114,7 @@ chunksize = 4194304
 # Path to a recovery space in case of I/O errors when reaching to the remote storage.
 # This is expected to be a local path, and it is provided in order to ease user support.
 # Defaults to the indicated spool folder.
-recoverypath = /var/spool/wopirecovery
+#recoverypath = /var/spool/wopirecovery
 
 [cs3]
 # Host and port of the Reva(-like) CS3-compliant GRPC gateway endpoint
diff --git a/deployments/examples/ocis_wopi/docker-compose.yml b/deployments/examples/ocis_wopi/docker-compose.yml
index bc5010bb572..3b5a65aac17 100644
--- a/deployments/examples/ocis_wopi/docker-compose.yml
+++ b/deployments/examples/ocis_wopi/docker-compose.yml
@@ -146,7 +146,7 @@ services:
     volumes:
       - ./config/wopiserver/entrypoint-override.sh:/entrypoint-override.sh
       - ./config/wopiserver/wopiserver.conf.dist:/etc/wopi/wopiserver.conf.dist
-      - wopi-recovery:/var/spool/wopirecovery
+      - wopi-data:/var/wopi_local_storage
     labels:
       - "traefik.enable=true"
       - "traefik.http.routers.wopiserver.entrypoints=https"
@@ -206,7 +206,7 @@ volumes:
   certs:
   ocis-config:
   ocis-data:
-  wopi-recovery:
+  wopi-data:
 
 networks:
   ocis-net:
diff --git a/go.mod b/go.mod
index 5fe8da58b7b..641ecbf28e7 100644
--- a/go.mod
+++ b/go.mod
@@ -9,8 +9,8 @@ require (
 	github.com/armon/go-radix v1.0.0
 	github.com/blevesearch/bleve/v2 v2.3.4
 	github.com/coreos/go-oidc/v3 v3.4.0
-	github.com/cs3org/go-cs3apis v0.0.0-20221012090518-ef2996678965
-	github.com/cs3org/reva/v2 v2.10.1-0.20221013183308-560ba925a814
+	github.com/cs3org/go-cs3apis v0.0.0-20221005085457-19ea8088a512
+	github.com/cs3org/reva/v2 v2.10.1-0.20221012104058-ae7c58b9bffa
 	github.com/disintegration/imaging v1.6.2
 	github.com/ggwhite/go-masker v1.0.9
 	github.com/go-chi/chi/v5 v5.0.7
@@ -45,12 +45,12 @@ require (
 	github.com/libregraph/lico v0.54.1-0.20220325072321-31efc3995d63
 	github.com/mitchellh/mapstructure v1.5.0
 	github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
-	github.com/nats-io/nats-server/v2 v2.9.3
+	github.com/nats-io/nats-server/v2 v2.9.2
 	github.com/oklog/run v1.1.0
 	github.com/olekukonko/tablewriter v0.0.5
 	github.com/onsi/ginkgo v1.16.5
-	github.com/onsi/ginkgo/v2 v2.3.1
-	github.com/onsi/gomega v1.22.1
+	github.com/onsi/ginkgo/v2 v2.2.0
+	github.com/onsi/gomega v1.21.1
 	github.com/orcaman/concurrent-map v1.0.0
 	github.com/owncloud/libre-graph-api-go v0.17.0
 	github.com/pkg/errors v0.9.1
@@ -61,7 +61,7 @@ require (
 	github.com/stretchr/testify v1.8.0
 	github.com/test-go/testify v1.1.4
 	github.com/thejerf/suture/v4 v4.0.2
-	github.com/tus/tusd v1.10.0
+	github.com/tus/tusd v1.9.2
 	github.com/urfave/cli/v2 v2.19.2
 	github.com/xhit/go-simple-mail/v2 v2.12.0
 	go-micro.dev/v4 v4.9.0
@@ -76,14 +76,14 @@ require (
 	golang.org/x/exp v0.0.0-20220518171630-0b5c67f07fdf
 	golang.org/x/image v0.0.0-20220321031419-a8550c1d254a
 	golang.org/x/net v0.0.0-20220921155015-db77216a4ee9
-	golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1
+	golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094
 	golang.org/x/term v0.0.0-20220722155259-a9ba230a4035
-	golang.org/x/text v0.3.8
+	golang.org/x/text v0.3.7
 	google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006
 	google.golang.org/grpc v1.50.0
 	google.golang.org/protobuf v1.28.1
 	gopkg.in/yaml.v2 v2.4.0
-	gotest.tools/v3 v3.4.0
+	gotest.tools/v3 v3.3.0
 	stash.kopano.io/kgol/oidc-go v0.3.4
 	stash.kopano.io/kgol/rndm v1.1.1
 )
@@ -103,7 +103,7 @@ require (
 	github.com/amoghe/go-crypt v0.0.0-20220222110647-20eada5f5964 // indirect
 	github.com/armon/go-metrics v0.4.1 // indirect
 	github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
-	github.com/aws/aws-sdk-go v1.44.114 // indirect
+	github.com/aws/aws-sdk-go v1.44.94 // indirect
 	github.com/beevik/etree v1.1.0 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/bitly/go-simplejson v0.5.0 // indirect
diff --git a/go.sum b/go.sum
index 10f15b68fd1..07c599ba8c5 100644
--- a/go.sum
+++ b/go.sum
@@ -29,24 +29,14 @@ cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Ud
 cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
 cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
 cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc=
+cloud.google.com/go v0.102.1 h1:vpK6iQWv/2uUeFJth4/cBHsQAGjn1iIE6AAlxipRaA0=
 cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU=
-cloud.google.com/go v0.104.0 h1:gSmWO7DY1vOm0MVU6DNXM11BWHHsTUmsC5cv1fuW5X8=
-cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA=
-cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI=
-cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4=
-cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ=
-cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o=
-cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY=
-cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0=
 cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
 cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
 cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
 cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
 cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
 cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
-cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY=
-cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM=
-cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY=
 cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=
 cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM=
 cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=
@@ -54,67 +44,21 @@ cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz
 cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=
 cloud.google.com/go/compute v1.7.0 h1:v/k9Eueb8aAJ0vZuxKMrgm6kPhCLZU9HxFU+AFDs9Uk=
 cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U=
-cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs=
-cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM=
-cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo=
-cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I=
-cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo=
 cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
 cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
-cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo=
-cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4=
-cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU=
-cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y=
-cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk=
 cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
-cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk=
-cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM=
-cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o=
-cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0=
 cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY=
-cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic=
-cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8=
-cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4=
-cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE=
-cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY=
-cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA=
-cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ=
-cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY=
-cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs=
-cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E=
-cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0=
-cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0=
 cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
 cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
 cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
 cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
-cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4=
-cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o=
-cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg=
-cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg=
-cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y=
-cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4=
-cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s=
-cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA=
-cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4=
-cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0=
-cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU=
-cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs=
-cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM=
 cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
 cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
 cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
 cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
 cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
 cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y=
-cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc=
-cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s=
-cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw=
-cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU=
-cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0=
-cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo=
-cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE=
-cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0=
+cloud.google.com/go/storage v1.26.0/go.mod h1:mk/N7YwIKEWyTvXAWQCIeiCTdLoRH6Pd5xmSnolQLTI=
 contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA=
 contrib.go.opencensus.io/exporter/prometheus v0.4.1 h1:oObVeKo2NxpdF/fIfrPsNj6K0Prg0R0mHM+uANlYMiM=
 contrib.go.opencensus.io/exporter/prometheus v0.4.1/go.mod h1:t9wvfitlUjGXG2IXAZsuFq26mDGid/JwCEXp+gTG/9U=
@@ -219,8 +163,8 @@ github.com/aws/aws-sdk-go v1.35.24/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9
 github.com/aws/aws-sdk-go v1.37.27/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
 github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
 github.com/aws/aws-sdk-go v1.43.11/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
-github.com/aws/aws-sdk-go v1.44.114 h1:plIkWc/RsHr3DXBj4MEw9sEW4CcL/e2ryokc+CKyq1I=
-github.com/aws/aws-sdk-go v1.44.114/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
+github.com/aws/aws-sdk-go v1.44.94 h1:hDqJSv03ZVvqT448gUE63JEIHKx++vKLoDkiZxbNmIk=
+github.com/aws/aws-sdk-go v1.44.94/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
 github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs=
 github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A=
 github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
@@ -349,10 +293,10 @@ github.com/crewjam/httperr v0.2.0 h1:b2BfXR8U3AlIHwNeFFvZ+BV1LFvKLlzMjzaTnZMybNo
 github.com/crewjam/httperr v0.2.0/go.mod h1:Jlz+Sg/XqBQhyMjdDiC+GNNRzZTD7x39Gu3pglZ5oH4=
 github.com/crewjam/saml v0.4.6 h1:XCUFPkQSJLvzyl4cW9OvpWUbRf0gE7VUpU8ZnilbeM4=
 github.com/crewjam/saml v0.4.6/go.mod h1:ZBOXnNPFzB3CgOkRm7Nd6IVdkG+l/wF+0ZXLqD96t1A=
-github.com/cs3org/go-cs3apis v0.0.0-20221012090518-ef2996678965 h1:y4n2j68LLnvac+zw/al8MfPgO5aQiIwLmHM/JzYN8AM=
-github.com/cs3org/go-cs3apis v0.0.0-20221012090518-ef2996678965/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
-github.com/cs3org/reva/v2 v2.10.1-0.20221013183308-560ba925a814 h1:/IpXuGNX01f2eKM5mSMJFoE+DGq4NULo0WwpO3LzmTg=
-github.com/cs3org/reva/v2 v2.10.1-0.20221013183308-560ba925a814/go.mod h1:lq+LRpBDYU1vHUmJDeK7sGquREciO8GDj5/SYIibMPY=
+github.com/cs3org/go-cs3apis v0.0.0-20221005085457-19ea8088a512 h1:xTvaIsLu1ezoWOJKnV0ehgiowkOiEhMaylaI1lD/Axw=
+github.com/cs3org/go-cs3apis v0.0.0-20221005085457-19ea8088a512/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
+github.com/cs3org/reva/v2 v2.10.1-0.20221012104058-ae7c58b9bffa h1:DSeaakiPW5zYrGGEDO0BkSZWhqq6LS+rd1DQ1DPztJo=
+github.com/cs3org/reva/v2 v2.10.1-0.20221012104058-ae7c58b9bffa/go.mod h1:QUHLTf/ACFG2ueNP3u1dslv1bIWTTQAqvWFCorVke6o=
 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=
@@ -706,7 +650,6 @@ github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0
 github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=
 github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=
 github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c=
-github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo=
 github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4=
 github.com/gookit/color v1.5.2 h1:uLnfXcaFjlrDnQDT+NCBcfhrXqYTx/rcCa6xn01Y8yI=
 github.com/gookit/color v1.5.2/go.mod h1:w8h4bGiHeeBpvQVePTutdbERIUf3oJE5lZ8HM0UgXyg=
@@ -1015,8 +958,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW
 github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04/go.mod h1:5sN+Lt1CaY4wsPvgQH/jsuJi4XO2ssZbdsIizr4CVC8=
 github.com/nats-io/jwt/v2 v2.3.0 h1:z2mA1a7tIf5ShggOFlR1oBPgd6hGqcDYsISxZByUzdI=
 github.com/nats-io/jwt/v2 v2.3.0/go.mod h1:0tqz9Hlu6bCBFLWAASKhE5vUA4c24L9KPUUgvwumE/k=
-github.com/nats-io/nats-server/v2 v2.9.3 h1:HrfzA7G9LNetKkm1z+jU/e9kuAe+E6uaBuuq9EB5sQQ=
-github.com/nats-io/nats-server/v2 v2.9.3/go.mod h1:4sq8wvrpbvSzL1n3ZfEYnH4qeUuIl5W990j3kw13rRk=
+github.com/nats-io/nats-server/v2 v2.9.2 h1:XNDgJgOYYaYlquLdbSHI3xssLipfKUOq3EmYIMNCOsE=
+github.com/nats-io/nats-server/v2 v2.9.2/go.mod h1:4sq8wvrpbvSzL1n3ZfEYnH4qeUuIl5W990j3kw13rRk=
 github.com/nats-io/nats.go v1.17.0 h1:1jp5BThsdGlN91hW0k3YEfJbfACjiOYtUiLXG0RL4IE=
 github.com/nats-io/nats.go v1.17.0/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w=
 github.com/nats-io/nkeys v0.3.0 h1:cgM5tL53EvYRU+2YLXIK0G2mJtK12Ft9oeooSZMA2G8=
@@ -1046,14 +989,14 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108
 github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg=
 github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
 github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
-github.com/onsi/ginkgo/v2 v2.3.1 h1:8SbseP7qM32WcvE6VaN6vfXxv698izmsJ1UQX9ve7T8=
-github.com/onsi/ginkgo/v2 v2.3.1/go.mod h1:Sv4yQXwG5VmF7tm3Q5Z+RWUpPo24LF1mpnz2crUb8Ys=
+github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
+github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk=
 github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
 github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
 github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48=
-github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI=
-github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM=
+github.com/onsi/gomega v1.21.1 h1:OB/euWYIExnPBohllTicTHmGTrMaqJ67nIu80j0/uEM=
+github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc=
 github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
 github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
 github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
@@ -1263,8 +1206,8 @@ github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208/go.mod h1:BzWtXXrXz
 github.com/transip/gotransip/v6 v6.2.0/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g=
 github.com/trustelem/zxcvbn v1.0.1 h1:mp4JFtzdDYGj9WYSD3KQSkwwUumWNFzXaAjckaTYpsc=
 github.com/trustelem/zxcvbn v1.0.1/go.mod h1:zonUyKeh7sw6psPf/e3DtRqkRyZvAbOfjNz/aO7YQ5s=
-github.com/tus/tusd v1.10.0 h1:oQIxjxrSD6mjvYkqIjDlB3KVoEA1DWSzqCgWcTPP/ok=
-github.com/tus/tusd v1.10.0/go.mod h1:2k5gtwQX7v1FbeYcCk1O5Sp/sOL9D9iBBtQ7n6XPyBo=
+github.com/tus/tusd v1.9.2 h1:DPD2M+4QECNPWCdHbkBCYViQbhLJVQQwYrqznZGy9Qk=
+github.com/tus/tusd v1.9.2/go.mod h1:1OmZr8VqJ6+3q7zuCm2mu05IlCw7Qm8Ik7a/Q+Bm7jo=
 github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
 github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
 github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
@@ -1519,10 +1462,8 @@ golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su
 golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
 golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
 golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
-golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
 golang.org/x/net v0.0.0-20220921155015-db77216a4ee9 h1:SdDGdqRuKrF2R4XGcnPzcvZ63c/55GvhoHUus0o+BNI=
 golang.org/x/net v0.0.0-20220921155015-db77216a4ee9/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -1546,10 +1487,8 @@ golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j
 golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
 golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
 golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
-golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
+golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 h1:2o1E+E8TpNLklK9nHiPiK1uzIYrIHt+cQx3ynCwq9V8=
 golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
-golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 h1:lxqLZaMad/dJHMFZH0NiNpiEZI/nhgWhe4wgzpE+MuA=
-golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -1677,7 +1616,6 @@ golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -1699,9 +1637,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
-golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -1826,17 +1763,11 @@ google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/S
 google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8=
 google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs=
 google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=
-google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=
 google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=
 google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg=
 google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o=
-google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g=
-google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=
-google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=
+google.golang.org/api v0.94.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI=
 google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI=
-google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s=
-google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s=
-google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -1920,7 +1851,6 @@ google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX
 google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
 google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
 google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
-google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
 google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
 google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
 google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
@@ -1928,19 +1858,7 @@ google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljW
 google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
 google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
 google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
-google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
-google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE=
-google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc=
-google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
-google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
-google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
-google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
-google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
-google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=
-google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=
-google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=
-google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=
-google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=
+google.golang.org/genproto v0.0.0-20220810155839-1856144b1d9c/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
 google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006 h1:mmbq5q8M1t7dhkLw320YK4PsOXm6jdnUAkErImaIqOg=
 google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw=
 google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
@@ -2050,8 +1968,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
 gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
-gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o=
-gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g=
+gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo=
+gotest.tools/v3 v3.3.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A=
 honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/ocis-pkg/log/log.go b/ocis-pkg/log/log.go
index 0c3ea4632e9..b217c778914 100644
--- a/ocis-pkg/log/log.go
+++ b/ocis-pkg/log/log.go
@@ -1,11 +1,13 @@
 package log
 
 import (
+	"context"
 	"fmt"
 	"os"
 	"strings"
 	"time"
 
+	chimiddleware "github.com/go-chi/chi/v5/middleware"
 	mzlog "github.com/go-micro/plugins/v4/logger/zerolog"
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
 	"github.com/rs/zerolog"
@@ -13,6 +15,10 @@ import (
 	"go-micro.dev/v4/logger"
 )
 
+var (
+	RequestIDString = "request-id"
+)
+
 func init() {
 	// this is ugly, but "logger.DefaultLogger" is a global variable and we need to set it _before_ anybody uses it
 	setMicroLogger()
@@ -117,3 +123,10 @@ func NewLogger(opts ...Option) Logger {
 		logger,
 	}
 }
+
+// SubloggerWithRequestID returns a sublogger with the x-request-id added to all events
+func (l Logger) SubloggerWithRequestID(c context.Context) Logger {
+	return Logger{
+		l.With().Str(RequestIDString, chimiddleware.GetReqID(c)).Logger(),
+	}
+}
diff --git a/ocis-pkg/middleware/logger.go b/ocis-pkg/middleware/logger.go
index c879de63d54..465c025de1a 100644
--- a/ocis-pkg/middleware/logger.go
+++ b/ocis-pkg/middleware/logger.go
@@ -17,7 +17,7 @@ func Logger(logger log.Logger) func(http.Handler) http.Handler {
 			next.ServeHTTP(wrap, r)
 
 			logger.Debug().
-				Str("request", r.Header.Get("X-Request-ID")).
+				Str(log.RequestIDString, r.Header.Get("X-Request-ID")).
 				Str("proto", r.Proto).
 				Str("method", r.Method).
 				Int("status", wrap.Status()).
diff --git a/ocis/pkg/init/init.go b/ocis/pkg/init/init.go
index 429d35998b0..512ba4ae693 100644
--- a/ocis/pkg/init/init.go
+++ b/ocis/pkg/init/init.go
@@ -19,11 +19,6 @@ const (
 	passwordLength = 32
 )
 
-var (
-	_insecureService = InsecureService{Insecure: true}
-	_insecureEvents  = Events{TLSInsecure: true}
-)
-
 type TokenManager struct {
 	JWTSecret string `yaml:"jwt_secret"`
 }
@@ -48,12 +43,7 @@ type LdapBasedService struct {
 	Ldap LdapSettings
 }
 
-type Events struct {
-	TLSInsecure bool `yaml:"tls_insecure"`
-}
-
 type GraphService struct {
-	Events   Events
 	Spaces   InsecureService
 	Identity LdapBasedService
 }
@@ -97,33 +87,6 @@ type ThumbnailService struct {
 	Thumbnail ThumbnailSettings
 }
 
-type Search struct {
-	Events Events
-}
-
-type Audit struct {
-	Events Events
-}
-
-type Sharing struct {
-	Events Events
-}
-
-type StorageUsers struct {
-	Events Events
-}
-
-type Notifications struct {
-	Notifications struct{ Events Events } // The notifications config has a field called notifications
-}
-
-type Nats struct {
-	// The nats config has a field called nats
-	Nats struct {
-		TLSSkipVerifyClientCert bool `yaml:"tls_skip_verify_client_cert"`
-	}
-}
-
 // TODO: use the oCIS config struct instead of this custom struct
 // We can't use it right now, because it would need  "omitempty" on
 // all elements, in order to produce a slim config file with `ocis init`.
@@ -154,12 +117,6 @@ type OcisConfig struct {
 	Groups            UsersAndGroupsService
 	Ocdav             InsecureService
 	Thumbnails        ThumbnailService
-	Search            Search
-	Audit             Audit
-	Sharing           Sharing
-	StorageUsers      StorageUsers `yaml:"storage_users"`
-	Notifications     Notifications
-	Nats              Nats
 }
 
 func checkConfigPath(configPath string) error {
@@ -310,20 +267,24 @@ func CreateConfig(insecure, forceOverwrite bool, configPath, adminPassword strin
 	}
 
 	if insecure {
-
 		cfg.AuthBearer = AuthbearerService{
-			AuthProviders: AuthProviderSettings{Oidc: _insecureService},
+			AuthProviders: AuthProviderSettings{
+				Oidc: InsecureService{
+					Insecure: true,
+				},
+			},
+		}
+		cfg.Frontend = FrontendService{
+			Archiver: InsecureService{
+				Insecure: true,
+			},
+		}
+		cfg.Graph.Spaces = InsecureService{
+			Insecure: true,
+		}
+		cfg.Ocdav = InsecureService{
+			Insecure: true,
 		}
-		cfg.Frontend = FrontendService{Archiver: _insecureService}
-		cfg.Graph.Spaces = _insecureService
-		cfg.Graph.Events = _insecureEvents
-		cfg.Notifications.Notifications.Events = _insecureEvents
-		cfg.Search.Events = _insecureEvents
-		cfg.Audit.Events = _insecureEvents
-		cfg.Sharing.Events = _insecureEvents
-		cfg.StorageUsers.Events = _insecureEvents
-		cfg.Nats.Nats.TLSSkipVerifyClientCert = true
-		cfg.Ocdav = _insecureService
 		cfg.Proxy = InsecureProxyService{
 			InsecureBackends: true,
 			OIDC: InsecureProxyOIDC{
diff --git a/services/app-provider/pkg/revaconfig/config.go b/services/app-provider/pkg/revaconfig/config.go
index 8b33d14a29a..96a8abbdfdf 100644
--- a/services/app-provider/pkg/revaconfig/config.go
+++ b/services/app-provider/pkg/revaconfig/config.go
@@ -43,12 +43,6 @@ func AppProviderConfigFromStruct(cfg *config.Config) map[string]interface{} {
 					},
 				},
 			},
-			"interceptors": map[string]interface{}{
-				"prometheus": map[string]interface{}{
-					"namespace": "ocis",
-					"subsystem": "app_provider",
-				},
-			},
 		},
 	}
 	return rcfg
diff --git a/services/app-registry/pkg/revaconfig/config.go b/services/app-registry/pkg/revaconfig/config.go
index 20b75434843..3f1b27caee4 100644
--- a/services/app-registry/pkg/revaconfig/config.go
+++ b/services/app-registry/pkg/revaconfig/config.go
@@ -33,12 +33,6 @@ func AppRegistryConfigFromStruct(cfg *config.Config, logger log.Logger) map[stri
 					},
 				},
 			},
-			"interceptors": map[string]interface{}{
-				"prometheus": map[string]interface{}{
-					"namespace": "ocis",
-					"subsystem": "app_registry",
-				},
-			},
 		},
 	}
 	return rcfg
diff --git a/services/auth-basic/pkg/revaconfig/config.go b/services/auth-basic/pkg/revaconfig/config.go
index 57cf6a80a7f..32833a1aa4f 100644
--- a/services/auth-basic/pkg/revaconfig/config.go
+++ b/services/auth-basic/pkg/revaconfig/config.go
@@ -42,12 +42,6 @@ func AuthBasicConfigFromStruct(cfg *config.Config) map[string]interface{} {
 					},
 				},
 			},
-			"interceptors": map[string]interface{}{
-				"prometheus": map[string]interface{}{
-					"namespace": "ocis",
-					"subsystem": "auth_basic",
-				},
-			},
 		},
 	}
 	return rcfg
diff --git a/services/auth-bearer/pkg/revaconfig/config.go b/services/auth-bearer/pkg/revaconfig/config.go
index b24f11e8228..cf51a02dcc8 100644
--- a/services/auth-bearer/pkg/revaconfig/config.go
+++ b/services/auth-bearer/pkg/revaconfig/config.go
@@ -33,12 +33,6 @@ func AuthBearerConfigFromStruct(cfg *config.Config) map[string]interface{} {
 					},
 				},
 			},
-			"interceptors": map[string]interface{}{
-				"prometheus": map[string]interface{}{
-					"namespace": "ocis",
-					"subsystem": "auth_bearer",
-				},
-			},
 		},
 	}
 }
diff --git a/services/auth-machine/pkg/revaconfig/config.go b/services/auth-machine/pkg/revaconfig/config.go
index bc2422156bd..637488da00e 100644
--- a/services/auth-machine/pkg/revaconfig/config.go
+++ b/services/auth-machine/pkg/revaconfig/config.go
@@ -32,12 +32,6 @@ func AuthMachineConfigFromStruct(cfg *config.Config) map[string]interface{} {
 					},
 				},
 			},
-			"interceptors": map[string]interface{}{
-				"prometheus": map[string]interface{}{
-					"namespace": "ocis",
-					"subsystem": "auth_machine",
-				},
-			},
 		},
 	}
 }
diff --git a/services/frontend/pkg/revaconfig/config.go b/services/frontend/pkg/revaconfig/config.go
index 5bd573bef7f..9d4a1f87f45 100644
--- a/services/frontend/pkg/revaconfig/config.go
+++ b/services/frontend/pkg/revaconfig/config.go
@@ -85,10 +85,6 @@ func FrontendConfigFromStruct(cfg *config.Config) (map[string]interface{}, error
 					"credentials_by_user_agent": cfg.Middleware.Auth.CredentialsByUserAgent,
 					"credential_chain":          []string{"bearer"},
 				},
-				"prometheus": map[string]interface{}{
-					"namespace": "ocis",
-					"subsystem": "frontend",
-				},
 			},
 			// TODO build services dynamically
 			"services": map[string]interface{}{
diff --git a/services/gateway/pkg/revaconfig/config.go b/services/gateway/pkg/revaconfig/config.go
index d8deec31d99..4f9f0378547 100644
--- a/services/gateway/pkg/revaconfig/config.go
+++ b/services/gateway/pkg/revaconfig/config.go
@@ -80,12 +80,6 @@ func GatewayConfigFromStruct(cfg *config.Config, logger log.Logger) map[string]i
 					},
 				},
 			},
-			"interceptors": map[string]interface{}{
-				"prometheus": map[string]interface{}{
-					"namespace": "ocis",
-					"subsystem": "gateway",
-				},
-			},
 		},
 	}
 	return rcfg
diff --git a/services/graph/pkg/identity/cs3.go b/services/graph/pkg/identity/cs3.go
index a42bbdbc43c..015de11917f 100644
--- a/services/graph/pkg/identity/cs3.go
+++ b/services/graph/pkg/identity/cs3.go
@@ -40,9 +40,11 @@ func (i *CS3) UpdateUser(ctx context.Context, nameOrID string, user libregraph.U
 }
 
 func (i *CS3) GetUser(ctx context.Context, userID string, queryParam url.Values) (*libregraph.User, error) {
+	logger := i.Logger.SubloggerWithRequestID(ctx)
+	logger.Debug().Str("backend", "cs3").Msg("GetUser")
 	client, err := pool.GetGatewayServiceClient(i.Config.Address)
 	if err != nil {
-		i.Logger.Error().Err(err).Msg("could not get client")
+		logger.Error().Str("backend", "cs3").Err(err).Msg("could not get client")
 		return nil, errorcode.New(errorcode.ServiceNotAvailable, err.Error())
 	}
 
@@ -53,22 +55,24 @@ func (i *CS3) GetUser(ctx context.Context, userID string, queryParam url.Values)
 
 	switch {
 	case err != nil:
-		i.Logger.Error().Err(err).Str("userid", userID).Msg("error sending get user by claim id grpc request")
+		logger.Error().Str("backend", "cs3").Err(err).Str("userid", userID).Msg("error sending get user by claim id grpc request: transport error")
 		return nil, errorcode.New(errorcode.ServiceNotAvailable, err.Error())
 	case res.Status.Code != cs3rpc.Code_CODE_OK:
 		if res.Status.Code == cs3rpc.Code_CODE_NOT_FOUND {
 			return nil, errorcode.New(errorcode.ItemNotFound, res.Status.Message)
 		}
-		i.Logger.Error().Err(err).Str("userid", userID).Msg("error sending get user by claim id grpc request")
+		logger.Debug().Str("backend", "cs3").Err(err).Str("userid", userID).Msg("error sending get user by claim id grpc request")
 		return nil, errorcode.New(errorcode.GeneralException, res.Status.Message)
 	}
 	return CreateUserModelFromCS3(res.User), nil
 }
 
 func (i *CS3) GetUsers(ctx context.Context, queryParam url.Values) ([]*libregraph.User, error) {
+	logger := i.Logger.SubloggerWithRequestID(ctx)
+	logger.Debug().Str("backend", "cs3").Msg("GetUsers")
 	client, err := pool.GetGatewayServiceClient(i.Config.Address)
 	if err != nil {
-		i.Logger.Error().Err(err).Msg("could not get client")
+		logger.Error().Str("backend", "cs3").Err(err).Msg("could not get client")
 		return nil, errorcode.New(errorcode.ServiceNotAvailable, err.Error())
 	}
 
@@ -84,13 +88,13 @@ func (i *CS3) GetUsers(ctx context.Context, queryParam url.Values) ([]*libregrap
 	})
 	switch {
 	case err != nil:
-		i.Logger.Error().Err(err).Str("search", search).Msg("error sending find users grpc request")
+		logger.Error().Str("backend", "cs3").Err(err).Str("search", search).Msg("error sending find users grpc request: transport error")
 		return nil, errorcode.New(errorcode.ServiceNotAvailable, err.Error())
 	case res.Status.Code != cs3rpc.Code_CODE_OK:
 		if res.Status.Code == cs3rpc.Code_CODE_NOT_FOUND {
 			return nil, errorcode.New(errorcode.ItemNotFound, res.Status.Message)
 		}
-		i.Logger.Error().Err(err).Str("search", search).Msg("error sending find users grpc request")
+		logger.Debug().Str("backend", "cs3").Err(err).Str("search", search).Msg("error sending find users grpc request")
 		return nil, errorcode.New(errorcode.GeneralException, res.Status.Message)
 	}
 
@@ -104,9 +108,11 @@ func (i *CS3) GetUsers(ctx context.Context, queryParam url.Values) ([]*libregrap
 }
 
 func (i *CS3) GetGroups(ctx context.Context, queryParam url.Values) ([]*libregraph.Group, error) {
+	logger := i.Logger.SubloggerWithRequestID(ctx)
+	logger.Debug().Str("backend", "cs3").Msg("GetGroups")
 	client, err := pool.GetGatewayServiceClient(i.Config.Address)
 	if err != nil {
-		i.Logger.Error().Err(err).Msg("could not get client")
+		logger.Error().Str("backend", "cs3").Err(err).Msg("could not get client")
 		return nil, errorcode.New(errorcode.ServiceNotAvailable, err.Error())
 	}
 
@@ -123,13 +129,13 @@ func (i *CS3) GetGroups(ctx context.Context, queryParam url.Values) ([]*libregra
 
 	switch {
 	case err != nil:
-		i.Logger.Error().Err(err).Str("search", search).Msg("error sending find groups grpc request")
+		logger.Error().Str("backend", "cs3").Err(err).Str("search", search).Msg("error sending find groups grpc request: transport error")
 		return nil, errorcode.New(errorcode.ServiceNotAvailable, err.Error())
 	case res.Status.Code != cs3rpc.Code_CODE_OK:
 		if res.Status.Code == cs3rpc.Code_CODE_NOT_FOUND {
 			return nil, errorcode.New(errorcode.ItemNotFound, res.Status.Message)
 		}
-		i.Logger.Error().Err(err).Str("search", search).Msg("error sending find groups grpc request")
+		logger.Debug().Str("backend", "cs3").Err(err).Str("search", search).Msg("error sending find groups grpc request")
 		return nil, errorcode.New(errorcode.GeneralException, res.Status.Message)
 	}
 
@@ -148,9 +154,11 @@ func (i *CS3) CreateGroup(ctx context.Context, group libregraph.Group) (*libregr
 }
 
 func (i *CS3) GetGroup(ctx context.Context, groupID string, queryParam url.Values) (*libregraph.Group, error) {
+	logger := i.Logger.SubloggerWithRequestID(ctx)
+	logger.Debug().Str("backend", "cs3").Msg("GetGroup")
 	client, err := pool.GetGatewayServiceClient(i.Config.Address)
 	if err != nil {
-		i.Logger.Error().Err(err).Msg("could not get client")
+		logger.Error().Str("backend", "cs3").Err(err).Msg("could not get client")
 		return nil, errorcode.New(errorcode.ServiceNotAvailable, err.Error())
 	}
 
@@ -161,13 +169,13 @@ func (i *CS3) GetGroup(ctx context.Context, groupID string, queryParam url.Value
 
 	switch {
 	case err != nil:
-		i.Logger.Error().Err(err).Str("groupid", groupID).Msg("error sending get group by claim id grpc request")
+		logger.Error().Str("backend", "cs3").Err(err).Str("groupid", groupID).Msg("error sending get group by claim id grpc request: transport error")
 		return nil, errorcode.New(errorcode.ServiceNotAvailable, err.Error())
 	case res.Status.Code != cs3rpc.Code_CODE_OK:
 		if res.Status.Code == cs3rpc.Code_CODE_NOT_FOUND {
 			return nil, errorcode.New(errorcode.ItemNotFound, res.Status.Message)
 		}
-		i.Logger.Error().Err(err).Str("groupid", groupID).Msg("error sending get group by claim id grpc request")
+		logger.Debug().Str("backend", "cs3").Err(err).Str("groupid", groupID).Msg("error sending get group by claim id grpc request")
 		return nil, errorcode.New(errorcode.GeneralException, res.Status.Message)
 	}
 
diff --git a/services/graph/pkg/identity/ldap.go b/services/graph/pkg/identity/ldap.go
index 24f8678c647..f9a3d1afab1 100644
--- a/services/graph/pkg/identity/ldap.go
+++ b/services/graph/pkg/identity/ldap.go
@@ -113,6 +113,8 @@ func NewLDAPBackend(lc ldap.Client, config config.LDAP, logger *log.Logger) (*LD
 // LDAP User Entry (using the inetOrgPerson LDAP Objectclass) add adds that to the
 // configured LDAP server
 func (i *LDAP) CreateUser(ctx context.Context, user libregraph.User) (*libregraph.User, error) {
+	logger := i.logger.SubloggerWithRequestID(ctx)
+	logger.Debug().Str("backend", "ldap").Msg("CreateUser")
 	if !i.writeEnabled {
 		return nil, errReadOnly
 	}
@@ -165,7 +167,7 @@ func (i *LDAP) CreateUser(ctx context.Context, user libregraph.User) (*libregrap
 
 	if err := i.conn.Add(&ar); err != nil {
 		var lerr *ldap.Error
-		i.logger.Debug().Err(err).Msg("error adding user")
+		logger.Debug().Err(err).Msg("error adding user")
 		if errors.As(err, &lerr) {
 			if lerr.ResultCode == ldap.LDAPResultEntryAlreadyExists {
 				err = errorcode.New(errorcode.NameAlreadyExists, lerr.Error())
@@ -175,7 +177,7 @@ func (i *LDAP) CreateUser(ctx context.Context, user libregraph.User) (*libregrap
 	}
 
 	if i.usePwModifyExOp && user.PasswordProfile != nil && user.PasswordProfile.Password != nil {
-		if err := i.updateUserPassowrd(ar.DN, user.PasswordProfile.GetPassword()); err != nil {
+		if err := i.updateUserPassowrd(ctx, ar.DN, user.PasswordProfile.GetPassword()); err != nil {
 			return nil, err
 		}
 	}
@@ -191,6 +193,8 @@ func (i *LDAP) CreateUser(ctx context.Context, user libregraph.User) (*libregrap
 // DeleteUser implements the Backend Interface. It permanently deletes a User identified
 // by name or id from the LDAP server
 func (i *LDAP) DeleteUser(ctx context.Context, nameOrID string) error {
+	logger := i.logger.SubloggerWithRequestID(ctx)
+	logger.Debug().Str("backend", "ldap").Msg("DeleteUser")
 	if !i.writeEnabled {
 		return errReadOnly
 	}
@@ -209,13 +213,13 @@ func (i *LDAP) DeleteUser(ctx context.Context, nameOrID string) error {
 		return err
 	}
 	for _, group := range groupEntries {
-		i.logger.Debug().Str("group", group.DN).Str("user", e.DN).Msg("Cleaning up group membership")
+		logger.Debug().Str("group", group.DN).Str("user", e.DN).Msg("Cleaning up group membership")
 
 		if mr, err := i.removeMemberFromGroupEntry(group, e.DN); err == nil && mr != nil {
 			if err = i.conn.Modify(mr); err != nil {
 				// Errors when deleting the memberships are only logged as warnings but not returned
 				// to the user as we already successfully deleted the users itself
-				i.logger.Warn().Str("group", group.DN).Str("user", e.DN).Err(err).Msg("failed to remove member")
+				logger.Warn().Str("group", group.DN).Str("user", e.DN).Err(err).Msg("failed to remove member")
 			}
 		}
 	}
@@ -224,6 +228,8 @@ func (i *LDAP) DeleteUser(ctx context.Context, nameOrID string) error {
 
 // UpdateUser implements the Backend Interface for the LDAP Backend
 func (i *LDAP) UpdateUser(ctx context.Context, nameOrID string, user libregraph.User) (*libregraph.User, error) {
+	logger := i.logger.SubloggerWithRequestID(ctx)
+	logger.Debug().Str("backend", "ldap").Msg("UpdateUser")
 	if !i.writeEnabled {
 		return nil, errReadOnly
 	}
@@ -264,7 +270,7 @@ func (i *LDAP) UpdateUser(ctx context.Context, nameOrID string, user libregraph.
 	}
 	if user.PasswordProfile != nil && user.PasswordProfile.Password != nil && *user.PasswordProfile.Password != "" {
 		if i.usePwModifyExOp {
-			if err := i.updateUserPassowrd(e.DN, user.PasswordProfile.GetPassword()); err != nil {
+			if err := i.updateUserPassowrd(ctx, e.DN, user.PasswordProfile.GetPassword()); err != nil {
 				return nil, err
 			}
 		} else {
@@ -387,7 +393,8 @@ func (i *LDAP) getLDAPUserByFilter(filter string) (*ldap.Entry, error) {
 }
 
 func (i *LDAP) GetUser(ctx context.Context, nameOrID string, queryParam url.Values) (*libregraph.User, error) {
-	i.logger.Debug().Str("backend", "ldap").Msg("GetUser")
+	logger := i.logger.SubloggerWithRequestID(ctx)
+	logger.Debug().Str("backend", "ldap").Msg("GetUser")
 	e, err := i.getLDAPUserByNameOrID(nameOrID)
 	if err != nil {
 		return nil, err
@@ -412,7 +419,8 @@ func (i *LDAP) GetUser(ctx context.Context, nameOrID string, queryParam url.Valu
 }
 
 func (i *LDAP) GetUsers(ctx context.Context, queryParam url.Values) ([]*libregraph.User, error) {
-	i.logger.Debug().Str("backend", "ldap").Msg("GetUsers")
+	logger := i.logger.SubloggerWithRequestID(ctx)
+	logger.Debug().Str("backend", "ldap").Msg("GetUsers")
 
 	search := queryParam.Get("search")
 	if search == "" {
@@ -440,7 +448,7 @@ func (i *LDAP) GetUsers(ctx context.Context, queryParam url.Values) ([]*libregra
 		},
 		nil,
 	)
-	i.logger.Debug().Str("backend", "ldap").
+	logger.Debug().Str("backend", "ldap").
 		Str("base", searchRequest.BaseDN).
 		Str("filter", searchRequest.Filter).
 		Int("scope", searchRequest.Scope).
@@ -494,7 +502,8 @@ func (i *LDAP) getGroupsForUser(dn string) ([]*ldap.Entry, error) {
 }
 
 func (i *LDAP) GetGroup(ctx context.Context, nameOrID string, queryParam url.Values) (*libregraph.Group, error) {
-	i.logger.Debug().Str("backend", "ldap").Msg("GetGroup")
+	logger := i.logger.SubloggerWithRequestID(ctx)
+	logger.Debug().Str("backend", "ldap").Msg("GetGroup")
 	e, err := i.getLDAPGroupByNameOrID(nameOrID, true)
 	if err != nil {
 		return nil, err
@@ -632,7 +641,8 @@ func (i *LDAP) removeMemberFromGroupEntry(group *ldap.Entry, memberDN string) (*
 }
 
 func (i *LDAP) GetGroups(ctx context.Context, queryParam url.Values) ([]*libregraph.Group, error) {
-	i.logger.Debug().Str("backend", "ldap").Msg("GetGroups")
+	logger := i.logger.SubloggerWithRequestID(ctx)
+	logger.Debug().Str("backend", "ldap").Msg("GetGroups")
 
 	search := queryParam.Get("search")
 	if search == "" {
@@ -671,7 +681,7 @@ func (i *LDAP) GetGroups(ctx context.Context, queryParam url.Values) ([]*libregr
 		groupAttrs,
 		nil,
 	)
-	i.logger.Debug().Str("backend", "ldap").
+	logger.Debug().Str("backend", "ldap").
 		Str("base", searchRequest.BaseDN).
 		Str("filter", searchRequest.Filter).
 		Int("scope", searchRequest.Scope).
@@ -712,6 +722,8 @@ func (i *LDAP) GetGroups(ctx context.Context, queryParam url.Values) ([]*libregr
 
 // GetGroupMembers implements the Backend Interface for the LDAP Backend
 func (i *LDAP) GetGroupMembers(ctx context.Context, groupID string) ([]*libregraph.User, error) {
+	logger := i.logger.SubloggerWithRequestID(ctx)
+	logger.Debug().Str("backend", "ldap").Msg("GetGroupMembers")
 	e, err := i.getLDAPGroupByNameOrID(groupID, true)
 	if err != nil {
 		return nil, err
@@ -732,17 +744,19 @@ func (i *LDAP) GetGroupMembers(ctx context.Context, groupID string) ([]*libregra
 }
 
 func (i *LDAP) expandLDAPGroupMembers(ctx context.Context, e *ldap.Entry) ([]*ldap.Entry, error) {
+	logger := i.logger.SubloggerWithRequestID(ctx)
+	logger.Debug().Str("backend", "ldap").Msg("expandLDAPGroupMembers")
 	result := []*ldap.Entry{}
 
 	for _, memberDN := range e.GetEqualFoldAttributeValues(i.groupAttributeMap.member) {
 		if memberDN == "" {
 			continue
 		}
-		i.logger.Debug().Str("memberDN", memberDN).Msg("lookup")
+		logger.Debug().Str("memberDN", memberDN).Msg("lookup")
 		ue, err := i.getUserByDN(memberDN)
 		if err != nil {
 			// Ignore errors when reading a specific member fails, just log them and continue
-			i.logger.Warn().Err(err).Str("member", memberDN).Msg("error reading group member")
+			logger.Debug().Err(err).Str("member", memberDN).Msg("error reading group member")
 			continue
 		}
 		result = append(result, ue)
@@ -756,6 +770,8 @@ func (i *LDAP) expandLDAPGroupMembers(ctx context.Context, e *ldap.Entry) ([]*ld
 // As "groupOfNames" requires a "member" Attribute to be present. Empty Groups (groups
 // without a member) a represented by adding an empty DN as the single member.
 func (i *LDAP) CreateGroup(ctx context.Context, group libregraph.Group) (*libregraph.Group, error) {
+	logger := i.logger.SubloggerWithRequestID(ctx)
+	logger.Debug().Str("backend", "ldap").Msg("create group")
 	if !i.writeEnabled {
 		return nil, errorcode.New(errorcode.NotAllowed, "server is configured read-only")
 	}
@@ -803,6 +819,8 @@ func (i *LDAP) CreateGroup(ctx context.Context, group libregraph.Group) (*libreg
 
 // DeleteGroup implements the Backend Interface.
 func (i *LDAP) DeleteGroup(ctx context.Context, id string) error {
+	logger := i.logger.SubloggerWithRequestID(ctx)
+	logger.Debug().Str("backend", "ldap").Msg("DeleteGroup")
 	if !i.writeEnabled {
 		return errorcode.New(errorcode.NotAllowed, "server is configured read-only")
 	}
@@ -821,6 +839,8 @@ func (i *LDAP) DeleteGroup(ctx context.Context, id string) error {
 // Currently it is limited to adding Users as Group members. Adding other groups
 // as members is not yet implemented
 func (i *LDAP) AddMembersToGroup(ctx context.Context, groupID string, memberIDs []string) error {
+	logger := i.logger.SubloggerWithRequestID(ctx)
+	logger.Debug().Str("backend", "ldap").Msg("AddMembersToGroup")
 	ge, err := i.getLDAPGroupByID(groupID, true)
 	if err != nil {
 		return err
@@ -843,7 +863,7 @@ func (i *LDAP) AddMembersToGroup(ctx context.Context, groupID string, memberIDs
 		nCurrentMember, err := ldapdn.ParseNormalize(currentMember)
 		if err != nil {
 			// We couldn't parse the member value as a DN. Let's skip it, but log a warning
-			i.logger.Warn().Str("memberDN", currentMember).Err(err).Msg("Couldn't parse DN")
+			logger.Warn().Str("memberDN", currentMember).Err(err).Msg("Couldn't parse DN")
 			continue
 		}
 		currentSet[nCurrentMember] = struct{}{}
@@ -857,13 +877,13 @@ func (i *LDAP) AddMembersToGroup(ctx context.Context, groupID string, memberIDs
 		}
 		nDN, err := ldapdn.ParseNormalize(me.DN)
 		if err != nil {
-			i.logger.Error().Str("new member", me.DN).Err(err).Msg("Couldn't parse DN")
+			logger.Error().Str("new member", me.DN).Err(err).Msg("Couldn't parse DN")
 			return err
 		}
 		if _, present := currentSet[nDN]; !present {
 			newMemberDNs = append(newMemberDNs, me.DN)
 		} else {
-			i.logger.Debug().Str("memberDN", me.DN).Msg("Member already present in group. Skipping")
+			logger.Debug().Str("memberDN", me.DN).Msg("Member already present in group. Skipping")
 		}
 	}
 
@@ -879,17 +899,19 @@ func (i *LDAP) AddMembersToGroup(ctx context.Context, groupID string, memberIDs
 
 // RemoveMemberFromGroup implements the Backend Interface.
 func (i *LDAP) RemoveMemberFromGroup(ctx context.Context, groupID string, memberID string) error {
+	logger := i.logger.SubloggerWithRequestID(ctx)
+	logger.Debug().Str("backend", "ldap").Msg("RemoveMemberFromGroup")
 	ge, err := i.getLDAPGroupByID(groupID, true)
 	if err != nil {
-		i.logger.Warn().Str("backend", "ldap").Str("groupID", groupID).Msg("Error looking up group")
+		logger.Debug().Str("backend", "ldap").Str("groupID", groupID).Msg("Error looking up group")
 		return err
 	}
 	me, err := i.getLDAPUserByID(memberID)
 	if err != nil {
-		i.logger.Warn().Str("backend", "ldap").Str("memberID", memberID).Msg("Error looking up group member")
+		logger.Debug().Str("backend", "ldap").Str("memberID", memberID).Msg("Error looking up group member")
 		return err
 	}
-	i.logger.Debug().Str("backend", "ldap").Str("groupdn", ge.DN).Str("member", me.DN).Msg("remove member")
+	logger.Debug().Str("backend", "ldap").Str("groupdn", ge.DN).Str("member", me.DN).Msg("remove member")
 
 	if mr, err := i.removeMemberFromGroupEntry(ge, me.DN); err == nil && mr != nil {
 		return i.conn.Modify(mr)
@@ -897,7 +919,9 @@ func (i *LDAP) RemoveMemberFromGroup(ctx context.Context, groupID string, member
 	return nil
 }
 
-func (i *LDAP) updateUserPassowrd(dn, password string) error {
+func (i *LDAP) updateUserPassowrd(ctx context.Context, dn, password string) error {
+	logger := i.logger.SubloggerWithRequestID(ctx)
+	logger.Debug().Str("backend", "ldap").Msg("updateUserPassowrd")
 	pwMod := ldap.PasswordModifyRequest{
 		UserIdentity: dn,
 		NewPassword:  password,
@@ -907,7 +931,7 @@ func (i *LDAP) updateUserPassowrd(dn, password string) error {
 	_, err := i.conn.PasswordModify(&pwMod)
 	if err != nil {
 		var lerr *ldap.Error
-		i.logger.Debug().Err(err).Msg("error setting password for user")
+		logger.Debug().Err(err).Msg("error setting password for user")
 		if errors.As(err, &lerr) {
 			if lerr.ResultCode == ldap.LDAPResultEntryAlreadyExists {
 				err = errorcode.New(errorcode.NameAlreadyExists, lerr.Error())
diff --git a/services/graph/pkg/middleware/auth.go b/services/graph/pkg/middleware/auth.go
index fc6c487f72f..6becccf9023 100644
--- a/services/graph/pkg/middleware/auth.go
+++ b/services/graph/pkg/middleware/auth.go
@@ -7,6 +7,7 @@ import (
 	revactx "github.com/cs3org/reva/v2/pkg/ctx"
 	"github.com/cs3org/reva/v2/pkg/token/manager/jwt"
 	"github.com/owncloud/ocis/v2/ocis-pkg/account"
+	"github.com/owncloud/ocis/v2/ocis-pkg/log"
 	opkgm "github.com/owncloud/ocis/v2/ocis-pkg/middleware"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/service/v0/errorcode"
 	gmmetadata "go-micro.dev/v4/metadata"
@@ -66,7 +67,7 @@ func Auth(opts ...account.Option) func(http.Handler) http.Handler {
 				return
 			}
 			if ok, err := scope.VerifyScope(ctx, tokenScope, r); err != nil || !ok {
-				opt.Logger.Error().Err(err).Msg("verifying scope failed")
+				opt.Logger.Error().Str(log.RequestIDString, r.Header.Get("X-Request-ID")).Err(err).Msg("verifying scope failed")
 				errorcode.InvalidAuthenticationToken.Render(w, r, http.StatusUnauthorized, "verifying scope failed")
 				return
 			}
diff --git a/services/graph/pkg/service/v0/drives.go b/services/graph/pkg/service/v0/drives.go
index 963501a5749..05dd0aeb341 100644
--- a/services/graph/pkg/service/v0/drives.go
+++ b/services/graph/pkg/service/v0/drives.go
@@ -29,6 +29,7 @@ import (
 	settingssvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/service/v0/errorcode"
 	settingsServiceExt "github.com/owncloud/ocis/v2/services/settings/pkg/service/v0"
+	"github.com/pkg/errors"
 	merrors "go-micro.dev/v4/errors"
 )
 
@@ -45,30 +46,36 @@ func (g Graph) GetAllDrives(w http.ResponseWriter, r *http.Request) {
 
 // getDrives implements the Service interface.
 func (g Graph) getDrives(w http.ResponseWriter, r *http.Request, unrestricted bool) {
+	logger := g.logger.SubloggerWithRequestID(r.Context())
+	logger.Info().
+		Interface("query", r.URL.Query()).
+		Bool("unrestricted", unrestricted).
+		Msg("calling get drives")
 	sanitizedPath := strings.TrimPrefix(r.URL.Path, "/graph/v1.0/")
 	// Parse the request with odata parser
 	odataReq, err := godata.ParseRequest(r.Context(), sanitizedPath, r.URL.Query())
 	if err != nil {
-		g.logger.Err(err).Interface("query", r.URL.Query()).Msg("query error")
+		logger.Debug().Err(err).Interface("query", r.URL.Query()).Msg("could not get drives: query error")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
 		return
 	}
-	g.logger.Debug().
-		Interface("query", r.URL.Query()).
-		Bool("unrestricted", unrestricted).
-		Msg("Calling getDrives")
 	ctx := r.Context()
 
 	filters, err := generateCs3Filters(odataReq)
 	if err != nil {
-		g.logger.Err(err).Interface("query", r.URL.Query()).Msg("query error")
+		logger.Debug().Err(err).Interface("query", r.URL.Query()).Msg("could not get drives: error parsing filters")
 		errorcode.NotSupported.Render(w, r, http.StatusNotImplemented, err.Error())
 		return
 	}
+
+	logger.Debug().
+		Interface("filters", filters).
+		Bool("unrestricted", unrestricted).
+		Msg("calling list storage spaces on backend")
 	res, err := g.ListStorageSpacesWithFilters(ctx, filters, unrestricted)
 	switch {
 	case err != nil:
-		g.logger.Error().Err(err).Msg(ListStorageSpacesTransportErr)
+		logger.Error().Err(err).Msg("could not get drives: transport error")
 		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
 		return
 	case res.Status.Code != cs3rpc.Code_CODE_OK:
@@ -78,27 +85,28 @@ func (g Graph) getDrives(w http.ResponseWriter, r *http.Request, unrestricted bo
 			render.JSON(w, r, &listResponse{})
 			return
 		}
-		g.logger.Error().Err(err).Msg(ListStorageSpacesReturnsErr)
+		logger.Debug().Str("message", res.GetStatus().GetMessage()).Msg("could not get drives: grpc error")
 		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, res.Status.Message)
 		return
 	}
 
-	wdu, err := url.Parse(g.config.Spaces.WebDavBase + g.config.Spaces.WebDavPath)
+	webDavBaseURL, err := g.getWebDavBaseURL()
 	if err != nil {
-		g.logger.Error().Err(err).Msg("error parsing url")
+		logger.Error().Err(err).Str("url", webDavBaseURL.String()).Msg("could not get drives: error parsing url")
 		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
 		return
 	}
-	spaces, err := g.formatDrives(ctx, wdu, res.StorageSpaces)
+
+	spaces, err := g.formatDrives(ctx, webDavBaseURL, res.StorageSpaces)
 	if err != nil {
-		g.logger.Error().Err(err).Msg("error encoding response as json")
+		logger.Debug().Err(err).Msg("could not get drives: error parsing grpc response")
 		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
 		return
 	}
 
 	spaces, err = sortSpaces(odataReq, spaces)
 	if err != nil {
-		g.logger.Error().Err(err).Msg("error sorting the spaces list")
+		logger.Debug().Err(err).Msg("could not get drives: error sorting the spaces list according to query")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
 		return
 	}
@@ -109,60 +117,71 @@ func (g Graph) getDrives(w http.ResponseWriter, r *http.Request, unrestricted bo
 
 // GetSingleDrive does a lookup of a single space by spaceId
 func (g Graph) GetSingleDrive(w http.ResponseWriter, r *http.Request) {
-	driveID, _ := url.PathUnescape(chi.URLParam(r, "driveID"))
+	logger := g.logger.SubloggerWithRequestID(r.Context())
+	logger.Info().Interface("query", r.URL.Query()).Msg("calling get drive")
+	driveID, err := url.PathUnescape(chi.URLParam(r, "driveID"))
+
+	if err != nil {
+		logger.Debug().Err(err).Str("driveID", chi.URLParam(r, "driveID")).Msg("could not get drive: unescaping drive id failed")
+		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "unescaping drive id failed")
+		return
+	}
+
 	if driveID == "" {
-		err := fmt.Errorf("no valid space id retrieved")
-		g.logger.Err(err)
-		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
+		logger.Debug().Msg("could not get drive: missing drive id")
+		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing drive id")
 		return
 	}
 
-	g.logger.Info().Str("driveID", driveID).Msg("Calling GetSingleDrive")
+	logger.Debug().Str("driveID", driveID).Msg("calling list storage spaces with id filter")
 	ctx := r.Context()
 
 	filters := []*storageprovider.ListStorageSpacesRequest_Filter{listStorageSpacesIDFilter(driveID)}
 	res, err := g.ListStorageSpacesWithFilters(ctx, filters, true)
 	switch {
 	case err != nil:
-		g.logger.Error().Err(err).Msg(ListStorageSpacesTransportErr)
-		errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, err.Error())
+		logger.Error().Err(err).Msg("could not get drive: transport error")
+		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
 		return
 	case res.Status.Code != cs3rpc.Code_CODE_OK:
 		if res.Status.Code == cs3rpc.Code_CODE_NOT_FOUND {
 			// the client is doing a lookup for a specific space, therefore we need to return
 			// not found to the caller
-			g.logger.Error().Str("driveID", driveID).Msg(fmt.Sprintf(NoSpaceFoundMessage, driveID))
-			errorcode.ItemNotFound.Render(w, r, http.StatusNotFound, fmt.Sprintf(NoSpaceFoundMessage, driveID))
+			logger.Debug().Str("driveID", driveID).Msg("could not get drive: not found")
+			errorcode.ItemNotFound.Render(w, r, http.StatusNotFound, "drive not found")
 			return
 		}
-		g.logger.Error().Err(err).Msg(ListStorageSpacesReturnsErr)
+		logger.Debug().
+			Str("id", driveID).
+			Str("grpcmessage", res.GetStatus().GetMessage()).
+			Msg("could not get drive: grpc error")
 		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, res.Status.Message)
 		return
 	}
 
-	wdu, err := url.Parse(g.config.Spaces.WebDavBase + g.config.Spaces.WebDavPath)
+	webDavBaseURL, err := g.getWebDavBaseURL()
 	if err != nil {
-		g.logger.Error().Err(err).Msg("error parsing url")
+		logger.Error().Err(err).Str("url", webDavBaseURL.String()).Msg("could not get drive: error parsing webdav base url")
 		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
 		return
 	}
-	spaces, err := g.formatDrives(ctx, wdu, res.StorageSpaces)
+	spaces, err := g.formatDrives(ctx, webDavBaseURL, res.StorageSpaces)
 	if err != nil {
-		g.logger.Error().Err(err).Msg("error encoding response")
+		logger.Debug().Err(err).Msg("could not get drive: error parsing grpc response")
 		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
 		return
 	}
 	switch num := len(spaces); {
 	case num == 0:
-		g.logger.Error().Str("driveID", driveID).Msg("no space found")
-		errorcode.ItemNotFound.Render(w, r, http.StatusNotFound, fmt.Sprintf(NoSpaceFoundMessage, driveID))
+		logger.Debug().Str("id", driveID).Msg("could not get drive: no drive returned from storage")
+		errorcode.ItemNotFound.Render(w, r, http.StatusNotFound, "no drive returned from storage")
 		return
 	case num == 1:
 		render.Status(r, http.StatusOK)
 		render.JSON(w, r, spaces[0])
 	default:
-		g.logger.Error().Int("number", num).Msg("expected to find a single space but found more")
-		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "expected to find a single space but found more")
+		logger.Debug().Int("number", num).Msg("could not get drive: expected to find a single drive but fetched more")
+		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "could not get drive: expected to find a single drive but fetched more")
 		return
 	}
 }
@@ -185,28 +204,35 @@ func canCreateSpace(ctx context.Context, ownPersonalHome bool) bool {
 
 // CreateDrive creates a storage drive (space).
 func (g Graph) CreateDrive(w http.ResponseWriter, r *http.Request) {
+	logger := g.logger.SubloggerWithRequestID(r.Context())
+	logger.Info().Msg("calling create drive")
 	us, ok := ctxpkg.ContextGetUser(r.Context())
 	if !ok {
-		errorcode.GeneralException.Render(w, r, http.StatusUnauthorized, "invalid user")
+		logger.Debug().Msg("could not create drive: invalid user")
+		errorcode.NotAllowed.Render(w, r, http.StatusUnauthorized, "invalid user")
 		return
 	}
 
 	// TODO determine if the user tries to create his own personal space and pass that as a boolean
-	if !canCreateSpace(r.Context(), false) {
+	canCreateSpace := canCreateSpace(r.Context(), false)
+	if !canCreateSpace {
+		logger.Debug().Bool("cancreatespace", canCreateSpace).Msg("could not create drive: insufficient permissions")
 		// if the permission is not existing for the user in context we can assume we don't have it. Return 401.
-		errorcode.GeneralException.Render(w, r, http.StatusUnauthorized, "insufficient permissions to create a space.")
+		errorcode.NotAllowed.Render(w, r, http.StatusUnauthorized, "insufficient permissions to create a space.")
 		return
 	}
 
 	client := g.GetGatewayClient()
 	drive := libregraph.Drive{}
 	if err := json.NewDecoder(r.Body).Decode(&drive); err != nil {
-		errorcode.GeneralException.Render(w, r, http.StatusBadRequest, "invalid schema definition")
+		logger.Debug().Err(err).Interface("body", r.Body).Msg("could not create drive: invalid body schema definition")
+		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "invalid body schema definition")
 		return
 	}
 	spaceName := *drive.Name
 	if spaceName == "" {
-		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "invalid name")
+		logger.Debug().Str("name", spaceName).Msg("could not create drive: invalid name")
+		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "invalid name")
 		return
 	}
 
@@ -218,7 +244,8 @@ func (g Graph) CreateDrive(w http.ResponseWriter, r *http.Request) {
 	case "", "project":
 		driveType = "project"
 	default:
-		errorcode.GeneralException.Render(w, r, http.StatusBadRequest, fmt.Sprintf("drives of type %s cannot be created via this api", driveType))
+		logger.Debug().Str("type", driveType).Msg("could not create drive: drives of this type cannot be created via this api")
+		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "drives of this type cannot be created via this api")
 		return
 	}
 
@@ -242,25 +269,32 @@ func (g Graph) CreateDrive(w http.ResponseWriter, r *http.Request) {
 
 	resp, err := client.CreateStorageSpace(r.Context(), &csr)
 	if err != nil {
+		logger.Error().Err(err).Msg("could not create drive: transport error")
 		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
 		return
 	}
 
 	if resp.GetStatus().GetCode() != cs3rpc.Code_CODE_OK {
-		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "")
+		if resp.GetStatus().GetCode() == cs3rpc.Code_CODE_PERMISSION_DENIED {
+			logger.Debug().Str("grpcmessage", resp.GetStatus().GetMessage()).Msg("could not create drive: permission denied")
+			errorcode.NotAllowed.Render(w, r, http.StatusForbidden, "permission denied")
+			return
+		}
+		logger.Debug().Interface("grpcmessage", csr).Str("grpc", resp.GetStatus().GetMessage()).Msg("could not create drive: grpc error")
+		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, resp.GetStatus().GetMessage())
 		return
 	}
 
-	wdu, err := url.Parse(g.config.Spaces.WebDavBase + g.config.Spaces.WebDavPath)
+	webDavBaseURL, err := g.getWebDavBaseURL()
 	if err != nil {
-		g.logger.Error().Err(err).Msg("error parsing url")
+		logger.Error().Str("url", webDavBaseURL.String()).Err(err).Msg("could not create drive: error parsing webdav base url")
 		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
 		return
 	}
 
-	newDrive, err := g.cs3StorageSpaceToDrive(r.Context(), wdu, resp.StorageSpace)
+	newDrive, err := g.cs3StorageSpaceToDrive(r.Context(), webDavBaseURL, resp.StorageSpace)
 	if err != nil {
-		g.logger.Error().Err(err).Msg("error parsing space")
+		logger.Debug().Err(err).Msg("could not create drive: error parsing drive")
 		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
 		return
 	}
@@ -269,20 +303,25 @@ func (g Graph) CreateDrive(w http.ResponseWriter, r *http.Request) {
 }
 
 func (g Graph) UpdateDrive(w http.ResponseWriter, r *http.Request) {
+	logger := g.logger.SubloggerWithRequestID(r.Context())
+	logger.Info().Msg("calling update drive")
 	driveID, err := url.PathUnescape(chi.URLParam(r, "driveID"))
 	if err != nil {
+		logger.Debug().Err(err).Str("id", chi.URLParam(r, "driveID")).Msg("could not update drive, unescaping drive id failed")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "unescaping drive id failed")
 		return
 	}
 
 	if driveID == "" {
+		logger.Debug().Msg("Could not update drive, missing drive id")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing drive id")
 		return
 	}
 
 	drive := libregraph.Drive{}
 	if err = json.NewDecoder(r.Body).Decode(&drive); err != nil {
-		errorcode.GeneralException.Render(w, r, http.StatusBadRequest, fmt.Sprintf("invalid request body: %v", r.Body))
+		logger.Debug().Err(err).Interface("body", r.Body).Msg("could not update drive, invalid request body")
+		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, fmt.Sprintf("invalid request body: error: %v", err.Error()))
 		return
 	}
 
@@ -290,7 +329,8 @@ func (g Graph) UpdateDrive(w http.ResponseWriter, r *http.Request) {
 
 	rid, err := storagespace.ParseID(driveID)
 	if err != nil {
-		errorcode.GeneralException.Render(w, r, http.StatusBadRequest, fmt.Sprintf("invalid resource id: %v", rid))
+		logger.Debug().Err(err).Interface("id", rid).Msg("could not update drive, invalid resource id")
+		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "invalid resource id")
 		w.WriteHeader(http.StatusInternalServerError)
 		return
 	}
@@ -343,11 +383,15 @@ func (g Graph) UpdateDrive(w http.ResponseWriter, r *http.Request) {
 		user := ctxpkg.ContextMustGetUser(r.Context())
 		canSetSpaceQuota, err := canSetSpaceQuota(r.Context(), user)
 		if err != nil {
+			logger.Error().Err(err).Msg("could not update drive: failed to check if the user can set space quota")
 			errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
 			return
 		}
 		if !canSetSpaceQuota {
-			errorcode.GeneralException.Render(w, r, http.StatusUnauthorized, "user is not allowed to set the space quota")
+			logger.Debug().
+				Bool("cansetspacequota", canSetSpaceQuota).
+				Msg("could not update drive: user is not allowed to set the space quota")
+			errorcode.NotAllowed.Render(w, r, http.StatusUnauthorized, "user is not allowed to set the space quota")
 			return
 		}
 		updateSpaceRequest.StorageSpace.Quota = &storageprovider.Quota{
@@ -355,36 +399,41 @@ func (g Graph) UpdateDrive(w http.ResponseWriter, r *http.Request) {
 		}
 	}
 
+	logger.Debug().Interface("payload", updateSpaceRequest).Msg("calling update space on backend")
 	resp, err := client.UpdateStorageSpace(r.Context(), updateSpaceRequest)
 	if err != nil {
-		w.WriteHeader(http.StatusInternalServerError)
+		logger.Error().Err(err).Msg("could not update drive: transport error")
+		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "transport error")
 		return
 	}
 
 	if resp.GetStatus().GetCode() != cs3rpc.Code_CODE_OK {
 		switch resp.Status.GetCode() {
 		case cs3rpc.Code_CODE_NOT_FOUND:
+			logger.Debug().Interface("id", rid).Msg("could not update drive: drive not found")
 			errorcode.ItemNotFound.Render(w, r, http.StatusNotFound, resp.GetStatus().GetMessage())
 			return
 		case cs3rpc.Code_CODE_PERMISSION_DENIED:
+			logger.Debug().Interface("id", rid).Msg("could not update drive, permission denied")
 			errorcode.NotAllowed.Render(w, r, http.StatusForbidden, resp.GetStatus().GetMessage())
 			return
 		default:
+			logger.Debug().Interface("id", rid).Str("grpc", resp.GetStatus().GetMessage()).Msg("could not update drive: grpc error")
 			errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, resp.GetStatus().GetMessage())
 			return
 		}
 	}
 
-	wdu, err := url.Parse(g.config.Spaces.WebDavBase + g.config.Spaces.WebDavPath)
+	webDavBaseURL, err := g.getWebDavBaseURL()
 	if err != nil {
-		g.logger.Error().Err(err).Msg("error parsing url")
+		logger.Error().Err(err).Interface("url", webDavBaseURL.String()).Msg("could not update drive: error parsing url")
 		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
 		return
 	}
 
-	spaces, err := g.formatDrives(r.Context(), wdu, []*storageprovider.StorageSpace{resp.StorageSpace})
+	spaces, err := g.formatDrives(r.Context(), webDavBaseURL, []*storageprovider.StorageSpace{resp.StorageSpace})
 	if err != nil {
-		g.logger.Error().Err(err).Msg("error parsing space")
+		logger.Debug().Err(err).Msg("could not update drive: error parsing grpc response")
 		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
 		return
 	}
@@ -452,8 +501,10 @@ func (g Graph) ListStorageSpacesWithFilters(ctx context.Context, filters []*stor
 }
 
 func (g Graph) cs3StorageSpaceToDrive(ctx context.Context, baseURL *url.URL, space *storageprovider.StorageSpace) (*libregraph.Drive, error) {
+	logger := g.logger.SubloggerWithRequestID(ctx)
 	if space.Root == nil {
-		return nil, fmt.Errorf("space has no root")
+		logger.Error().Msg("unable to parse space: space has no root")
+		return nil, errors.New("space has no root")
 	}
 	spaceRid := *space.Root
 	if space.Root.GetSpaceId() == space.Root.GetOpaqueId() {
@@ -468,10 +519,11 @@ func (g Graph) cs3StorageSpaceToDrive(ctx context.Context, baseURL *url.URL, spa
 		if ok {
 			err := json.Unmarshal(entry.Value, &m)
 			if err != nil {
-				g.logger.Error().
+				logger.Debug().
 					Err(err).
-					Str("space", space.Root.OpaqueId).
-					Msg("failed to read spaces grants")
+					Interface("space", space.Root).
+					Bytes("grants", entry.Value).
+					Msg("unable to parse space: failed to read spaces grants")
 			}
 		}
 		if len(m) != 0 {
@@ -542,7 +594,7 @@ func (g Graph) cs3StorageSpaceToDrive(ctx context.Context, baseURL *url.URL, spa
 			var err error
 			remoteItem, err = g.getRemoteItem(ctx, &grantID, baseURL)
 			if err != nil {
-				g.logger.Debug().Err(err).Msg(err.Error())
+				logger.Debug().Err(err).Interface("id", grantID).Msg("could not fetch remote item for space, continue")
 			}
 		}
 		if remoteItem != nil {
@@ -578,10 +630,10 @@ func (g Graph) cs3StorageSpaceToDrive(ctx context.Context, baseURL *url.URL, spa
 
 	webURL, err := url.Parse(g.config.Spaces.WebDavBase)
 	if err != nil {
-		g.logger.Error().
+		logger.Error().
 			Err(err).
 			Str("url", g.config.Spaces.WebDavBase).
-			Msg("failed to parse base url")
+			Msg("failed to parse webURL base url")
 		return nil, err
 	}
 
@@ -616,6 +668,7 @@ func (g Graph) cs3StorageSpaceToDrive(ctx context.Context, baseURL *url.URL, spa
 }
 
 func (g Graph) getDriveQuota(ctx context.Context, space *storageprovider.StorageSpace) (*libregraph.Quota, error) {
+	logger := g.logger.SubloggerWithRequestID(ctx)
 	client := g.GetGatewayClient()
 
 	req := &gateway.GetQuotaRequest{
@@ -627,13 +680,13 @@ func (g Graph) getDriveQuota(ctx context.Context, space *storageprovider.Storage
 	res, err := client.GetQuota(ctx, req)
 	switch {
 	case err != nil:
-		g.logger.Error().Err(err).Msg("could not call GetQuota")
+		logger.Error().Err(err).Interface("ref", req.Ref).Msg("could not call GetQuota: transport error")
 		return nil, nil
-	case res.Status.Code == cs3rpc.Code_CODE_UNIMPLEMENTED:
-		// TODO well duh
+	case res.GetStatus().GetCode() == cs3rpc.Code_CODE_UNIMPLEMENTED:
+		logger.Debug().Msg("get quota is not implemented on the storage driver")
 		return nil, nil
-	case res.Status.Code != cs3rpc.Code_CODE_OK:
-		g.logger.Error().Err(err).Msg("error sending get quota grpc request")
+	case res.GetStatus().GetCode() != cs3rpc.Code_CODE_OK:
+		logger.Debug().Str("grpc", res.GetStatus().GetMessage()).Msg("error sending get quota grpc request")
 		return nil, err
 	}
 
@@ -723,7 +776,7 @@ func generateCs3Filters(request *godata.GoDataRequest) ([]*storageprovider.ListS
 				filters = append(filters, listStorageSpacesIDFilter(strings.Trim(request.Query.Filter.Tree.Children[1].Token.Value, "'")))
 			}
 		} else {
-			err := fmt.Errorf("unsupported filter operand: %s", request.Query.Filter.Tree.Token.Value)
+			err := errors.Errorf("unsupported filter operand: %s", request.Query.Filter.Tree.Token.Value)
 			return nil, err
 		}
 	}
@@ -762,21 +815,25 @@ func listStorageSpacesTypeFilter(spaceType string) *storageprovider.ListStorageS
 }
 
 func (g Graph) DeleteDrive(w http.ResponseWriter, r *http.Request) {
+	logger := g.logger.SubloggerWithRequestID(r.Context())
+	logger.Info().Msg("calling delete drive")
 	driveID, err := url.PathUnescape(chi.URLParam(r, "driveID"))
 	if err != nil {
+		logger.Debug().Err(err).Str("id", chi.URLParam(r, "driveID")).Msg("could not delete drive: unescaping drive id failed")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "unescaping drive id failed")
 		return
 	}
 
 	if driveID == "" {
+		logger.Debug().Msg("could not delete drive: missing drive id")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing drive id")
 		return
 	}
 
 	rid, err := storagespace.ParseID(driveID)
 	if err != nil {
-		errorcode.GeneralException.Render(w, r, http.StatusBadRequest, fmt.Sprintf("invalid resource id: %v", rid))
-		w.WriteHeader(http.StatusInternalServerError)
+		logger.Debug().Interface("id", rid).Err(err).Msg("could not delete drive: invalid resource id")
+		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "invalid resource id")
 		return
 	}
 
@@ -798,8 +855,8 @@ func (g Graph) DeleteDrive(w http.ResponseWriter, r *http.Request) {
 		},
 	})
 	if err != nil {
-		g.logger.Error().Err(err).Msg("error deleting storage space")
-		w.WriteHeader(http.StatusInternalServerError)
+		logger.Error().Err(err).Interface("id", rid).Msg("could not delete drive: transport error")
+		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "transport error")
 		return
 	}
 
@@ -808,16 +865,17 @@ func (g Graph) DeleteDrive(w http.ResponseWriter, r *http.Request) {
 		w.WriteHeader(http.StatusNoContent)
 		return
 	case cs3rpc.Code_CODE_INVALID_ARGUMENT:
-		errorcode.GeneralException.Render(w, r, http.StatusBadRequest, dRes.Status.Message)
-		w.WriteHeader(http.StatusBadRequest)
+		logger.Debug().Interface("id", rid).Str("grpc", dRes.GetStatus().GetMessage()).Msg("could not delete drive: invalid argument")
+		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, dRes.Status.Message)
 		return
 	case cs3rpc.Code_CODE_PERMISSION_DENIED:
-		w.WriteHeader(http.StatusForbidden)
+		logger.Debug().Interface("id", rid).Msg("could not delete drive: permission denied")
+		errorcode.NotAllowed.Render(w, r, http.StatusForbidden, "permission denied to delete drive")
 		return
 	// don't expose internal error codes to the outside world
 	default:
-		g.logger.Error().Err(err).Msg("error deleting storage space")
-		w.WriteHeader(http.StatusInternalServerError)
+		logger.Debug().Str("grpc", dRes.GetStatus().GetMessage()).Interface("id", rid).Msg("could not delete drive: grpc error")
+		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "grpc error")
 		return
 	}
 
@@ -834,7 +892,7 @@ func sortSpaces(req *godata.GoDataRequest, spaces []*libregraph.Drive) ([]*libre
 	case "lastModifiedDateTime":
 		sorter = spacesByLastModifiedDateTime{spaces}
 	default:
-		return nil, fmt.Errorf("we do not support <%s> as a order parameter", req.Query.OrderBy.OrderByItems[0].Field.Value)
+		return nil, errors.Errorf("we do not support <%s> as a order parameter", req.Query.OrderBy.OrderByItems[0].Field.Value)
 	}
 
 	if req.Query.OrderBy.OrderByItems[0].Order == "desc" {
diff --git a/services/graph/pkg/service/v0/errorcode/errorcode.go b/services/graph/pkg/service/v0/errorcode/errorcode.go
index b39a7004601..28887c8a507 100644
--- a/services/graph/pkg/service/v0/errorcode/errorcode.go
+++ b/services/graph/pkg/service/v0/errorcode/errorcode.go
@@ -50,6 +50,8 @@ const (
 	QuotaLimitReached
 	// Unauthenticated the caller is not authenticated.
 	Unauthenticated
+	// PreconditionFailed the request cannot be made and this error response is sent back
+	PreconditionFailed
 )
 
 var errorCodes = [...]string{
@@ -69,6 +71,7 @@ var errorCodes = [...]string{
 	"serviceNotAvailable",
 	"quotaLimitReached",
 	"unauthenticated",
+	"preconditionFailed",
 }
 
 func New(e ErrorCode, msg string) Error {
@@ -82,7 +85,6 @@ func New(e ErrorCode, msg string) Error {
 func (e ErrorCode) Render(w http.ResponseWriter, r *http.Request, status int, msg string) {
 	innererror := map[string]interface{}{
 		"date": time.Now().UTC().Format(time.RFC3339),
-		// TODO return client-request-id?
 	}
 
 	innererror["request-id"] = middleware.GetReqID(r.Context())
diff --git a/services/graph/pkg/service/v0/graph.go b/services/graph/pkg/service/v0/graph.go
index 02112ce4981..45f6ab68a78 100644
--- a/services/graph/pkg/service/v0/graph.go
+++ b/services/graph/pkg/service/v0/graph.go
@@ -3,6 +3,8 @@ package svc
 import (
 	"context"
 	"net/http"
+	"net/url"
+	"path"
 
 	gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
 	provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
@@ -100,14 +102,20 @@ func (g Graph) publishEvent(ev interface{}) {
 	}
 }
 
+func (g Graph) getWebDavBaseURL() (*url.URL, error) {
+	webDavBaseURL, err := url.Parse(g.config.Spaces.WebDavBase)
+	if err != nil {
+		return nil, err
+	}
+	webDavBaseURL.Path = path.Join(webDavBaseURL.Path, g.config.Spaces.WebDavPath)
+	return webDavBaseURL, nil
+}
+
 type listResponse struct {
 	Value interface{} `json:"value,omitempty"`
 }
 
 const (
-	NoSpaceFoundMessage           = "space with id `%s` not found"
-	ListStorageSpacesTransportErr = "transport error sending list storage spaces grpc request"
-	ListStorageSpacesReturnsErr   = "list storage spaces grpc request returns an errorcode in the response"
-	ReadmeSpecialFolderName       = "readme"
-	SpaceImageSpecialFolderName   = "image"
+	ReadmeSpecialFolderName     = "readme"
+	SpaceImageSpecialFolderName = "image"
 )
diff --git a/services/graph/pkg/service/v0/groups.go b/services/graph/pkg/service/v0/groups.go
index 8afdf65a014..48c657b73ed 100644
--- a/services/graph/pkg/service/v0/groups.go
+++ b/services/graph/pkg/service/v0/groups.go
@@ -23,17 +23,19 @@ const memberRefsLimit = 20
 
 // GetGroups implements the Service interface.
 func (g Graph) GetGroups(w http.ResponseWriter, r *http.Request) {
+	logger := g.logger.SubloggerWithRequestID(r.Context())
+	logger.Info().Interface("query", r.URL.Query()).Msg("calling get groups")
 	sanitizedPath := strings.TrimPrefix(r.URL.Path, "/graph/v1.0/")
 	odataReq, err := godata.ParseRequest(r.Context(), sanitizedPath, r.URL.Query())
 	if err != nil {
-		g.logger.Err(err).Interface("query", r.URL.Query()).Msg("query error")
+		logger.Debug().Err(err).Interface("query", r.URL.Query()).Msg("could not get groups: query error")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
 		return
 	}
 
 	groups, err := g.identityBackend.GetGroups(r.Context(), r.URL.Query())
-
 	if err != nil {
+		logger.Debug().Err(err).Msg("could not get groups: backend error")
 		var errcode errorcode.Error
 		if errors.As(err, &errcode) {
 			errcode.Render(w, r)
@@ -44,12 +46,8 @@ func (g Graph) GetGroups(w http.ResponseWriter, r *http.Request) {
 
 	groups, err = sortGroups(odataReq, groups)
 	if err != nil {
-		var errcode errorcode.Error
-		if errors.As(err, &errcode) {
-			errcode.Render(w, r)
-		} else {
-			errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
-		}
+		logger.Debug().Err(err).Interface("query", r.URL.Query()).Msg("cannot get groups: could not sort groups according to query")
+		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
 		return
 	}
 	render.Status(r, http.StatusOK)
@@ -58,14 +56,18 @@ func (g Graph) GetGroups(w http.ResponseWriter, r *http.Request) {
 
 // PostGroup implements the Service interface.
 func (g Graph) PostGroup(w http.ResponseWriter, r *http.Request) {
+	logger := g.logger.SubloggerWithRequestID(r.Context())
+	logger.Info().Msg("calling post group")
 	grp := libregraph.NewGroup()
 	err := json.NewDecoder(r.Body).Decode(grp)
 	if err != nil {
-		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
+		logger.Debug().Err(err).Interface("body", r.Body).Msg("could not create group: invalid request body")
+		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, fmt.Sprintf("invalid request body: %s", err.Error()))
 		return
 	}
 
 	if _, ok := grp.GetDisplayNameOk(); !ok {
+		logger.Debug().Err(err).Interface("group", grp).Msg("could not create group: missing required attribute")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "Missing Required Attribute")
 		return
 	}
@@ -74,11 +76,13 @@ func (g Graph) PostGroup(w http.ResponseWriter, r *http.Request) {
 	// generating them in the backend ourselves or rely on the Backend's
 	// storage (e.g. LDAP) to provide a unique ID.
 	if _, ok := grp.GetIdOk(); ok {
+		logger.Debug().Msg("could not create group: id is a read-only attribute")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "group id is a read-only attribute")
 		return
 	}
 
 	if grp, err = g.identityBackend.CreateGroup(r.Context(), *grp); err != nil {
+		logger.Debug().Interface("group", grp).Msg("could not create group: backend error")
 		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
 		return
 	}
@@ -93,29 +97,37 @@ func (g Graph) PostGroup(w http.ResponseWriter, r *http.Request) {
 
 // PatchGroup implements the Service interface.
 func (g Graph) PatchGroup(w http.ResponseWriter, r *http.Request) {
-	g.logger.Debug().Msg("Calling PatchGroup")
+	logger := g.logger.SubloggerWithRequestID(r.Context())
+	logger.Info().Msg("calling patch group")
 	groupID := chi.URLParam(r, "groupID")
 	groupID, err := url.PathUnescape(groupID)
 	if err != nil {
+		logger.Debug().Str("id", groupID).Msg("could not change group: unescaping group id failed")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "unescaping group id failed")
 		return
 	}
 
 	if groupID == "" {
+		logger.Debug().Msg("could not change group: missing group id")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing group id")
 		return
 	}
 	changes := libregraph.NewGroup()
 	err = json.NewDecoder(r.Body).Decode(changes)
 	if err != nil {
-		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
+		logger.Debug().Err(err).Interface("body", r.Body).Msg("could not change group: invalid request body")
+		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, fmt.Sprintf("invalid request body: %s", err.Error()))
 		return
 	}
 
 	if memberRefs, ok := changes.GetMembersodataBindOk(); ok {
 		// The spec defines a limit of 20 members maxium per Request
 		if len(memberRefs) > memberRefsLimit {
-			errorcode.NotAllowed.Render(w, r, http.StatusInternalServerError,
+			logger.Debug().
+				Int("number", len(memberRefs)).
+				Int("limit", memberRefsLimit).
+				Msg("could not create group, exceeded members limit")
+			errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest,
 				fmt.Sprintf("Request is limited to %d members", memberRefsLimit))
 			return
 		}
@@ -123,14 +135,20 @@ func (g Graph) PatchGroup(w http.ResponseWriter, r *http.Request) {
 		for _, memberRef := range memberRefs {
 			memberType, id, err := g.parseMemberRef(memberRef)
 			if err != nil {
-				errorcode.InvalidRequest.Render(w, r, http.StatusInternalServerError, "Error parsing member@odata.bind values")
+				logger.Debug().
+					Str("memberref", memberRef).
+					Msg("could not change group: Error parsing member@odata.bind values")
+				errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "Error parsing member@odata.bind values")
 				return
 			}
-			g.logger.Debug().Str("memberType", memberType).Str("memberid", id).Msg("Add Member")
+			logger.Debug().Str("membertype", memberType).Str("memberid", id).Msg("add group member")
 			// The MS Graph spec allows "directoryObject", "user", "group" and "organizational Contact"
 			// we restrict this to users for now. Might add Groups as members later
 			if memberType != "users" {
-				errorcode.InvalidRequest.Render(w, r, http.StatusInternalServerError, "Only user are allowed as group members")
+				logger.Debug().
+					Str("type", memberType).
+					Msg("could not change group: could not add member, only user type is allowed")
+				errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "Only user are allowed as group members")
 				return
 			}
 			memberIDs = append(memberIDs, id)
@@ -139,6 +157,7 @@ func (g Graph) PatchGroup(w http.ResponseWriter, r *http.Request) {
 	}
 
 	if err != nil {
+		logger.Debug().Err(err).Msg("could not change group: backend could not add members")
 		var errcode errorcode.Error
 		if errors.As(err, &errcode) {
 			errcode.Render(w, r)
@@ -153,19 +172,28 @@ func (g Graph) PatchGroup(w http.ResponseWriter, r *http.Request) {
 
 // GetGroup implements the Service interface.
 func (g Graph) GetGroup(w http.ResponseWriter, r *http.Request) {
+	logger := g.logger.SubloggerWithRequestID(r.Context())
+	logger.Info().Msg("calling get group")
 	groupID := chi.URLParam(r, "groupID")
 	groupID, err := url.PathUnescape(groupID)
 	if err != nil {
+		logger.Debug().Str("id", groupID).Msg("could not get group: unescaping group id failed")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "unescaping group id failed")
 	}
 
 	if groupID == "" {
+		logger.Debug().Msg("could not get group: missing group id")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing group id")
 		return
 	}
 
+	logger.Debug().
+		Str("id", groupID).
+		Interface("query", r.URL.Query()).
+		Msg("calling get group on backend")
 	group, err := g.identityBackend.GetGroup(r.Context(), groupID, r.URL.Query())
 	if err != nil {
+		logger.Debug().Err(err).Msg("could not get group: backend error")
 		var errcode errorcode.Error
 		if errors.As(err, &errcode) {
 			errcode.Render(w, r)
@@ -180,21 +208,27 @@ func (g Graph) GetGroup(w http.ResponseWriter, r *http.Request) {
 
 // DeleteGroup implements the Service interface.
 func (g Graph) DeleteGroup(w http.ResponseWriter, r *http.Request) {
+	logger := g.logger.SubloggerWithRequestID(r.Context())
+	logger.Info().Msg("calling delete group")
 	groupID := chi.URLParam(r, "groupID")
 	groupID, err := url.PathUnescape(groupID)
 	if err != nil {
+		logger.Debug().Err(err).Str("id", groupID).Msg("could not delete group: unescaping group id failed")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "unescaping group id failed")
 		return
 	}
 
 	if groupID == "" {
+		logger.Debug().Msg("could not delete group: missing group id")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing group id")
 		return
 	}
 
+	logger.Debug().Str("id", groupID).Msg("calling delete group on backend")
 	err = g.identityBackend.DeleteGroup(r.Context(), groupID)
 
 	if err != nil {
+		logger.Debug().Err(err).Msg("could not delete group: backend error")
 		var errcode errorcode.Error
 		if errors.As(err, &errcode) {
 			errcode.Render(w, r)
@@ -211,20 +245,26 @@ func (g Graph) DeleteGroup(w http.ResponseWriter, r *http.Request) {
 }
 
 func (g Graph) GetGroupMembers(w http.ResponseWriter, r *http.Request) {
+	logger := g.logger.SubloggerWithRequestID(r.Context())
+	logger.Info().Msg("calling get group members")
 	groupID := chi.URLParam(r, "groupID")
 	groupID, err := url.PathUnescape(groupID)
 	if err != nil {
+		logger.Debug().Str("id", groupID).Msg("could not get group members: unescaping group id failed")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "unescaping group id failed")
 		return
 	}
 
 	if groupID == "" {
+		logger.Debug().Msg("could not get group members: missing group id")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing group id")
 		return
 	}
 
+	logger.Debug().Str("id", groupID).Msg("calling get group members on backend")
 	members, err := g.identityBackend.GetGroupMembers(r.Context(), groupID)
 	if err != nil {
+		logger.Debug().Err(err).Msg("could not get group members: backend error")
 		var errcode errorcode.Error
 		if errors.As(err, &errcode) {
 			errcode.Render(w, r)
@@ -240,46 +280,60 @@ func (g Graph) GetGroupMembers(w http.ResponseWriter, r *http.Request) {
 
 // PostGroupMember implements the Service interface.
 func (g Graph) PostGroupMember(w http.ResponseWriter, r *http.Request) {
-	g.logger.Info().Msg("Calling PostGroupMember")
+	logger := g.logger.SubloggerWithRequestID(r.Context())
+	logger.Info().Msg("Calling post group member")
 
 	groupID := chi.URLParam(r, "groupID")
 	groupID, err := url.PathUnescape(groupID)
 	if err != nil {
+		logger.Debug().
+			Err(err).
+			Str("id", groupID).
+			Msg("could not add member to group: unescaping group id failed")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "unescaping group id failed")
 		return
 	}
 
 	if groupID == "" {
+		logger.Debug().Msg("could not add group member: missing group id")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing group id")
 		return
 	}
 	memberRef := libregraph.NewMemberReference()
 	err = json.NewDecoder(r.Body).Decode(memberRef)
 	if err != nil {
-		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
+		logger.Debug().
+			Err(err).
+			Interface("body", r.Body).
+			Msg("could not add group member: invalid request body")
+		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, fmt.Sprintf("invalid request body: %s", err.Error()))
 		return
 	}
 	memberRefURL, ok := memberRef.GetOdataIdOk()
 	if !ok {
-		errorcode.InvalidRequest.Render(w, r, http.StatusInternalServerError, "@odata.id refernce is missing")
+		logger.Debug().Msg("could not add group member: @odata.id reference is missing")
+		errorcode.InvalidRequest.Render(w, r, http.StatusInternalServerError, "@odata.id reference is missing")
 		return
 	}
 	memberType, id, err := g.parseMemberRef(*memberRefURL)
 	if err != nil {
+		logger.Debug().Err(err).Msg("could not add group member: error parsing @odata.id url")
 		errorcode.InvalidRequest.Render(w, r, http.StatusInternalServerError, "Error parsing @odata.id url")
 		return
 	}
 	// The MS Graph spec allows "directoryObject", "user", "group" and "organizational Contact"
 	// we restrict this to users for now. Might add Groups as members later
 	if memberType != "users" {
-		errorcode.InvalidRequest.Render(w, r, http.StatusInternalServerError, "Only user are allowed as group members")
+		logger.Debug().Str("type", memberType).Msg("could not add group member: Only users are allowed as group members")
+		errorcode.InvalidRequest.Render(w, r, http.StatusInternalServerError, "Only users are allowed as group members")
 		return
 	}
 
-	g.logger.Debug().Str("memberType", memberType).Str("id", id).Msg("Add Member")
+	logger.Debug().Str("memberType", memberType).Str("id", id).Msg("calling add member on backend")
 	err = g.identityBackend.AddMembersToGroup(r.Context(), groupID, []string{id})
 
 	if err != nil {
+		logger.Debug().Err(err).Msg("could not add group member: backend error")
 		var errcode errorcode.Error
 		if errors.As(err, &errcode) {
 			errcode.Render(w, r)
@@ -297,16 +351,19 @@ func (g Graph) PostGroupMember(w http.ResponseWriter, r *http.Request) {
 
 // DeleteGroupMember implements the Service interface.
 func (g Graph) DeleteGroupMember(w http.ResponseWriter, r *http.Request) {
-	g.logger.Info().Msg("Calling DeleteGroupMember")
+	logger := g.logger.SubloggerWithRequestID(r.Context())
+	logger.Info().Msg("calling delete group member")
 
 	groupID := chi.URLParam(r, "groupID")
 	groupID, err := url.PathUnescape(groupID)
 	if err != nil {
+		logger.Debug().Err(err).Str("id", groupID).Msg("could not delete group member: unescaping group id failed")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "unescaping group id failed")
 		return
 	}
 
 	if groupID == "" {
+		logger.Debug().Msg("could not delete group member: missing group id")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing group id")
 		return
 	}
@@ -314,18 +371,21 @@ func (g Graph) DeleteGroupMember(w http.ResponseWriter, r *http.Request) {
 	memberID := chi.URLParam(r, "memberID")
 	memberID, err = url.PathUnescape(memberID)
 	if err != nil {
+		logger.Debug().Err(err).Str("id", memberID).Msg("could not delete group member: unescaping group id failed")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "unescaping group id failed")
 		return
 	}
 
 	if memberID == "" {
+		logger.Debug().Msg("could not delete group member: missing group id")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing group id")
 		return
 	}
-	g.logger.Debug().Str("groupID", groupID).Str("memberID", memberID).Msg("DeleteGroupMember")
+	logger.Debug().Str("groupID", groupID).Str("memberID", memberID).Msg("calling delete member on backend")
 	err = g.identityBackend.RemoveMemberFromGroup(r.Context(), groupID, memberID)
 
 	if err != nil {
+		logger.Debug().Err(err).Msg("could not delete group member: backend error")
 		var errcode errorcode.Error
 		if errors.As(err, &errcode) {
 			errcode.Render(w, r)
diff --git a/services/graph/pkg/service/v0/users.go b/services/graph/pkg/service/v0/users.go
index 0efcf0f92b7..82521085aa7 100644
--- a/services/graph/pkg/service/v0/users.go
+++ b/services/graph/pkg/service/v0/users.go
@@ -30,15 +30,15 @@ import (
 
 // GetMe implements the Service interface.
 func (g Graph) GetMe(w http.ResponseWriter, r *http.Request) {
+	logger := g.logger.SubloggerWithRequestID(r.Context())
+	logger.Info().Msg("calling get user in /me")
 
 	u, ok := revactx.ContextGetUser(r.Context())
 	if !ok {
-		g.logger.Error().Msg("user not in context")
-		errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, "user not in context")
+		logger.Debug().Msg("could not get user: user not in context")
+		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "user not in context")
 		return
 	}
-
-	g.logger.Info().Interface("user", u).Msg("User in /me")
 	exp := strings.Split(r.URL.Query().Get("$expand"), ",")
 	var me *libregraph.User
 	// We can just return the user from context unless we need to expand the group memberships
@@ -46,8 +46,10 @@ func (g Graph) GetMe(w http.ResponseWriter, r *http.Request) {
 		me = identity.CreateUserModelFromCS3(u)
 	} else {
 		var err error
+		logger.Debug().Msg("calling get user on backend")
 		me, err = g.identityBackend.GetUser(r.Context(), u.GetId().GetOpaqueId(), r.URL.Query())
 		if err != nil {
+			logger.Debug().Err(err).Interface("user", u).Msg("could not get user from backend")
 			var errcode errorcode.Error
 			if errors.As(err, &errcode) {
 				errcode.Render(w, r)
@@ -63,15 +65,20 @@ func (g Graph) GetMe(w http.ResponseWriter, r *http.Request) {
 
 // GetUsers implements the Service interface.
 func (g Graph) GetUsers(w http.ResponseWriter, r *http.Request) {
+	logger := g.logger.SubloggerWithRequestID(r.Context())
+	logger.Info().Interface("query", r.URL.Query()).Msg("calling get users")
 	sanitizedPath := strings.TrimPrefix(r.URL.Path, "/graph/v1.0/")
 	odataReq, err := godata.ParseRequest(r.Context(), sanitizedPath, r.URL.Query())
 	if err != nil {
-		g.logger.Err(err).Interface("query", r.URL.Query()).Msg("query error")
+		logger.Debug().Err(err).Interface("query", r.URL.Query()).Msg("could not get users: query error")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
 		return
 	}
+
+	logger.Debug().Interface("query", r.URL.Query()).Msg("calling get users on backend")
 	users, err := g.identityBackend.GetUsers(r.Context(), r.URL.Query())
 	if err != nil {
+		logger.Debug().Err(err).Interface("query", r.URL.Query()).Msg("could not get users from backend")
 		var errcode errorcode.Error
 		if errors.As(err, &errcode) {
 			errcode.Render(w, r)
@@ -83,12 +90,8 @@ func (g Graph) GetUsers(w http.ResponseWriter, r *http.Request) {
 
 	users, err = sortUsers(odataReq, users)
 	if err != nil {
-		var errcode errorcode.Error
-		if errors.As(err, &errcode) {
-			errcode.Render(w, r)
-		} else {
-			errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
-		}
+		logger.Debug().Interface("query", odataReq).Msg("error while sorting users according to query")
+		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
 		return
 	}
 	render.Status(r, http.StatusOK)
@@ -96,35 +99,41 @@ func (g Graph) GetUsers(w http.ResponseWriter, r *http.Request) {
 }
 
 func (g Graph) PostUser(w http.ResponseWriter, r *http.Request) {
+	logger := g.logger.SubloggerWithRequestID(r.Context())
+	logger.Info().Interface("body", r.Body).Msg("calling create user")
 	u := libregraph.NewUser()
 	err := json.NewDecoder(r.Body).Decode(u)
 	if err != nil {
-		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
+		logger.Debug().Err(err).Interface("body", r.Body).Msg("could not create user: invalid request body")
+		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, fmt.Sprintf("invalid request body: %v", err.Error()))
 		return
 	}
 
 	if _, ok := u.GetDisplayNameOk(); !ok {
+		logger.Debug().Err(err).Interface("user", u).Msg("could not create user: missing required Attribute: 'displayName'")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing required Attribute: 'displayName'")
 		return
 	}
 	if accountName, ok := u.GetOnPremisesSamAccountNameOk(); ok {
 		if !isValidUsername(*accountName) {
-			errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest,
-				fmt.Sprintf("username '%s' must be at least the local part of an email", *u.OnPremisesSamAccountName))
+			logger.Debug().Str("username", *accountName).Msg("could not create user: username must be at least the local part of an email")
+			errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, fmt.Sprintf("username %s must be at least the local part of an email", *u.OnPremisesSamAccountName))
 			return
 		}
 	} else {
+		logger.Debug().Interface("user", u).Msg("could not create user: missing required Attribute: 'onPremisesSamAccountName'")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing required Attribute: 'onPremisesSamAccountName'")
 		return
 	}
 
 	if mail, ok := u.GetMailOk(); ok {
 		if !isValidEmail(*mail) {
-			errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest,
-				fmt.Sprintf("'%s' is not a valid email address", *u.Mail))
+			logger.Debug().Str("mail", *u.Mail).Msg("could not create user: invalid email address")
+			errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, fmt.Sprintf("%v is not a valid email address", *u.Mail))
 			return
 		}
 	} else {
+		logger.Debug().Interface("user", u).Msg("could not create user: missing required Attribute: 'mail'")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing required Attribute: 'mail'")
 		return
 	}
@@ -133,11 +142,14 @@ func (g Graph) PostUser(w http.ResponseWriter, r *http.Request) {
 	// generating them in the backend ourselves or rely on the Backend's
 	// storage (e.g. LDAP) to provide a unique ID.
 	if _, ok := u.GetIdOk(); ok {
+		logger.Debug().Interface("user", u).Msg("could not create user: user id is a read-only attribute")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "user id is a read-only attribute")
 		return
 	}
 
+	logger.Debug().Interface("user", u).Msg("calling create user on backend")
 	if u, err = g.identityBackend.CreateUser(r.Context(), *u); err != nil {
+		logger.Debug().Err(err).Msg("could not create user: backend error")
 		var ecErr errorcode.Error
 		if errors.As(err, &ecErr) {
 			ecErr.Render(w, r)
@@ -150,6 +162,8 @@ func (g Graph) PostUser(w http.ResponseWriter, r *http.Request) {
 	// All users get the user role by default currently.
 	// to all new users for now, as create Account request does not have any role field
 	if g.roleService == nil {
+		// log as error, admin needs to do something about it
+		logger.Error().Str("id", *u.Id).Msg("could not create user: role service not configured")
 		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "could not assign role to account: roleService not configured")
 		return
 	}
@@ -157,7 +171,9 @@ func (g Graph) PostUser(w http.ResponseWriter, r *http.Request) {
 		AccountUuid: *u.Id,
 		RoleId:      settingssvc.BundleUUIDRoleUser,
 	}); err != nil {
-		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, fmt.Sprintf("could not assign role to account %s", err.Error()))
+		// log as error, admin eventually needs to do something
+		logger.Error().Err(err).Str("id", *u.Id).Str("role", settingssvc.BundleUUIDRoleUser).Msg("could not create user: role assignment failed")
+		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "role assignment failed")
 		return
 	}
 
@@ -170,21 +186,27 @@ func (g Graph) PostUser(w http.ResponseWriter, r *http.Request) {
 
 // GetUser implements the Service interface.
 func (g Graph) GetUser(w http.ResponseWriter, r *http.Request) {
+	logger := g.logger.SubloggerWithRequestID(r.Context())
+	logger.Info().Msg("calling get user")
 	userID := chi.URLParam(r, "userID")
 	userID, err := url.PathUnescape(userID)
 	if err != nil {
+		logger.Debug().Err(err).Str("id", userID).Msg("could not get user: unescaping user id failed")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "unescaping user id failed")
 		return
 	}
 
 	if userID == "" {
+		logger.Debug().Msg("could not get user: missing user id")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing user id")
 		return
 	}
 
+	logger.Debug().Str("id", userID).Msg("calling get user from backend")
 	user, err := g.identityBackend.GetUser(r.Context(), userID, r.URL.Query())
 
 	if err != nil {
+		logger.Debug().Err(err).Msg("could not get user: error fetching user from backend")
 		var errcode errorcode.Error
 		if errors.As(err, &errcode) {
 			errcode.Render(w, r)
@@ -196,15 +218,18 @@ func (g Graph) GetUser(w http.ResponseWriter, r *http.Request) {
 	sel := strings.Split(r.URL.Query().Get("$select"), ",")
 	exp := strings.Split(r.URL.Query().Get("$expand"), ",")
 	if slices.Contains(sel, "drive") || slices.Contains(sel, "drives") || slices.Contains(exp, "drive") || slices.Contains(exp, "drives") {
-		wdu, err := url.Parse(g.config.Spaces.WebDavBase + g.config.Spaces.WebDavPath)
+		wdu, err := g.getWebDavBaseURL()
 		if err != nil {
-			g.logger.Err(err).
+			// log error, wrong configuration
+			logger.Error().
+				Err(err).
 				Str("webdav_base", g.config.Spaces.WebDavBase).
 				Str("webdav_path", g.config.Spaces.WebDavPath).
 				Msg("error parsing webdav URL")
 			render.Status(r, http.StatusInternalServerError)
 			return
 		}
+		logger.Debug().Str("id", user.GetId()).Msg("calling list storage spaces with user id filter")
 		f := listStorageSpacesUserFilter(user.GetId())
 		// use the unrestricted flag to get all possible spaces
 		// users with the canListAllSpaces permission should see all spaces
@@ -214,12 +239,14 @@ func (g Graph) GetUser(w http.ResponseWriter, r *http.Request) {
 			Filters: []*storageprovider.ListStorageSpacesRequest_Filter{f},
 		})
 		if err != nil {
-			g.logger.Err(err).Interface("query", r.URL.Query()).Msg("error getting storages")
+			// transport error, needs to be fixed by admin
+			logger.Error().Err(err).Interface("query", r.URL.Query()).Msg("error getting storages: transport error")
 			render.Status(r, http.StatusInternalServerError)
 			render.JSON(w, r, user)
 			return
 		}
-		if lspr.Status.Code != cs3rpc.Code_CODE_OK {
+		if lspr.GetStatus().GetCode() != cs3rpc.Code_CODE_OK {
+			logger.Debug().Str("grpc", lspr.GetStatus().GetMessage()).Msg("could not get drive for user")
 			// in case of NOT_OK, we can just return the user object with empty drives
 			render.Status(r, status.HTTPStatusFromCode(http.StatusOK))
 			render.JSON(w, r, user)
@@ -229,11 +256,11 @@ func (g Graph) GetUser(w http.ResponseWriter, r *http.Request) {
 		for _, sp := range lspr.GetStorageSpaces() {
 			d, err := g.cs3StorageSpaceToDrive(r.Context(), wdu, sp)
 			if err != nil {
-				g.logger.Err(err).Interface("query", r.URL.Query()).Msg("error converting space to drive")
+				logger.Debug().Err(err).Interface("id", sp.Id).Msg("error converting space to drive")
 			}
 			quota, err := g.getDriveQuota(r.Context(), sp)
 			if err != nil {
-				g.logger.Err(err).Interface("query", r.URL.Query()).Msg("error calling get quota")
+				logger.Debug().Err(err).Interface("id", sp.Id).Msg("error calling get quota on drive")
 			}
 			d.Quota = quota
 			if slices.Contains(sel, "drive") || slices.Contains(exp, "drive") {
@@ -252,21 +279,25 @@ func (g Graph) GetUser(w http.ResponseWriter, r *http.Request) {
 }
 
 func (g Graph) DeleteUser(w http.ResponseWriter, r *http.Request) {
+	logger := g.logger.SubloggerWithRequestID(r.Context())
+	logger.Info().Msg("calling delete user")
 	userID := chi.URLParam(r, "userID")
 	userID, err := url.PathUnescape(userID)
 	if err != nil {
-		g.logger.Debug().Err(err).Msg("unescaping user id failed")
+		logger.Debug().Err(err).Str("id", userID).Msg("could not delete user: unescaping user id failed")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "unescaping user id failed")
 		return
 	}
 
 	if userID == "" {
+		logger.Debug().Msg("could not delete user: missing user id")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing user id")
 		return
 	}
+	logger.Debug().Str("id", userID).Msg("calling get user on user backend")
 	user, err := g.identityBackend.GetUser(r.Context(), userID, r.URL.Query())
 	if err != nil {
-		g.logger.Debug().Err(err).Str("userID", userID).Msg("failed to get user")
+		logger.Debug().Err(err).Str("userID", userID).Msg("failed to get user from backend")
 		var errcode errorcode.Error
 		if errors.As(err, &errcode) {
 			errcode.Render(w, r)
@@ -279,11 +310,14 @@ func (g Graph) DeleteUser(w http.ResponseWriter, r *http.Request) {
 	currentUser := ctxpkg.ContextMustGetUser(r.Context())
 
 	if currentUser.GetId().GetOpaqueId() == user.GetId() {
-		g.logger.Debug().Msg("self deletion forbidden")
+		logger.Debug().Msg("could not delete user: self deletion forbidden")
 		errorcode.NotAllowed.Render(w, r, http.StatusForbidden, "self deletion forbidden")
 		return
 	}
 
+	logger.Debug().
+		Str("user", user.GetId()).
+		Msg("calling list spaces with user filter to fetch the personal space for deletion")
 	opaque := utils.AppendPlainToOpaque(nil, "unrestricted", "T")
 	f := listStorageSpacesUserFilter(user.GetId())
 	lspr, err := g.gatewayClient.ListStorageSpaces(r.Context(), &storageprovider.ListStorageSpacesRequest{
@@ -291,8 +325,9 @@ func (g Graph) DeleteUser(w http.ResponseWriter, r *http.Request) {
 		Filters: []*storageprovider.ListStorageSpacesRequest_Filter{f},
 	})
 	if err != nil {
-		g.logger.Debug().Err(err).Msg("could not read spaces")
-		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "could not read spaces")
+		// transport error, log as error
+		logger.Error().Err(err).Msg("could not fetch spaces: transport error")
+		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "could not fetch spaces for deletion, aborting")
 		return
 	}
 	for _, sp := range lspr.GetStorageSpaces() {
@@ -312,8 +347,8 @@ func (g Graph) DeleteUser(w http.ResponseWriter, r *http.Request) {
 				},
 			})
 			if err != nil {
-				g.logger.Debug().Err(err).Msg("could not disable homespace")
-				errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "could not disable homespace")
+				logger.Error().Err(err).Msg("could not disable homespace: transport error")
+				errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "could not disable homespace, aborting")
 				return
 			}
 		}
@@ -325,16 +360,19 @@ func (g Graph) DeleteUser(w http.ResponseWriter, r *http.Request) {
 			},
 		})
 		if err != nil {
-			g.logger.Debug().Err(err).Msg("could not delete homespace")
-			errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "could not delete homespace")
+			// transport error, log as error
+			logger.Error().Err(err).Msg("could not delete homespace: transport error")
+			errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "could not delete homespace, aborting")
 			return
 		}
 		break
 	}
 
+	logger.Debug().Str("id", user.GetId()).Msg("calling delete user on backend")
 	err = g.identityBackend.DeleteUser(r.Context(), user.GetId())
 
 	if err != nil {
+		logger.Debug().Err(err).Msg("could not delete user: backend error")
 		var errcode errorcode.Error
 		if errors.As(err, &errcode) {
 			errcode.Render(w, r)
@@ -353,27 +391,34 @@ func (g Graph) DeleteUser(w http.ResponseWriter, r *http.Request) {
 // PatchUser implements the Service Interface. Updates the specified attributes of an
 // ExistingUser
 func (g Graph) PatchUser(w http.ResponseWriter, r *http.Request) {
+	logger := g.logger.SubloggerWithRequestID(r.Context())
+	logger.Info().Msg("calling patch user")
 	nameOrID := chi.URLParam(r, "userID")
 	nameOrID, err := url.PathUnescape(nameOrID)
 	if err != nil {
+		logger.Debug().Err(err).Str("id", nameOrID).Msg("could not update user: unescaping user id failed")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "unescaping user id failed")
 		return
 	}
 
 	if nameOrID == "" {
+		logger.Debug().Msg("could not update user: missing user id")
 		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing user id")
 		return
 	}
 	changes := libregraph.NewUser()
 	err = json.NewDecoder(r.Body).Decode(changes)
 	if err != nil {
-		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
+		logger.Debug().Err(err).Interface("body", r.Body).Msg("could not update user: invalid request body")
+		errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest,
+			fmt.Sprintf("invalid request body: %s", err.Error()))
 		return
 	}
 
 	var features []events.UserFeature
 	if mail, ok := changes.GetMailOk(); ok {
 		if !isValidEmail(*mail) {
+			logger.Debug().Str("mail", *mail).Msg("could not update user: email is not a valid email address")
 			errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest,
 				fmt.Sprintf("'%s' is not a valid email address", *mail))
 			return
@@ -385,8 +430,10 @@ func (g Graph) PatchUser(w http.ResponseWriter, r *http.Request) {
 		features = append(features, events.UserFeature{Name: "displayname", Value: *name})
 	}
 
+	logger.Debug().Str("nameid", nameOrID).Interface("changes", *changes).Msg("calling update user on backend")
 	u, err := g.identityBackend.UpdateUser(r.Context(), nameOrID, *changes)
 	if err != nil {
+		logger.Debug().Err(err).Str("id", nameOrID).Msg("could not update user: backend error")
 		var errcode errorcode.Error
 		if errors.As(err, &errcode) {
 			errcode.Render(w, r)
diff --git a/services/groups/pkg/revaconfig/config.go b/services/groups/pkg/revaconfig/config.go
index 6e899c1a752..e5d048abf22 100644
--- a/services/groups/pkg/revaconfig/config.go
+++ b/services/groups/pkg/revaconfig/config.go
@@ -44,12 +44,6 @@ func GroupsConfigFromStruct(cfg *config.Config) map[string]interface{} {
 					},
 				},
 			},
-			"interceptors": map[string]interface{}{
-				"prometheus": map[string]interface{}{
-					"namespace": "ocis",
-					"subsystem": "groups",
-				},
-			},
 		},
 	}
 }
diff --git a/services/nats/pkg/config/config.go b/services/nats/pkg/config/config.go
index 903a4de9be8..eaec9f483d8 100644
--- a/services/nats/pkg/config/config.go
+++ b/services/nats/pkg/config/config.go
@@ -25,8 +25,8 @@ 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."`
 	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:"The directory where the filesystem storage will store NATS JetStream data. If not definied, the root directory derives from $OCIS_BASE_DATA_PATH:/nats."`
+	StoreDir                string `yaml:"store_dir" env:"NATS_NATS_STORE_DIR" desc:"Path for the NATS JetStream persistence directory."`
 	TLSCert                 string `yaml:"tls_cert" env:"NATS_TLS_CERT" desc:"File name of the TLS server certificate for the nats listener."`
 	TLSKey                  string `yaml:"tls_key" env:"NATS_TLS_KEY" desc:"File name for the TLS certificate key for the server certificate."`
-	TLSSkipVerifyClientCert bool   `yaml:"tls_skip_verify_client_cert" env:"OCIS_INSECURE;NATS_TLS_SKIP_VERIFY_CLIENT_CERT" desc:"Whether the NATS server should skip the client certificate verification during the TLS handshake."`
+	TLSSkipVerifyClientCert bool   `yaml:"tls_skip_verify_client_cert" env:"OCIS_INSECURE;NATS_TLS_SKIP_VERIFY_CLIENT_CERT" desc:"Whether the nats server should skip the client certificate verification during the TLS handshake."`
 }
diff --git a/services/notifications/pkg/email/templates/shares/shareCreated.email.body.tmpl b/services/notifications/pkg/email/templates/shareCreated.email.tmpl
similarity index 100%
rename from services/notifications/pkg/email/templates/shares/shareCreated.email.body.tmpl
rename to services/notifications/pkg/email/templates/shareCreated.email.tmpl
diff --git a/services/notifications/pkg/email/templates/spaces/sharedSpace.email.body.tmpl b/services/notifications/pkg/email/templates/sharedSpace.email.tmpl
similarity index 100%
rename from services/notifications/pkg/email/templates/spaces/sharedSpace.email.body.tmpl
rename to services/notifications/pkg/email/templates/sharedSpace.email.tmpl
diff --git a/services/notifications/pkg/email/templates/shares/shareCreated.email.subject.tmpl b/services/notifications/pkg/email/templates/shares/shareCreated.email.subject.tmpl
deleted file mode 100644
index 09dccb9d801..00000000000
--- a/services/notifications/pkg/email/templates/shares/shareCreated.email.subject.tmpl
+++ /dev/null
@@ -1,1 +0,0 @@
-{{ .ShareSharer }} shared '{{ .ShareFolder }}' with you
\ No newline at end of file
diff --git a/services/notifications/pkg/email/templates/spaces/sharedSpace.email.subject.tmpl b/services/notifications/pkg/email/templates/spaces/sharedSpace.email.subject.tmpl
deleted file mode 100644
index e65e04292d1..00000000000
--- a/services/notifications/pkg/email/templates/spaces/sharedSpace.email.subject.tmpl
+++ /dev/null
@@ -1,1 +0,0 @@
-{{ .SpaceSharer }} invited you to join {{ .SpaceName }}
\ No newline at end of file
diff --git a/services/notifications/pkg/service/service.go b/services/notifications/pkg/service/service.go
index 94e74c9b456..c16b48ee22a 100644
--- a/services/notifications/pkg/service/service.go
+++ b/services/notifications/pkg/service/service.go
@@ -2,6 +2,7 @@ package service
 
 import (
 	"context"
+	"fmt"
 	"net/url"
 	"os"
 	"os/signal"
@@ -199,7 +200,7 @@ func (s eventsNotifier) handleSpaceShared(e events.SpaceShared) {
 	}
 
 	sharerDisplayName := sharerUserResponse.GetUser().DisplayName
-	msg, err := email.RenderEmailTemplate("spaces/sharedSpace.email.body.tmpl", map[string]string{
+	msg, err := email.RenderEmailTemplate("sharedSpace.email.tmpl", map[string]string{
 		"SpaceGrantee": spaceGrantee,
 		"SpaceSharer":  sharerDisplayName,
 		"SpaceName":    md.GetInfo().GetSpace().Name,
@@ -210,21 +211,10 @@ func (s eventsNotifier) handleSpaceShared(e events.SpaceShared) {
 		s.logger.Error().
 			Err(err).
 			Str("event", "SpaceCreated").
-			Msg("Could not render E-Mail body template for spaces")
-	}
-
-	emailSubject, err := email.RenderEmailTemplate("spaces/sharedSpace.email.subject.tmpl", map[string]string{
-		"SpaceSharer": sharerDisplayName,
-		"SpaceName":   md.GetInfo().GetSpace().Name,
-	}, s.emailTemplatePath)
-
-	if err != nil {
-		s.logger.Error().
-			Err(err).
-			Str("event", "SpaceCreated").
-			Msg("Could not render E-Mail subject template for spaces")
+			Msg("Could not render E-Mail template for spaces")
 	}
 
+	emailSubject := fmt.Sprintf("%s invited you to join %s", sharerUserResponse.GetUser().DisplayName, md.GetInfo().GetSpace().Name)
 	if e.GranteeUserID != nil {
 		err = s.channel.SendMessage(ownerCtx, []string{e.GranteeUserID.OpaqueId}, msg, emailSubject, sharerDisplayName)
 	} else if e.GranteeGroupID != nil {
@@ -348,7 +338,7 @@ func (s eventsNotifier) handleShareCreated(e events.ShareCreated) {
 	}
 
 	sharerDisplayName := sharerUserResponse.GetUser().DisplayName
-	msg, err := email.RenderEmailTemplate("shares/shareCreated.email.body.tmpl", map[string]string{
+	msg, err := email.RenderEmailTemplate("shareCreated.email.tmpl", map[string]string{
 		"ShareGrantee": shareGrantee,
 		"ShareSharer":  sharerDisplayName,
 		"ShareFolder":  md.GetInfo().Name,
@@ -359,21 +349,10 @@ func (s eventsNotifier) handleShareCreated(e events.ShareCreated) {
 		s.logger.Error().
 			Err(err).
 			Str("event", "ShareCreated").
-			Msg("Could not render E-Mail body template for shares")
-	}
-
-	emailSubject, err := email.RenderEmailTemplate("shares/shareCreated.email.subject.tmpl", map[string]string{
-		"ShareSharer": sharerDisplayName,
-		"ShareFolder": md.GetInfo().Name,
-	}, s.emailTemplatePath)
-
-	if err != nil {
-		s.logger.Error().
-			Err(err).
-			Str("event", "SpaceCreated").
-			Msg("Could not render E-Mail subject template for shares")
+			Msg("Could not render E-Mail template for shares")
 	}
 
+	emailSubject := fmt.Sprintf("%s shared '%s' with you", sharerUserResponse.GetUser().DisplayName, md.GetInfo().Name)
 	if e.GranteeUserID != nil {
 		err = s.channel.SendMessage(ownerCtx, []string{e.GranteeUserID.OpaqueId}, msg, emailSubject, sharerDisplayName)
 	} else if e.GranteeGroupID != nil {
diff --git a/services/ocdav/pkg/command/server.go b/services/ocdav/pkg/command/server.go
index afd3a06c12e..f300810c0de 100644
--- a/services/ocdav/pkg/command/server.go
+++ b/services/ocdav/pkg/command/server.go
@@ -65,8 +65,6 @@ func Server(cfg *config.Config) *cli.Command {
 					// ocdav.FavoriteManager() // FIXME needs a proper persistence implementation https://github.com/owncloud/ocis/issues/1228
 					// ocdav.LockSystem(), // will default to the CS3 lock system
 					// ocdav.TLSConfig() // tls config for the http server
-					ocdav.MetricsEnabled(true),
-					ocdav.MetricsNamespace("ocis"),
 				}
 
 				if cfg.Tracing.Enabled {
diff --git a/services/proxy/pkg/middleware/accesslog.go b/services/proxy/pkg/middleware/accesslog.go
index 43d96e41bff..ff5508f4750 100644
--- a/services/proxy/pkg/middleware/accesslog.go
+++ b/services/proxy/pkg/middleware/accesslog.go
@@ -19,7 +19,7 @@ func AccessLog(logger log.Logger) func(http.Handler) http.Handler {
 
 			logger.Info().
 				Str("proto", r.Proto).
-				Str("request", chimiddleware.GetReqID(r.Context())).
+				Str(log.RequestIDString, chimiddleware.GetReqID(r.Context())).
 				Str("remote-addr", r.RemoteAddr).
 				Str("method", r.Method).
 				Int("status", wrap.Status()).
diff --git a/services/proxy/pkg/user/backend/cs3.go b/services/proxy/pkg/user/backend/cs3.go
index 997ba33b925..d6efa2e7db0 100644
--- a/services/proxy/pkg/user/backend/cs3.go
+++ b/services/proxy/pkg/user/backend/cs3.go
@@ -17,14 +17,12 @@ import (
 	"github.com/cs3org/reva/v2/pkg/token"
 	libregraph "github.com/owncloud/libre-graph-api-go"
 	"github.com/owncloud/ocis/v2/ocis-pkg/log"
-	"github.com/owncloud/ocis/v2/ocis-pkg/middleware"
 	"github.com/owncloud/ocis/v2/ocis-pkg/oidc"
 	"github.com/owncloud/ocis/v2/ocis-pkg/registry"
 	settingssvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/service/v0/errorcode"
 	settingsService "github.com/owncloud/ocis/v2/services/settings/pkg/service/v0"
 	merrors "go-micro.dev/v4/errors"
-	"go-micro.dev/v4/metadata"
 	"go-micro.dev/v4/selector"
 )
 
@@ -87,9 +85,6 @@ func (c *cs3backend) GetUserByClaims(ctx context.Context, claim, value string, w
 				// https://github.com/owncloud/ocis/v2/issues/1825 for more context.
 				if user.Id.Type == cs3.UserType_USER_TYPE_PRIMARY {
 					c.logger.Info().Str("userid", user.Id.OpaqueId).Msg("user has no role assigned, assigning default user role")
-					// Updating context to have the Account-ID field and suffixing with _init
-					// so that the safety check for setting users' own role doesn't fail
-					ctx = metadata.Set(ctx, middleware.AccountID, user.Id.OpaqueId+"_init")
 					_, err := c.settingsRoleService.AssignRoleToUser(ctx, &settingssvc.AssignRoleToUserRequest{
 						AccountUuid: user.Id.OpaqueId,
 						RoleId:      settingsService.BundleUUIDRoleUser,
diff --git a/services/search/pkg/command/index.go b/services/search/pkg/command/index.go
index 791cf116af0..ecb44fa7dcf 100644
--- a/services/search/pkg/command/index.go
+++ b/services/search/pkg/command/index.go
@@ -3,12 +3,9 @@ package command
 import (
 	"context"
 	"fmt"
-	"time"
 
 	"github.com/urfave/cli/v2"
-	"go-micro.dev/v4/client"
 
-	"github.com/owncloud/ocis/v2/ocis-pkg/config/configlog"
 	"github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
 	searchsvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/search/v0"
 	"github.com/owncloud/ocis/v2/services/search/pkg/config"
@@ -33,20 +30,18 @@ func Index(cfg *config.Config) *cli.Command {
 				Name:     "user",
 				Aliases:  []string{"u"},
 				Required: true,
-				Usage:    "the username of the user that shall be used to access the files",
+				Usage:    "the username of the user tha shall be used to access the files",
 			},
 		},
 		Before: func(c *cli.Context) error {
-			return configlog.ReturnFatal(parser.ParseConfig(cfg))
+			return parser.ParseConfig(cfg)
 		},
-		Action: func(ctx *cli.Context) error {
-			grpcClient := grpc.DefaultClient()
-			grpcClient.Options()
-			c := searchsvc.NewSearchProviderService("com.owncloud.api.search", grpcClient)
-			_, err := c.IndexSpace(context.Background(), &searchsvc.IndexSpaceRequest{
-				SpaceId: ctx.String("space"),
-				UserId:  ctx.String("user"),
-			}, func(opts *client.CallOptions) { opts.RequestTimeout = 10 * time.Minute })
+		Action: func(c *cli.Context) error {
+			client := searchsvc.NewSearchProviderService("com.owncloud.api.search", grpc.DefaultClient())
+			_, err := client.IndexSpace(context.Background(), &searchsvc.IndexSpaceRequest{
+				SpaceId: c.String("space"),
+				UserId:  c.String("user"),
+			})
 			if err != nil {
 				fmt.Println("failed to index space: " + err.Error())
 				return err
diff --git a/services/search/pkg/config/config.go b/services/search/pkg/config/config.go
index 6a1f56e8391..e47ced27756 100644
--- a/services/search/pkg/config/config.go
+++ b/services/search/pkg/config/config.go
@@ -18,7 +18,7 @@ type Config struct {
 
 	GRPC GRPC `yaml:"grpc"`
 
-	Datapath string `yaml:"data_path" env:"SEARCH_DATA_PATH" desc:"The directory where the filesystem storage will store search data. If not definied, the root directory derives from $OCIS_BASE_DATA_PATH:/search."`
+	Datapath string `yaml:"data_path" env:"SEARCH_DATA_PATH" desc:"Path for the search persistence directory."`
 	Reva     *Reva  `yaml:"reva"`
 	Events   Events `yaml:"events"`
 
diff --git a/services/search/pkg/search/index/index.go b/services/search/pkg/search/index/index.go
index 3a274d1afcf..f822841b087 100644
--- a/services/search/pkg/search/index/index.go
+++ b/services/search/pkg/search/index/index.go
@@ -222,18 +222,13 @@ func (i *Index) Search(ctx context.Context, req *searchsvc.SearchIndexRequest) (
 	query := bleve.NewConjunctionQuery(
 		bleve.NewQueryStringQuery(req.Query),
 		deletedQuery, // Skip documents that have been marked as deleted
+		bleve.NewQueryStringQuery("RootID:"+idToBleveId(&sprovider.ResourceId{
+			StorageId: req.Ref.GetResourceId().GetStorageId(),
+			SpaceId:   req.Ref.GetResourceId().GetSpaceId(),
+			OpaqueId:  req.Ref.GetResourceId().GetOpaqueId(),
+		})), // Limit search to the space
+		bleve.NewQueryStringQuery("Path:"+queryEscape(utils.MakeRelativePath(path.Join(req.Ref.Path, "/"))+"*")), // Limit search to this directory in the space
 	)
-	if req.Ref != nil {
-		query = bleve.NewConjunctionQuery(
-			query,
-			bleve.NewQueryStringQuery("RootID:"+idToBleveId(&sprovider.ResourceId{
-				StorageId: req.Ref.GetResourceId().GetStorageId(),
-				SpaceId:   req.Ref.GetResourceId().GetSpaceId(),
-				OpaqueId:  req.Ref.GetResourceId().GetOpaqueId(),
-			})), // Limit search to the space
-			bleve.NewQueryStringQuery("Path:"+queryEscape(utils.MakeRelativePath(path.Join(req.Ref.Path, "/"))+"*")), // Limit search to this directory in the space
-		)
-	}
 	bleveReq := bleve.NewSearchRequest(query)
 	bleveReq.Size = 200
 	if req.PageSize > 0 {
@@ -300,7 +295,7 @@ func toEntity(ref *sprovider.Reference, ri *sprovider.ResourceInfo) *indexDocume
 	}
 
 	if ri.Mtime != nil {
-		doc.Mtime = time.Unix(int64(ri.Mtime.Seconds), int64(ri.Mtime.Nanos)).UTC().Format(time.RFC3339Nano)
+		doc.Mtime = time.Unix(int64(ri.Mtime.Seconds), int64(ri.Mtime.Nanos)).UTC().Format(time.RFC3339)
 	}
 
 	return doc
@@ -355,7 +350,7 @@ func fromDocumentMatch(hit *search.DocumentMatch) (*searchmsg.Match, error) {
 		match.Entity.ParentId = resourceIDtoSearchID(parentID)
 	}
 
-	if mtime, err := time.Parse(time.RFC3339Nano, hit.Fields["Mtime"].(string)); err == nil {
+	if mtime, err := time.Parse(time.RFC3339, hit.Fields["Mtime"].(string)); err == nil {
 		match.Entity.LastModifiedTime = &timestamppb.Timestamp{Seconds: mtime.Unix(), Nanos: int32(mtime.Nanosecond())}
 	}
 
diff --git a/services/search/pkg/search/provider/events.go b/services/search/pkg/search/provider/events.go
index f8b63b58bad..c3c7ab7d14b 100644
--- a/services/search/pkg/search/provider/events.go
+++ b/services/search/pkg/search/provider/events.go
@@ -2,8 +2,6 @@ package provider
 
 import (
 	"context"
-	"sync"
-	"time"
 
 	gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
 	user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
@@ -13,43 +11,12 @@ import (
 	ctxpkg "github.com/cs3org/reva/v2/pkg/ctx"
 	"github.com/cs3org/reva/v2/pkg/errtypes"
 	"github.com/cs3org/reva/v2/pkg/events"
-	"github.com/cs3org/reva/v2/pkg/storagespace"
 	"google.golang.org/grpc/metadata"
 )
 
-// SpaceDebouncer debounces operations on spaces for a configurable amount of time
-type SpaceDebouncer struct {
-	after   time.Duration
-	f       func(id *provider.StorageSpaceId, userID *user.UserId)
-	pending map[string]*time.Timer
-
-	mutex sync.Mutex
-}
-
-// NewSpaceDebouncer returns a new SpaceDebouncer instance
-func NewSpaceDebouncer(d time.Duration, f func(id *provider.StorageSpaceId, userID *user.UserId)) *SpaceDebouncer {
-	return &SpaceDebouncer{
-		after:   d,
-		f:       f,
-		pending: map[string]*time.Timer{},
-	}
-}
-
-// Debounce restars the debounce timer for the given space
-func (d *SpaceDebouncer) Debounce(id *provider.StorageSpaceId, userID *user.UserId) {
-	d.mutex.Lock()
-	defer d.mutex.Unlock()
-
-	if t := d.pending[id.OpaqueId]; t != nil {
-		t.Stop()
-	}
-
-	d.pending[id.OpaqueId] = time.AfterFunc(d.after, func() {
-		d.f(id, userID)
-	})
-}
-
 func (p *Provider) handleEvent(ev interface{}) {
+	var ref *provider.Reference
+	var owner *user.User
 	switch e := ev.(type) {
 	case events.ItemTrashed:
 		p.logger.Debug().Interface("event", ev).Msg("marking document as deleted")
@@ -57,10 +24,11 @@ func (p *Provider) handleEvent(ev interface{}) {
 		if err != nil {
 			p.logger.Error().Err(err).Interface("Id", e.ID).Msg("failed to remove item from index")
 		}
-		p.reindexSpace(ev, e.Ref, e.Executant, e.SpaceOwner)
+		return
 	case events.ItemRestored:
 		p.logger.Debug().Interface("event", ev).Msg("marking document as restored")
-		owner := &user.User{
+		ref = e.Ref
+		owner = &user.User{
 			Id: e.Executant,
 		}
 
@@ -68,13 +36,13 @@ func (p *Provider) handleEvent(ev interface{}) {
 		if err != nil {
 			return
 		}
-		statRes, err := p.statResource(ownerCtx, e.Ref, owner)
+		statRes, err := p.statResource(ownerCtx, ref, owner)
 		if err != nil {
 			p.logger.Error().Err(err).
-				Str("storageid", e.Ref.GetResourceId().GetStorageId()).
-				Str("spaceid", e.Ref.GetResourceId().GetSpaceId()).
-				Str("opaqueid", e.Ref.GetResourceId().GetOpaqueId()).
-				Str("path", e.Ref.GetPath()).
+				Str("storageid", ref.GetResourceId().GetStorageId()).
+				Str("spaceid", ref.GetResourceId().GetSpaceId()).
+				Str("opaqueid", ref.GetResourceId().GetOpaqueId()).
+				Str("path", ref.GetPath()).
 				Msg("failed to make stat call for the restored resource")
 			return
 		}
@@ -84,24 +52,26 @@ func (p *Provider) handleEvent(ev interface{}) {
 			err = p.indexClient.Restore(statRes.Info.Id)
 			if err != nil {
 				p.logger.Error().Err(err).
-					Str("storageid", e.Ref.GetResourceId().GetStorageId()).
-					Str("spaceid", e.Ref.GetResourceId().GetSpaceId()).
-					Str("opaqueid", e.Ref.GetResourceId().GetOpaqueId()).
-					Str("path", e.Ref.GetPath()).
+					Str("storageid", ref.GetResourceId().GetStorageId()).
+					Str("spaceid", ref.GetResourceId().GetSpaceId()).
+					Str("opaqueid", ref.GetResourceId().GetOpaqueId()).
+					Str("path", ref.GetPath()).
 					Msg("failed to restore the changed resource in the index")
 			}
 		default:
 			p.logger.Error().Interface("statRes", statRes).
-				Str("storageid", e.Ref.GetResourceId().GetStorageId()).
-				Str("spaceid", e.Ref.GetResourceId().GetSpaceId()).
-				Str("opaqueid", e.Ref.GetResourceId().GetOpaqueId()).
-				Str("path", e.Ref.GetPath()).
+				Str("storageid", ref.GetResourceId().GetStorageId()).
+				Str("spaceid", ref.GetResourceId().GetSpaceId()).
+				Str("opaqueid", ref.GetResourceId().GetOpaqueId()).
+				Str("path", ref.GetPath()).
 				Msg("failed to stat the restored resource")
 		}
-		p.reindexSpace(ev, e.Ref, e.Executant, e.SpaceOwner)
+
+		return
 	case events.ItemMoved:
 		p.logger.Debug().Interface("event", ev).Msg("resource has been moved, updating the document")
-		owner := &user.User{
+		ref = e.Ref
+		owner = &user.User{
 			Id: e.Executant,
 		}
 
@@ -109,7 +79,7 @@ func (p *Provider) handleEvent(ev interface{}) {
 		if err != nil {
 			return
 		}
-		statRes, err := p.statResource(ownerCtx, e.Ref, owner)
+		statRes, err := p.statResource(ownerCtx, ref, owner)
 		if err != nil {
 			p.logger.Error().Err(err).Msg("failed to stat the moved resource")
 			return
@@ -121,11 +91,11 @@ func (p *Provider) handleEvent(ev interface{}) {
 
 		gpRes, err := p.getPath(ownerCtx, statRes.Info.Id, owner)
 		if err != nil {
-			p.logger.Error().Err(err).Interface("ref", e.Ref).Msg("failed to get path for moved resource")
+			p.logger.Error().Err(err).Interface("ref", ref).Msg("failed to get path for moved resource")
 			return
 		}
 		if gpRes.Status.Code != rpcv1beta1.Code_CODE_OK {
-			p.logger.Error().Interface("status", gpRes.Status).Interface("ref", e.Ref).Msg("failed to get path for moved resource")
+			p.logger.Error().Interface("status", gpRes.Status).Interface("ref", ref).Msg("failed to get path for moved resource")
 			return
 		}
 
@@ -133,34 +103,68 @@ func (p *Provider) handleEvent(ev interface{}) {
 		if err != nil {
 			p.logger.Error().Err(err).Msg("failed to move the changed resource in the index")
 		}
-		p.reindexSpace(ev, e.Ref, e.Executant, e.SpaceOwner)
+		return
 	case events.ContainerCreated:
-		p.reindexSpace(ev, e.Ref, e.Executant, e.SpaceOwner)
+		ref = e.Ref
+		owner = &user.User{
+			Id: e.Executant,
+		}
 	case events.FileUploaded:
-		p.reindexSpace(ev, e.Ref, e.Executant, e.SpaceOwner)
+		ref = e.Ref
+		owner = &user.User{
+			Id: e.Executant,
+		}
 	case events.FileTouched:
-		p.reindexSpace(ev, e.Ref, e.Executant, e.SpaceOwner)
+		ref = e.Ref
+		owner = &user.User{
+			Id: e.Executant,
+		}
 	case events.FileVersionRestored:
-		p.reindexSpace(ev, e.Ref, e.Executant, e.SpaceOwner)
+		ref = e.Ref
+		owner = &user.User{
+			Id: e.Executant,
+		}
 	default:
 		// Not sure what to do here. Skip.
 		return
 	}
-}
+	p.logger.Debug().Interface("event", ev).Msg("resource has been changed, updating the document")
+
+	ownerCtx, err := p.getAuthContext(owner)
+	if err != nil {
+		return
+	}
 
-func (p *Provider) reindexSpace(ev interface{}, ref *provider.Reference, executant, owner *user.UserId) {
-	p.logger.Debug().Interface("event", ev).Msg("resource has been changed, scheduling a space resync")
+	statRes, err := p.statResource(ownerCtx, ref, owner)
+	if err != nil {
+		p.logger.Error().Err(err).
+			Str("storageid", ref.GetResourceId().GetStorageId()).
+			Str("spaceid", ref.GetResourceId().GetSpaceId()).
+			Str("opaqueid", ref.GetResourceId().GetOpaqueId()).
+			Str("path", ref.GetPath()).
+			Msg("failed to make stat call for changed resource")
+		return
+	}
+	if statRes.Status.Code != rpc.Code_CODE_OK {
+		p.logger.Error().Interface("statRes", statRes).
+			Str("storageid", ref.GetResourceId().GetStorageId()).
+			Str("spaceid", ref.GetResourceId().GetSpaceId()).
+			Str("opaqueid", ref.GetResourceId().GetOpaqueId()).
+			Str("path", ref.GetPath()).
+			Msg("failed to stat the changed resource")
+		return
+	}
 
-	spaceID := &provider.StorageSpaceId{
-		OpaqueId: storagespace.FormatResourceID(provider.ResourceId{
-			StorageId: ref.GetResourceId().GetStorageId(),
-			SpaceId:   ref.GetResourceId().GetSpaceId(),
-		}),
+	ref, err = p.resolveReference(ownerCtx, ref, statRes.Info)
+	if err != nil {
+		p.logger.Error().Err(err).Msg("error resolving reference")
+		return
 	}
-	if owner != nil {
-		p.indexSpaceDebouncer.Debounce(spaceID, owner)
+	err = p.indexClient.Add(ref, statRes.Info)
+	if err != nil {
+		p.logger.Error().Err(err).Msg("error adding updating the resource in the index")
 	} else {
-		p.indexSpaceDebouncer.Debounce(spaceID, executant)
+		p.logDocCount()
 	}
 }
 
diff --git a/services/search/pkg/search/provider/searchprovider.go b/services/search/pkg/search/provider/searchprovider.go
index 1bfe01286bb..9e314a97fb6 100644
--- a/services/search/pkg/search/provider/searchprovider.go
+++ b/services/search/pkg/search/provider/searchprovider.go
@@ -8,8 +8,6 @@ import (
 	"strings"
 	"time"
 
-	"google.golang.org/grpc/metadata"
-
 	gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
 	user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
 	rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
@@ -24,6 +22,7 @@ import (
 	"github.com/cs3org/reva/v2/pkg/utils"
 	"github.com/owncloud/ocis/v2/ocis-pkg/log"
 	"github.com/owncloud/ocis/v2/services/search/pkg/search"
+	"google.golang.org/grpc/metadata"
 
 	searchmsg "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/search/v0"
 	searchsvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/search/v0"
@@ -63,8 +62,6 @@ type Provider struct {
 	gwClient          gateway.GatewayAPIClient
 	indexClient       search.IndexClient
 	machineAuthAPIKey string
-
-	indexSpaceDebouncer *SpaceDebouncer
 }
 
 type MatchArray []*searchmsg.Match
@@ -87,13 +84,6 @@ func New(gwClient gateway.GatewayAPIClient, indexClient search.IndexClient, mach
 		logger:            logger,
 	}
 
-	p.indexSpaceDebouncer = NewSpaceDebouncer(50*time.Millisecond, func(id *provider.StorageSpaceId, userID *user.UserId) {
-		err := p.doIndexSpace(context.Background(), id, userID)
-		if err != nil {
-			p.logger.Error().Err(err).Interface("spaceID", id).Interface("userID", userID).Msg("error while indexing a space")
-		}
-	})
-
 	go func() {
 		for {
 			ev := <-eventsChan
@@ -107,13 +97,6 @@ func New(gwClient gateway.GatewayAPIClient, indexClient search.IndexClient, mach
 	return p
 }
 
-// NewWithDebouncer returns a new provider with a customer index space debouncer
-func NewWithDebouncer(gwClient gateway.GatewayAPIClient, indexClient search.IndexClient, machineAuthAPIKey string, eventsChan <-chan interface{}, logger log.Logger, debouncer *SpaceDebouncer) *Provider {
-	p := New(gwClient, indexClient, machineAuthAPIKey, eventsChan, logger)
-	p.indexSpaceDebouncer = debouncer
-	return p
-}
-
 func (p *Provider) Search(ctx context.Context, req *searchsvc.SearchRequest) (*searchsvc.SearchResponse, error) {
 	if req.Query == "" {
 		return nil, errtypes.BadRequest("empty query provided")
@@ -258,70 +241,52 @@ func (p *Provider) Search(ctx context.Context, req *searchsvc.SearchRequest) (*s
 }
 
 func (p *Provider) IndexSpace(ctx context.Context, req *searchsvc.IndexSpaceRequest) (*searchsvc.IndexSpaceResponse, error) {
-	err := p.doIndexSpace(ctx, &provider.StorageSpaceId{OpaqueId: req.SpaceId}, &user.UserId{OpaqueId: req.UserId})
-	if err != nil {
+	// get user
+	res, err := p.gwClient.GetUserByClaim(context.Background(), &user.GetUserByClaimRequest{
+		Claim: "username",
+		Value: req.UserId,
+	})
+	if err != nil || res.Status.Code != rpc.Code_CODE_OK {
+		fmt.Println("error: Could not get user by userid")
 		return nil, err
 	}
-	return &searchsvc.IndexSpaceResponse{}, nil
-}
 
-func (p *Provider) doIndexSpace(ctx context.Context, spaceID *provider.StorageSpaceId, userID *user.UserId) error {
-	authRes, err := p.gwClient.Authenticate(ctx, &gateway.AuthenticateRequest{
+	// Get auth context
+	ownerCtx := ctxpkg.ContextSetUser(context.Background(), res.User)
+	authRes, err := p.gwClient.Authenticate(ownerCtx, &gateway.AuthenticateRequest{
 		Type:         "machine",
-		ClientId:     "userid:" + userID.OpaqueId,
+		ClientId:     "userid:" + res.User.Id.OpaqueId,
 		ClientSecret: p.machineAuthAPIKey,
 	})
 	if err != nil || authRes.GetStatus().GetCode() != rpc.Code_CODE_OK {
-		return err
+		return nil, err
 	}
 
 	if authRes.GetStatus().GetCode() != rpc.Code_CODE_OK {
-		return fmt.Errorf("could not get authenticated context for user")
+		return nil, fmt.Errorf("could not get authenticated context for user")
 	}
-	ownerCtx := metadata.AppendToOutgoingContext(ctx, ctxpkg.TokenHeader, authRes.Token)
+	ownerCtx = metadata.AppendToOutgoingContext(ownerCtx, ctxpkg.TokenHeader, authRes.Token)
 
 	// Walk the space and index all files
 	walker := walker.NewWalker(p.gwClient)
-	rootID, err := storagespace.ParseID(spaceID.OpaqueId)
+	rootId, err := storagespace.ParseID(req.SpaceId)
 	if err != nil {
-		p.logger.Error().Err(err).Msg("invalid space id")
-		return err
-	}
-	if rootID.StorageId == "" || rootID.SpaceId == "" {
-		p.logger.Error().Err(err).Msg("invalid space id")
-		return fmt.Errorf("invalid space id")
+		p.logger.Error().Err(err).Msg(err.Error())
+		return nil, err
 	}
-	rootID.OpaqueId = rootID.SpaceId
-
-	err = walker.Walk(ownerCtx, &rootID, func(wd string, info *provider.ResourceInfo, err error) error {
+	err = walker.Walk(ownerCtx, &rootId, func(wd string, info *provider.ResourceInfo, err error) error {
 		if err != nil {
 			p.logger.Error().Err(err).Msg("error walking the tree")
-			return err
 		}
-
-		if info == nil {
-			return nil
-		}
-
 		ref := &provider.Reference{
 			Path:       utils.MakeRelativePath(filepath.Join(wd, info.Path)),
-			ResourceId: &rootID,
+			ResourceId: &rootId,
 		}
-		p.logger.Debug().Str("path", ref.Path).Msg("Walking tree")
-
-		// Has this item/subtree changed?
-		searchRes, err := p.indexClient.Search(ownerCtx, &searchsvc.SearchIndexRequest{
-			Query: "+ID:" + storagespace.FormatResourceID(*info.Id) + ` +Mtime:>="` + utils.TSToTime(info.Mtime).Format(time.RFC3339Nano) + `"`,
-		})
-		if err == nil && len(searchRes.Matches) >= 1 {
-			if info.Type == provider.ResourceType_RESOURCE_TYPE_CONTAINER {
-				p.logger.Debug().Str("path", ref.Path).Msg("subtree hasn't changed. Skipping.")
-				return filepath.SkipDir
-			}
-			p.logger.Debug().Str("path", ref.Path).Msg("element hasn't changed. Skipping.")
+		ref, err = p.resolveReference(ownerCtx, ref, info)
+		if err != nil {
+			p.logger.Error().Err(err).Msg("error resolving reference")
 			return nil
 		}
-
 		err = p.indexClient.Add(ref, info)
 		if err != nil {
 			p.logger.Error().Err(err).Msg("error adding resource to the index")
@@ -331,11 +296,32 @@ func (p *Provider) doIndexSpace(ctx context.Context, spaceID *provider.StorageSp
 		return nil
 	})
 	if err != nil {
-		return err
+		return nil, err
 	}
 
 	p.logDocCount()
-	return nil
+	return &searchsvc.IndexSpaceResponse{}, nil
+}
+
+func (p *Provider) resolveReference(ctx context.Context, ref *provider.Reference, ri *provider.ResourceInfo) (*provider.Reference, error) {
+	if ref.GetResourceId().GetOpaqueId() == ref.GetResourceId().GetSpaceId() {
+		return ref, nil
+	}
+
+	gpRes, err := p.gwClient.GetPath(ctx, &provider.GetPathRequest{
+		ResourceId: ri.Id,
+	})
+	if err != nil || gpRes.Status.Code != rpcv1beta1.Code_CODE_OK {
+		return nil, err
+	}
+	return &provider.Reference{
+		ResourceId: &provider.ResourceId{
+			StorageId: ref.GetResourceId().GetStorageId(),
+			SpaceId:   ref.GetResourceId().GetSpaceId(),
+			OpaqueId:  ref.GetResourceId().GetSpaceId(),
+		},
+		Path: utils.MakeRelativePath(gpRes.Path),
+	}, nil
 }
 
 func (p *Provider) logDocCount() {
diff --git a/services/settings/pkg/config/config.go b/services/settings/pkg/config/config.go
index 39069543410..141e7a82c23 100644
--- a/services/settings/pkg/config/config.go
+++ b/services/settings/pkg/config/config.go
@@ -20,7 +20,7 @@ type Config struct {
 	GRPC GRPC `yaml:"grpc"`
 
 	StoreType string   `yaml:"store_type" env:"SETTINGS_STORE_TYPE" desc:"Store type configures the persistency driver. Supported values are \"metadata\" and \"filesystem\"."`
-	DataPath  string   `yaml:"data_path" env:"SETTINGS_DATA_PATH" desc:"The directory where the filesystem storage will store ocis settings. If not definied, the root directory derives from $OCIS_BASE_DATA_PATH:/settings."`
+	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 the user that should receive admin privileges."`
diff --git a/services/sharing/pkg/revaconfig/config.go b/services/sharing/pkg/revaconfig/config.go
index 49761b8ae02..fc4f675b8ff 100644
--- a/services/sharing/pkg/revaconfig/config.go
+++ b/services/sharing/pkg/revaconfig/config.go
@@ -109,10 +109,6 @@ func SharingConfigFromStruct(cfg *config.Config) map[string]interface{} {
 					"tls-insecure":     cfg.Events.TLSInsecure,
 					"tls-root-ca-cert": cfg.Events.TLSRootCaCertPath,
 				},
-				"prometheus": map[string]interface{}{
-					"namespace": "ocis",
-					"subsystem": "sharing",
-				},
 			},
 		},
 	}
diff --git a/services/storage-publiclink/pkg/revaconfig/config.go b/services/storage-publiclink/pkg/revaconfig/config.go
index ab335219d50..2c2cfd9c00d 100644
--- a/services/storage-publiclink/pkg/revaconfig/config.go
+++ b/services/storage-publiclink/pkg/revaconfig/config.go
@@ -23,10 +23,6 @@ func StoragePublicLinkConfigFromStruct(cfg *config.Config) map[string]interface{
 			"address": cfg.GRPC.Addr,
 			"interceptors": map[string]interface{}{
 				"log": map[string]interface{}{},
-				"prometheus": map[string]interface{}{
-					"namespace": "ocis",
-					"subsystem": "storage_publiclink",
-				},
 			},
 			"services": map[string]interface{}{
 				"publicstorageprovider": map[string]interface{}{
diff --git a/services/storage-shares/pkg/revaconfig/config.go b/services/storage-shares/pkg/revaconfig/config.go
index 320681317fc..d6d29ba0ef5 100644
--- a/services/storage-shares/pkg/revaconfig/config.go
+++ b/services/storage-shares/pkg/revaconfig/config.go
@@ -27,12 +27,6 @@ func StorageSharesConfigFromStruct(cfg *config.Config) map[string]interface{} {
 					"mount_id":             cfg.MountID,
 				},
 			},
-			"interceptors": map[string]interface{}{
-				"prometheus": map[string]interface{}{
-					"namespace": "ocis",
-					"subsystem": "storage_shares",
-				},
-			},
 		},
 	}
 	if cfg.ReadOnly {
diff --git a/services/storage-system/pkg/config/config.go b/services/storage-system/pkg/config/config.go
index 5a87745fc90..0b6e5b52a07 100644
--- a/services/storage-system/pkg/config/config.go
+++ b/services/storage-system/pkg/config/config.go
@@ -13,8 +13,9 @@ type Config struct {
 	Log     *Log            `yaml:"log"`
 	Debug   Debug           `yaml:"debug"`
 
-	GRPC GRPCConfig `yaml:"grpc"`
-	HTTP HTTPConfig `yaml:"http"`
+	GRPC   GRPCConfig `yaml:"grpc"`
+	HTTP   HTTPConfig `yaml:"http"`
+	Events Events     `yaml:"events"`
 
 	TokenManager     *TokenManager `yaml:"token_manager"`
 	Reva             *Reva         `yaml:"reva"`
@@ -75,3 +76,8 @@ 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."`
 }
+
+type Events struct {
+	Addr      string `yaml:"endpoint" env:"STORAGE_SYSTEM_EVENTS_ENDPOINT" desc:"The address of the event system. The event system is the message queuing service. It is used as message broker for the microservice architecture."`
+	ClusterID string `yaml:"cluster" env:"STORAGE_SYSTEM_EVENTS_CLUSTER" desc:"The clusterID of the event system. The event system is the message queuing service. It is used as message broker for the microservice architecture. Mandatory when using NATS as event system."`
+}
diff --git a/services/storage-system/pkg/revaconfig/config.go b/services/storage-system/pkg/revaconfig/config.go
index aa7e64cfefa..b7026b18080 100644
--- a/services/storage-system/pkg/revaconfig/config.go
+++ b/services/storage-system/pkg/revaconfig/config.go
@@ -98,12 +98,6 @@ func StorageSystemFromStruct(cfg *config.Config) map[string]interface{} {
 					"data_server_url": cfg.DataServerURL,
 				},
 			},
-			"interceptors": map[string]interface{}{
-				"prometheus": map[string]interface{}{
-					"namespace": "ocis",
-					"subsystem": "storage_system",
-				},
-			},
 		},
 		"http": map[string]interface{}{
 			"network": cfg.HTTP.Protocol,
@@ -133,12 +127,6 @@ func StorageSystemFromStruct(cfg *config.Config) map[string]interface{} {
 					},
 				},
 			},
-			"middlewares": map[string]interface{}{
-				"prometheus": map[string]interface{}{
-					"namespace": "ocis",
-					"subsystem": "storage_system",
-				},
-			},
 		},
 	}
 	return rcfg
diff --git a/services/storage-users/pkg/config/config.go b/services/storage-users/pkg/config/config.go
index 4fb933caeee..c6ade71a0bd 100644
--- a/services/storage-users/pkg/config/config.go
+++ b/services/storage-users/pkg/config/config.go
@@ -84,8 +84,8 @@ type Drivers struct {
 
 type OCISDriver struct {
 	// Root is the absolute path to the location of the data
-	Root                string `yaml:"root" env:"STORAGE_USERS_OCIS_ROOT" desc:"The directory where the filesystem storage will store user files. If not definied, the root directory derives from $OCIS_BASE_DATA_PATH:/storage/users."`
-	UserLayout          string `yaml:"user_layout" env:"STORAGE_USERS_OCIS_USER_LAYOUT" desc:"Template string for the user storage layout in the user directory."`
+	Root                string `yaml:"root" env:"STORAGE_USERS_OCIS_ROOT" desc:"Path for the persistence directory."`
+	UserLayout          string `yaml:"user_layout" env:"STORAGE_USERS_OCIS_USER_LAYOUT" desc:"Template string for the user storage layout in the persistence directory."`
 	PermissionsEndpoint string `yaml:"permissions_endpoint" env:"STORAGE_USERS_PERMISSION_ENDPOINT,STORAGE_USERS_OCIS_PERMISSIONS_ENDPOINT" desc:"Endpoint of the permissions service."`
 	// PersonalSpaceAliasTemplate  contains the template used to construct
 	// the personal space alias, eg: `"{{.SpaceType}}/{{.User.Username | lower}}"`
@@ -99,8 +99,8 @@ type OCISDriver struct {
 
 type S3NGDriver struct {
 	// Root is the absolute path to the location of the data
-	Root                string `yaml:"root" env:"STORAGE_USERS_S3NG_ROOT" desc:"The directory where the filesystem storage will store user files. If not definied, the root directory derives from $OCIS_BASE_DATA_PATH:/storage/users."`
-	UserLayout          string `yaml:"user_layout" env:"STORAGE_USERS_S3NG_USER_LAYOUT" desc:"Template string for the user storage layout in the user directory."`
+	Root                string `yaml:"root" env:"STORAGE_USERS_S3NG_ROOT" desc:"Path for the persistence directory."`
+	UserLayout          string `yaml:"user_layout" env:"STORAGE_USERS_S3NG_USER_LAYOUT" desc:"Template string for the user storage layout in the persistence directory."`
 	PermissionsEndpoint string `yaml:"permissions_endpoint" env:"STORAGE_USERS_PERMISSION_ENDPOINT;STORAGE_USERS_S3NG_PERMISSIONS_ENDPOINT" desc:"Endpoint of the permissions service."`
 	Region              string `yaml:"region" env:"STORAGE_USERS_S3NG_REGION" desc:"Region of the S3 bucket."`
 	AccessKey           string `yaml:"access_key" env:"STORAGE_USERS_S3NG_ACCESS_KEY" desc:"Access key for the S3 bucket."`
@@ -119,7 +119,7 @@ type S3NGDriver struct {
 
 type OwnCloudSQLDriver struct {
 	// Root is the absolute path to the location of the data
-	Root string `yaml:"root" env:"STORAGE_USERS_OWNCLOUDSQL_DATADIR" desc:"The directory where the filesystem storage will store SQL migration data. If not definied, the root directory derives from $OCIS_BASE_DATA_PATH:/storage/owncloud."`
+	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 directory"`
diff --git a/services/storage-users/pkg/revaconfig/config.go b/services/storage-users/pkg/revaconfig/config.go
index 332f8a5efdd..e6642cac98f 100644
--- a/services/storage-users/pkg/revaconfig/config.go
+++ b/services/storage-users/pkg/revaconfig/config.go
@@ -41,10 +41,6 @@ func StorageUsersConfigFromStruct(cfg *config.Config) map[string]interface{} {
 					"tls-insecure":     cfg.Events.TLSInsecure,
 					"tls-root-ca-cert": cfg.Events.TLSRootCaCertPath,
 				},
-				"prometheus": map[string]interface{}{
-					"namespace": "ocis",
-					"subsystem": "storage_users",
-				},
 			},
 		},
 		"http": map[string]interface{}{
diff --git a/services/store/pkg/config/config.go b/services/store/pkg/config/config.go
index 2e2556ef0c6..3024daff2f4 100644
--- a/services/store/pkg/config/config.go
+++ b/services/store/pkg/config/config.go
@@ -18,7 +18,7 @@ type Config struct {
 
 	GRPC GRPC `yaml:"grpc"`
 
-	Datapath string `yaml:"data_path" env:"STORE_DATA_PATH" desc:"The directory where the filesystem storage will store ocis settings. If not definied, the root directory derives from $OCIS_BASE_DATA_PATH:/store."`
+	Datapath string `yaml:"data_path" env:"STORE_DATA_PATH" desc:"Path for the store persistence directory."`
 
 	Context context.Context `yaml:"-"`
 }
diff --git a/services/thumbnails/pkg/config/config.go b/services/thumbnails/pkg/config/config.go
index 781a613f780..20d66c72c78 100644
--- a/services/thumbnails/pkg/config/config.go
+++ b/services/thumbnails/pkg/config/config.go
@@ -26,7 +26,7 @@ type Config struct {
 
 // FileSystemStorage defines the available filesystem storage configuration.
 type FileSystemStorage struct {
-	RootDirectory string `yaml:"root_directory" env:"THUMBNAILS_FILESYSTEMSTORAGE_ROOT" desc:"The directory where the filesystem storage will store the thumbnails. If not definied, the root directory derives from $OCIS_BASE_DATA_PATH:/thumbnails."`
+	RootDirectory string `yaml:"root_directory" env:"THUMBNAILS_FILESYSTEMSTORAGE_ROOT" desc:"The directory where the filesystem storage will store the thumbnails."`
 }
 
 // Thumbnail defines the available thumbnail related configuration.
diff --git a/services/thumbnails/pkg/service/http/v0/service.go b/services/thumbnails/pkg/service/http/v0/service.go
index 8b201658c4c..428986a3a19 100644
--- a/services/thumbnails/pkg/service/http/v0/service.go
+++ b/services/thumbnails/pkg/service/http/v0/service.go
@@ -73,11 +73,12 @@ func (s Thumbnails) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 
 // GetThumbnail implements the Service interface.
 func (s Thumbnails) GetThumbnail(w http.ResponseWriter, r *http.Request) {
+	logger := s.logger.SubloggerWithRequestID(r.Context())
 	key := r.Context().Value(keyContextKey).(string)
 
 	thumbnail, err := s.manager.GetThumbnail(key)
 	if err != nil {
-		s.logger.Error().
+		logger.Debug().
 			Err(err).
 			Str("key", key).
 			Msg("could not get the thumbnail")
@@ -88,7 +89,7 @@ func (s Thumbnails) GetThumbnail(w http.ResponseWriter, r *http.Request) {
 	w.WriteHeader(http.StatusOK)
 	w.Header().Set("Content-Length", strconv.Itoa(len(thumbnail)))
 	if _, err = w.Write(thumbnail); err != nil {
-		s.logger.Error().
+		logger.Error().
 			Err(err).
 			Str("key", key).
 			Msg("could not write the thumbnail response")
@@ -97,6 +98,7 @@ func (s Thumbnails) GetThumbnail(w http.ResponseWriter, r *http.Request) {
 
 func (s Thumbnails) TransferTokenValidator(next http.Handler) http.Handler {
 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		logger := s.logger.SubloggerWithRequestID(r.Context())
 		tokenString := r.Header.Get("Transfer-Token")
 		token, err := jwt.ParseWithClaims(tokenString, &tjwt.ThumbnailClaims{}, func(token *jwt.Token) (interface{}, error) {
 			if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
@@ -105,7 +107,7 @@ func (s Thumbnails) TransferTokenValidator(next http.Handler) http.Handler {
 			return []byte(s.config.Thumbnail.TransferSecret), nil
 		})
 		if err != nil {
-			s.logger.Error().
+			logger.Debug().
 				Err(err).
 				Str("transfer-token", tokenString).
 				Msg("failed to parse transfer token")
@@ -118,6 +120,7 @@ func (s Thumbnails) TransferTokenValidator(next http.Handler) http.Handler {
 			next.ServeHTTP(w, r.WithContext(ctx))
 			return
 		}
+		logger.Debug().Msg("invalid transfer token")
 		w.WriteHeader(http.StatusUnauthorized)
 	})
 }
diff --git a/services/users/pkg/revaconfig/config.go b/services/users/pkg/revaconfig/config.go
index c00b31506f0..187381c020f 100644
--- a/services/users/pkg/revaconfig/config.go
+++ b/services/users/pkg/revaconfig/config.go
@@ -45,12 +45,6 @@ func UsersConfigFromStruct(cfg *config.Config) map[string]interface{} {
 					},
 				},
 			},
-			"interceptors": map[string]interface{}{
-				"prometheus": map[string]interface{}{
-					"namespace": "ocis",
-					"subsystem": "users",
-				},
-			},
 		},
 	}
 	return rcfg
diff --git a/services/web/pkg/assets/server.go b/services/web/pkg/assets/server.go
index af97f498dfe..527134330c8 100644
--- a/services/web/pkg/assets/server.go
+++ b/services/web/pkg/assets/server.go
@@ -22,24 +22,18 @@ func (f *fileServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	upath := path.Clean(path.Join("/", r.URL.Path))
 	r.URL.Path = upath
 
-	disableCache := func() {
-		w.Header().Set("Cache-Control", "no-cache")
-	}
-	handleIndex := func() {
-		disableCache()
-		r.URL.Path = "/index.html"
-		f.ServeHTTP(w, r)
-	}
 	asset, err := f.root.Open(upath)
 	if err != nil {
-		handleIndex()
+		r.URL.Path = "/index.html"
+		f.ServeHTTP(w, r)
 		return
 	}
 	defer asset.Close()
 
 	s, _ := asset.Stat()
 	if s.IsDir() {
-		handleIndex()
+		r.URL.Path = "/index.html"
+		f.ServeHTTP(w, r)
 		return
 	}
 
@@ -49,7 +43,6 @@ func (f *fileServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 
 	switch s.Name() {
 	case "index.html", "oidc-callback.html", "oidc-silent-redirect.html":
-		disableCache()
 		_ = withBase(buf, asset, "/")
 	default:
 		_, _ = buf.ReadFrom(asset)
diff --git a/services/web/pkg/service/v0/service.go b/services/web/pkg/service/v0/service.go
index a00e28bcdd9..d3aef6e4254 100644
--- a/services/web/pkg/service/v0/service.go
+++ b/services/web/pkg/service/v0/service.go
@@ -3,6 +3,7 @@ package svc
 import (
 	"encoding/json"
 	"fmt"
+	"io/ioutil"
 	"net/http"
 	"net/url"
 	"os"
@@ -89,7 +90,7 @@ func (p Web) getPayload() (payload []byte, err error) {
 			Msg("web config doesn't exist")
 	}
 
-	payload, err = os.ReadFile(p.config.Web.Path)
+	payload, err = ioutil.ReadFile(p.config.Web.Path)
 
 	if err != nil {
 		p.logger.Fatal().
@@ -101,7 +102,7 @@ func (p Web) getPayload() (payload []byte, err error) {
 }
 
 // Config implements the Service interface.
-func (p Web) Config(w http.ResponseWriter, _ *http.Request) {
+func (p Web) Config(w http.ResponseWriter, r *http.Request) {
 
 	payload, err := p.getPayload()
 	if err != nil {
diff --git a/services/webdav/pkg/service/v0/search.go b/services/webdav/pkg/service/v0/search.go
index 6c5a3d66cbd..d53969fe54b 100644
--- a/services/webdav/pkg/service/v0/search.go
+++ b/services/webdav/pkg/service/v0/search.go
@@ -31,16 +31,17 @@ const (
 
 // Search is the endpoint for retrieving search results for REPORT requests
 func (g Webdav) Search(w http.ResponseWriter, r *http.Request) {
+	logger := g.log.SubloggerWithRequestID(r.Context())
 	rep, err := readReport(r.Body)
 	if err != nil {
 		renderError(w, r, errBadRequest(err.Error()))
-		g.log.Error().Err(err).Msg("error reading report")
+		logger.Debug().Err(err).Msg("error reading report")
 		return
 	}
 
 	if rep.SearchFiles == nil {
 		renderError(w, r, errBadRequest("missing search-files tag"))
-		g.log.Error().Err(err).Msg("error reading report")
+		logger.Debug().Err(err).Msg("error reading report")
 		return
 	}
 
@@ -58,7 +59,7 @@ func (g Webdav) Search(w http.ResponseWriter, r *http.Request) {
 		space := strings.TrimPrefix(r.URL.Path, "/dav/spaces/")
 		rid, err := storagespace.ParseID(space)
 		if err != nil {
-			g.log.Error().Err(err).Msg("error parsing the space id for filtering")
+			logger.Debug().Err(err).Msg("error parsing the space id for filtering")
 		} else {
 			req.Ref = &searchmsg.Reference{
 				ResourceId: &searchmsg.ResourceID{
@@ -79,7 +80,7 @@ func (g Webdav) Search(w http.ResponseWriter, r *http.Request) {
 		default:
 			renderError(w, r, errInternalError(err.Error()))
 		}
-		g.log.Error().Err(err).Msg("could not get search results")
+		logger.Error().Err(err).Msg("could not get search results")
 		return
 	}
 
@@ -87,9 +88,10 @@ func (g Webdav) Search(w http.ResponseWriter, r *http.Request) {
 }
 
 func (g Webdav) sendSearchResponse(rsp *searchsvc.SearchResponse, w http.ResponseWriter, r *http.Request) {
+	logger := g.log.SubloggerWithRequestID(r.Context())
 	responsesXML, err := multistatusResponse(r.Context(), rsp.Matches)
 	if err != nil {
-		g.log.Error().Err(err).Msg("error formatting propfind")
+		logger.Error().Err(err).Msg("error formatting propfind")
 		w.WriteHeader(http.StatusInternalServerError)
 		return
 	}
@@ -100,7 +102,7 @@ func (g Webdav) sendSearchResponse(rsp *searchsvc.SearchResponse, w http.Respons
 	}
 	w.WriteHeader(http.StatusMultiStatus)
 	if _, err := w.Write(responsesXML); err != nil {
-		g.log.Err(err).Msg("error writing response")
+		logger.Err(err).Msg("error writing response")
 	}
 }
 
diff --git a/services/webdav/pkg/service/v0/service.go b/services/webdav/pkg/service/v0/service.go
index 13e74c90648..1daa30deb86 100644
--- a/services/webdav/pkg/service/v0/service.go
+++ b/services/webdav/pkg/service/v0/service.go
@@ -209,9 +209,10 @@ func (g Webdav) WebDAVContext() func(next http.Handler) http.Handler {
 
 // SpacesThumbnail is the endpoint for retrieving thumbnails inside of spaces.
 func (g Webdav) SpacesThumbnail(w http.ResponseWriter, r *http.Request) {
+	logger := g.log.SubloggerWithRequestID(r.Context())
 	tr, err := requests.ParseThumbnailRequest(r)
 	if err != nil {
-		g.log.Error().Err(err).Msg("could not create Request")
+		logger.Debug().Err(err).Msg("could not create Request")
 		renderError(w, r, errBadRequest(err.Error()))
 		return
 	}
@@ -242,7 +243,7 @@ func (g Webdav) SpacesThumbnail(w http.ResponseWriter, r *http.Request) {
 		default:
 			renderError(w, r, errInternalError(err.Error()))
 		}
-		g.log.Error().Err(err).Msg("could not get thumbnail")
+		logger.Debug().Err(err).Msg("could not get thumbnail")
 		return
 	}
 
@@ -251,9 +252,10 @@ func (g Webdav) SpacesThumbnail(w http.ResponseWriter, r *http.Request) {
 
 // Thumbnail implements the Service interface.
 func (g Webdav) Thumbnail(w http.ResponseWriter, r *http.Request) {
+	logger := g.log.SubloggerWithRequestID(r.Context())
 	tr, err := requests.ParseThumbnailRequest(r)
 	if err != nil {
-		g.log.Error().Err(err).Msg("could not create Request")
+		logger.Debug().Err(err).Msg("could not create Request")
 		renderError(w, r, errBadRequest(err.Error()))
 		return
 	}
@@ -267,8 +269,13 @@ func (g Webdav) Thumbnail(w http.ResponseWriter, r *http.Request) {
 		userRes, err := g.revaClient.WhoAmI(r.Context(), &gatewayv1beta1.WhoAmIRequest{
 			Token: t,
 		})
-		if err != nil || userRes.Status.Code != rpcv1beta1.Code_CODE_OK {
-			g.log.Error().Err(err).Msg("could not get user")
+		if err != nil {
+			logger.Error().Err(err).Msg("could not get user: transport error")
+			renderError(w, r, errInternalError("could not get user"))
+			return
+		}
+		if userRes.Status.Code != rpcv1beta1.Code_CODE_OK {
+			logger.Debug().Str("grpcmessage", userRes.GetStatus().GetMessage()).Msg("could not get user")
 			renderError(w, r, errInternalError("could not get user"))
 			return
 		}
@@ -280,8 +287,13 @@ func (g Webdav) Thumbnail(w http.ResponseWriter, r *http.Request) {
 			Claim: "username",
 			Value: tr.Identifier,
 		})
-		if err != nil || userRes.Status.Code != rpcv1beta1.Code_CODE_OK {
-			g.log.Error().Err(err).Msg("could not get user")
+		if err != nil {
+			logger.Error().Err(err).Msg("could not get user: transport error")
+			renderError(w, r, errInternalError("could not get user"))
+			return
+		}
+		if userRes.Status.Code != rpcv1beta1.Code_CODE_OK {
+			logger.Debug().Str("grpcmessage", userRes.GetStatus().GetMessage()).Msg("could not get user")
 			renderError(w, r, errInternalError("could not get user"))
 			return
 		}
@@ -321,9 +333,10 @@ func (g Webdav) Thumbnail(w http.ResponseWriter, r *http.Request) {
 }
 
 func (g Webdav) PublicThumbnail(w http.ResponseWriter, r *http.Request) {
+	logger := g.log.SubloggerWithRequestID(r.Context())
 	tr, err := requests.ParseThumbnailRequest(r)
 	if err != nil {
-		g.log.Error().Err(err).Msg("could not create Request")
+		logger.Debug().Err(err).Msg("could not create Request")
 		renderError(w, r, errBadRequest(err.Error()))
 		return
 	}
@@ -361,9 +374,10 @@ func (g Webdav) PublicThumbnail(w http.ResponseWriter, r *http.Request) {
 }
 
 func (g Webdav) PublicThumbnailHead(w http.ResponseWriter, r *http.Request) {
+	logger := g.log.SubloggerWithRequestID(r.Context())
 	tr, err := requests.ParseThumbnailRequest(r)
 	if err != nil {
-		g.log.Error().Err(err).Msg("could not create Request")
+		logger.Debug().Err(err).Msg("could not create Request")
 		renderError(w, r, errBadRequest(err.Error()))
 		return
 	}
@@ -393,7 +407,7 @@ func (g Webdav) PublicThumbnailHead(w http.ResponseWriter, r *http.Request) {
 		default:
 			renderError(w, r, errInternalError(err.Error()))
 		}
-		g.log.Error().Err(err).Msg("could not get thumbnail")
+		logger.Debug().Err(err).Msg("could not get thumbnail")
 		return
 	}
 
@@ -401,6 +415,7 @@ func (g Webdav) PublicThumbnailHead(w http.ResponseWriter, r *http.Request) {
 }
 
 func (g Webdav) sendThumbnailResponse(rsp *thumbnailssvc.GetThumbnailResponse, w http.ResponseWriter, r *http.Request) {
+	logger := g.log.SubloggerWithRequestID(r.Context())
 	client := &http.Client{
 		// Timeout: time.Second * 5,
 	}
@@ -408,7 +423,7 @@ func (g Webdav) sendThumbnailResponse(rsp *thumbnailssvc.GetThumbnailResponse, w
 	dlReq, err := http.NewRequest(http.MethodGet, rsp.DataEndpoint, http.NoBody)
 	if err != nil {
 		renderError(w, r, errInternalError(err.Error()))
-		g.log.Error().Err(err).Msg("could not download thumbnail")
+		logger.Error().Err(err).Msg("could not create download thumbnail request")
 		return
 	}
 	dlReq.Header.Set("Transfer-Token", rsp.TransferToken)
@@ -416,13 +431,13 @@ func (g Webdav) sendThumbnailResponse(rsp *thumbnailssvc.GetThumbnailResponse, w
 	dlRsp, err := client.Do(dlReq)
 	if err != nil {
 		renderError(w, r, errInternalError(err.Error()))
-		g.log.Error().Err(err).Msg("could not download thumbnail")
+		logger.Error().Err(err).Msg("could not download thumbnail: transport error")
 		return
 	}
 	defer dlRsp.Body.Close()
 
 	if dlRsp.StatusCode != http.StatusOK {
-		g.log.Error().
+		logger.Debug().
 			Str("transfer_token", rsp.TransferToken).
 			Str("data_endpoint", rsp.DataEndpoint).
 			Str("response_status", dlRsp.Status).
@@ -435,7 +450,7 @@ func (g Webdav) sendThumbnailResponse(rsp *thumbnailssvc.GetThumbnailResponse, w
 	w.Header().Set("Content-Type", rsp.Mimetype)
 	_, err = io.Copy(w, dlRsp.Body)
 	if err != nil {
-		g.log.Error().Err(err).Msg("failed to write thumbnail to response writer")
+		logger.Error().Err(err).Msg("failed to write thumbnail to response writer")
 	}
 }
 


Test patch:
diff --git a/services/search/pkg/search/provider/events_test.go b/services/search/pkg/search/provider/events_test.go
index 73ca2a17c78..1917b732697 100644
--- a/services/search/pkg/search/provider/events_test.go
+++ b/services/search/pkg/search/provider/events_test.go
@@ -2,19 +2,16 @@ package provider_test
 
 import (
 	"context"
-	"time"
 
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
 	"github.com/stretchr/testify/mock"
 
 	gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
-	user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
 	userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
 	sprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
 	"github.com/cs3org/reva/v2/pkg/events"
 	"github.com/cs3org/reva/v2/pkg/rgrpc/status"
-	"github.com/cs3org/reva/v2/pkg/utils"
 	cs3mocks "github.com/cs3org/reva/v2/tests/cs3mocks/mocks"
 	"github.com/owncloud/ocis/v2/ocis-pkg/log"
 	"github.com/owncloud/ocis/v2/services/search/pkg/search/mocks"
@@ -23,10 +20,9 @@ import (
 
 var _ = Describe("Searchprovider", func() {
 	var (
-		p                   *provider.Provider
-		gwClient            *cs3mocks.GatewayAPIClient
-		indexClient         *mocks.IndexClient
-		debouncedIndexCalls int
+		p           *provider.Provider
+		gwClient    *cs3mocks.GatewayAPIClient
+		indexClient *mocks.IndexClient
 
 		ctx        context.Context
 		eventsChan chan interface{}
@@ -52,9 +48,8 @@ var _ = Describe("Searchprovider", func() {
 				SpaceId:   "rootopaqueid",
 				OpaqueId:  "opaqueid",
 			},
-			Path:  "foo.pdf",
-			Size:  12345,
-			Mtime: utils.TimeToTS(time.Now().Add(-time.Hour)),
+			Path: "foo.pdf",
+			Size: 12345,
 		}
 	)
 
@@ -64,12 +59,7 @@ var _ = Describe("Searchprovider", func() {
 		gwClient = &cs3mocks.GatewayAPIClient{}
 		indexClient = &mocks.IndexClient{}
 
-		debouncedIndexCalls = 0
-		debouncer := provider.NewSpaceDebouncer(100*time.Millisecond, func(id *sprovider.StorageSpaceId, userID *userv1beta1.UserId) {
-			debouncedIndexCalls += 1
-		})
-
-		p = provider.NewWithDebouncer(gwClient, indexClient, "", eventsChan, logger, debouncer)
+		p = provider.New(gwClient, indexClient, "", eventsChan, logger)
 
 		gwClient.On("Authenticate", mock.Anything, mock.Anything).Return(&gateway.AuthenticateResponse{
 			Status: status.NewOK(ctx),
@@ -101,25 +91,37 @@ var _ = Describe("Searchprovider", func() {
 			})
 
 			It("triggers an index update when a file has been uploaded", func() {
+				called := false
+				indexClient.On("Add", mock.Anything, mock.MatchedBy(func(riToIndex *sprovider.ResourceInfo) bool {
+					return riToIndex.Id.OpaqueId == ri.Id.OpaqueId
+				})).Return(nil).Run(func(args mock.Arguments) {
+					called = true
+				})
 				eventsChan <- events.FileUploaded{
 					Ref:       ref,
 					Executant: user.Id,
 				}
 
-				Eventually(func() int {
-					return debouncedIndexCalls
-				}, "2s").Should(Equal(1))
+				Eventually(func() bool {
+					return called
+				}, "2s").Should(BeTrue())
 			})
 
 			It("triggers an index update when a file has been touched", func() {
+				called := false
+				indexClient.On("Add", mock.Anything, mock.MatchedBy(func(riToIndex *sprovider.ResourceInfo) bool {
+					return riToIndex.Id.OpaqueId == ri.Id.OpaqueId
+				})).Return(nil).Run(func(args mock.Arguments) {
+					called = true
+				})
 				eventsChan <- events.FileTouched{
 					Ref:       ref,
 					Executant: user.Id,
 				}
 
-				Eventually(func() int {
-					return debouncedIndexCalls
-				}, "2s").Should(Equal(1))
+				Eventually(func() bool {
+					return called
+				}, "2s").Should(BeTrue())
 			})
 
 			It("removes an entry from the index when the file has been deleted", func() {
@@ -161,14 +163,20 @@ var _ = Describe("Searchprovider", func() {
 			})
 
 			It("indexes items when a version has been restored", func() {
+				called := false
+				indexClient.On("Add", mock.Anything, mock.MatchedBy(func(riToIndex *sprovider.ResourceInfo) bool {
+					return riToIndex.Id.OpaqueId == ri.Id.OpaqueId
+				})).Return(nil).Run(func(args mock.Arguments) {
+					called = true
+				})
 				eventsChan <- events.FileVersionRestored{
 					Ref:       ref,
 					Executant: user.Id,
 				}
 
-				Eventually(func() int {
-					return debouncedIndexCalls
-				}, "2s").Should(Equal(1))
+				Eventually(func() bool {
+					return called
+				}, "2s").Should(BeTrue())
 			})
 		})
 
@@ -195,50 +203,3 @@ var _ = Describe("Searchprovider", func() {
 		})
 	})
 })
-
-var _ = Describe("SpaceDebouncer", func() {
-	var (
-		debouncer *provider.SpaceDebouncer
-		callCount map[string]int
-
-		userId = &user.UserId{
-			OpaqueId: "user",
-		}
-	)
-
-	BeforeEach(func() {
-		callCount = map[string]int{}
-		debouncer = provider.NewSpaceDebouncer(50*time.Millisecond, func(id *sprovider.StorageSpaceId, _ *user.UserId) {
-			callCount[id.OpaqueId] += 1
-		})
-	})
-
-	It("debounces", func() {
-		spaceid := &sprovider.StorageSpaceId{
-			OpaqueId: "spaceid",
-		}
-		debouncer.Debounce(spaceid, userId)
-		debouncer.Debounce(spaceid, userId)
-		debouncer.Debounce(spaceid, userId)
-		Eventually(func() int {
-			return callCount["spaceid"]
-		}, "200ms").Should(Equal(1))
-	})
-
-	It("works multiple times", func() {
-		spaceid := &sprovider.StorageSpaceId{
-			OpaqueId: "spaceid",
-		}
-		debouncer.Debounce(spaceid, userId)
-		debouncer.Debounce(spaceid, userId)
-		debouncer.Debounce(spaceid, userId)
-		time.Sleep(100 * time.Millisecond)
-
-		debouncer.Debounce(spaceid, userId)
-		debouncer.Debounce(spaceid, userId)
-
-		Eventually(func() int {
-			return callCount["spaceid"]
-		}, "200ms").Should(Equal(2))
-	})
-})
diff --git a/services/search/pkg/search/provider/searchprovider_test.go b/services/search/pkg/search/provider/searchprovider_test.go
index 58439198763..933200ab4cf 100644
--- a/services/search/pkg/search/provider/searchprovider_test.go
+++ b/services/search/pkg/search/provider/searchprovider_test.go
@@ -2,7 +2,6 @@ package provider_test
 
 import (
 	"context"
-	"time"
 
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
@@ -13,7 +12,6 @@ import (
 	sprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
 	typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
 	"github.com/cs3org/reva/v2/pkg/rgrpc/status"
-	"github.com/cs3org/reva/v2/pkg/utils"
 	cs3mocks "github.com/cs3org/reva/v2/tests/cs3mocks/mocks"
 	"github.com/owncloud/ocis/v2/ocis-pkg/log"
 	searchmsg "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/search/v0"
@@ -61,9 +59,8 @@ var _ = Describe("Searchprovider", func() {
 				StorageId: "storageid",
 				OpaqueId:  "opaqueid",
 			},
-			Path:  "foo.pdf",
-			Size:  12345,
-			Mtime: utils.TimeToTS(time.Now().Add(-time.Hour)),
+			Path: "foo.pdf",
+			Size: 12345,
 		}
 	)
 
@@ -108,7 +105,6 @@ var _ = Describe("Searchprovider", func() {
 			indexClient.On("Add", mock.Anything, mock.MatchedBy(func(riToIndex *sprovider.ResourceInfo) bool {
 				return riToIndex.Id.OpaqueId == ri.Id.OpaqueId
 			})).Return(nil)
-			indexClient.On("Search", mock.Anything, mock.Anything).Return(&searchsvc.SearchIndexResponse{}, nil)
 
 			res, err := p.IndexSpace(ctx, &searchsvc.IndexSpaceRequest{
 				SpaceId: "storageid$spaceid!spaceid",
diff --git a/tests/acceptance/expected-failures-API-on-OCIS-storage.md b/tests/acceptance/expected-failures-API-on-OCIS-storage.md
index ce2d76b5acf..94d4d3c8c72 100644
--- a/tests/acceptance/expected-failures-API-on-OCIS-storage.md
+++ b/tests/acceptance/expected-failures-API-on-OCIS-storage.md
@@ -566,6 +566,8 @@ _ocdav: api compatibility, return correct status code_
 
 - [apiAuthWebDav/webDavSpecialURLs.feature:13](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiAuthWebDav/webDavSpecialURLs.feature#L13)
 - [apiAuthWebDav/webDavSpecialURLs.feature:24](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiAuthWebDav/webDavSpecialURLs.feature#L24)
+- [apiAuthWebDav/webDavSpecialURLs.feature:34](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiAuthWebDav/webDavSpecialURLs.feature#L34)
+- [apiAuthWebDav/webDavSpecialURLs.feature:45](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiAuthWebDav/webDavSpecialURLs.feature#L45)
 - [apiAuthWebDav/webDavSpecialURLs.feature:55](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiAuthWebDav/webDavSpecialURLs.feature#L55)
 - [apiAuthWebDav/webDavSpecialURLs.feature:66](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiAuthWebDav/webDavSpecialURLs.feature#L66)
 - [apiAuthWebDav/webDavSpecialURLs.feature:76](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiAuthWebDav/webDavSpecialURLs.feature#L76)
@@ -585,7 +587,7 @@ _ocdav: api compatibility, return correct status code_
 
 - [apiCapabilities/capabilitiesWithNormalUser.feature:11](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiCapabilities/capabilitiesWithNormalUser.feature#L11)
 
-#### [[old/new/spaces] In ocis and oc10, REPORT request response differently](https://github.com/owncloud/ocis/issues/4712)
+#### [/webdav and spaces endpoint does not allow REPORT requests](https://github.com/owncloud/ocis/issues/4034)
 
 - [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)
diff --git a/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md b/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md
index 9451012e5ae..97d70fbb5d3 100644
--- a/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md
+++ b/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md
@@ -37,8 +37,3 @@ The expected failures in this file are from features in the owncloud/ocis repo.
 - [apiSpacesShares/shareUploadTUS.feature:204](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpacesShares/shareUploadTUS.feature#L204)
 - [apiSpacesShares/shareUploadTUS.feature:219](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpacesShares/shareUploadTUS.feature#L219)
 - [apiSpacesShares/shareUploadTUS.feature:284](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpacesShares/shareUploadTUS.feature#L284)
-
-### [Copy or move on an existing resource doesn't create a new version but deletes instead](https://github.com/owncloud/ocis/issues/4797)
-- [apiSpacesShares/moveSpaces.feature:304](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpacesShares/moveSpaces.feature#L304)
-- [apiSpacesShares/copySpaces.feature:711](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpacesShares/copySpaces.feature#L711)
-- [apiSpacesShares/copySpaces.feature:748](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpacesShares/copySpaces.feature#L748)
diff --git a/tests/acceptance/expected-failures-webUI-on-OCIS-storage.md b/tests/acceptance/expected-failures-webUI-on-OCIS-storage.md
index b4b104ef518..a85398e67b6 100644
--- a/tests/acceptance/expected-failures-webUI-on-OCIS-storage.md
+++ b/tests/acceptance/expected-failures-webUI-on-OCIS-storage.md
@@ -34,6 +34,17 @@ Other free text and Markdown formatting can be used elsewhere in the document if
 ### [when sharer renames the shared resource, sharee get the updated name](https://github.com/owncloud/ocis/issues/2256)
 - [webUIRenameFiles/renameFiles.feature:234](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIRenameFiles/renameFiles.feature#L234)
 
+### [No share indicators inside share jail](https://github.com/owncloud/web/issues/6894)
+- [webUISharingInternalUsersSharingIndicator/shareWithUsers.feature:100](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingInternalUsersSharingIndicator/shareWithUsers.feature#L100)
+- [webUISharingInternalUsersSharingIndicator/shareWithUsers.feature:121](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingInternalUsersSharingIndicator/shareWithUsers.feature#L121)
+- [webUISharingPublicManagement/publicLinkIndicator.feature:64](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingPublicManagement/publicLinkIndicator.feature#L64)
+- [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: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)
+
 ### [Scoped links](https://github.com/owncloud/web/issues/6844)
 - [webUIFilesCopy/copyPrivateLinks.feature:20](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFilesCopy/copyPrivateLinks.feature#L20)
 - [webUIFilesCopy/copyPrivateLinks.feature:21](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFilesCopy/copyPrivateLinks.feature#L21)
diff --git a/tests/acceptance/features/apiSpaces/search.feature b/tests/acceptance/features/apiSpaces/search.feature
index 3a6367bf310..8fcd40f5c57 100644
--- a/tests/acceptance/features/apiSpaces/search.feature
+++ b/tests/acceptance/features/apiSpaces/search.feature
@@ -13,8 +13,8 @@ Feature: Search
     And using spaces DAV path
     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 "folderMain/SubFolder1/subFOLDER2" in space "find data"
-    And user "Alice" has uploaded a file inside space "find data" with content "some content" to "folderMain/SubFolder1/subFOLDER2/insideTheFolder.txt"
+    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"
     And using new DAV path
 
   Scenario: Alice can find data from the project space
@@ -22,10 +22,10 @@ Feature: Search
     Then the HTTP status code should be "207"
     And the search result should contain "4" entries
     And the search result of user "Alice" should contain these entries:
-      | /folderMain                                           |
-      | /folderMain/SubFolder1                                |
-      | /folderMain/SubFolder1/subFOLDER2                     |
-      | /folderMain/SubFolder1/subFOLDER2/insideTheFolder.txt |
+      | /folder                                           |
+      | /folder/SubFolder1                                |
+      | /folder/SubFolder1/subFOLDER2                     |
+      | /folder/SubFolder1/subFOLDER2/insideTheFolder.txt |
 
 
   Scenario: Alice can find data from the project space
@@ -33,16 +33,16 @@ Feature: Search
     Then the HTTP status code should be "207"
     And the search result should contain "2" entries
     And the search result of user "Alice" should contain these entries:
-      | /folderMain/SubFolder1            |
-      | /folderMain/SubFolder1/subFOLDER2 |
+      | /folder/SubFolder1             |
+      | /folder/SubFolder1/subFOLDER2  |
     But the search result of user "Alice" should not contain these entries:
-      | /folderMain                                           |
-      | /folderMain/SubFolder1/subFOLDER2/insideTheFolder.txt |
+      | /folder                                           |
+      | /folder/SubFolder1/subFOLDER2/insideTheFolder.txt |
 
 
   Scenario: Brian can find data from the shares jail
-    Given user "Alice" shares the following entity "folderMain" inside of space "find data" with user "Brian" with role "viewer"
-    And user "Brian" has accepted share "/folderMain" offered by user "Alice"
+    Given user "Alice" shares the following entity "folder" inside of space "find data" with user "Brian" with role "viewer"
+    And user "Brian" has accepted share "/folder" offered by user "Alice"
     When user "Brian" searches for "folder" using the WebDAV API
     Then the HTTP status code should be "207"
     And the search result should contain "4" entries
@@ -50,7 +50,7 @@ Feature: Search
       | /SubFolder1                                |
       | /SubFolder1/subFOLDER2                     |
       | /SubFolder1/subFOLDER2/insideTheFolder.txt |
-    And for user "Brian" the search result should contain space "mountpoint/folderMain"
+    And for user "Brian" the search result should contain space "mountpoint/folder"
 
 
   Scenario: User can find hidden file
@@ -63,7 +63,7 @@ Feature: Search
 
 
   Scenario: User cannot find pending folder
-    Given user "Alice" shares the following entity "folderMain" inside of space "find data" with user "Brian" with role "viewer"
+    Given user "Alice" shares the following entity "folder" inside of space "find data" with user "Brian" with role "viewer"
     When user "Brian" searches for "folder" using the WebDAV API
     Then the HTTP status code should be "207"
     And the search result should contain "0" entries
@@ -74,8 +74,8 @@ Feature: Search
 
 
   Scenario: User cannot find declined folder
-    Given user "Alice" shares the following entity "folderMain" inside of space "find data" with user "Brian" with role "viewer"
-    And user "Brian" has declined share "/folderMain" offered by user "Alice"
+    Given user "Alice" shares the following entity "folder" inside of space "find data" with user "Brian" with role "viewer"
+    And user "Brian" has declined share "/folder" offered by user "Alice"
     When user "Brian" searches for "folder" using the WebDAV API
     Then the HTTP status code should be "207"
     And the search result should contain "0" entries
@@ -86,8 +86,8 @@ Feature: Search
 
 
   Scenario: User cannot find deleted folder
-    Given user "Alice" has removed the folder "folderMain" from space "find data"
-    When user "Alice" searches for "folderMain" using the WebDAV API
+    Given user "Alice" has removed the folder "folder" from space "find data"
+    When user "Alice" searches for "folder" using the WebDAV API
     Then the HTTP status code should be "207"
     And the search result should contain "0" entries
 
@@ -98,31 +98,3 @@ Feature: Search
     And the search result should contain "1" entries
     And for user "Alice" the search result should contain space "find data"
 
-
-  Scenario Outline: search result for project space contains resource parentID
-    When user "Alice" searches for "<searchObject>" using the WebDAV API
-    Then the HTTP status code should be "207"
-    And the search result should contain "1" entries
-    And the search result of user "Alice" should contain these entries:
-      | /<searchObject> |
-    And for user "Alice" the response should contains the parent "<parentFolder>" from space "find data"
-    Examples:
-      | searchObject        | parentFolder                     |
-      | SubFolder1          | folderMain                       |
-      | insideTheFolder.txt | folderMain/SubFolder1/subFOLDER2 |
-      | folderMain          | find data                        |
-
-
-  Scenario Outline: search result for shares jail contains resource parentID
-    Given user "Alice" shares the following entity "folderMain" inside of space "find data" with user "Brian" with role "viewer"
-    And user "Brian" has accepted share "/folderMain" offered by user "Alice"
-    When user "Brian" searches for "<searchObject>" using the WebDAV API
-    Then the HTTP status code should be "207"
-    And the search result should contain "1" entries
-    And the search result of user "Brian" should contain these entries:
-      | /<searchObject> |
-    And for user "Brian" the response should contains the parent "<parentFolder>" from mountpoint "folderMain"
-    Examples:
-      | searchObject        | parentFolder          |
-      | insideTheFolder.txt | SubFolder1/subFOLDER2 |
-      | SubFolder1          | folderMain            |
diff --git a/tests/acceptance/features/apiSpacesShares/changingFilesShare.feature b/tests/acceptance/features/apiSpacesShares/changingFilesShare.feature
index b609ab4d521..8ecb4c80017 100644
--- a/tests/acceptance/features/apiSpacesShares/changingFilesShare.feature
+++ b/tests/acceptance/features/apiSpacesShares/changingFilesShare.feature
@@ -28,8 +28,7 @@ Feature:
 
 
   Scenario: overwrite a received file share
-    Given user "Alice" has uploaded file with content "old content version 1" to "/textfile1.txt"
-    And user "Alice" has uploaded file with content "old content version 2" to "/textfile1.txt"
+    Given user "Alice" has uploaded file with content "this is the old content" to "/textfile1.txt"
     And user "Alice" has shared file "/textfile1.txt" with user "Brian"
     And user "Brian" has accepted share "/textfile1.txt" offered by user "Alice"
     When user "Brian" uploads a file inside space "Shares Jail" with content "this is a new content" to "textfile1.txt" using the WebDAV API
@@ -38,9 +37,3 @@ Feature:
       | textfile1.txt |
     And for user "Brian" the content of the file "/textfile1.txt" of the space "Shares Jail" should be "this is a new content"
     And for user "Alice" the content of the file "/textfile1.txt" of the space "Personal" should be "this is a new content"
-    When user "Alice" downloads version of the file "/textfile1.txt" with the index "2" of the space "Personal" using the WebDAV API
-    Then the HTTP status code should be "200"
-    And the downloaded content should be "old content version 1"
-    When user "Brian" downloads version of the file "/textfile1.txt" with the index "1" of the space "Shares Jail" using the WebDAV API
-    Then the HTTP status code should be "200"
-    And the downloaded content should be "old content version 2"
diff --git a/tests/acceptance/features/apiSpacesShares/copySpaces.feature b/tests/acceptance/features/apiSpacesShares/copySpaces.feature
index 5d7a47e7416..09de24ed33d 100644
--- a/tests/acceptance/features/apiSpacesShares/copySpaces.feature
+++ b/tests/acceptance/features/apiSpacesShares/copySpaces.feature
@@ -692,77 +692,3 @@ Feature: copy file
       | /second-level-folder/second-level-folder |
     And the response when user "Alice" gets the info of the last share should include
       | file_target | /Shares/BRIAN-FOLDER |
-
-
-  Scenario: Copying a file with an option "keep both" inside of the project space
-    Given the administrator has given "Alice" the role "Space Admin" using the settings api
-    And user "Alice" has created a space "Project" with the default quota using the GraphApi
-    And user "Alice" has created a folder "/newfolder" in space "Project"
-    And user "Alice" has uploaded a file inside space "Project" with content "some content" to "/newfolder/insideSpace.txt"
-    And user "Alice" has uploaded a file inside space "Project" with content "new content" to "/insideSpace.txt"
-    When user "Alice" copies file "/insideSpace.txt" to "/newfolder/insideSpace (1).txt" inside space "Project" using the WebDAV API
-    Then the HTTP status code should be "201"
-    And for user "Alice" the space "Project" should contain these entries:
-      | newfolder/insideSpace.txt     |
-      | newfolder/insideSpace (1).txt |
-    And for user "Alice" the content of the file "/newfolder/insideSpace (1).txt" of the space "Project" should be "new content"
-    
-
-  Scenario: Copying a file with an option "replace" inside of the project space
-    Given the administrator has given "Alice" the role "Space Admin" using the settings api
-    And user "Alice" has created a space "Project" with the default quota using the GraphApi
-    And user "Alice" has created a folder "/newfolder" in space "Project"
-    And user "Alice" has uploaded a file inside space "Project" with content "old content version 1" to "/newfolder/insideSpace.txt"
-    And user "Alice" has uploaded a file inside space "Project" with content "old content version 2" to "/newfolder/insideSpace.txt"
-    And user "Alice" has uploaded a file inside space "Project" with content "new content" to "/insideSpace.txt"
-    When user "Alice" overwrites file "/insideSpace.txt" from space "Project" to "/newfolder/insideSpace.txt" inside space "Project" while copying using the WebDAV API
-    Then the HTTP status code should be "204"
-    And for user "Alice" the content of the file "/newfolder/insideSpace.txt" of the space "Project" should be "new content"
-    When user "Alice" downloads version of the file "/newfolder/insideSpace.txt" with the index "2" of the space "Project" using the WebDAV API
-    Then the HTTP status code should be "200"
-    And the downloaded content should be "old content version 1"
-    When user "Alice" downloads version of the file "/newfolder/insideSpace.txt" with the index "1" of the space "Project" using the WebDAV API
-    Then the HTTP status code should be "200"
-    And the downloaded content should be "old content version 2"
-
-
-  Scenario: Copying a file from Personal to Shares Jail with an option "keep both"
-    Given the administrator has given "Alice" the role "Space Admin" using the settings api
-    And user "Alice" has created a space "Project" with the default quota using the GraphApi
-    And user "Alice" has created a folder "/newfolder" in space "Project"
-    And user "Alice" has uploaded a file inside space "Project" with content "some content" to "/newfolder/personal.txt"
-    And user "Alice" shares the following entity "newfolder" inside of space "Project" with user "Brian" with role "editor"
-    And user "Brian" has accepted share "/newfolder" offered by user "Alice"
-    And user "Brian" has uploaded file with content "new content" to "/personal.txt"
-    When user "Brian" copies file "/personal.txt" from space "Personal" to "/newfolder/personal (1).txt" inside space "Shares Jail" using the WebDAV API
-    Then the HTTP status code should be "201"
-    And for user "Alice" the space "Project" should contain these entries:
-      | newfolder/personal.txt     |
-      | newfolder/personal (1).txt |
-    And for user "Alice" the content of the file "/newfolder/personal (1).txt" of the space "Project" should be "new content"
-    And for user "Brian" the space "Shares Jail" should contain these entries:
-      | newfolder/personal.txt     |
-      | newfolder/personal (1).txt |
-
-
-  Scenario: Copying a file from Personal to Shares Jail with an option "replace"
-    Given the administrator has given "Alice" the role "Space Admin" using the settings api
-    And user "Alice" has created a space "Project" with the default quota using the GraphApi
-    And user "Alice" has created a folder "/newfolder" in space "Project"
-    And user "Alice" has uploaded a file inside space "Project" with content "old content version 1" to "/newfolder/personal.txt"
-    And user "Alice" has uploaded a file inside space "Project" with content "old content version 2" to "/newfolder/personal.txt"
-    And user "Alice" shares the following entity "newfolder" inside of space "Project" with user "Brian" with role "editor"
-    And user "Brian" has accepted share "/newfolder" offered by user "Alice"
-    And user "Brian" has uploaded file with content "new content" to "/personal.txt"
-    When user "Brian" overwrites file "/personal.txt" from space "Personal" to "/newfolder/personal.txt" inside space "Shares Jail" while copying using the WebDAV API
-    Then the HTTP status code should be "204"
-    And for user "Alice" the space "Project" should contain these entries:
-      | newfolder/personal.txt     |
-    And for user "Alice" the content of the file "/newfolder/personal.txt" of the space "Project" should be "new content"
-    When user "Alice" downloads version of the file "/newfolder/personal.txt" with the index "1" of the space "Project" using the WebDAV API
-    Then the HTTP status code should be "200"
-    And the downloaded content should be "old content version 2"
-    And for user "Brian" the content of the file "/newfolder/personal.txt" of the space "Shares Jail" should be "new content"
-    When user "Brian" downloads version of the file "/newfolder/personal.txt" with the index "2" of the space "Shares Jail" using the WebDAV API
-    Then the HTTP status code should be "200"
-    And the downloaded content should be "old content version 1"
diff --git a/tests/acceptance/features/apiSpacesShares/moveSpaces.feature b/tests/acceptance/features/apiSpacesShares/moveSpaces.feature
index cbbe0d440e6..4a04c377314 100644
--- a/tests/acceptance/features/apiSpacesShares/moveSpaces.feature
+++ b/tests/acceptance/features/apiSpacesShares/moveSpaces.feature
@@ -300,21 +300,3 @@ Feature: move (rename) file
       | testsubfolder |
     And for user "Brian" the space "Personal" should not contain these entries:
       | /testshare/testsubfolder |
-
-   Scenario: Overwriting a file while moving
-    Given user "Brian" has created folder "/folder"
-    And user "Brian" has uploaded file with content "old content version 1" to "/folder/testfile.txt"
-    And user "Brian" has uploaded file with content "old content version 2" to "/folder/testfile.txt"
-    And user "Brian" has uploaded file with content "new data" to "/testfile.txt"
-    When user "Brian" overwrites file "/testfile.txt" from space "Personal" to "folder/testfile.txt" inside space "Personal" while moving using the WebDAV API
-    Then the HTTP status code should be "204"
-    And the content of file "/folder/testfile.txt" for user "Brian" should be "new data"
-    And for user "Brian" the space "Personal" should not contain these entries:
-      | /testfile.txt |
-    When user "Brian" downloads version of the file "/folder/testfile.txt" with the index "1" of the space "Personal" using the WebDAV API
-    Then the HTTP status code should be "200"
-    And the downloaded content should be "old content version 2"
-    When user "Brian" downloads version of the file "/folder/testfile.txt" with the index "2" of the space "Personal" using the WebDAV API
-    Then the HTTP status code should be "200"
-    And the downloaded content should be "old content version 1"
-
diff --git a/tests/acceptance/features/bootstrap/SpacesContext.php b/tests/acceptance/features/bootstrap/SpacesContext.php
index 331e5c5ab98..6c5a2288028 100644
--- a/tests/acceptance/features/bootstrap/SpacesContext.php
+++ b/tests/acceptance/features/bootstrap/SpacesContext.php
@@ -332,38 +332,6 @@ class SpacesContext implements Context {
 		return $fileData["Oc-Fileid"][0];
 	}
 
-	/**
-	 * The method returns folderId
-	 *
-	 * @param string $user
-	 * @param string $spaceName
-	 * @param string $folderName
-	 *
-	 * @return string
-	 * @throws GuzzleException
-	 */
-	public function getFolderId(string $user, string $spaceName, string $folderName): string {
-		$space = $this->getSpaceByName($user, $spaceName);
-		// For a level 1 folder, the parent is space so $folderName = ''
-		if ($folderName === $space["name"]) {
-			$folderName = '';
-		}
-		$fullUrl = $this->baseUrl . $this->davSpacesUrl . $space["id"] . "/" . $folderName;
-		$this->featureContext->setResponse(
-			HttpRequestHelper::sendRequest(
-				$fullUrl,
-				$this->featureContext->getStepLineRef(),
-				'PROPFIND',
-				$user,
-				$this->featureContext->getPasswordForUser($user),
-				['Depth' => '0'],
-			)
-		);
-		$responseArray = json_decode(json_encode($this->featureContext->getResponseXml()->xpath("//d:response/d:propstat/d:prop/oc:fileid")), true, 512, JSON_THROW_ON_ERROR);
-		Assert::assertNotEmpty($responseArray, "the PROPFIND response for $folderName is empty");
-		return $responseArray[0][0];
-	}
-
 	/**
 	 * The method returns eTag
 	 *
@@ -1705,38 +1673,6 @@ class SpacesContext implements Context {
 		$this->copyFilesAndFoldersRequest($user, $fullUrl, $headers);
 	}
 
-	/**
-	 * @When /^user "([^"]*)" overwrites file "([^"]*)" from space "([^"]*)" to "([^"]*)" inside space "([^"]*)" while (copying|moving)\s? using the WebDAV API$/
-	 *
-	 * @param string $user
-	 * @param string $fileSource
-	 * @param string $fromSpaceName
-	 * @param string $fileDestination
-	 * @param string $toSpaceName
-	 * @param string $action
-	 *
-	 * @return void
-	 * @throws GuzzleException
-	 */
-	public function userOverwritesFileFromAndToSpaceBetweenSpaces(
-		string $user,
-		string $fileSource,
-		string $fromSpaceName,
-		string $fileDestination,
-		string $toSpaceName,
-		string $action
-	):void {
-		$space = $this->getSpaceByName($user, $fromSpaceName);
-		$headers['Destination'] = $this->destinationHeaderValueWithSpaceName($user, $fileDestination, $toSpaceName);
-		$headers['Overwrite'] = 'T';
-		$fullUrl = $space["root"]["webDavUrl"] . '/' . ltrim($fileSource, "/");
-		if ($action === 'copying') {
-			$this->copyFilesAndFoldersRequest($user, $fullUrl, $headers);
-		} else {
-			$this->moveFilesAndFoldersRequest($user, $fullUrl, $headers);
-		}
-	}
-
 	/**
 	 * @Then /^user "([^"]*)" should not be able to download file "([^"]*)" from space "([^"]*)"$/
 	 *
@@ -2993,21 +2929,4 @@ class SpacesContext implements Context {
 		}
 		Assert::assertTrue($spaceFound, "response does not contain the space '$spaceName'");
 	}
-
-	/**
-	 * @Then /^for user "([^"]*)" the response should contains the parent "([^"]*)" from (?:space|mountpoint) "([^"]*)"$/
-	 *
-	 * @param string $user
-	 * @param string $parent
-	 * @param string $space
-	 *
-	 * @return void
-	 * @throws GuzzleException
-	 */
-	public function responseShouldContainParent(string $user, string $parent, string $space): void {
-		// get a response after a Report request (called in the core)
-		$responseArray = json_decode(json_encode($this->featureContext->getResponseXml()->xpath("//d:response/d:propstat/d:prop/oc:file-parent")), true, 512, JSON_THROW_ON_ERROR);
-		Assert::assertNotEmpty($responseArray, "search result is empty");
-		Assert::assertEquals($this->getFolderId($user, $space, $parent), $responseArray[0][0], 'wrong file-parentId');
-	}
 }