Repository: owncloud/ocis
Pull request #5826 (2023-03-14 15:10:24)

Avoid repeated default role assignment
Avoid repeated default role assignments
    
When using the metadata storage (the current default) the default role
assignments were recreated at every start of the settings service. Leading to
duplicated role assignments
    
Fixes: #3432


Patch:
diff --git a/.bingo/Variables.mk b/.bingo/Variables.mk
index 559efc0369f..2dfa10bf8d6 100644
--- a/.bingo/Variables.mk
+++ b/.bingo/Variables.mk
@@ -1,4 +1,4 @@
-# Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.6. DO NOT EDIT.
+# Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.7. DO NOT EDIT.
 # All tools are designed to be build inside $GOBIN.
 BINGO_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
 GOPATH ?= $(shell go env GOPATH)
@@ -21,101 +21,95 @@ BINGO := $(GOBIN)/bingo-v0.7.0
 $(BINGO): $(BINGO_DIR)/bingo.mod
 	@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
 	@echo "(re)installing $(GOBIN)/bingo-v0.7.0"
-	@cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=bingo.mod -o=$(GOBIN)/bingo-v0.7.0 "github.com/bwplotka/bingo"
+	@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=bingo.mod -o=$(GOBIN)/bingo-v0.7.0 "github.com/bwplotka/bingo"
 
 BUF := $(GOBIN)/buf-v1.3.1
 $(BUF): $(BINGO_DIR)/buf.mod
 	@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
 	@echo "(re)installing $(GOBIN)/buf-v1.3.1"
-	@cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=buf.mod -o=$(GOBIN)/buf-v1.3.1 "github.com/bufbuild/buf/cmd/buf"
+	@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=buf.mod -o=$(GOBIN)/buf-v1.3.1 "github.com/bufbuild/buf/cmd/buf"
 
 BUILDIFIER := $(GOBIN)/buildifier-v0.0.0-20220323134444-a9f46b2bb3de
 $(BUILDIFIER): $(BINGO_DIR)/buildifier.mod
 	@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
 	@echo "(re)installing $(GOBIN)/buildifier-v0.0.0-20220323134444-a9f46b2bb3de"
-	@cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=buildifier.mod -o=$(GOBIN)/buildifier-v0.0.0-20220323134444-a9f46b2bb3de "github.com/bazelbuild/buildtools/buildifier"
+	@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=buildifier.mod -o=$(GOBIN)/buildifier-v0.0.0-20220323134444-a9f46b2bb3de "github.com/bazelbuild/buildtools/buildifier"
 
 CALENS := $(GOBIN)/calens-v0.2.0
 $(CALENS): $(BINGO_DIR)/calens.mod
 	@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
 	@echo "(re)installing $(GOBIN)/calens-v0.2.0"
-	@cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=calens.mod -o=$(GOBIN)/calens-v0.2.0 "github.com/restic/calens"
+	@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=calens.mod -o=$(GOBIN)/calens-v0.2.0 "github.com/restic/calens"
 
 GO_LICENSES := $(GOBIN)/go-licenses-v1.5.0
 $(GO_LICENSES): $(BINGO_DIR)/go-licenses.mod
 	@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
 	@echo "(re)installing $(GOBIN)/go-licenses-v1.5.0"
-	@cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=go-licenses.mod -o=$(GOBIN)/go-licenses-v1.5.0 "github.com/google/go-licenses"
-
-GO_XGETTEXT := $(GOBIN)/go-xgettext-v0.0.0-20160830220431-74466a0a0c4a
-$(GO_XGETTEXT): $(BINGO_DIR)/go-xgettext.mod
-	@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
-	@echo "(re)installing $(GOBIN)/go-xgettext-v0.0.0-20160830220431-74466a0a0c4a"
-	@cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=go-xgettext.mod -o=$(GOBIN)/go-xgettext-v0.0.0-20160830220431-74466a0a0c4a "github.com/gosexy/gettext/go-xgettext"
+	@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=go-licenses.mod -o=$(GOBIN)/go-licenses-v1.5.0 "github.com/google/go-licenses"
 
 GOLANGCI_LINT := $(GOBIN)/golangci-lint-v1.47.3
 $(GOLANGCI_LINT): $(BINGO_DIR)/golangci-lint.mod
 	@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
 	@echo "(re)installing $(GOBIN)/golangci-lint-v1.47.3"
-	@cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=golangci-lint.mod -o=$(GOBIN)/golangci-lint-v1.47.3 "github.com/golangci/golangci-lint/cmd/golangci-lint"
+	@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=golangci-lint.mod -o=$(GOBIN)/golangci-lint-v1.47.3 "github.com/golangci/golangci-lint/cmd/golangci-lint"
 
 HUGO := $(GOBIN)/hugo-v0.94.0
 $(HUGO): $(BINGO_DIR)/hugo.mod
 	@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
 	@echo "(re)installing $(GOBIN)/hugo-v0.94.0"
-	@cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=hugo.mod -o=$(GOBIN)/hugo-v0.94.0 "github.com/gohugoio/hugo"
+	@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=hugo.mod -o=$(GOBIN)/hugo-v0.94.0 "github.com/gohugoio/hugo"
 
 MOCKERY := $(GOBIN)/mockery-v2.14.1
 $(MOCKERY): $(BINGO_DIR)/mockery.mod
 	@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
 	@echo "(re)installing $(GOBIN)/mockery-v2.14.1"
-	@cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=mockery.mod -o=$(GOBIN)/mockery-v2.14.1 "github.com/vektra/mockery/v2"
+	@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=mockery.mod -o=$(GOBIN)/mockery-v2.14.1 "github.com/vektra/mockery/v2"
 
 MUTAGEN := $(GOBIN)/mutagen-v0.13.1
 $(MUTAGEN): $(BINGO_DIR)/mutagen.mod
 	@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
 	@echo "(re)installing $(GOBIN)/mutagen-v0.13.1"
-	@cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=mutagen.mod -o=$(GOBIN)/mutagen-v0.13.1 "github.com/mutagen-io/mutagen/cmd/mutagen"
+	@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=mutagen.mod -o=$(GOBIN)/mutagen-v0.13.1 "github.com/mutagen-io/mutagen/cmd/mutagen"
 
 PROTOC_GEN_DOC := $(GOBIN)/protoc-gen-doc-v1.5.1
 $(PROTOC_GEN_DOC): $(BINGO_DIR)/protoc-gen-doc.mod
 	@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
 	@echo "(re)installing $(GOBIN)/protoc-gen-doc-v1.5.1"
-	@cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=protoc-gen-doc.mod -o=$(GOBIN)/protoc-gen-doc-v1.5.1 "github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc"
+	@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=protoc-gen-doc.mod -o=$(GOBIN)/protoc-gen-doc-v1.5.1 "github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc"
 
 PROTOC_GEN_GO := $(GOBIN)/protoc-gen-go-v1.28.1
 $(PROTOC_GEN_GO): $(BINGO_DIR)/protoc-gen-go.mod
 	@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
 	@echo "(re)installing $(GOBIN)/protoc-gen-go-v1.28.1"
-	@cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=protoc-gen-go.mod -o=$(GOBIN)/protoc-gen-go-v1.28.1 "google.golang.org/protobuf/cmd/protoc-gen-go"
+	@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=protoc-gen-go.mod -o=$(GOBIN)/protoc-gen-go-v1.28.1 "google.golang.org/protobuf/cmd/protoc-gen-go"
 
 PROTOC_GEN_MICRO := $(GOBIN)/protoc-gen-micro-v1.0.0
 $(PROTOC_GEN_MICRO): $(BINGO_DIR)/protoc-gen-micro.mod
 	@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
 	@echo "(re)installing $(GOBIN)/protoc-gen-micro-v1.0.0"
-	@cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=protoc-gen-micro.mod -o=$(GOBIN)/protoc-gen-micro-v1.0.0 "github.com/go-micro/generator/cmd/protoc-gen-micro"
+	@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=protoc-gen-micro.mod -o=$(GOBIN)/protoc-gen-micro-v1.0.0 "github.com/go-micro/generator/cmd/protoc-gen-micro"
 
 PROTOC_GEN_MICROWEB := $(GOBIN)/protoc-gen-microweb-v0.0.0-20220808092353-b5d6c3960e19
 $(PROTOC_GEN_MICROWEB): $(BINGO_DIR)/protoc-gen-microweb.mod
 	@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
 	@echo "(re)installing $(GOBIN)/protoc-gen-microweb-v0.0.0-20220808092353-b5d6c3960e19"
-	@cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=protoc-gen-microweb.mod -o=$(GOBIN)/protoc-gen-microweb-v0.0.0-20220808092353-b5d6c3960e19 "github.com/owncloud/protoc-gen-microweb"
+	@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=protoc-gen-microweb.mod -o=$(GOBIN)/protoc-gen-microweb-v0.0.0-20220808092353-b5d6c3960e19 "github.com/owncloud/protoc-gen-microweb"
 
 PROTOC_GEN_OPENAPIV2 := $(GOBIN)/protoc-gen-openapiv2-v2.13.0
 $(PROTOC_GEN_OPENAPIV2): $(BINGO_DIR)/protoc-gen-openapiv2.mod
 	@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
 	@echo "(re)installing $(GOBIN)/protoc-gen-openapiv2-v2.13.0"
-	@cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=protoc-gen-openapiv2.mod -o=$(GOBIN)/protoc-gen-openapiv2-v2.13.0 "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2"
+	@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=protoc-gen-openapiv2.mod -o=$(GOBIN)/protoc-gen-openapiv2-v2.13.0 "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2"
 
 PROTOC_GO_INJECT_TAG := $(GOBIN)/protoc-go-inject-tag-v1.4.0
 $(PROTOC_GO_INJECT_TAG): $(BINGO_DIR)/protoc-go-inject-tag.mod
 	@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
 	@echo "(re)installing $(GOBIN)/protoc-go-inject-tag-v1.4.0"
-	@cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=protoc-go-inject-tag.mod -o=$(GOBIN)/protoc-go-inject-tag-v1.4.0 "github.com/favadi/protoc-go-inject-tag"
+	@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=protoc-go-inject-tag.mod -o=$(GOBIN)/protoc-go-inject-tag-v1.4.0 "github.com/favadi/protoc-go-inject-tag"
 
 REFLEX := $(GOBIN)/reflex-v0.3.1
 $(REFLEX): $(BINGO_DIR)/reflex.mod
 	@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
 	@echo "(re)installing $(GOBIN)/reflex-v0.3.1"
-	@cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=reflex.mod -o=$(GOBIN)/reflex-v0.3.1 "github.com/cespare/reflex"
+	@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=reflex.mod -o=$(GOBIN)/reflex-v0.3.1 "github.com/cespare/reflex"
 
diff --git a/.bingo/variables.env b/.bingo/variables.env
index 6ccf239b2d9..2044ef41123 100644
--- a/.bingo/variables.env
+++ b/.bingo/variables.env
@@ -1,4 +1,4 @@
-# Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.6. DO NOT EDIT.
+# Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.7. DO NOT EDIT.
 # All tools are designed to be build inside $GOBIN.
 # Those variables will work only until 'bingo get' was invoked, or if tools were installed via Makefile's Variables.mk.
 GOBIN=${GOBIN:=$(go env GOBIN)}
@@ -18,8 +18,6 @@ CALENS="${GOBIN}/calens-v0.2.0"
 
 GO_LICENSES="${GOBIN}/go-licenses-v1.5.0"
 
-GO_XGETTEXT="${GOBIN}/go-xgettext-v0.0.0-20160830220431-74466a0a0c4a"
-
 GOLANGCI_LINT="${GOBIN}/golangci-lint-v1.47.3"
 
 HUGO="${GOBIN}/hugo-v0.94.0"
diff --git a/.drone.star b/.drone.star
index 16cff1fb319..170c2c376d0 100644
--- a/.drone.star
+++ b/.drone.star
@@ -71,7 +71,6 @@ config = {
         "services/notifications",
         "services/ocdav",
         "services/ocs",
-        "services/policies",
         "services/proxy",
         "services/search",
         "services/settings",
@@ -86,7 +85,6 @@ config = {
         "services/users",
         "services/web",
         "services/webdav",
-        "services/webfinger",
         "ocis-pkg",
         "ocis",
     ],
diff --git a/.gitignore b/.gitignore
index ed822db682e..68c73746e07 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,6 +41,7 @@ vendor-php
 # drone CI is in .drone.star, do not let someone accidentally commit a local .drone.yml
 .drone.yml
 
+**/l10n/locale
 **/l10n/template.pot
 
 # protogen autogenerated
@@ -51,5 +52,3 @@ protogen/buf.sha1.lock
 
 # misc
 go.work
-.env
-.envrc
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3a16fe50fac..93c139a7bf4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -33,7 +33,6 @@ The following sections list the changes for unreleased.
 * Enhancement - Expiration Notifications: [#5330](https://github.com/owncloud/ocis/pull/5330)
 * Enhancement - Make graph/education API errors more consistent: [#5682](https://github.com/owncloud/ocis/pull/5682)
 * Enhancement - Add endpoint to list permissions: [#5594](https://github.com/owncloud/ocis/pull/5594)
-* Enhancement - Introduce policies-service: [#5714](https://github.com/owncloud/ocis/pull/5714)
 * Enhancement - Better config for postprocessing service: [#5457](https://github.com/owncloud/ocis/pull/5457)
 * Enhancement - Add config option to enforce passwords on public links: [#5785](https://github.com/owncloud/ocis/pull/5785)
 * Enhancement - Add new permission for public links: [#5690](https://github.com/owncloud/ocis/pull/5690)
diff --git a/Makefile b/Makefile
index 63eed859962..1e30910b706 100644
--- a/Makefile
+++ b/Makefile
@@ -12,9 +12,7 @@ WHITE        := $(shell tput -Txterm setaf 7)
 
 RESET := $(shell tput -Txterm sgr0)
 
-# add a service here when it uses transifex
-L10N_MODULES := \
-	services/userlog
+L10N_MODULES := $(shell find . -path '*.tx*' -name 'config' | sed 's|/[^/]*$$||' | sed 's|/[^/]*$$||' | sed 's|/[^/]*$$||')
 
 # if you add a module here please also add it to the .drone.star file
 OCIS_MODULES = \
@@ -35,7 +33,6 @@ OCIS_MODULES = \
 	services/notifications \
 	services/ocdav \
 	services/ocs \
-	services/policies \
 	services/postprocessing \
 	services/proxy \
 	services/search \
diff --git a/changelog/unreleased/fix-duplicated-demouser-roles.md b/changelog/unreleased/fix-duplicated-demouser-roles.md
new file mode 100644
index 00000000000..6e015198cb4
--- /dev/null
+++ b/changelog/unreleased/fix-duplicated-demouser-roles.md
@@ -0,0 +1,6 @@
+Bugfix: Fix default role assignment for demo users
+
+The roles-assignments for demo users where duplicated with every
+restart of the settings service.
+
+https://github.com/owncloud/ocis/issues/3432
diff --git a/changelog/unreleased/policies-service.md b/changelog/unreleased/policies-service.md
deleted file mode 100644
index cb24ddba613..00000000000
--- a/changelog/unreleased/policies-service.md
+++ /dev/null
@@ -1,20 +0,0 @@
-Enhancement: Introduce policies-service
-
-Introduces policies service. The policies-service provides a new grpc api which can be used to return whether a requested operation is allowed or not.
-Open Policy Agent is used to determine the set of rules of what is permitted and what is not.
-
-2 further levels of authorization build on this:
-
-* Proxy Authorization
-* Event Authorization (needs async post-processing enabled)
-
-The simplest authorization layer is in the proxy, since every request is processed here, only simple decisions that can be processed quickly are made here, more complex queries such as file evaluation are explicitly excluded in this layer.
-
-The next layer is event-based as a pipeline step in asynchronous post-processing, since processing at this point is asynchronous, the operations there can also take longer and be more expensive,
-the bytes of a file can be examined here as an example.
-
-Since the base block is a grpc api, it is also possible to use it directly.
-The policies are written in the [rego query language](https://www.openpolicyagent.org/docs/latest/policy-language/).
-
-https://github.com/owncloud/ocis/pull/5714
-https://github.com/owncloud/ocis/issues/5580
diff --git a/deployments/examples/service_policies/policies/postprocessing.rego b/deployments/examples/service_policies/policies/postprocessing.rego
deleted file mode 100644
index 8b77f0446fc..00000000000
--- a/deployments/examples/service_policies/policies/postprocessing.rego
+++ /dev/null
@@ -1,10 +0,0 @@
-package postprocessing
-
-import future.keywords.if
-import data.utils
-
-default granted = true
-
-granted := false if {
-    not utils.collection_contains(utils.ALLOWED_FILE_EXTENSIONS, input.resource.name)
-}
diff --git a/deployments/examples/service_policies/policies/proxy.rego b/deployments/examples/service_policies/policies/proxy.rego
deleted file mode 100644
index c1e9da78301..00000000000
--- a/deployments/examples/service_policies/policies/proxy.rego
+++ /dev/null
@@ -1,12 +0,0 @@
-package proxy
-
-import future.keywords.if
-import data.utils
-
-default granted = true
-
-granted := false if {
-    utils.is_request_type_put
-    not input.request.path == "/data"
-    not utils.collection_contains(utils.ALLOWED_FILE_EXTENSIONS, input.request.path)
-}
diff --git a/deployments/examples/service_policies/policies/utils.rego b/deployments/examples/service_policies/policies/utils.rego
deleted file mode 100644
index 65e55e31b75..00000000000
--- a/deployments/examples/service_policies/policies/utils.rego
+++ /dev/null
@@ -1,53 +0,0 @@
-package utils
-
-import future.keywords.if
-
-ALLOWED_FILE_EXTENSIONS := [
-    ".apk", ".avi", ".bat", ".bmp", ".css", ".csv", ".doc", ".docm", ".docx",
-    ".docxf", ".dotx", ".eml", ".epub", ".htm", ".html", ".ipa", ".jar", ".java",
-    ".jpg", ".js", ".json", ".mp3", ".mp4", ".msg", ".odp", ".ods", ".odt", ".oform",
-    ".ots", ".ott", ".pdf", ".php", ".png", ".potm", ".potx", ".ppsm", ".ppsx", ".ppt",
-    ".pptm", ".pptx", ".py", ".rtf", ".sb3", ".sprite3", ".sql", ".svg", ".tif", ".tiff",
-    ".txt", ".xls", ".xlsm", ".xlsx", ".xltm", ".xltx", ".xml", ".zip", ".md"
-]
-
-##
-
-is_stage_http {
-    input.stage == "http"
-}
-
-is_stage_pp {
-    input.stage == "pp"
-}
-
-##
-
-is_user_admin {
-    input.user.username == "admin"
-}
-
-##
-
-is_request_type_put {
-    is_stage_http
-    input.request.method == "PUT"
-}
-
-is_request_path_file {
-    is_stage_http
-    input.request.method == "PUT"
-}
-
-is_request_type_mkcol {
-    is_stage_http
-    input.request.method == "MKCOL"
-}
-
-##
-
-collection_contains(collection, source) {
-     current := collection[_]
-     endswith(source, current)
-}
-
diff --git a/docs/services/policies/_index.md b/docs/services/policies/_index.md
deleted file mode 100644
index cfb962e410c..00000000000
--- a/docs/services/policies/_index.md
+++ /dev/null
@@ -1,89 +0,0 @@
----
-title: Policies
-weight: 20
-geekdocRepo: https://github.com/owncloud/ocis
-geekdocEditPath: edit/master/docs/services/policies
-geekdocFilePath: _index.md
-geekdocCollapseSection: true
----
-
-## Abstract
-
-The policies service provides a new grpc api which can be used to return whether a requested operation is allowed or not. To do so, Open Policy Agent (OPA) is used to determine the set of rules of what is permitted and what is not.
-
-## Table of Contents
-
-{{< toc-tree >}}
-
-## Rego
-
-Policies are written in the [rego query language](https://www.openpolicyagent.org/docs/latest/policy-language/). The location of the rego files can be configured via yaml, a configuration via environment variables is not possible.
-
-The Policies Service consists of the following modules:
-
-*   Proxy Authorization (middleware)
-*   Event Authorization (async post-processing)
-*   GRPC API (can be used from other services)
-
-To configure the Policies Service, three environment variables need to be defined:
-
-*   `POLICIES_ENGINE_TIMEOUT`
-*   `POLICIES_POSTPROCESSING_QUERY`
-*   `PROXY_POLICIES_QUERY`
-
-Note that each query setting defines the [Complete Rules](https://www.openpolicyagent.org/docs/latest/#complete-rules) variable defined in the rego rule set the corresponding step uses for the evaluation. If the variable is mistyped or not found, the evaluation defaults to deny. Individual query definitions can be defined for each module.
-
-To activate a the policies service for a module, it must be started with a yaml configuration that points to one or more rego files. Note that if the service is scaled horizontally, each instance should have access to the same rego files to avoid unpredictable results. If a file path has been configured but the file it is not present or accessible, the evaluation defaults to deny.
-
-When using async post-processing which is done via the postprocessing service, the value `policies` must be added to the `POSTPROCESSING_STEPS` configuration in postprocessing service in the order where the evaluation should take place.
-
-## Modules
-
-### GRPC Service
-
-This service can be used from any other internal service. It can also be used for example by third parties to find out if an action is allowed or not. This layer is already used by the proxy middleware.
-
-### Event Service
-
-This layer is event-based and part of the postprocessing service. Since processing at this point is asynchronous, the operations can also take longer and be more expensive, like evaluating the bytes of a file.
-
-### Proxy Middleware
-
-The [ocis proxy](../proxy) already includes such a middleware which uses the [GRPC service](#grpc-service) to evaluate the policies by using a configurable query. Since the Proxy is in heavy use and every request is processed here, only simple and quick decisions should be evaluated. More complex queries such as file evaluation are strongly discouraged.
-
-## Example Policies
-
-The policies service contains a set of pre-configured example policies. Those policies can be found in the [examples directory](https://github.com/owncloud/ocis/tree/master/deployments/examples/service_policies/policies). The contained policies disallows ocis to create certain filetypes, both for the proxy middleware and the events service.
-
-To use the example policies, it's required to configure ocis to use these files which can be done by adding:
-
-```yaml
-policies:
-  engine:
-    policies:
-      - YOUR_PATH/examples/policies/proxy.rego
-      - YOUR_PATH/examples/policies/postprocessing.rego
-      - YOUR_PATH/examples/policies/utils.rego
-```
-
-Once the policies are configured correctly, the _QUERY configuration needs to be defined for the proxy middleware and for the events service.
-
-### Proxy
-
-```yaml
-proxy:
-  policies_middleware:
-    query: data.proxy.granted
-```
-
-The same can be achieved by setting the `PROXY_POLICIES_QUERY=data.proxy.granted` environment variable.
-
-### ASYNC Postprocessing
-
-```yaml
-policies:
-  postprocessing:
-    query: data.postprocessing.granted
-```
-
-The same can be achieved by setting the `POLICIES_POSTPROCESSING_QUERY=data.postprocessing.granted` environment variable. As soon as that query is configured correctly, postprocessing must be informed to use the policies step by setting the environment variable `POSTPROCESSING_STEPS=policies`. Note that additional steps can be configured and their appearance defines the order of processing. For details see the postprocessing service documentation.
diff --git a/docs/services/policies/configuration.md b/docs/services/policies/configuration.md
deleted file mode 100644
index 25e4d9c0fac..00000000000
--- a/docs/services/policies/configuration.md
+++ /dev/null
@@ -1,15 +0,0 @@
----
-title: Service Configuration
-date: 2018-05-02T00:00:00+00:00
-weight: 20
-geekdocRepo: https://github.com/owncloud/ocis
-geekdocEditPath: edit/master/docs/services/policies
-geekdocFilePath: configuration.md
-geekdocCollapseSection: true
----
-
-## Example YAML Config
-
-{{< include file="services/_includes/policies-config-example.yaml"  language="yaml" >}}
-
-{{< include file="services/_includes/policies_configvars.md" >}}
diff --git a/docs/services/port-ranges.md b/docs/services/port-ranges.md
index 0a75793c4ca..4a9e8128f8f 100644
--- a/docs/services/port-ranges.md
+++ b/docs/services/port-ranges.md
@@ -21,193 +21,193 @@ We also suggest to use the last port in your extensions' range as a debug/metric
 
 ## Allocations
 
-| Port range | Service                                                                                |
-|------------|----------------------------------------------------------------------------------------|
-| 9000-9010  | [reserved for Infinite Scale]({{< ref "../../../ocis/_index.md" >}})                   |
-| 9100-9104  | [web]({{< ref "./web/_index.md" >}})                                                   |
-| 9105-9109  | [hello](https://github.com/owncloud/ocis-hello)                                        |
-| 9110-9114  | [ocs]({{< ref "./ocs/_index.md" >}})                                                   |
-| 9115-9119  | [webdav]({{< ref "./webdav/_index.md" >}})                                             |
-| 9120-9124  | [graph]({{< ref "./graph/_index.md" >}})                                               |
-| 9125-9129  | [policies]({{< ref "./policies/_index.md" >}})                                         |
-| 9130-9134  | [idp]({{< ref "./idp/_index.md" >}})                                                   |
-| 9135-9139  | FREE (formerly used by graph-explorer)                                                 |
-| 9140-9141  | [frontend]({{< ref "./frontend/_index.md" >}})                                         |
-| 9142-9143  | [gateway]({{< ref "./gateway/_index.md" >}})                                           |
-| 9144-9145  | [users]({{< ref "./users/_index.md" >}})                                               |
-| 9146-9147  | [auth-basic]({{< ref "./auth-basic/_index.md" >}})                                     |
-| 9148-9149  | [auth-bearer]({{< ref "./auth-bearer/_index.md" >}})                                   |
-| 9150-9153  | [sharing]({{< ref "./sharing/_index.md" >}})                                           |
-| 9154-9156  | [storage-shares]({{< ref "./storage-shares/_index.md" >}})                             |
-| 9157-9159  | [storage-users]({{< ref "./storage-users/_index.md" >}})                               |
-| 9160-9162  | [groups]({{< ref "./groups/_index.md" >}})                                             |
-| 9163       | [ocdav]({{< ref "./ocdav/_index.md" >}})                                               |
-| 9164       | [groups]({{< ref "./groups/_index.md" >}})                                             |
-| 9165       | [app-provider]({{< ref "./app-provider/_index.md" >}})                                 |
-| 9166-9169  | [auth-machine]({{< ref "./auth-machine/_index.md" >}})                                 |
-| 9170-9174  | [notifications]({{< ref "./notifications/_index.md" >}})                               |
-| 9175-9179  | [storage-publiclink]({{< ref "./storage-publiclink/_index.md" >}})                     |
-| 9180-9184  | FREE (formerly used by accounts)                                                       |
-| 9185-9189  | [thumbnails]({{< ref "./thumbnails/_index.md" >}})                                     |
-| 9190-9194  | [settings]({{< ref "./settings/_index.md" >}})                                         |
-| 9195-9199  | FREE                                                                                   |
-| 9200-9204  | [proxy]({{< ref "./proxy/_index.md" >}})                                               |
-| 9205-9209  | [proxy]({{< ref "./proxy/_index.md" >}})                                               |
-| 9210-9214  | FREE                                                                                   |
-| 9215-9219  | [storage-system]({{< ref "./storage-system/_index.md" >}})                             |
-| 9220-9224  | [search]({{< ref "./search/_index.md" >}})                                             |
-| 9225-9229  | FREE                                                                                   |
-| 9230-9234  | [nats]({{< ref "./nats/_index.md" >}})                                                 |
-| 9235-9239  | [idm]({{< ref "./idm/_index.md" >}})                                                   |
-| 9240-9244  | [app-registry]({{< ref "./app-registry/_index.md" >}})                                 |
-| 9245-9249  | FREE                                                                                   |
+| Port range | Service                                                                       |
+| ---------- | ----------------------------------------------------------------------------- |
+| 9000-9010  | [reserved for Infinite Scale]({{< ref "../../../ocis/_index.md" >}})                    |
+| 9100-9104  | [web]({{< ref "./web/_index.md" >}})                                          |
+| 9105-9109  | [hello](https://github.com/owncloud/ocis-hello)                               |
+| 9110-9114  | [ocs]({{< ref "./ocs/_index.md" >}})                                          |
+| 9115-9119  | [webdav]({{< ref "./webdav/_index.md" >}})                                    |
+| 9120-9124  | [graph]({{< ref "./graph/_index.md" >}})                                      |
+| 9125-9129  | FREE (formerly used by glauth)                                                |
+| 9130-9134  | [idp]({{< ref "./idp/_index.md" >}})                                          |
+| 9135-9139  | FREE (formerly used by graph-explorer)                                        |
+| 9140-9141  | [frontend]({{< ref "./frontend/_index.md" >}})                                |
+| 9142-9143  | [gateway]({{< ref "./gateway/_index.md" >}})                                  |
+| 9144-9145  | [users]({{< ref "./users/_index.md" >}})                                      |
+| 9146-9147  | [auth-basic]({{< ref "./auth-basic/_index.md" >}})                            |
+| 9148-9149  | [auth-bearer]({{< ref "./auth-bearer/_index.md" >}})                          |
+| 9150-9153  | [sharing]({{< ref "./sharing/_index.md" >}})                                  |
+| 9154-9156  | [storage-shares]({{< ref "./storage-shares/_index.md" >}})                    |
+| 9157-9159  | [storage-users]({{< ref "./storage-users/_index.md" >}})                      |
+| 9160-9162  | [groups]({{< ref "./groups/_index.md" >}})                                    |
+| 9163       | [ocdav]({{< ref "./ocdav/_index.md" >}})                                      |
+| 9164       | [groups]({{< ref "./groups/_index.md" >}})                                    |
+| 9165       | [app-provider]({{< ref "./app-provider/_index.md" >}})                        |
+| 9166-9169  | [auth-machine]({{< ref "./auth-machine/_index.md" >}})                        |
+| 9170-9174  | [notifications]({{< ref "./notifications/_index.md" >}})                      |
+| 9175-9179  | [storage-publiclink]({{< ref "./storage-publiclink/_index.md" >}})            |
+| 9180-9184  | FREE (formerly used by accounts)                                              |
+| 9185-9189  | [thumbnails]({{< ref "./thumbnails/_index.md" >}})                            |
+| 9190-9194  | [settings]({{< ref "./settings/_index.md" >}})                                |
+| 9195-9199  | FREE                                                                          |
+| 9200-9204  | [proxy]({{< ref "./proxy/_index.md" >}})                                      |
+| 9205-9209  | [proxy]({{< ref "./proxy/_index.md" >}})                                      |
+| 9210-9214  | FREE                                                                          |
+| 9215-9219  | [storage-system]({{< ref "./storage-system/_index.md" >}})                    |
+| 9220-9224  | [search]({{< ref "./search/_index.md" >}})                                    |
+| 9225-9229  | FREE                                                                          |
+| 9230-9234  | [nats]({{< ref "./nats/_index.md" >}})                                        |
+| 9235-9239  | [idm]({{< ref "./idm/_index.md" >}})                                          |
+| 9240-9244  | [app-registry]({{< ref "./app-registry/_index.md" >}})                        |
+| 9245-9249  | FREE                                                                          |
 | 9250-9254  | [ocis server (runtime)](https://github.com/owncloud/ocis/tree/master/ocis/pkg/runtime) |
-| 9255-9259  | FREE                                                                                   |
-| 9260-9264  | FREE                                                                                   |
-| 9265-9269  | FREE                                                                                   |
-| 9270-9274  | FREE                                                                                   |
-| 9275-9279  | FREE                                                                                   |
-| 9280-9284  | FREE                                                                                   |
-| 9285-9289  | FREE                                                                                   |
-| 9290-9294  | FREE                                                                                   |
-| 9295-9299  | FREE                                                                                   |
-| 9300-9304  | FREE                                                                                   |
-| 9305-9309  | FREE                                                                                   |
-| 9310-9314  | FREE                                                                                   |
-| 9315-9319  | FREE                                                                                   |
-| 9320-9324  | FREE                                                                                   |
-| 9325-9329  | FREE                                                                                   |
-| 9330-9334  | FREE                                                                                   |
-| 9335-9339  | FREE                                                                                   |
-| 9340-9344  | FREE                                                                                   |
-| 9345-9349  | FREE                                                                                   |
-| 9350-9354  | FREE                                                                                   |
-| 9355-9359  | FREE                                                                                   |
-| 9360-9364  | FREE                                                                                   |
-| 9365-9369  | FREE                                                                                   |
-| 9370-9374  | FREE                                                                                   |
-| 9375-9379  | FREE                                                                                   |
-| 9380-9384  | FREE                                                                                   |
-| 9385-9389  | FREE                                                                                   |
-| 9390-9394  | FREE                                                                                   |
-| 9395-9399  | FREE                                                                                   |
-| 9400-9404  | FREE                                                                                   |
-| 9405-9409  | FREE                                                                                   |
-| 9410-9414  | FREE                                                                                   |
-| 9415-9419  | FREE                                                                                   |
-| 9420-9424  | FREE                                                                                   |
-| 9425-9429  | FREE                                                                                   |
-| 9430-9434  | FREE                                                                                   |
-| 9435-9439  | FREE                                                                                   |
-| 9440-9444  | FREE                                                                                   |
-| 9445-9449  | FREE                                                                                   |
-| 9450-9454  | FREE                                                                                   |
-| 9455-9459  | FREE                                                                                   |
-| 9460-9464  | [store]({{< ref "./store/_index.md" >}})                                               |
-| 9465-9469  | FREE                                                                                   |
-| 9470-9474  | FREE                                                                                   |
-| 9475-9479  | FREE                                                                                   |
-| 9480-9484  | FREE                                                                                   |
-| 9485-9489  | FREE                                                                                   |
-| 9490-9494  | FREE                                                                                   |
-| 9495-9499  | FREE                                                                                   |
-| 9500-9504  | FREE                                                                                   |
-| 9505-9509  | FREE                                                                                   |
-| 9510-9514  | FREE                                                                                   |
-| 9515-9519  | FREE                                                                                   |
-| 9520-9524  | FREE                                                                                   |
-| 9525-9529  | FREE                                                                                   |
-| 9530-9534  | FREE                                                                                   |
-| 9535-9539  | FREE                                                                                   |
-| 9540-9544  | FREE                                                                                   |
-| 9545-9549  | FREE                                                                                   |
-| 9550-9554  | FREE                                                                                   |
-| 9555-9559  | FREE                                                                                   |
-| 9560-9564  | FREE                                                                                   |
-| 9565-9569  | FREE                                                                                   |
-| 9570-9574  | FREE                                                                                   |
-| 9575-9579  | FREE                                                                                   |
-| 9580-9584  | FREE                                                                                   |
-| 9585-9589  | FREE                                                                                   |
-| 9590-9594  | FREE                                                                                   |
-| 9595-9599  | FREE                                                                                   |
-| 9600-9604  | FREE                                                                                   |
-| 9605-9609  | FREE                                                                                   |
-| 9610-9614  | FREE                                                                                   |
-| 9615-9619  | FREE                                                                                   |
-| 9620-9624  | FREE                                                                                   |
-| 9625-9629  | FREE                                                                                   |
-| 9630-9634  | FREE                                                                                   |
-| 9635-9639  | FREE                                                                                   |
-| 9640-9644  | FREE                                                                                   |
-| 9645-9649  | FREE                                                                                   |
-| 9650-9654  | FREE                                                                                   |
-| 9655-9659  | FREE                                                                                   |
-| 9660-9664  | FREE                                                                                   |
-| 9665-9669  | FREE                                                                                   |
-| 9670-9674  | FREE                                                                                   |
-| 9675-9679  | FREE                                                                                   |
-| 9680-9684  | FREE                                                                                   |
-| 9685-9689  | FREE                                                                                   |
-| 9690-9694  | FREE                                                                                   |
-| 9695-9699  | FREE                                                                                   |
-| 9700-9704  | FREE                                                                                   |
-| 9705-9709  | FREE                                                                                   |
-| 9710-9714  | FREE                                                                                   |
-| 9715-9719  | FREE                                                                                   |
-| 9720-9724  | FREE                                                                                   |
-| 9725-9729  | FREE                                                                                   |
-| 9730-9734  | FREE                                                                                   |
-| 9735-9739  | FREE                                                                                   |
-| 9740-9744  | FREE                                                                                   |
-| 9745-9749  | FREE                                                                                   |
-| 9750-9754  | FREE                                                                                   |
-| 9755-9759  | FREE                                                                                   |
-| 9760-9764  | FREE                                                                                   |
-| 9765-9769  | FREE                                                                                   |
-| 9770-9774  | FREE                                                                                   |
-| 9775-9779  | FREE                                                                                   |
-| 9780-9784  | FREE                                                                                   |
-| 9785-9789  | FREE                                                                                   |
-| 9790-9794  | FREE                                                                                   |
-| 9795-9799  | FREE                                                                                   |
-| 9800-9804  | FREE                                                                                   |
-| 9805-9809  | FREE                                                                                   |
-| 9810-9814  | FREE                                                                                   |
-| 9815-9819  | FREE                                                                                   |
-| 9820-9824  | FREE                                                                                   |
-| 9825-9829  | FREE                                                                                   |
-| 9830-9834  | FREE                                                                                   |
-| 9835-9839  | FREE                                                                                   |
-| 9840-9844  | FREE                                                                                   |
-| 9845-9849  | FREE                                                                                   |
-| 9850-9854  | FREE                                                                                   |
-| 9855-9859  | FREE                                                                                   |
-| 9860-9864  | FREE                                                                                   |
-| 9865-9869  | FREE                                                                                   |
-| 9870-9874  | FREE                                                                                   |
-| 9875-9879  | FREE                                                                                   |
-| 9880-9884  | FREE                                                                                   |
-| 9885-9889  | FREE                                                                                   |
-| 9890-9894  | FREE                                                                                   |
-| 9895-9899  | FREE                                                                                   |
-| 9900-9904  | FREE                                                                                   |
-| 9905-9909  | FREE                                                                                   |
-| 9910-9914  | FREE                                                                                   |
-| 9915-9919  | FREE                                                                                   |
-| 9920-9924  | FREE                                                                                   |
-| 9925-9929  | FREE                                                                                   |
-| 9930-9934  | FREE                                                                                   |
-| 9935-9939  | FREE                                                                                   |
-| 9940-9944  | FREE                                                                                   |
-| 9945-9949  | FREE                                                                                   |
-| 9950-9954  | FREE                                                                                   |
-| 9955-9959  | FREE                                                                                   |
-| 9960-9964  | FREE                                                                                   |
-| 9965-9969  | FREE                                                                                   |
-| 9970-9974  | FREE                                                                                   |
-| 9975-9979  | FREE                                                                                   |
-| 9980-9984  | FREE                                                                                   |
-| 9985-9989  | FREE                                                                                   |
-| 9990-9994  | FREE                                                                                   |
-| 9995-9999  | FREE                                                                                   |
+| 9255-9259  | FREE                                                                          |
+| 9260-9264  | FREE                                                                          |
+| 9265-9269  | FREE                                                                          |
+| 9270-9274  | FREE                                                                          |
+| 9275-9279  | FREE                                                                          |
+| 9280-9284  | FREE                                                                          |
+| 9285-9289  | FREE                                                                          |
+| 9290-9294  | FREE                                                                          |
+| 9295-9299  | FREE                                                                          |
+| 9300-9304  | FREE                                                                          |
+| 9305-9309  | FREE                                                                          |
+| 9310-9314  | FREE                                                                          |
+| 9315-9319  | FREE                                                                          |
+| 9320-9324  | FREE                                                                          |
+| 9325-9329  | FREE                                                                          |
+| 9330-9334  | FREE                                                                          |
+| 9335-9339  | FREE                                                                          |
+| 9340-9344  | FREE                                                                          |
+| 9345-9349  | FREE                                                                          |
+| 9350-9354  | FREE                                                                          |
+| 9355-9359  | FREE                                                                          |
+| 9360-9364  | FREE                                                                          |
+| 9365-9369  | FREE                                                                          |
+| 9370-9374  | FREE                                                                          |
+| 9375-9379  | FREE                                                                          |
+| 9380-9384  | FREE                                                                          |
+| 9385-9389  | FREE                                                                          |
+| 9390-9394  | FREE                                                                          |
+| 9395-9399  | FREE                                                                          |
+| 9400-9404  | FREE                                                                          |
+| 9405-9409  | FREE                                                                          |
+| 9410-9414  | FREE                                                                          |
+| 9415-9419  | FREE                                                                          |
+| 9420-9424  | FREE                                                                          |
+| 9425-9429  | FREE                                                                          |
+| 9430-9434  | FREE                                                                          |
+| 9435-9439  | FREE                                                                          |
+| 9440-9444  | FREE                                                                          |
+| 9445-9449  | FREE                                                                          |
+| 9450-9454  | FREE                                                                          |
+| 9455-9459  | FREE                                                                          |
+| 9460-9464  | [store]({{< ref "./store/_index.md" >}})                                      |
+| 9465-9469  | FREE                                                                          |
+| 9470-9474  | FREE                                                                          |
+| 9475-9479  | FREE                                                                          |
+| 9480-9484  | FREE                                                                          |
+| 9485-9489  | FREE                                                                          |
+| 9490-9494  | FREE                                                                          |
+| 9495-9499  | FREE                                                                          |
+| 9500-9504  | FREE                                                                          |
+| 9505-9509  | FREE                                                                          |
+| 9510-9514  | FREE                                                                          |
+| 9515-9519  | FREE                                                                          |
+| 9520-9524  | FREE                                                                          |
+| 9525-9529  | FREE                                                                          |
+| 9530-9534  | FREE                                                                          |
+| 9535-9539  | FREE                                                                          |
+| 9540-9544  | FREE                                                                          |
+| 9545-9549  | FREE                                                                          |
+| 9550-9554  | FREE                                                                          |
+| 9555-9559  | FREE                                                                          |
+| 9560-9564  | FREE                                                                          |
+| 9565-9569  | FREE                                                                          |
+| 9570-9574  | FREE                                                                          |
+| 9575-9579  | FREE                                                                          |
+| 9580-9584  | FREE                                                                          |
+| 9585-9589  | FREE                                                                          |
+| 9590-9594  | FREE                                                                          |
+| 9595-9599  | FREE                                                                          |
+| 9600-9604  | FREE                                                                          |
+| 9605-9609  | FREE                                                                          |
+| 9610-9614  | FREE                                                                          |
+| 9615-9619  | FREE                                                                          |
+| 9620-9624  | FREE                                                                          |
+| 9625-9629  | FREE                                                                          |
+| 9630-9634  | FREE                                                                          |
+| 9635-9639  | FREE                                                                          |
+| 9640-9644  | FREE                                                                          |
+| 9645-9649  | FREE                                                                          |
+| 9650-9654  | FREE                                                                          |
+| 9655-9659  | FREE                                                                          |
+| 9660-9664  | FREE                                                                          |
+| 9665-9669  | FREE                                                                          |
+| 9670-9674  | FREE                                                                          |
+| 9675-9679  | FREE                                                                          |
+| 9680-9684  | FREE                                                                          |
+| 9685-9689  | FREE                                                                          |
+| 9690-9694  | FREE                                                                          |
+| 9695-9699  | FREE                                                                          |
+| 9700-9704  | FREE                                                                          |
+| 9705-9709  | FREE                                                                          |
+| 9710-9714  | FREE                                                                          |
+| 9715-9719  | FREE                                                                          |
+| 9720-9724  | FREE                                                                          |
+| 9725-9729  | FREE                                                                          |
+| 9730-9734  | FREE                                                                          |
+| 9735-9739  | FREE                                                                          |
+| 9740-9744  | FREE                                                                          |
+| 9745-9749  | FREE                                                                          |
+| 9750-9754  | FREE                                                                          |
+| 9755-9759  | FREE                                                                          |
+| 9760-9764  | FREE                                                                          |
+| 9765-9769  | FREE                                                                          |
+| 9770-9774  | FREE                                                                          |
+| 9775-9779  | FREE                                                                          |
+| 9780-9784  | FREE                                                                          |
+| 9785-9789  | FREE                                                                          |
+| 9790-9794  | FREE                                                                          |
+| 9795-9799  | FREE                                                                          |
+| 9800-9804  | FREE                                                                          |
+| 9805-9809  | FREE                                                                          |
+| 9810-9814  | FREE                                                                          |
+| 9815-9819  | FREE                                                                          |
+| 9820-9824  | FREE                                                                          |
+| 9825-9829  | FREE                                                                          |
+| 9830-9834  | FREE                                                                          |
+| 9835-9839  | FREE                                                                          |
+| 9840-9844  | FREE                                                                          |
+| 9845-9849  | FREE                                                                          |
+| 9850-9854  | FREE                                                                          |
+| 9855-9859  | FREE                                                                          |
+| 9860-9864  | FREE                                                                          |
+| 9865-9869  | FREE                                                                          |
+| 9870-9874  | FREE                                                                          |
+| 9875-9879  | FREE                                                                          |
+| 9880-9884  | FREE                                                                          |
+| 9885-9889  | FREE                                                                          |
+| 9890-9894  | FREE                                                                          |
+| 9895-9899  | FREE                                                                          |
+| 9900-9904  | FREE                                                                          |
+| 9905-9909  | FREE                                                                          |
+| 9910-9914  | FREE                                                                          |
+| 9915-9919  | FREE                                                                          |
+| 9920-9924  | FREE                                                                          |
+| 9925-9929  | FREE                                                                          |
+| 9930-9934  | FREE                                                                          |
+| 9935-9939  | FREE                                                                          |
+| 9940-9944  | FREE                                                                          |
+| 9945-9949  | FREE                                                                          |
+| 9950-9954  | FREE                                                                          |
+| 9955-9959  | FREE                                                                          |
+| 9960-9964  | FREE                                                                          |
+| 9965-9969  | FREE                                                                          |
+| 9970-9974  | FREE                                                                          |
+| 9975-9979  | FREE                                                                          |
+| 9980-9984  | FREE                                                                          |
+| 9985-9989  | FREE                                                                          |
+| 9990-9994  | FREE                                                                          |
+| 9995-9999  | FREE                                                                          |
diff --git a/go.mod b/go.mod
index a028048c28a..0d8c052ed29 100644
--- a/go.mod
+++ b/go.mod
@@ -13,7 +13,6 @@ require (
 	github.com/cs3org/go-cs3apis v0.0.0-20221012090518-ef2996678965
 	github.com/cs3org/reva/v2 v2.12.1-0.20230313151335-4339b8ab4759
 	github.com/disintegration/imaging v1.6.2
-	github.com/gabriel-vasile/mimetype v1.4.1
 	github.com/ggwhite/go-masker v1.0.9
 	github.com/go-chi/chi/v5 v5.0.8
 	github.com/go-chi/cors v1.2.1
@@ -48,7 +47,6 @@ require (
 	github.com/jellydator/ttlcache/v2 v2.11.1
 	github.com/jellydator/ttlcache/v3 v3.0.1
 	github.com/justinas/alice v1.2.0
-	github.com/leonelquinteros/gotext v1.5.2
 	github.com/libregraph/idm v0.4.1-0.20230221143410-3503963047a5
 	github.com/libregraph/lico v0.59.4
 	github.com/mitchellh/mapstructure v1.5.0
@@ -60,7 +58,6 @@ require (
 	github.com/onsi/ginkgo v1.16.5
 	github.com/onsi/ginkgo/v2 v2.9.1
 	github.com/onsi/gomega v1.27.4
-	github.com/open-policy-agent/opa v0.50.0
 	github.com/orcaman/concurrent-map v1.0.0
 	github.com/owncloud/libre-graph-api-go v1.0.2-0.20230309112802-ff71ba8c90aa
 	github.com/pkg/errors v0.9.1
@@ -107,11 +104,9 @@ require (
 	github.com/Masterminds/goutils v1.1.1 // indirect
 	github.com/Masterminds/sprig v2.22.0+incompatible // indirect
 	github.com/Microsoft/go-winio v0.6.0 // indirect
-	github.com/OneOfOne/xxhash v1.2.8 // indirect
 	github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad // indirect
 	github.com/RoaringBitmap/roaring v0.9.4 // indirect
 	github.com/acomagu/bufpipe v1.0.3 // indirect
-	github.com/agnivade/levenshtein v1.1.1 // indirect
 	github.com/ajg/form v1.5.1 // indirect
 	github.com/alexedwards/argon2id v0.0.0-20211130144151-3585854a6387 // indirect
 	github.com/amoghe/go-crypt v0.0.0-20220222110647-20eada5f5964 // indirect
@@ -163,10 +158,10 @@ require (
 	github.com/emvi/iso-639-1 v1.0.1 // indirect
 	github.com/evanphx/json-patch/v5 v5.5.0 // indirect
 	github.com/fatih/color v1.13.0 // indirect
-	github.com/felixge/httpsnoop v1.0.3 // indirect
-	github.com/fsnotify/fsnotify v1.6.0 // indirect
+	github.com/felixge/httpsnoop v1.0.1 // indirect
+	github.com/fsnotify/fsnotify v1.5.4 // indirect
+	github.com/gabriel-vasile/mimetype v1.4.1 // indirect
 	github.com/gdexlab/go-render v1.0.1 // indirect
-	github.com/ghodss/yaml v1.0.0 // indirect
 	github.com/go-acme/lego/v4 v4.4.0 // indirect
 	github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect
 	github.com/go-git/gcfg v1.5.0 // indirect
@@ -179,7 +174,6 @@ require (
 	github.com/go-redis/redis/v8 v8.11.5 // indirect
 	github.com/go-sql-driver/mysql v1.6.0 // indirect
 	github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
-	github.com/gobwas/glob v0.2.3 // indirect
 	github.com/gobwas/httphead v0.1.0 // indirect
 	github.com/gobwas/pool v0.2.1 // indirect
 	github.com/gobwas/ws v1.0.4 // indirect
@@ -229,7 +223,7 @@ require (
 	github.com/mattn/go-isatty v0.0.16 // indirect
 	github.com/mattn/go-runewidth v0.0.13 // indirect
 	github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
-	github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
+	github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
 	github.com/maxymania/go-system v0.0.0-20170110133659-647cc364bf0b // indirect
 	github.com/mendsley/gojwk v0.0.0-20141217222730-4d5ec6e58103 // indirect
 	github.com/miekg/dns v1.1.50 // indirect
@@ -259,7 +253,6 @@ require (
 	github.com/prometheus/common v0.37.0 // indirect
 	github.com/prometheus/procfs v0.8.0 // indirect
 	github.com/prometheus/statsd_exporter v0.22.8 // indirect
-	github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect
 	github.com/rivo/uniseg v0.4.2 // indirect
 	github.com/rs/cors v1.8.2 // indirect
 	github.com/rs/xid v1.4.0 // indirect
@@ -275,16 +268,12 @@ require (
 	github.com/spacewander/go-suffix-tree v0.0.0-20191010040751-0865e368c784 // indirect
 	github.com/spf13/pflag v1.0.5 // indirect
 	github.com/stretchr/objx v0.5.0 // indirect
-	github.com/tchap/go-patricia/v2 v2.3.1 // indirect
 	github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208 // indirect
 	github.com/trustelem/zxcvbn v1.0.1 // indirect
 	github.com/wk8/go-ordered-map v1.0.0 // indirect
 	github.com/xanzy/ssh-agent v0.3.2 // indirect
-	github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
-	github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
 	github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
 	github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
-	github.com/yashtewari/glob-intersection v0.1.0 // indirect
 	go.etcd.io/etcd/api/v3 v3.5.6 // indirect
 	go.etcd.io/etcd/client/pkg/v3 v3.5.6 // indirect
 	go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.4 // indirect
@@ -294,7 +283,7 @@ require (
 	golang.org/x/mod v0.9.0 // indirect
 	golang.org/x/sync v0.1.0 // indirect
 	golang.org/x/sys v0.6.0 // indirect
-	golang.org/x/time v0.3.0 // indirect
+	golang.org/x/time v0.1.0 // indirect
 	golang.org/x/tools v0.7.0 // indirect
 	google.golang.org/appengine v1.6.7 // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
@@ -306,5 +295,3 @@ require (
 )
 
 replace github.com/cs3org/go-cs3apis => github.com/c0rby/go-cs3apis v0.0.0-20230110100311-5b424f1baa35
-
-replace github.com/leonelquinteros/gotext => github.com/kobergj/gotext v0.0.0-20230309141732-b909eb0b8956
diff --git a/go.sum b/go.sum
index 0be9690b235..1009b517b50 100644
--- a/go.sum
+++ b/go.sum
@@ -166,8 +166,6 @@ github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v
 github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
 github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
-github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8=
-github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
 github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87/go.mod h1:iGLljf5n9GjT6kc0HBvyI1nOKnGQbNB66VzSNbK5iks=
 github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
 github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad h1:QeeqI2zxxgZVe11UrYFXXx6gVxPVF40ygekjBzEg4XY=
@@ -181,8 +179,6 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMx
 github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk=
 github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
 github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
-github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
-github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
 github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
 github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
 github.com/akamai/AkamaiOPEN-edgegrid-golang v1.1.0/go.mod h1:kX6YddBkXqqywAe8c9LyvgTCyFuZCTMF4cRPQhc3Fy8=
@@ -204,8 +200,6 @@ github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb
 github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM=
 github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk=
 github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
-github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
-github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
 github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
 github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
 github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
@@ -287,7 +281,6 @@ github.com/bombsimon/logrusr/v3 v3.1.0/go.mod h1:PksPPgSFEL2I52pla2glgCyyd2OqOHA
 github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
 github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
 github.com/bwesterb/go-ristretto v1.2.1/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
-github.com/bytecodealliance/wasmtime-go/v3 v3.0.2 h1:3uZCA/BLTIu+DqCfguByNMJa2HVHpXvjfy0Dy7g6fuA=
 github.com/c-bata/go-prompt v0.2.5/go.mod h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7FVlAwDAVw=
 github.com/c0rby/go-cs3apis v0.0.0-20230110100311-5b424f1baa35 h1:bbpRY/l4z5MTH+TRGZdkIqDM9JXQQewJdO1o+80zcok=
 github.com/c0rby/go-cs3apis v0.0.0-20230110100311-5b424f1baa35/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
@@ -299,7 +292,6 @@ github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/ceph/go-ceph v0.18.0 h1:4WM6yAq/iqBDaeeADDiPKLqKiP0iZ4fffdgCr1lnOL4=
 github.com/ceph/go-ceph v0.18.0/go.mod h1:cflETVTBNAQM6jdr7hpNHHFHKYiJiWWcAeRDrRx/1ng=
-github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
 github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
@@ -363,17 +355,14 @@ github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS3
 github.com/deepmap/oapi-codegen v1.3.11/go.mod h1:suMvK7+rKlx3+tpa8ByptmvoXbAV70wERKTOGH3hLp0=
 github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I=
 github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE=
-github.com/dgraph-io/badger/v3 v3.2103.5 h1:ylPa6qzbjYRQMU6jokoj4wzcaweHylt//CH0AKt0akg=
 github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8=
 github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA=
 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA=
 github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
-github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y=
 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
 github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
-github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g=
-github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
 github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
 github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
 github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
@@ -411,17 +400,14 @@ github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGE
 github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
 github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
 github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
+github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ=
 github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
-github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
-github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
 github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
 github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
-github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
-github.com/foxcpp/go-mockdns v1.0.0 h1:7jBqxd3WDWwi/6WhDvacvH1XsN3rOLXyHM1uhvIx6FI=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
-github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
-github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
+github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
+github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
 github.com/gabriel-vasile/mimetype v1.4.1 h1:TRWk7se+TOjCYgRth7+1/OYLNiRNIotknkFtf/dnN7Q=
 github.com/gabriel-vasile/mimetype v1.4.1/go.mod h1:05Vi0w3Y9c/lNvJOdmIwvrrAhX3rYhfQQCaf9VJcv7M=
 github.com/gdexlab/go-render v1.0.1 h1:rxqB3vo5s4n1kF0ySmoNeSPRYkEsyHgln4jFIQY7v0U=
@@ -429,7 +415,6 @@ github.com/gdexlab/go-render v1.0.1/go.mod h1:wRi5nW2qfjiGj4mPukH4UV0IknS1cHD4Vg
 github.com/getkin/kin-openapi v0.13.0/go.mod h1:WGRs2ZMM1Q8LR1QBEwUxC6RJEfaBcD0s+pcEVXFuAjw=
 github.com/ggwhite/go-masker v1.0.9 h1:9mKJzhLwJN1E5ekqNMk2ppP9ntWubIGtrUNV9wRouZo=
 github.com/ggwhite/go-masker v1.0.9/go.mod h1:xnTRHwrIU9FtBADwEjUC5Dy/BVedvoTxyOE7/d3CNwY=
-github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
 github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
 github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
@@ -573,8 +558,6 @@ github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWe
 github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ=
 github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0=
 github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
-github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
-github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
 github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
 github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
 github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
@@ -653,7 +636,6 @@ github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs0
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
-github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -884,8 +866,6 @@ github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02
 github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
 github.com/klauspost/cpuid/v2 v2.1.0 h1:eyi1Ad2aNJMW95zcSbmGg7Cg6cq3ADwLpMAP96d8rF0=
 github.com/klauspost/cpuid/v2 v2.1.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
-github.com/kobergj/gotext v0.0.0-20230309141732-b909eb0b8956 h1:b3MBTVgsfKXD/CdnAAqD7czu9Npx9QG+rHZycBIXJGE=
-github.com/kobergj/gotext v0.0.0-20230309141732-b909eb0b8956/go.mod h1:AT4NpQrOmyj1L/+hLja6aR0lk81yYYL4ePnj2kp7d6M=
 github.com/kolo/xmlrpc v0.0.0-20200310150728-e0350524596b/go.mod h1:o03bZfuBwAXHetKXuInt4S7omeXUu62/A845kiycsSQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -965,9 +945,8 @@ github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJK
 github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/mattn/go-tty v0.0.0-20180219170247-931426f7535a/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=
 github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0=
+github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
-github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
-github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
 github.com/maxymania/go-system v0.0.0-20170110133659-647cc364bf0b h1:Q53idHrTuQDDHyXaxZ6pUl0I9uyD6Z6uKFK3ocX6LzI=
 github.com/maxymania/go-system v0.0.0-20170110133659-647cc364bf0b/go.mod h1:KirJrATYGbTyUwVR26xIkaipRqRcMRXBf8N5dacvGus=
 github.com/mendsley/gojwk v0.0.0-20141217222730-4d5ec6e58103 h1:Z/i1e+gTZrmcGeZyWckaLfucYG6KYOXLWo4co8pZYNY=
@@ -1067,8 +1046,6 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
 github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
 github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E=
 github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ=
-github.com/open-policy-agent/opa v0.50.0 h1:CBRj7lJ9DFDHvlx2SRP6uFOCD9ooxDdNW9fYK2IIW+0=
-github.com/open-policy-agent/opa v0.50.0/go.mod h1:9jKfDk0L5b9rnhH4M0nq10cGHbYOxqygxzTT3dsvhec=
 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=
@@ -1165,8 +1142,6 @@ github.com/prometheus/statsd_exporter v0.22.8/go.mod h1:/DzwbTEaFTE0Ojz5PqcSk6+P
 github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
 github.com/rainycape/memcache v0.0.0-20150622160815-1031fa0ce2f2/go.mod h1:7tZKcyumwBO6qip7RNQ5r77yrssm9bfCowcLEBcU5IA=
 github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
-github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ=
-github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
 github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
 github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8=
 github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
@@ -1267,8 +1242,6 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ
 github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc=
 github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
-github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes=
-github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k=
 github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE=
 github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU=
 github.com/thanhpk/randstr v1.0.4 h1:IN78qu/bR+My+gHCvMEXhR/i5oriVHcTB/BJJIRTsNo=
@@ -1307,9 +1280,6 @@ github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT
 github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
 github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
 github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
-github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
-github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
-github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
 github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
 github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
 github.com/xhit/go-simple-mail/v2 v2.13.0 h1:OANWU9jHZrVfBkNkvLf8Ww0fexwpQVF/v/5f96fFTLI=
@@ -1320,8 +1290,6 @@ github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHg
 github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
 github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
 github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
-github.com/yashtewari/glob-intersection v0.1.0 h1:6gJvMYQlTDOL3dMsPF6J0+26vwX9MB8/1q3uAdhmTrg=
-github.com/yashtewari/glob-intersection v0.1.0/go.mod h1:LK7pIC3piUjovexikBbJ26Yml7g8xa5bsjfx2v1fwok=
 github.com/yosuke-furukawa/json5 v0.1.1/go.mod h1:sw49aWDqNdRJ6DYUtIQiaA3xyj2IL9tjeNYmX2ixwcU=
 github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
 github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -1691,7 +1659,6 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -1720,8 +1687,8 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxb
 golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
-golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA=
+golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
diff --git a/ocis-pkg/config/config.go b/ocis-pkg/config/config.go
index 3d368f832c3..a9ab12f6c80 100644
--- a/ocis-pkg/config/config.go
+++ b/ocis-pkg/config/config.go
@@ -2,6 +2,7 @@ package config
 
 import (
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+
 	appProvider "github.com/owncloud/ocis/v2/services/app-provider/pkg/config"
 	appRegistry "github.com/owncloud/ocis/v2/services/app-registry/pkg/config"
 	audit "github.com/owncloud/ocis/v2/services/audit/pkg/config"
@@ -19,7 +20,6 @@ import (
 	notifications "github.com/owncloud/ocis/v2/services/notifications/pkg/config"
 	ocdav "github.com/owncloud/ocis/v2/services/ocdav/pkg/config"
 	ocs "github.com/owncloud/ocis/v2/services/ocs/pkg/config"
-	policies "github.com/owncloud/ocis/v2/services/policies/pkg/config"
 	postprocessing "github.com/owncloud/ocis/v2/services/postprocessing/pkg/config"
 	proxy "github.com/owncloud/ocis/v2/services/proxy/pkg/config"
 	search "github.com/owncloud/ocis/v2/services/search/pkg/config"
@@ -38,6 +38,14 @@ import (
 	webfinger "github.com/owncloud/ocis/v2/services/webfinger/pkg/config"
 )
 
+const (
+	// SUPERVISED sets the runtime mode as supervised threads.
+	SUPERVISED = iota
+
+	// UNSUPERVISED sets the runtime mode as a single thread.
+	UNSUPERVISED
+)
+
 type Mode int
 
 // Runtime configures the oCIS runtime when running in supervised mode.
@@ -90,7 +98,6 @@ type Config struct {
 	OCDav             *ocdav.Config          `yaml:"ocdav"`
 	OCS               *ocs.Config            `yaml:"ocs"`
 	Postprocessing    *postprocessing.Config `yaml:"postprocessing"`
-	Policies          *policies.Config       `yaml:"policies"`
 	Proxy             *proxy.Config          `yaml:"proxy"`
 	Settings          *settings.Config       `yaml:"settings"`
 	Sharing           *sharing.Config        `yaml:"sharing"`
diff --git a/ocis-pkg/config/defaultconfig.go b/ocis-pkg/config/defaultconfig.go
index d59571d1153..434c42e139c 100644
--- a/ocis-pkg/config/defaultconfig.go
+++ b/ocis-pkg/config/defaultconfig.go
@@ -18,7 +18,6 @@ import (
 	notifications "github.com/owncloud/ocis/v2/services/notifications/pkg/config/defaults"
 	ocdav "github.com/owncloud/ocis/v2/services/ocdav/pkg/config/defaults"
 	ocs "github.com/owncloud/ocis/v2/services/ocs/pkg/config/defaults"
-	policies "github.com/owncloud/ocis/v2/services/policies/pkg/config/defaults"
 	postprocessing "github.com/owncloud/ocis/v2/services/postprocessing/pkg/config/defaults"
 	proxy "github.com/owncloud/ocis/v2/services/proxy/pkg/config/defaults"
 	search "github.com/owncloud/ocis/v2/services/search/pkg/config/defaults"
@@ -63,7 +62,6 @@ func DefaultConfig() *Config {
 		OCDav:             ocdav.DefaultConfig(),
 		OCS:               ocs.DefaultConfig(),
 		Postprocessing:    postprocessing.DefaultConfig(),
-		Policies:          policies.DefaultConfig(),
 		Proxy:             proxy.DefaultConfig(),
 		Search:            search.FullDefaultConfig(),
 		Settings:          settings.DefaultConfig(),
diff --git a/ocis-pkg/ldap/ldap.go b/ocis-pkg/ldap/ldap.go
index f9b5786b79b..194ddb42ed6 100644
--- a/ocis-pkg/ldap/ldap.go
+++ b/ocis-pkg/ldap/ldap.go
@@ -4,6 +4,7 @@ import (
 	"crypto/x509"
 	"errors"
 	"os"
+	"strings"
 	"time"
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/log"
@@ -14,6 +15,20 @@ const (
 	caCheckSleep   = 2
 )
 
+var (
+	dnEscaper = strings.NewReplacer(
+		"\\", "\\\\",
+		",", "\\,",
+		"+", "\\+",
+		`"`, `\\"`,
+		"<", "\\<",
+		">", "\\>",
+		";", "\\;",
+		"=", "\\=",
+		"\000", "\\00",
+	)
+)
+
 func WaitForCA(log log.Logger, insecure bool, caCert string) error {
 	if !insecure && caCert != "" {
 		for i := 0; i < caCheckRetries; i++ {
@@ -37,3 +52,20 @@ func WaitForCA(log log.Logger, insecure bool, caCert string) error {
 	}
 	return nil
 }
+
+// EscapeDNAttributeValue escapes special characters in an attribute value as [described in RFC4514](https://datatracker.ietf.org/doc/html/rfc4514).
+func EscapeDNAttributeValue(v string) string {
+	if v == "" {
+		return v
+	}
+
+	v = dnEscaper.Replace(v)
+
+	if strings.HasSuffix(v, " ") {
+		v = v[:len(v)-1] + "\\ "
+	}
+	if strings.HasPrefix(v, "#") || strings.HasPrefix(v, " ") {
+		v = "\\" + v
+	}
+	return v
+}
diff --git a/ocis/pkg/command/policies.go b/ocis/pkg/command/policies.go
deleted file mode 100644
index 69540d50bbb..00000000000
--- a/ocis/pkg/command/policies.go
+++ /dev/null
@@ -1,30 +0,0 @@
-package command
-
-import (
-	"github.com/owncloud/ocis/v2/ocis-pkg/config"
-	"github.com/owncloud/ocis/v2/ocis-pkg/config/configlog"
-	"github.com/owncloud/ocis/v2/ocis-pkg/config/parser"
-	"github.com/owncloud/ocis/v2/ocis/pkg/command/helper"
-	"github.com/owncloud/ocis/v2/ocis/pkg/register"
-	"github.com/owncloud/ocis/v2/services/policies/pkg/command"
-	"github.com/urfave/cli/v2"
-)
-
-// PoliciesCommand is the entrypoint for the policies service.
-func PoliciesCommand(cfg *config.Config) *cli.Command {
-	return &cli.Command{
-		Name:     cfg.Policies.Service.Name,
-		Usage:    helper.SubcommandDescription(cfg.Policies.Service.Name),
-		Category: "services",
-		Before: func(c *cli.Context) error {
-			configlog.Error(parser.ParseConfig(cfg, true))
-			cfg.Policies.Commons = cfg.Commons
-			return nil
-		},
-		Subcommands: command.GetCommands(cfg.Policies),
-	}
-}
-
-func init() {
-	register.AddCommand(PoliciesCommand)
-}
diff --git a/ocis/pkg/runtime/service/service.go b/ocis/pkg/runtime/service/service.go
index f3a10eb4582..fe7060c05b5 100644
--- a/ocis/pkg/runtime/service/service.go
+++ b/ocis/pkg/runtime/service/service.go
@@ -13,11 +13,13 @@ import (
 	"syscall"
 	"time"
 
+	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+
 	"github.com/mohae/deepcopy"
 	"github.com/olekukonko/tablewriter"
+
 	ociscfg "github.com/owncloud/ocis/v2/ocis-pkg/config"
 	"github.com/owncloud/ocis/v2/ocis-pkg/log"
-	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
 	appProvider "github.com/owncloud/ocis/v2/services/app-provider/pkg/command"
 	appRegistry "github.com/owncloud/ocis/v2/services/app-registry/pkg/command"
 	authbasic "github.com/owncloud/ocis/v2/services/auth-basic/pkg/command"
diff --git a/protogen/gen/ocis/messages/policies/v0/policies.pb.go b/protogen/gen/ocis/messages/policies/v0/policies.pb.go
deleted file mode 100644
index 9bc4770b42f..00000000000
--- a/protogen/gen/ocis/messages/policies/v0/policies.pb.go
+++ /dev/null
@@ -1,653 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// versions:
-// 	protoc-gen-go v1.28.1
-// 	protoc        (unknown)
-// source: ocis/messages/policies/v0/policies.proto
-
-package v0
-
-import (
-	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
-	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
-	reflect "reflect"
-	sync "sync"
-)
-
-const (
-	// Verify that this generated code is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
-	// Verify that runtime/protoimpl is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
-)
-
-type Stage int32
-
-const (
-	Stage_STAGE_PP   Stage = 0
-	Stage_STAGE_HTTP Stage = 1
-)
-
-// Enum value maps for Stage.
-var (
-	Stage_name = map[int32]string{
-		0: "STAGE_PP",
-		1: "STAGE_HTTP",
-	}
-	Stage_value = map[string]int32{
-		"STAGE_PP":   0,
-		"STAGE_HTTP": 1,
-	}
-)
-
-func (x Stage) Enum() *Stage {
-	p := new(Stage)
-	*p = x
-	return p
-}
-
-func (x Stage) String() string {
-	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
-}
-
-func (Stage) Descriptor() protoreflect.EnumDescriptor {
-	return file_ocis_messages_policies_v0_policies_proto_enumTypes[0].Descriptor()
-}
-
-func (Stage) Type() protoreflect.EnumType {
-	return &file_ocis_messages_policies_v0_policies_proto_enumTypes[0]
-}
-
-func (x Stage) Number() protoreflect.EnumNumber {
-	return protoreflect.EnumNumber(x)
-}
-
-// Deprecated: Use Stage.Descriptor instead.
-func (Stage) EnumDescriptor() ([]byte, []int) {
-	return file_ocis_messages_policies_v0_policies_proto_rawDescGZIP(), []int{0}
-}
-
-type User struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	Id          *User_ID `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
-	Username    string   `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"`
-	Mail        string   `protobuf:"bytes,3,opt,name=mail,proto3" json:"mail,omitempty"`
-	DisplayName string   `protobuf:"bytes,4,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"`
-	Groups      []string `protobuf:"bytes,5,rep,name=groups,proto3" json:"groups,omitempty"`
-}
-
-func (x *User) Reset() {
-	*x = User{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_ocis_messages_policies_v0_policies_proto_msgTypes[0]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *User) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*User) ProtoMessage() {}
-
-func (x *User) ProtoReflect() protoreflect.Message {
-	mi := &file_ocis_messages_policies_v0_policies_proto_msgTypes[0]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use User.ProtoReflect.Descriptor instead.
-func (*User) Descriptor() ([]byte, []int) {
-	return file_ocis_messages_policies_v0_policies_proto_rawDescGZIP(), []int{0}
-}
-
-func (x *User) GetId() *User_ID {
-	if x != nil {
-		return x.Id
-	}
-	return nil
-}
-
-func (x *User) GetUsername() string {
-	if x != nil {
-		return x.Username
-	}
-	return ""
-}
-
-func (x *User) GetMail() string {
-	if x != nil {
-		return x.Mail
-	}
-	return ""
-}
-
-func (x *User) GetDisplayName() string {
-	if x != nil {
-		return x.DisplayName
-	}
-	return ""
-}
-
-func (x *User) GetGroups() []string {
-	if x != nil {
-		return x.Groups
-	}
-	return nil
-}
-
-type Resource struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	Id   *Resource_ID `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
-	Name string       `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
-	Size uint64       `protobuf:"varint,3,opt,name=size,proto3" json:"size,omitempty"`
-	Url  string       `protobuf:"bytes,4,opt,name=url,proto3" json:"url,omitempty"`
-}
-
-func (x *Resource) Reset() {
-	*x = Resource{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_ocis_messages_policies_v0_policies_proto_msgTypes[1]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *Resource) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*Resource) ProtoMessage() {}
-
-func (x *Resource) ProtoReflect() protoreflect.Message {
-	mi := &file_ocis_messages_policies_v0_policies_proto_msgTypes[1]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use Resource.ProtoReflect.Descriptor instead.
-func (*Resource) Descriptor() ([]byte, []int) {
-	return file_ocis_messages_policies_v0_policies_proto_rawDescGZIP(), []int{1}
-}
-
-func (x *Resource) GetId() *Resource_ID {
-	if x != nil {
-		return x.Id
-	}
-	return nil
-}
-
-func (x *Resource) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-func (x *Resource) GetSize() uint64 {
-	if x != nil {
-		return x.Size
-	}
-	return 0
-}
-
-func (x *Resource) GetUrl() string {
-	if x != nil {
-		return x.Url
-	}
-	return ""
-}
-
-type Request struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	Method string `protobuf:"bytes,1,opt,name=method,proto3" json:"method,omitempty"`
-	Path   string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"`
-}
-
-func (x *Request) Reset() {
-	*x = Request{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_ocis_messages_policies_v0_policies_proto_msgTypes[2]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *Request) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*Request) ProtoMessage() {}
-
-func (x *Request) ProtoReflect() protoreflect.Message {
-	mi := &file_ocis_messages_policies_v0_policies_proto_msgTypes[2]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use Request.ProtoReflect.Descriptor instead.
-func (*Request) Descriptor() ([]byte, []int) {
-	return file_ocis_messages_policies_v0_policies_proto_rawDescGZIP(), []int{2}
-}
-
-func (x *Request) GetMethod() string {
-	if x != nil {
-		return x.Method
-	}
-	return ""
-}
-
-func (x *Request) GetPath() string {
-	if x != nil {
-		return x.Path
-	}
-	return ""
-}
-
-type Environment struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	Stage    Stage     `protobuf:"varint,1,opt,name=stage,proto3,enum=ocis.messages.policies.v0.Stage" json:"stage,omitempty"`
-	User     *User     `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty"`
-	Request  *Request  `protobuf:"bytes,3,opt,name=request,proto3" json:"request,omitempty"`
-	Resource *Resource `protobuf:"bytes,4,opt,name=resource,proto3" json:"resource,omitempty"`
-}
-
-func (x *Environment) Reset() {
-	*x = Environment{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_ocis_messages_policies_v0_policies_proto_msgTypes[3]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *Environment) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*Environment) ProtoMessage() {}
-
-func (x *Environment) ProtoReflect() protoreflect.Message {
-	mi := &file_ocis_messages_policies_v0_policies_proto_msgTypes[3]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use Environment.ProtoReflect.Descriptor instead.
-func (*Environment) Descriptor() ([]byte, []int) {
-	return file_ocis_messages_policies_v0_policies_proto_rawDescGZIP(), []int{3}
-}
-
-func (x *Environment) GetStage() Stage {
-	if x != nil {
-		return x.Stage
-	}
-	return Stage_STAGE_PP
-}
-
-func (x *Environment) GetUser() *User {
-	if x != nil {
-		return x.User
-	}
-	return nil
-}
-
-func (x *Environment) GetRequest() *Request {
-	if x != nil {
-		return x.Request
-	}
-	return nil
-}
-
-func (x *Environment) GetResource() *Resource {
-	if x != nil {
-		return x.Resource
-	}
-	return nil
-}
-
-type User_ID struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	OpaqueId string `protobuf:"bytes,1,opt,name=opaque_id,json=opaqueId,proto3" json:"opaque_id,omitempty"`
-}
-
-func (x *User_ID) Reset() {
-	*x = User_ID{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_ocis_messages_policies_v0_policies_proto_msgTypes[4]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *User_ID) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*User_ID) ProtoMessage() {}
-
-func (x *User_ID) ProtoReflect() protoreflect.Message {
-	mi := &file_ocis_messages_policies_v0_policies_proto_msgTypes[4]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use User_ID.ProtoReflect.Descriptor instead.
-func (*User_ID) Descriptor() ([]byte, []int) {
-	return file_ocis_messages_policies_v0_policies_proto_rawDescGZIP(), []int{0, 0}
-}
-
-func (x *User_ID) GetOpaqueId() string {
-	if x != nil {
-		return x.OpaqueId
-	}
-	return ""
-}
-
-type Resource_ID struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	StorageId string `protobuf:"bytes,1,opt,name=storage_id,json=storageId,proto3" json:"storage_id,omitempty"`
-	OpaqueId  string `protobuf:"bytes,2,opt,name=opaque_id,json=opaqueId,proto3" json:"opaque_id,omitempty"`
-	SpaceId   string `protobuf:"bytes,3,opt,name=space_id,json=spaceId,proto3" json:"space_id,omitempty"`
-}
-
-func (x *Resource_ID) Reset() {
-	*x = Resource_ID{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_ocis_messages_policies_v0_policies_proto_msgTypes[5]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *Resource_ID) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*Resource_ID) ProtoMessage() {}
-
-func (x *Resource_ID) ProtoReflect() protoreflect.Message {
-	mi := &file_ocis_messages_policies_v0_policies_proto_msgTypes[5]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use Resource_ID.ProtoReflect.Descriptor instead.
-func (*Resource_ID) Descriptor() ([]byte, []int) {
-	return file_ocis_messages_policies_v0_policies_proto_rawDescGZIP(), []int{1, 0}
-}
-
-func (x *Resource_ID) GetStorageId() string {
-	if x != nil {
-		return x.StorageId
-	}
-	return ""
-}
-
-func (x *Resource_ID) GetOpaqueId() string {
-	if x != nil {
-		return x.OpaqueId
-	}
-	return ""
-}
-
-func (x *Resource_ID) GetSpaceId() string {
-	if x != nil {
-		return x.SpaceId
-	}
-	return ""
-}
-
-var File_ocis_messages_policies_v0_policies_proto protoreflect.FileDescriptor
-
-var file_ocis_messages_policies_v0_policies_proto_rawDesc = []byte{
-	0x0a, 0x28, 0x6f, 0x63, 0x69, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2f,
-	0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x76, 0x30, 0x2f, 0x70, 0x6f, 0x6c, 0x69,
-	0x63, 0x69, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x6f, 0x63, 0x69, 0x73,
-	0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69,
-	0x65, 0x73, 0x2e, 0x76, 0x30, 0x22, 0xc8, 0x01, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x32,
-	0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6f, 0x63, 0x69,
-	0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63,
-	0x69, 0x65, 0x73, 0x2e, 0x76, 0x30, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x44, 0x52, 0x02,
-	0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12,
-	0x0a, 0x04, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x61,
-	0x69, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61,
-	0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61,
-	0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18,
-	0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x1a, 0x21, 0x0a,
-	0x02, 0x49, 0x44, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x5f, 0x69, 0x64,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x49, 0x64,
-	0x22, 0xd9, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x36, 0x0a,
-	0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x6f, 0x63, 0x69, 0x73,
-	0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69,
-	0x65, 0x73, 0x2e, 0x76, 0x30, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x49,
-	0x44, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a,
-	0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x10, 0x0a,
-	0x03, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x1a,
-	0x5b, 0x0a, 0x02, 0x49, 0x44, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65,
-	0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x6f, 0x72, 0x61,
-	0x67, 0x65, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x5f, 0x69,
-	0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x49,
-	0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x22, 0x35, 0x0a, 0x07,
-	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f,
-	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12,
-	0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70,
-	0x61, 0x74, 0x68, 0x22, 0xf9, 0x01, 0x0a, 0x0b, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d,
-	0x65, 0x6e, 0x74, 0x12, 0x36, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x0e, 0x32, 0x20, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
-	0x65, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x76, 0x30, 0x2e, 0x53,
-	0x74, 0x61, 0x67, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12, 0x33, 0x0a, 0x04, 0x75,
-	0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6f, 0x63, 0x69, 0x73,
-	0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69,
-	0x65, 0x73, 0x2e, 0x76, 0x30, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72,
-	0x12, 0x3c, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
-	0x0b, 0x32, 0x22, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
-	0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x76, 0x30, 0x2e, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f,
-	0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b,
-	0x32, 0x23, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73,
-	0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x76, 0x30, 0x2e, 0x52, 0x65, 0x73,
-	0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2a,
-	0x25, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x67, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x54, 0x41, 0x47,
-	0x45, 0x5f, 0x50, 0x50, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f,
-	0x48, 0x54, 0x54, 0x50, 0x10, 0x01, 0x42, 0x44, 0x5a, 0x42, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
-	0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x77, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x63,
-	0x69, 0x73, 0x2f, 0x76, 0x32, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x67, 0x65, 0x6e, 0x2f, 0x67,
-	0x65, 0x6e, 0x2f, 0x6f, 0x63, 0x69, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73,
-	0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x76, 0x30, 0x62, 0x06, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x33,
-}
-
-var (
-	file_ocis_messages_policies_v0_policies_proto_rawDescOnce sync.Once
-	file_ocis_messages_policies_v0_policies_proto_rawDescData = file_ocis_messages_policies_v0_policies_proto_rawDesc
-)
-
-func file_ocis_messages_policies_v0_policies_proto_rawDescGZIP() []byte {
-	file_ocis_messages_policies_v0_policies_proto_rawDescOnce.Do(func() {
-		file_ocis_messages_policies_v0_policies_proto_rawDescData = protoimpl.X.CompressGZIP(file_ocis_messages_policies_v0_policies_proto_rawDescData)
-	})
-	return file_ocis_messages_policies_v0_policies_proto_rawDescData
-}
-
-var file_ocis_messages_policies_v0_policies_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_ocis_messages_policies_v0_policies_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
-var file_ocis_messages_policies_v0_policies_proto_goTypes = []interface{}{
-	(Stage)(0),          // 0: ocis.messages.policies.v0.Stage
-	(*User)(nil),        // 1: ocis.messages.policies.v0.User
-	(*Resource)(nil),    // 2: ocis.messages.policies.v0.Resource
-	(*Request)(nil),     // 3: ocis.messages.policies.v0.Request
-	(*Environment)(nil), // 4: ocis.messages.policies.v0.Environment
-	(*User_ID)(nil),     // 5: ocis.messages.policies.v0.User.ID
-	(*Resource_ID)(nil), // 6: ocis.messages.policies.v0.Resource.ID
-}
-var file_ocis_messages_policies_v0_policies_proto_depIdxs = []int32{
-	5, // 0: ocis.messages.policies.v0.User.id:type_name -> ocis.messages.policies.v0.User.ID
-	6, // 1: ocis.messages.policies.v0.Resource.id:type_name -> ocis.messages.policies.v0.Resource.ID
-	0, // 2: ocis.messages.policies.v0.Environment.stage:type_name -> ocis.messages.policies.v0.Stage
-	1, // 3: ocis.messages.policies.v0.Environment.user:type_name -> ocis.messages.policies.v0.User
-	3, // 4: ocis.messages.policies.v0.Environment.request:type_name -> ocis.messages.policies.v0.Request
-	2, // 5: ocis.messages.policies.v0.Environment.resource:type_name -> ocis.messages.policies.v0.Resource
-	6, // [6:6] is the sub-list for method output_type
-	6, // [6:6] is the sub-list for method input_type
-	6, // [6:6] is the sub-list for extension type_name
-	6, // [6:6] is the sub-list for extension extendee
-	0, // [0:6] is the sub-list for field type_name
-}
-
-func init() { file_ocis_messages_policies_v0_policies_proto_init() }
-func file_ocis_messages_policies_v0_policies_proto_init() {
-	if File_ocis_messages_policies_v0_policies_proto != nil {
-		return
-	}
-	if !protoimpl.UnsafeEnabled {
-		file_ocis_messages_policies_v0_policies_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*User); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_ocis_messages_policies_v0_policies_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*Resource); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_ocis_messages_policies_v0_policies_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*Request); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_ocis_messages_policies_v0_policies_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*Environment); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_ocis_messages_policies_v0_policies_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*User_ID); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_ocis_messages_policies_v0_policies_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*Resource_ID); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-	}
-	type x struct{}
-	out := protoimpl.TypeBuilder{
-		File: protoimpl.DescBuilder{
-			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_ocis_messages_policies_v0_policies_proto_rawDesc,
-			NumEnums:      1,
-			NumMessages:   6,
-			NumExtensions: 0,
-			NumServices:   0,
-		},
-		GoTypes:           file_ocis_messages_policies_v0_policies_proto_goTypes,
-		DependencyIndexes: file_ocis_messages_policies_v0_policies_proto_depIdxs,
-		EnumInfos:         file_ocis_messages_policies_v0_policies_proto_enumTypes,
-		MessageInfos:      file_ocis_messages_policies_v0_policies_proto_msgTypes,
-	}.Build()
-	File_ocis_messages_policies_v0_policies_proto = out.File
-	file_ocis_messages_policies_v0_policies_proto_rawDesc = nil
-	file_ocis_messages_policies_v0_policies_proto_goTypes = nil
-	file_ocis_messages_policies_v0_policies_proto_depIdxs = nil
-}
diff --git a/protogen/gen/ocis/messages/policies/v0/policies.pb.micro.go b/protogen/gen/ocis/messages/policies/v0/policies.pb.micro.go
deleted file mode 100644
index 7b2c9b0524b..00000000000
--- a/protogen/gen/ocis/messages/policies/v0/policies.pb.micro.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Code generated by protoc-gen-micro. DO NOT EDIT.
-// source: ocis/messages/policies/v0/policies.proto
-
-package v0
-
-import (
-	fmt "fmt"
-	proto "google.golang.org/protobuf/proto"
-	math "math"
-)
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
diff --git a/protogen/gen/ocis/messages/policies/v0/policies.swagger.json b/protogen/gen/ocis/messages/policies/v0/policies.swagger.json
deleted file mode 100644
index db2d89e2cd0..00000000000
--- a/protogen/gen/ocis/messages/policies/v0/policies.swagger.json
+++ /dev/null
@@ -1,43 +0,0 @@
-{
-  "swagger": "2.0",
-  "info": {
-    "title": "ocis/messages/policies/v0/policies.proto",
-    "version": "version not set"
-  },
-  "consumes": [
-    "application/json"
-  ],
-  "produces": [
-    "application/json"
-  ],
-  "paths": {},
-  "definitions": {
-    "protobufAny": {
-      "type": "object",
-      "properties": {
-        "@type": {
-          "type": "string"
-        }
-      },
-      "additionalProperties": {}
-    },
-    "rpcStatus": {
-      "type": "object",
-      "properties": {
-        "code": {
-          "type": "integer",
-          "format": "int32"
-        },
-        "message": {
-          "type": "string"
-        },
-        "details": {
-          "type": "array",
-          "items": {
-            "$ref": "#/definitions/protobufAny"
-          }
-        }
-      }
-    }
-  }
-}
diff --git a/protogen/gen/ocis/messages/settings/v0/settings.pb.go b/protogen/gen/ocis/messages/settings/v0/settings.pb.go
index 9f0f3d92c64..bae3a9c8710 100644
--- a/protogen/gen/ocis/messages/settings/v0/settings.pb.go
+++ b/protogen/gen/ocis/messages/settings/v0/settings.pb.go
@@ -489,13 +489,13 @@ type Bundle struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Id          string      `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`                                                 // @gotags: yaml:"id"
-	Name        string      `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`                                             // @gotags: yaml:"name"
-	Type        Bundle_Type `protobuf:"varint,3,opt,name=type,proto3,enum=ocis.messages.settings.v0.Bundle_Type" json:"type,omitempty"` // @gotags: yaml:"type"
-	Extension   string      `protobuf:"bytes,4,opt,name=extension,proto3" json:"extension,omitempty"`                                   // @gotags: yaml:"extension"
-	DisplayName string      `protobuf:"bytes,5,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"`            // @gotags: yaml:"display_name"
-	Settings    []*Setting  `protobuf:"bytes,6,rep,name=settings,proto3" json:"settings,omitempty"`                                     // @gotags: yaml:"settings"
-	Resource    *Resource   `protobuf:"bytes,7,opt,name=resource,proto3" json:"resource,omitempty"`                                     // @gotags: yaml:"resource"
+	Id          string      `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" yaml:"id"`                                                 // @gotags: yaml:"id"
+	Name        string      `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty" yaml:"name"`                                             // @gotags: yaml:"name"
+	Type        Bundle_Type `protobuf:"varint,3,opt,name=type,proto3,enum=ocis.messages.settings.v0.Bundle_Type" json:"type,omitempty" yaml:"type"` // @gotags: yaml:"type"
+	Extension   string      `protobuf:"bytes,4,opt,name=extension,proto3" json:"extension,omitempty" yaml:"extension"`                                   // @gotags: yaml:"extension"
+	DisplayName string      `protobuf:"bytes,5,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty" yaml:"display_name"`            // @gotags: yaml:"display_name"
+	Settings    []*Setting  `protobuf:"bytes,6,rep,name=settings,proto3" json:"settings,omitempty" yaml:"settings"`                                     // @gotags: yaml:"settings"
+	Resource    *Resource   `protobuf:"bytes,7,opt,name=resource,proto3" json:"resource,omitempty" yaml:"resource"`                                     // @gotags: yaml:"resource"
 }
 
 func (x *Bundle) Reset() {
@@ -584,10 +584,10 @@ type Setting struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Id          string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`                                      // @gotags: yaml:"id"
-	Name        string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`                                  // @gotags: yaml:"name"
-	DisplayName string `protobuf:"bytes,3,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` // @gotags: yaml:"display_name"
-	Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"`                    // @gotags: yaml:"description"
+	Id          string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" yaml:"id"`                                      // @gotags: yaml:"id"
+	Name        string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty" yaml:"name"`                                  // @gotags: yaml:"name"
+	DisplayName string `protobuf:"bytes,3,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty" yaml:"display_name"` // @gotags: yaml:"display_name"
+	Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty" yaml:"description"`                    // @gotags: yaml:"description"
 	// Types that are assignable to Value:
 	//
 	//	*Setting_IntValue
@@ -597,7 +597,7 @@ type Setting struct {
 	//	*Setting_MultiChoiceValue
 	//	*Setting_PermissionValue
 	Value    isSetting_Value `protobuf_oneof:"value"`
-	Resource *Resource       `protobuf:"bytes,11,opt,name=resource,proto3" json:"resource,omitempty"` // @gotags: yaml:"resource"
+	Resource *Resource       `protobuf:"bytes,11,opt,name=resource,proto3" json:"resource,omitempty" yaml:"resource"` // @gotags: yaml:"resource"
 }
 
 func (x *Setting) Reset() {
@@ -721,27 +721,27 @@ type isSetting_Value interface {
 }
 
 type Setting_IntValue struct {
-	IntValue *Int `protobuf:"bytes,5,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value"
+	IntValue *Int `protobuf:"bytes,5,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value"
 }
 
 type Setting_StringValue struct {
-	StringValue *String `protobuf:"bytes,6,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value"
+	StringValue *String `protobuf:"bytes,6,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value"
 }
 
 type Setting_BoolValue struct {
-	BoolValue *Bool `protobuf:"bytes,7,opt,name=bool_value,json=boolValue,proto3,oneof"` // @gotags: yaml:"bool_value"
+	BoolValue *Bool `protobuf:"bytes,7,opt,name=bool_value,json=boolValue,proto3,oneof" yaml:"bool_value"` // @gotags: yaml:"bool_value"
 }
 
 type Setting_SingleChoiceValue struct {
-	SingleChoiceValue *SingleChoiceList `protobuf:"bytes,8,opt,name=single_choice_value,json=singleChoiceValue,proto3,oneof"` // @gotags: yaml:"single_choice_value"
+	SingleChoiceValue *SingleChoiceList `protobuf:"bytes,8,opt,name=single_choice_value,json=singleChoiceValue,proto3,oneof" yaml:"single_choice_value"` // @gotags: yaml:"single_choice_value"
 }
 
 type Setting_MultiChoiceValue struct {
-	MultiChoiceValue *MultiChoiceList `protobuf:"bytes,9,opt,name=multi_choice_value,json=multiChoiceValue,proto3,oneof"` // @gotags: yaml:"multi_choice_value"
+	MultiChoiceValue *MultiChoiceList `protobuf:"bytes,9,opt,name=multi_choice_value,json=multiChoiceValue,proto3,oneof" yaml:"multi_choice_value"` // @gotags: yaml:"multi_choice_value"
 }
 
 type Setting_PermissionValue struct {
-	PermissionValue *Permission `protobuf:"bytes,10,opt,name=permission_value,json=permissionValue,proto3,oneof"` // @gotags: yaml:"permission_value"
+	PermissionValue *Permission `protobuf:"bytes,10,opt,name=permission_value,json=permissionValue,proto3,oneof" yaml:"permission_value"` // @gotags: yaml:"permission_value"
 }
 
 func (*Setting_IntValue) isSetting_Value() {}
@@ -761,11 +761,11 @@ type Int struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Default     int64  `protobuf:"varint,1,opt,name=default,proto3" json:"default,omitempty"`        // @gotags: yaml:"default"
-	Min         int64  `protobuf:"varint,2,opt,name=min,proto3" json:"min,omitempty"`                // @gotags: yaml:"min"
-	Max         int64  `protobuf:"varint,3,opt,name=max,proto3" json:"max,omitempty"`                // @gotags: yaml:"max"
-	Step        int64  `protobuf:"varint,4,opt,name=step,proto3" json:"step,omitempty"`              // @gotags: yaml:"step"
-	Placeholder string `protobuf:"bytes,5,opt,name=placeholder,proto3" json:"placeholder,omitempty"` // @gotags: yaml:"placeholder"
+	Default     int64  `protobuf:"varint,1,opt,name=default,proto3" json:"default,omitempty" yaml:"default"`        // @gotags: yaml:"default"
+	Min         int64  `protobuf:"varint,2,opt,name=min,proto3" json:"min,omitempty" yaml:"min"`                // @gotags: yaml:"min"
+	Max         int64  `protobuf:"varint,3,opt,name=max,proto3" json:"max,omitempty" yaml:"max"`                // @gotags: yaml:"max"
+	Step        int64  `protobuf:"varint,4,opt,name=step,proto3" json:"step,omitempty" yaml:"step"`              // @gotags: yaml:"step"
+	Placeholder string `protobuf:"bytes,5,opt,name=placeholder,proto3" json:"placeholder,omitempty" yaml:"placeholder"` // @gotags: yaml:"placeholder"
 }
 
 func (x *Int) Reset() {
@@ -840,11 +840,11 @@ type String struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Default     string `protobuf:"bytes,1,opt,name=default,proto3" json:"default,omitempty"`                       // @gotags: yaml:"default"
-	Required    bool   `protobuf:"varint,2,opt,name=required,proto3" json:"required,omitempty"`                    // @gotags: yaml:"required"
-	MinLength   int32  `protobuf:"varint,3,opt,name=min_length,json=minLength,proto3" json:"min_length,omitempty"` // @gotags: yaml:"min_length"
-	MaxLength   int32  `protobuf:"varint,4,opt,name=max_length,json=maxLength,proto3" json:"max_length,omitempty"` // @gotags: yaml:"max_length"
-	Placeholder string `protobuf:"bytes,5,opt,name=placeholder,proto3" json:"placeholder,omitempty"`               // @gotags: yaml:"placeholder"
+	Default     string `protobuf:"bytes,1,opt,name=default,proto3" json:"default,omitempty" yaml:"default"`                       // @gotags: yaml:"default"
+	Required    bool   `protobuf:"varint,2,opt,name=required,proto3" json:"required,omitempty" yaml:"required"`                    // @gotags: yaml:"required"
+	MinLength   int32  `protobuf:"varint,3,opt,name=min_length,json=minLength,proto3" json:"min_length,omitempty" yaml:"min_length"` // @gotags: yaml:"min_length"
+	MaxLength   int32  `protobuf:"varint,4,opt,name=max_length,json=maxLength,proto3" json:"max_length,omitempty" yaml:"max_length"` // @gotags: yaml:"max_length"
+	Placeholder string `protobuf:"bytes,5,opt,name=placeholder,proto3" json:"placeholder,omitempty" yaml:"placeholder"`               // @gotags: yaml:"placeholder"
 }
 
 func (x *String) Reset() {
@@ -919,8 +919,8 @@ type Bool struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Default bool   `protobuf:"varint,1,opt,name=default,proto3" json:"default,omitempty"` // @gotags: yaml:"default"
-	Label   string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty"`      // @gotags: yaml:"label"
+	Default bool   `protobuf:"varint,1,opt,name=default,proto3" json:"default,omitempty" yaml:"default"` // @gotags: yaml:"default"
+	Label   string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty" yaml:"label"`      // @gotags: yaml:"label"
 }
 
 func (x *Bool) Reset() {
@@ -974,7 +974,7 @@ type SingleChoiceList struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Options []*ListOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty"` // @gotags: yaml:"options"
+	Options []*ListOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty" yaml:"options"` // @gotags: yaml:"options"
 }
 
 func (x *SingleChoiceList) Reset() {
@@ -1021,7 +1021,7 @@ type MultiChoiceList struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Options []*ListOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty"` // @gotags: yaml:"options"
+	Options []*ListOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty" yaml:"options"` // @gotags: yaml:"options"
 }
 
 func (x *MultiChoiceList) Reset() {
@@ -1068,9 +1068,9 @@ type ListOption struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Value        *ListOptionValue `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`                                   // @gotags: yaml:"value"
-	Default      bool             `protobuf:"varint,2,opt,name=default,proto3" json:"default,omitempty"`                              // @gotags: yaml:"default"
-	DisplayValue string           `protobuf:"bytes,3,opt,name=display_value,json=displayValue,proto3" json:"display_value,omitempty"` // @gotags: yaml:"display_value"
+	Value        *ListOptionValue `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty" yaml:"value"`                                   // @gotags: yaml:"value"
+	Default      bool             `protobuf:"varint,2,opt,name=default,proto3" json:"default,omitempty" yaml:"default"`                              // @gotags: yaml:"default"
+	DisplayValue string           `protobuf:"bytes,3,opt,name=display_value,json=displayValue,proto3" json:"display_value,omitempty" yaml:"display_value"` // @gotags: yaml:"display_value"
 }
 
 func (x *ListOption) Reset() {
@@ -1131,8 +1131,8 @@ type Permission struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Operation  Permission_Operation  `protobuf:"varint,1,opt,name=operation,proto3,enum=ocis.messages.settings.v0.Permission_Operation" json:"operation,omitempty"`    // @gotags: yaml:"operation"
-	Constraint Permission_Constraint `protobuf:"varint,2,opt,name=constraint,proto3,enum=ocis.messages.settings.v0.Permission_Constraint" json:"constraint,omitempty"` // @gotags: yaml:"constraint"
+	Operation  Permission_Operation  `protobuf:"varint,1,opt,name=operation,proto3,enum=ocis.messages.settings.v0.Permission_Operation" json:"operation,omitempty" yaml:"operation"`    // @gotags: yaml:"operation"
+	Constraint Permission_Constraint `protobuf:"varint,2,opt,name=constraint,proto3,enum=ocis.messages.settings.v0.Permission_Constraint" json:"constraint,omitempty" yaml:"constraint"` // @gotags: yaml:"constraint"
 }
 
 func (x *Permission) Reset() {
@@ -1187,12 +1187,12 @@ type Value struct {
 	unknownFields protoimpl.UnknownFields
 
 	// id is the id of the Value. It is generated on saving it.
-	Id       string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`                             // @gotags: yaml:"id"
-	BundleId string `protobuf:"bytes,2,opt,name=bundle_id,json=bundleId,proto3" json:"bundle_id,omitempty"` // @gotags: yaml:"bundle_id"
+	Id       string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" yaml:"id"`                             // @gotags: yaml:"id"
+	BundleId string `protobuf:"bytes,2,opt,name=bundle_id,json=bundleId,proto3" json:"bundle_id,omitempty" yaml:"bundle_id"` // @gotags: yaml:"bundle_id"
 	// setting_id is the id of the setting from within its bundle.
-	SettingId   string    `protobuf:"bytes,3,opt,name=setting_id,json=settingId,proto3" json:"setting_id,omitempty"`       // @gotags: yaml:"setting_id"
-	AccountUuid string    `protobuf:"bytes,4,opt,name=account_uuid,json=accountUuid,proto3" json:"account_uuid,omitempty"` // @gotags: yaml:"account_uuid"
-	Resource    *Resource `protobuf:"bytes,5,opt,name=resource,proto3" json:"resource,omitempty"`                          // @gotags: yaml:"resource"
+	SettingId   string    `protobuf:"bytes,3,opt,name=setting_id,json=settingId,proto3" json:"setting_id,omitempty" yaml:"setting_id"`       // @gotags: yaml:"setting_id"
+	AccountUuid string    `protobuf:"bytes,4,opt,name=account_uuid,json=accountUuid,proto3" json:"account_uuid,omitempty" yaml:"account_uuid"` // @gotags: yaml:"account_uuid"
+	Resource    *Resource `protobuf:"bytes,5,opt,name=resource,proto3" json:"resource,omitempty" yaml:"resource"`                          // @gotags: yaml:"resource"
 	// Types that are assignable to Value:
 	//
 	//	*Value_BoolValue
@@ -1309,19 +1309,19 @@ type isValue_Value interface {
 }
 
 type Value_BoolValue struct {
-	BoolValue bool `protobuf:"varint,6,opt,name=bool_value,json=boolValue,proto3,oneof"` // @gotags: yaml:"bool_value"
+	BoolValue bool `protobuf:"varint,6,opt,name=bool_value,json=boolValue,proto3,oneof" yaml:"bool_value"` // @gotags: yaml:"bool_value"
 }
 
 type Value_IntValue struct {
-	IntValue int64 `protobuf:"varint,7,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value"
+	IntValue int64 `protobuf:"varint,7,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value"
 }
 
 type Value_StringValue struct {
-	StringValue string `protobuf:"bytes,8,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value"
+	StringValue string `protobuf:"bytes,8,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value"
 }
 
 type Value_ListValue struct {
-	ListValue *ListValue `protobuf:"bytes,9,opt,name=list_value,json=listValue,proto3,oneof"` // @gotags: yaml:"list_value"
+	ListValue *ListValue `protobuf:"bytes,9,opt,name=list_value,json=listValue,proto3,oneof" yaml:"list_value"` // @gotags: yaml:"list_value"
 }
 
 func (*Value_BoolValue) isValue_Value() {}
@@ -1337,7 +1337,7 @@ type ListValue struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Values []*ListOptionValue `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` // @gotags: yaml:"values"
+	Values []*ListOptionValue `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty" yaml:"values"` // @gotags: yaml:"values"
 }
 
 func (x *ListValue) Reset() {
@@ -1449,11 +1449,11 @@ type isListOptionValue_Option interface {
 }
 
 type ListOptionValue_StringValue struct {
-	StringValue string `protobuf:"bytes,1,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value"
+	StringValue string `protobuf:"bytes,1,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value"
 }
 
 type ListOptionValue_IntValue struct {
-	IntValue int64 `protobuf:"varint,2,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value"
+	IntValue int64 `protobuf:"varint,2,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value"
 }
 
 func (*ListOptionValue_StringValue) isListOptionValue_Option() {}
diff --git a/protogen/gen/ocis/services/policies/v0/policies.pb.go b/protogen/gen/ocis/services/policies/v0/policies.pb.go
deleted file mode 100644
index fa2f474f92e..00000000000
--- a/protogen/gen/ocis/services/policies/v0/policies.pb.go
+++ /dev/null
@@ -1,266 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// versions:
-// 	protoc-gen-go v1.28.1
-// 	protoc        (unknown)
-// source: ocis/services/policies/v0/policies.proto
-
-package v0
-
-import (
-	_ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options"
-	v0 "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/policies/v0"
-	_ "google.golang.org/genproto/googleapis/api/annotations"
-	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
-	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
-	reflect "reflect"
-	sync "sync"
-)
-
-const (
-	// Verify that this generated code is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
-	// Verify that runtime/protoimpl is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
-)
-
-type EvaluateRequest struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	Query       string          `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"`
-	Environment *v0.Environment `protobuf:"bytes,2,opt,name=environment,proto3" json:"environment,omitempty"`
-}
-
-func (x *EvaluateRequest) Reset() {
-	*x = EvaluateRequest{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_ocis_services_policies_v0_policies_proto_msgTypes[0]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *EvaluateRequest) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*EvaluateRequest) ProtoMessage() {}
-
-func (x *EvaluateRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_ocis_services_policies_v0_policies_proto_msgTypes[0]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use EvaluateRequest.ProtoReflect.Descriptor instead.
-func (*EvaluateRequest) Descriptor() ([]byte, []int) {
-	return file_ocis_services_policies_v0_policies_proto_rawDescGZIP(), []int{0}
-}
-
-func (x *EvaluateRequest) GetQuery() string {
-	if x != nil {
-		return x.Query
-	}
-	return ""
-}
-
-func (x *EvaluateRequest) GetEnvironment() *v0.Environment {
-	if x != nil {
-		return x.Environment
-	}
-	return nil
-}
-
-type EvaluateResponse struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	Result bool `protobuf:"varint,1,opt,name=result,proto3" json:"result,omitempty"`
-}
-
-func (x *EvaluateResponse) Reset() {
-	*x = EvaluateResponse{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_ocis_services_policies_v0_policies_proto_msgTypes[1]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *EvaluateResponse) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*EvaluateResponse) ProtoMessage() {}
-
-func (x *EvaluateResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_ocis_services_policies_v0_policies_proto_msgTypes[1]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use EvaluateResponse.ProtoReflect.Descriptor instead.
-func (*EvaluateResponse) Descriptor() ([]byte, []int) {
-	return file_ocis_services_policies_v0_policies_proto_rawDescGZIP(), []int{1}
-}
-
-func (x *EvaluateResponse) GetResult() bool {
-	if x != nil {
-		return x.Result
-	}
-	return false
-}
-
-var File_ocis_services_policies_v0_policies_proto protoreflect.FileDescriptor
-
-var file_ocis_services_policies_v0_policies_proto_rawDesc = []byte{
-	0x0a, 0x28, 0x6f, 0x63, 0x69, 0x73, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f,
-	0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x76, 0x30, 0x2f, 0x70, 0x6f, 0x6c, 0x69,
-	0x63, 0x69, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x6f, 0x63, 0x69, 0x73,
-	0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69,
-	0x65, 0x73, 0x2e, 0x76, 0x30, 0x1a, 0x28, 0x6f, 0x63, 0x69, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73,
-	0x61, 0x67, 0x65, 0x73, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x76, 0x30,
-	0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
-	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65, 0x6e,
-	0x61, 0x70, 0x69, 0x76, 0x32, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61, 0x6e,
-	0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
-	0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f,
-	0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x71, 0x0a,
-	0x0f, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x48, 0x0a, 0x0b, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f,
-	0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x6f, 0x63,
-	0x69, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69,
-	0x63, 0x69, 0x65, 0x73, 0x2e, 0x76, 0x30, 0x2e, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d,
-	0x65, 0x6e, 0x74, 0x52, 0x0b, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74,
-	0x22, 0x2a, 0x0a, 0x10, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x32, 0x9e, 0x01, 0x0a,
-	0x10, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65,
-	0x72, 0x12, 0x89, 0x01, 0x0a, 0x08, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x12, 0x2a,
-	0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70,
-	0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x76, 0x30, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75,
-	0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x6f, 0x63, 0x69,
-	0x73, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63,
-	0x69, 0x65, 0x73, 0x2e, 0x76, 0x30, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x22,
-	0x19, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x30, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65,
-	0x73, 0x2f, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x3a, 0x01, 0x2a, 0x42, 0xe2, 0x02,
-	0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x77, 0x6e,
-	0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x63, 0x69, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x67, 0x65, 0x6e, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x6f, 0x63, 0x69, 0x73, 0x2f, 0x73, 0x65, 0x72,
-	0x76, 0x69, 0x63, 0x65, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x76, 0x30,
-	0x92, 0x41, 0x9e, 0x02, 0x12, 0xb6, 0x01, 0x0a, 0x20, 0x6f, 0x77, 0x6e, 0x43, 0x6c, 0x6f, 0x75,
-	0x64, 0x20, 0x49, 0x6e, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x65, 0x20, 0x53, 0x63, 0x61, 0x6c, 0x65,
-	0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x22, 0x47, 0x0a, 0x0d, 0x6f, 0x77, 0x6e,
-	0x43, 0x6c, 0x6f, 0x75, 0x64, 0x20, 0x47, 0x6d, 0x62, 0x48, 0x12, 0x20, 0x68, 0x74, 0x74, 0x70,
-	0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f,
-	0x77, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x63, 0x69, 0x73, 0x1a, 0x14, 0x73, 0x75,
-	0x70, 0x70, 0x6f, 0x72, 0x74, 0x40, 0x6f, 0x77, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x63,
-	0x6f, 0x6d, 0x2a, 0x42, 0x0a, 0x0a, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2d, 0x32, 0x2e, 0x30,
-	0x12, 0x34, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
-	0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x77, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x63,
-	0x69, 0x73, 0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2f, 0x4c,
-	0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x32, 0x05, 0x31, 0x2e, 0x30, 0x2e, 0x30, 0x2a, 0x02, 0x01,
-	0x02, 0x32, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a,
-	0x73, 0x6f, 0x6e, 0x3a, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-	0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x72, 0x3b, 0x0a, 0x10, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70,
-	0x65, 0x72, 0x20, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x12, 0x27, 0x68, 0x74, 0x74, 0x70, 0x73,
-	0x3a, 0x2f, 0x2f, 0x6f, 0x77, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x64, 0x65, 0x76, 0x2f,
-	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65,
-	0x73, 0x2f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
-}
-
-var (
-	file_ocis_services_policies_v0_policies_proto_rawDescOnce sync.Once
-	file_ocis_services_policies_v0_policies_proto_rawDescData = file_ocis_services_policies_v0_policies_proto_rawDesc
-)
-
-func file_ocis_services_policies_v0_policies_proto_rawDescGZIP() []byte {
-	file_ocis_services_policies_v0_policies_proto_rawDescOnce.Do(func() {
-		file_ocis_services_policies_v0_policies_proto_rawDescData = protoimpl.X.CompressGZIP(file_ocis_services_policies_v0_policies_proto_rawDescData)
-	})
-	return file_ocis_services_policies_v0_policies_proto_rawDescData
-}
-
-var file_ocis_services_policies_v0_policies_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
-var file_ocis_services_policies_v0_policies_proto_goTypes = []interface{}{
-	(*EvaluateRequest)(nil),  // 0: ocis.services.policies.v0.EvaluateRequest
-	(*EvaluateResponse)(nil), // 1: ocis.services.policies.v0.EvaluateResponse
-	(*v0.Environment)(nil),   // 2: ocis.messages.policies.v0.Environment
-}
-var file_ocis_services_policies_v0_policies_proto_depIdxs = []int32{
-	2, // 0: ocis.services.policies.v0.EvaluateRequest.environment:type_name -> ocis.messages.policies.v0.Environment
-	0, // 1: ocis.services.policies.v0.policiesProvider.Evaluate:input_type -> ocis.services.policies.v0.EvaluateRequest
-	1, // 2: ocis.services.policies.v0.policiesProvider.Evaluate:output_type -> ocis.services.policies.v0.EvaluateResponse
-	2, // [2:3] is the sub-list for method output_type
-	1, // [1:2] is the sub-list for method input_type
-	1, // [1:1] is the sub-list for extension type_name
-	1, // [1:1] is the sub-list for extension extendee
-	0, // [0:1] is the sub-list for field type_name
-}
-
-func init() { file_ocis_services_policies_v0_policies_proto_init() }
-func file_ocis_services_policies_v0_policies_proto_init() {
-	if File_ocis_services_policies_v0_policies_proto != nil {
-		return
-	}
-	if !protoimpl.UnsafeEnabled {
-		file_ocis_services_policies_v0_policies_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*EvaluateRequest); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_ocis_services_policies_v0_policies_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*EvaluateResponse); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-	}
-	type x struct{}
-	out := protoimpl.TypeBuilder{
-		File: protoimpl.DescBuilder{
-			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_ocis_services_policies_v0_policies_proto_rawDesc,
-			NumEnums:      0,
-			NumMessages:   2,
-			NumExtensions: 0,
-			NumServices:   1,
-		},
-		GoTypes:           file_ocis_services_policies_v0_policies_proto_goTypes,
-		DependencyIndexes: file_ocis_services_policies_v0_policies_proto_depIdxs,
-		MessageInfos:      file_ocis_services_policies_v0_policies_proto_msgTypes,
-	}.Build()
-	File_ocis_services_policies_v0_policies_proto = out.File
-	file_ocis_services_policies_v0_policies_proto_rawDesc = nil
-	file_ocis_services_policies_v0_policies_proto_goTypes = nil
-	file_ocis_services_policies_v0_policies_proto_depIdxs = nil
-}
diff --git a/protogen/gen/ocis/services/policies/v0/policies.pb.micro.go b/protogen/gen/ocis/services/policies/v0/policies.pb.micro.go
deleted file mode 100644
index 4d813c16848..00000000000
--- a/protogen/gen/ocis/services/policies/v0/policies.pb.micro.go
+++ /dev/null
@@ -1,103 +0,0 @@
-// Code generated by protoc-gen-micro. DO NOT EDIT.
-// source: ocis/services/policies/v0/policies.proto
-
-package v0
-
-import (
-	fmt "fmt"
-	_ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options"
-	_ "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/policies/v0"
-	_ "google.golang.org/genproto/googleapis/api/annotations"
-	proto "google.golang.org/protobuf/proto"
-	math "math"
-)
-
-import (
-	context "context"
-	api "go-micro.dev/v4/api"
-	client "go-micro.dev/v4/client"
-	server "go-micro.dev/v4/server"
-)
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ api.Endpoint
-var _ context.Context
-var _ client.Option
-var _ server.Option
-
-// Api Endpoints for PoliciesProvider service
-
-func NewPoliciesProviderEndpoints() []*api.Endpoint {
-	return []*api.Endpoint{
-		{
-			Name:    "PoliciesProvider.Evaluate",
-			Path:    []string{"/api/v0/policies/evaluate"},
-			Method:  []string{"POST"},
-			Handler: "rpc",
-		},
-	}
-}
-
-// Client API for PoliciesProvider service
-
-type PoliciesProviderService interface {
-	Evaluate(ctx context.Context, in *EvaluateRequest, opts ...client.CallOption) (*EvaluateResponse, error)
-}
-
-type policiesProviderService struct {
-	c    client.Client
-	name string
-}
-
-func NewPoliciesProviderService(name string, c client.Client) PoliciesProviderService {
-	return &policiesProviderService{
-		c:    c,
-		name: name,
-	}
-}
-
-func (c *policiesProviderService) Evaluate(ctx context.Context, in *EvaluateRequest, opts ...client.CallOption) (*EvaluateResponse, error) {
-	req := c.c.NewRequest(c.name, "PoliciesProvider.Evaluate", in)
-	out := new(EvaluateResponse)
-	err := c.c.Call(ctx, req, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-// Server API for PoliciesProvider service
-
-type PoliciesProviderHandler interface {
-	Evaluate(context.Context, *EvaluateRequest, *EvaluateResponse) error
-}
-
-func RegisterPoliciesProviderHandler(s server.Server, hdlr PoliciesProviderHandler, opts ...server.HandlerOption) error {
-	type policiesProvider interface {
-		Evaluate(ctx context.Context, in *EvaluateRequest, out *EvaluateResponse) error
-	}
-	type PoliciesProvider struct {
-		policiesProvider
-	}
-	h := &policiesProviderHandler{hdlr}
-	opts = append(opts, api.WithEndpoint(&api.Endpoint{
-		Name:    "PoliciesProvider.Evaluate",
-		Path:    []string{"/api/v0/policies/evaluate"},
-		Method:  []string{"POST"},
-		Handler: "rpc",
-	}))
-	return s.Handle(s.NewHandler(&PoliciesProvider{h}, opts...))
-}
-
-type policiesProviderHandler struct {
-	PoliciesProviderHandler
-}
-
-func (h *policiesProviderHandler) Evaluate(ctx context.Context, in *EvaluateRequest, out *EvaluateResponse) error {
-	return h.PoliciesProviderHandler.Evaluate(ctx, in, out)
-}
diff --git a/protogen/gen/ocis/services/policies/v0/policies.swagger.json b/protogen/gen/ocis/services/policies/v0/policies.swagger.json
deleted file mode 100644
index 6eaf5b9803f..00000000000
--- a/protogen/gen/ocis/services/policies/v0/policies.swagger.json
+++ /dev/null
@@ -1,216 +0,0 @@
-{
-  "swagger": "2.0",
-  "info": {
-    "title": "ownCloud Infinite Scale policies",
-    "version": "1.0.0",
-    "contact": {
-      "name": "ownCloud GmbH",
-      "url": "https://github.com/owncloud/ocis",
-      "email": "support@owncloud.com"
-    },
-    "license": {
-      "name": "Apache-2.0",
-      "url": "https://github.com/owncloud/ocis/blob/master/LICENSE"
-    }
-  },
-  "tags": [
-    {
-      "name": "policiesProvider"
-    }
-  ],
-  "schemes": [
-    "http",
-    "https"
-  ],
-  "consumes": [
-    "application/json"
-  ],
-  "produces": [
-    "application/json"
-  ],
-  "paths": {
-    "/api/v0/policies/evaluate": {
-      "post": {
-        "operationId": "policiesProvider_Evaluate",
-        "responses": {
-          "200": {
-            "description": "A successful response.",
-            "schema": {
-              "$ref": "#/definitions/v0EvaluateResponse"
-            }
-          },
-          "default": {
-            "description": "An unexpected error response.",
-            "schema": {
-              "$ref": "#/definitions/rpcStatus"
-            }
-          }
-        },
-        "parameters": [
-          {
-            "name": "body",
-            "in": "body",
-            "required": true,
-            "schema": {
-              "$ref": "#/definitions/v0EvaluateRequest"
-            }
-          }
-        ],
-        "tags": [
-          "policiesProvider"
-        ]
-      }
-    }
-  },
-  "definitions": {
-    "protobufAny": {
-      "type": "object",
-      "properties": {
-        "@type": {
-          "type": "string"
-        }
-      },
-      "additionalProperties": {}
-    },
-    "rpcStatus": {
-      "type": "object",
-      "properties": {
-        "code": {
-          "type": "integer",
-          "format": "int32"
-        },
-        "message": {
-          "type": "string"
-        },
-        "details": {
-          "type": "array",
-          "items": {
-            "$ref": "#/definitions/protobufAny"
-          }
-        }
-      }
-    },
-    "v0Environment": {
-      "type": "object",
-      "properties": {
-        "stage": {
-          "$ref": "#/definitions/v0Stage"
-        },
-        "user": {
-          "$ref": "#/definitions/v0User"
-        },
-        "request": {
-          "$ref": "#/definitions/v0Request"
-        },
-        "resource": {
-          "$ref": "#/definitions/v0Resource"
-        }
-      }
-    },
-    "v0EvaluateRequest": {
-      "type": "object",
-      "properties": {
-        "query": {
-          "type": "string"
-        },
-        "environment": {
-          "$ref": "#/definitions/v0Environment"
-        }
-      }
-    },
-    "v0EvaluateResponse": {
-      "type": "object",
-      "properties": {
-        "result": {
-          "type": "boolean"
-        }
-      }
-    },
-    "v0Request": {
-      "type": "object",
-      "properties": {
-        "method": {
-          "type": "string"
-        },
-        "path": {
-          "type": "string"
-        }
-      }
-    },
-    "v0Resource": {
-      "type": "object",
-      "properties": {
-        "id": {
-          "$ref": "#/definitions/v0ResourceID"
-        },
-        "name": {
-          "type": "string"
-        },
-        "size": {
-          "type": "string",
-          "format": "uint64"
-        },
-        "url": {
-          "type": "string"
-        }
-      }
-    },
-    "v0ResourceID": {
-      "type": "object",
-      "properties": {
-        "storageId": {
-          "type": "string"
-        },
-        "opaqueId": {
-          "type": "string"
-        },
-        "spaceId": {
-          "type": "string"
-        }
-      }
-    },
-    "v0Stage": {
-      "type": "string",
-      "enum": [
-        "STAGE_PP",
-        "STAGE_HTTP"
-      ],
-      "default": "STAGE_PP"
-    },
-    "v0User": {
-      "type": "object",
-      "properties": {
-        "id": {
-          "$ref": "#/definitions/v0UserID"
-        },
-        "username": {
-          "type": "string"
-        },
-        "mail": {
-          "type": "string"
-        },
-        "displayName": {
-          "type": "string"
-        },
-        "groups": {
-          "type": "array",
-          "items": {
-            "type": "string"
-          }
-        }
-      }
-    },
-    "v0UserID": {
-      "type": "object",
-      "properties": {
-        "opaqueId": {
-          "type": "string"
-        }
-      }
-    }
-  },
-  "externalDocs": {
-    "description": "Developer Manual",
-    "url": "https://owncloud.dev/services/policies/"
-  }
-}
diff --git a/protogen/proto/buf.gen.yaml b/protogen/proto/buf.gen.yaml
index 2285da28629..37f05fce272 100644
--- a/protogen/proto/buf.gen.yaml
+++ b/protogen/proto/buf.gen.yaml
@@ -23,9 +23,7 @@ plugins:
          ocis.services.store.v0;\
          ocis.messages.store.v0;\
          ocis.services.eventhistory.v0;\
-         ocis.messages.eventhistory.v0;\
-         ocis.services.policies.v0;\
-         ocis.messages.policies.v0"
+         ocis.messages.eventhistory.v0"
 
   - name: openapiv2
     path: ../../.bingo/protoc-gen-openapiv2
diff --git a/protogen/proto/ocis/messages/policies/v0/policies.proto b/protogen/proto/ocis/messages/policies/v0/policies.proto
deleted file mode 100644
index e6763745fe9..00000000000
--- a/protogen/proto/ocis/messages/policies/v0/policies.proto
+++ /dev/null
@@ -1,49 +0,0 @@
-syntax = "proto3";
-
-package ocis.messages.policies.v0;
-
-option go_package = "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/policies/v0";
-
-message User {
-	message ID {
-			string opaque_id = 1;
-	}
-
-	ID id = 1;
-	string username = 2;
-	string mail = 3;
-	string display_name = 4;
-	repeated string groups = 5;
-}
-
-message Resource {
-	message ID {
-		string storage_id = 1;
-		string opaque_id = 2;
-		string space_id = 3;
-	}
-
-	ID id = 1;
-	string name = 2;
-	uint64 size = 3;
-	string url = 4;
-}
-
-message Request {
-	string method = 1;
-	string path = 2;
-}
-
-enum Stage {
-	STAGE_PP = 0;
-	STAGE_HTTP = 1;
-}
-
-message Environment {
-	Stage stage = 1;
-	User user = 2;
-	Request request = 3;
-	Resource resource = 4;
-}
-
-
diff --git a/protogen/proto/ocis/services/policies/v0/policies.proto b/protogen/proto/ocis/services/policies/v0/policies.proto
deleted file mode 100644
index e2612db8d08..00000000000
--- a/protogen/proto/ocis/services/policies/v0/policies.proto
+++ /dev/null
@@ -1,51 +0,0 @@
-syntax = "proto3";
-
-package ocis.services.policies.v0;
-
-option go_package = "github.com/owncloud/ocis/protogen/gen/ocis/service/policies/v0";
-
-import "ocis/messages/policies/v0/policies.proto";
-import "protoc-gen-openapiv2/options/annotations.proto";
-import "google/api/annotations.proto";
-
-option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
-  info: {
-    title: "ownCloud Infinite Scale policies";
-    version: "1.0.0";
-    contact: {
-      name: "ownCloud GmbH";
-      url: "https://github.com/owncloud/ocis";
-      email: "support@owncloud.com";
-    };
-    license: {
-      name: "Apache-2.0";
-      url: "https://github.com/owncloud/ocis/blob/master/LICENSE";
-    };
-  };
-  schemes: HTTP;
-  schemes: HTTPS;
-  consumes: "application/json";
-  produces: "application/json";
-  external_docs: {
-    description: "Developer Manual";
-    url: "https://owncloud.dev/services/policies/";
-  };
-};
-
-service policiesProvider {
-	rpc Evaluate(EvaluateRequest) returns (EvaluateResponse) {
-    option (google.api.http) = {
-        post: "/api/v0/policies/evaluate",
-        body: "*"
-    };
-  };
-}
-
-message EvaluateRequest {
-  string query = 1;
-  ocis.messages.policies.v0.Environment environment = 2;
-}
-
-message EvaluateResponse {
-  bool result = 1;
-}
diff --git a/services/graph/pkg/identity/ldap.go b/services/graph/pkg/identity/ldap.go
index 4a5dffbb478..5266e4f06e7 100644
--- a/services/graph/pkg/identity/ldap.go
+++ b/services/graph/pkg/identity/ldap.go
@@ -12,6 +12,7 @@ import (
 	"github.com/gofrs/uuid"
 	"github.com/libregraph/idm/pkg/ldapdn"
 	libregraph "github.com/owncloud/libre-graph-api-go"
+	oldap "github.com/owncloud/ocis/v2/ocis-pkg/ldap"
 	"github.com/owncloud/ocis/v2/ocis-pkg/log"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/config"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/service/v0/errorcode"
@@ -595,18 +596,14 @@ func (i *LDAP) GetUsers(ctx context.Context, oreq *godata.GoDataRequest) ([]*lib
 func (i *LDAP) changeUserName(ctx context.Context, dn, originalUserName, newUserName string) (*ldap.Entry, error) {
 	logger := i.logger.SubloggerWithRequestID(ctx)
 
-	attributeTypeAndValue := ldap.AttributeTypeAndValue{
-		Type:  i.userAttributeMap.userName,
-		Value: newUserName,
-	}
-	newDNString := attributeTypeAndValue.String()
+	newDN := fmt.Sprintf("%s=%s", i.userAttributeMap.userName, newUserName)
 
-	logger.Debug().Str("originalDN", dn).Str("newDN", newDNString).Msg("Modifying DN")
-	mrdn := ldap.NewModifyDNRequest(dn, newDNString, true, "")
+	logger.Debug().Str("originalDN", dn).Str("newDN", newDN).Msg("Modifying DN")
+	mrdn := ldap.NewModifyDNRequest(dn, newDN, true, "")
 
 	if err := i.conn.ModifyDN(mrdn); err != nil {
 		var lerr *ldap.Error
-		logger.Debug().Str("originalDN", dn).Str("newDN", newDNString).Err(err).Msg("Failed to modify DN")
+		logger.Debug().Str("originalDN", dn).Str("newDN", newDN).Err(err).Msg("Failed to modify DN")
 		if errors.As(err, &lerr) {
 			if lerr.ResultCode == ldap.LDAPResultEntryAlreadyExists {
 				err = errorcode.New(errorcode.NameAlreadyExists, lerr.Error())
@@ -620,7 +617,7 @@ func (i *LDAP) changeUserName(ctx context.Context, dn, originalUserName, newUser
 		return nil, err
 	}
 
-	newFullDN, err := replaceDN(parsed, newDNString)
+	newFullDN, err := replaceDN(parsed, newDN)
 	if err != nil {
 		return nil, err
 	}
@@ -782,11 +779,7 @@ func (i *LDAP) getUserAttrTypes() []string {
 }
 
 func (i *LDAP) getUserLDAPDN(user libregraph.User) string {
-	attributeTypeAndValue := ldap.AttributeTypeAndValue{
-		Type:  "uid",
-		Value: *user.OnPremisesSamAccountName,
-	}
-	return fmt.Sprintf("%s,%s", attributeTypeAndValue.String(), i.userBaseDN)
+	return fmt.Sprintf("uid=%s,%s", oldap.EscapeDNAttributeValue(*user.OnPremisesSamAccountName), i.userBaseDN)
 }
 
 func (i *LDAP) userToAddRequest(user libregraph.User) (*ldap.AddRequest, error) {
diff --git a/services/graph/pkg/identity/ldap_education_class.go b/services/graph/pkg/identity/ldap_education_class.go
index ee65eb970da..52856f7741e 100644
--- a/services/graph/pkg/identity/ldap_education_class.go
+++ b/services/graph/pkg/identity/ldap_education_class.go
@@ -8,6 +8,7 @@ import (
 	"github.com/go-ldap/ldap/v3"
 	"github.com/libregraph/idm/pkg/ldapdn"
 	libregraph "github.com/owncloud/libre-graph-api-go"
+	oldap "github.com/owncloud/ocis/v2/ocis-pkg/ldap"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/service/v0/errorcode"
 )
 
@@ -333,11 +334,7 @@ func (i *LDAP) groupToEducationClass(group libregraph.Group, e *ldap.Entry) *lib
 }
 
 func (i *LDAP) getEducationClassLDAPDN(class libregraph.EducationClass) string {
-	attributeTypeAndValue := ldap.AttributeTypeAndValue{
-		Type:  "ocEducationExternalId",
-		Value: class.GetExternalId(),
-	}
-	return fmt.Sprintf("%s,%s", attributeTypeAndValue.String(), i.groupBaseDN)
+	return fmt.Sprintf("ocEducationExternalId=%s,%s", oldap.EscapeDNAttributeValue(class.GetExternalId()), i.groupBaseDN)
 }
 
 func (i *LDAP) getEducationClassByID(nameOrID string, requestMembers bool) (*ldap.Entry, error) {
diff --git a/services/graph/pkg/identity/ldap_education_school.go b/services/graph/pkg/identity/ldap_education_school.go
index 48858ab3446..884366d386c 100644
--- a/services/graph/pkg/identity/ldap_education_school.go
+++ b/services/graph/pkg/identity/ldap_education_school.go
@@ -8,6 +8,7 @@ import (
 	"github.com/go-ldap/ldap/v3"
 	"github.com/gofrs/uuid"
 	libregraph "github.com/owncloud/libre-graph-api-go"
+	oldap "github.com/owncloud/ocis/v2/ocis-pkg/ldap"
 	"github.com/owncloud/ocis/v2/ocis-pkg/log"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/config"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/service/v0/errorcode"
@@ -111,13 +112,9 @@ func (i *LDAP) CreateEducationSchool(ctx context.Context, school libregraph.Educ
 
 	// Here we should verify that the school number is not already used
 
-	attributeTypeAndValue := ldap.AttributeTypeAndValue{
-		Type:  i.educationConfig.schoolAttributeMap.displayName,
-		Value: school.GetDisplayName(),
-	}
-
-	dn := fmt.Sprintf("%s,%s",
-		attributeTypeAndValue.String(),
+	dn := fmt.Sprintf("%s=%s,%s",
+		i.educationConfig.schoolAttributeMap.displayName,
+		oldap.EscapeDNAttributeValue(school.GetDisplayName()),
 		i.educationConfig.schoolBaseDN,
 	)
 	ar := ldap.NewAddRequest(dn, nil)
@@ -174,12 +171,13 @@ func (i *LDAP) UpdateEducationSchoolOperation(
 // updateDisplayName updates the school OU in the identity backend
 func (i *LDAP) updateDisplayName(ctx context.Context, dn string, providedDisplayName string) error {
 	logger := i.logger.SubloggerWithRequestID(ctx)
-	attributeTypeAndValue := ldap.AttributeTypeAndValue{
-		Type:  i.educationConfig.schoolAttributeMap.displayName,
-		Value: providedDisplayName,
-	}
+	newDisplayName := fmt.Sprintf(
+		"%s=%s",
+		i.educationConfig.schoolAttributeMap.displayName,
+		providedDisplayName,
+	)
 
-	mrdn := ldap.NewModifyDNRequest(dn, attributeTypeAndValue.String(), true, "")
+	mrdn := ldap.NewModifyDNRequest(dn, newDisplayName, true, "")
 	i.logger.Debug().Str("backend", "ldap").
 		Str("dn", mrdn.DN).
 		Str("newrdn", mrdn.NewRDN).
diff --git a/services/graph/pkg/identity/ldap_group.go b/services/graph/pkg/identity/ldap_group.go
index 778ae5b8970..786235cdc24 100644
--- a/services/graph/pkg/identity/ldap_group.go
+++ b/services/graph/pkg/identity/ldap_group.go
@@ -11,6 +11,7 @@ import (
 	"github.com/gofrs/uuid"
 	ldapdn "github.com/libregraph/idm/pkg/ldapdn"
 	libregraph "github.com/owncloud/libre-graph-api-go"
+	oldap "github.com/owncloud/ocis/v2/ocis-pkg/ldap"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/service/v0/errorcode"
 	"golang.org/x/exp/slices"
 )
@@ -312,11 +313,7 @@ func (i *LDAP) groupToAddRequest(group libregraph.Group) (*ldap.AddRequest, erro
 }
 
 func (i *LDAP) getGroupLDAPDN(group libregraph.Group) string {
-	attributeTypeAndValue := ldap.AttributeTypeAndValue{
-		Type:  "cn",
-		Value: group.GetDisplayName(),
-	}
-	return fmt.Sprintf("%s,%s", attributeTypeAndValue.String(), i.groupBaseDN)
+	return fmt.Sprintf("cn=%s,%s", oldap.EscapeDNAttributeValue(group.GetDisplayName()), i.groupBaseDN)
 }
 
 func (i *LDAP) groupToLDAPAttrValues(group libregraph.Group) (map[string][]string, error) {
diff --git a/services/policies/Makefile b/services/policies/Makefile
deleted file mode 100644
index 2af58976147..00000000000
--- a/services/policies/Makefile
+++ /dev/null
@@ -1,37 +0,0 @@
-SHELL := bash
-NAME := policies
-
-include ../../.make/recursion.mk
-
-############ tooling ############
-ifneq (, $(shell command -v go 2> /dev/null)) # suppress `command not found warnings` for non go targets in CI
-include ../../.bingo/Variables.mk
-endif
-
-############ go tooling ############
-include ../../.make/go.mk
-
-############ release ############
-include ../../.make/release.mk
-
-############ docs generate ############
-include ../../.make/docs.mk
-
-.PHONY: docs-generate
-docs-generate: config-docs-generate
-
-############ generate ############
-include ../../.make/generate.mk
-
-.PHONY: ci-go-generate
-ci-go-generate: # CI runs ci-node-generate automatically before this target
-
-.PHONY: ci-node-generate
-ci-node-generate:
-
-############ licenses ############
-.PHONY: ci-node-check-licenses
-ci-node-check-licenses:
-
-.PHONY: ci-node-save-licenses
-ci-node-save-licenses:
diff --git a/services/policies/README.md b/services/policies/README.md
deleted file mode 100644
index 82a67e18ba7..00000000000
--- a/services/policies/README.md
+++ /dev/null
@@ -1,73 +0,0 @@
-# Policies Service
-
-The policies service provides a new grpc api which can be used to return whether a requested operation is allowed or not. To do so, Open Policy Agent (OPA) is used to determine the set of rules of what is permitted and what is not.
-
-Policies are written in the [rego query language](https://www.openpolicyagent.org/docs/latest/policy-language/). The location of the rego files can be configured via yaml, a configuration via environment variables is not possible.
-
-The Policies Service consists of the following modules:
-
-*   Proxy Authorization (middleware)
-*   Event Authorization (async post-processing)
-*   GRPC API (can be used from other services)
-
-To configure the Policies Service, three environment variables need to be defined:
-
-*   `POLICIES_ENGINE_TIMEOUT`
-*   `POLICIES_POSTPROCESSING_QUERY`
-*   `PROXY_POLICIES_QUERY`
-
-Note that each query setting defines the [Complete Rules](https://www.openpolicyagent.org/docs/latest/#complete-rules) variable defined in the rego rule set the corresponding step uses for the evaluation. If the variable is mistyped or not found, the evaluation defaults to deny. Individual query definitions can be defined for each module.
-
-To activate a the policies service for a module, it must be started with a yaml configuration that points to one or more rego files. Note that if the service is scaled horizontally, each instance should have access to the same rego files to avoid unpredictable results. If a file path has been configured but the file it is not present or accessible, the evaluation defaults to deny.
-
-When using async post-processing which is done via the postprocessing service, the value `policies` must be added to the `POSTPROCESSING_STEPS` configuration in postprocessing service in the order where the evaluation should take place.
-
-## Modules
-
-### GRPC Service
-
-This service can be used from any other internal service. It can also be used for example by third parties to find out if an action is allowed or not. This layer is already used by the proxy middleware.
-
-### Event Service
-
-This layer is event-based and part of the postprocessing service. Since processing at this point is asynchronous, the operations can also take longer and be more expensive, like evaluating the bytes of a file.
-
-### Proxy Middleware
-
-The [ocis proxy](../proxy) already includes such a middleware which uses the [GRPC service](#grpc-service) to evaluate the policies by using a configurable query. Since the Proxy is in heavy use and every request is processed here, only simple and quick decisions should be evaluated. More complex queries such as file evaluation are strongly discouraged.
-
-## Example Policies
-
-The policies service contains a set of pre-configured example policies. Those policies can be found in the [examples directory](../../deployments/examples/service_policies/policies). The contained policies disallows ocis to create certain filetypes, both for the proxy middleware and the events service.
-
-To use the example policies, it's required to configure ocis to use these files which can be done by adding:
-
-```yaml
-policies:
-  engine:
-    policies:
-      - YOUR_PATH/examples/policies/proxy.rego
-      - YOUR_PATH/examples/policies/postprocessing.rego
-      - YOUR_PATH/examples/policies/utils.rego
-```
-Once the policies are configured correctly, the _QUERY configuration needs to be defined for the proxy middleware and for the events service.
-
-### Proxy
-
-```yaml
-proxy:
-  policies_middleware:
-    query: data.proxy.granted
-```
-
-The same can be achieved by setting the `PROXY_POLICIES_QUERY=data.proxy.granted` environment variable.
-
-### ASYNC Postprocessing
-
-```yaml
-policies:
-  postprocessing:
-    query: data.postprocessing.granted
-```
-
-The same can be achieved by setting the `POLICIES_POSTPROCESSING_QUERY=data.postprocessing.granted` environment variable. As soon as that query is configured correctly, postprocessing must be informed to use the policies step by setting the environment variable `POSTPROCESSING_STEPS=policies`. Note that additional steps can be configured and their appearance defines the order of processing. For details see the postprocessing service documentation.
diff --git a/services/policies/cmd/policies/main.go b/services/policies/cmd/policies/main.go
deleted file mode 100644
index db0896e4072..00000000000
--- a/services/policies/cmd/policies/main.go
+++ /dev/null
@@ -1,14 +0,0 @@
-package main
-
-import (
-	"os"
-
-	"github.com/owncloud/ocis/v2/services/policies/pkg/command"
-	"github.com/owncloud/ocis/v2/services/policies/pkg/config/defaults"
-)
-
-func main() {
-	if err := command.Execute(defaults.DefaultConfig()); err != nil {
-		os.Exit(1)
-	}
-}
diff --git a/services/policies/pkg/command/health.go b/services/policies/pkg/command/health.go
deleted file mode 100644
index ec03f6a0ce3..00000000000
--- a/services/policies/pkg/command/health.go
+++ /dev/null
@@ -1,60 +0,0 @@
-package command
-
-import (
-	"fmt"
-	"github.com/owncloud/ocis/v2/ocis-pkg/log"
-	"net/http"
-
-	"github.com/owncloud/ocis/v2/ocis-pkg/config/configlog"
-	"github.com/owncloud/ocis/v2/services/policies/pkg/config"
-	"github.com/owncloud/ocis/v2/services/policies/pkg/config/parser"
-	"github.com/urfave/cli/v2"
-)
-
-// Health is the entrypoint for the health command.
-func Health(cfg *config.Config) *cli.Command {
-	return &cli.Command{
-		Name:     "health",
-		Usage:    "check health status",
-		Category: "info",
-		Before: func(c *cli.Context) error {
-			return configlog.ReturnError(parser.ParseConfig(cfg))
-		},
-		Action: func(c *cli.Context) error {
-			logger := log.NewLogger(
-				log.Name(cfg.Service.Name),
-				log.Level(cfg.Log.Level),
-				log.Pretty(cfg.Log.Pretty),
-				log.Color(cfg.Log.Color),
-				log.File(cfg.Log.File),
-			)
-
-			resp, err := http.Get(
-				fmt.Sprintf(
-					"http://%s/healthz",
-					cfg.Debug.Addr,
-				),
-			)
-
-			if err != nil {
-				logger.Fatal().
-					Err(err).
-					Msg("Failed to request health check")
-			}
-
-			defer resp.Body.Close()
-
-			if resp.StatusCode != http.StatusOK {
-				logger.Fatal().
-					Int("code", resp.StatusCode).
-					Msg("Health seems to be in bad state")
-			}
-
-			logger.Debug().
-				Int("code", resp.StatusCode).
-				Msg("Health got a good state")
-
-			return nil
-		},
-	}
-}
diff --git a/services/policies/pkg/command/root.go b/services/policies/pkg/command/root.go
deleted file mode 100644
index b57f8aa62e0..00000000000
--- a/services/policies/pkg/command/root.go
+++ /dev/null
@@ -1,54 +0,0 @@
-package command
-
-import (
-	"context"
-	"os"
-
-	"github.com/owncloud/ocis/v2/ocis-pkg/clihelper"
-	ociscfg "github.com/owncloud/ocis/v2/ocis-pkg/config"
-	"github.com/owncloud/ocis/v2/services/policies/pkg/config"
-	"github.com/thejerf/suture/v4"
-	"github.com/urfave/cli/v2"
-)
-
-// GetCommands provides all commands for this service
-func GetCommands(cfg *config.Config) cli.Commands {
-	return []*cli.Command{
-		Server(cfg),
-		Health(cfg),
-		Version(cfg),
-	}
-}
-
-// Execute is the entry point for the policies command.
-func Execute(cfg *config.Config) error {
-	app := clihelper.DefaultApp(&cli.App{
-		Name:     "policies",
-		Usage:    "Serve ownCloud policies for oCIS",
-		Commands: GetCommands(cfg),
-	})
-
-	return app.Run(os.Args)
-}
-
-// SutureService allows for the web command to be embedded and supervised by a suture supervisor tree.
-type SutureService struct {
-	cfg *config.Config
-}
-
-// NewSutureService creates a new web.SutureService
-func NewSutureService(cfg *ociscfg.Config) suture.Service {
-	cfg.Policies.Commons = cfg.Commons
-	return SutureService{
-		cfg: cfg.Policies,
-	}
-}
-
-func (s SutureService) Serve(ctx context.Context) error {
-	s.cfg.Context = ctx
-	if err := Execute(s.cfg); err != nil {
-		return err
-	}
-
-	return nil
-}
diff --git a/services/policies/pkg/command/server.go b/services/policies/pkg/command/server.go
deleted file mode 100644
index 9c3cb3eb94e..00000000000
--- a/services/policies/pkg/command/server.go
+++ /dev/null
@@ -1,193 +0,0 @@
-package command
-
-import (
-	"context"
-	"crypto/tls"
-	"crypto/x509"
-	"fmt"
-	"io"
-	"net/http"
-	"os"
-
-	"github.com/cs3org/reva/v2/pkg/events/stream"
-	"github.com/go-micro/plugins/v4/events/natsjs"
-	"github.com/oklog/run"
-	"github.com/owncloud/ocis/v2/ocis-pkg/config/configlog"
-	ociscrypto "github.com/owncloud/ocis/v2/ocis-pkg/crypto"
-	"github.com/owncloud/ocis/v2/ocis-pkg/log"
-	"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
-	"github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
-	"github.com/owncloud/ocis/v2/ocis-pkg/version"
-	svcProtogen "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/policies/v0"
-	"github.com/owncloud/ocis/v2/services/policies/pkg/config"
-	"github.com/owncloud/ocis/v2/services/policies/pkg/config/parser"
-	"github.com/owncloud/ocis/v2/services/policies/pkg/engine"
-	svcEvent "github.com/owncloud/ocis/v2/services/policies/pkg/service/event"
-	svcGRPC "github.com/owncloud/ocis/v2/services/policies/pkg/service/grpc"
-	"github.com/urfave/cli/v2"
-)
-
-// Server is the entrypoint for the server command.
-func Server(cfg *config.Config) *cli.Command {
-	return &cli.Command{
-		Name:     "server",
-		Usage:    fmt.Sprintf("start the %s service without runtime (unsupervised mode)", "authz"),
-		Category: "server",
-		Before: func(c *cli.Context) error {
-			return configlog.ReturnFatal(parser.ParseConfig(cfg))
-		},
-		Action: func(c *cli.Context) error {
-			var (
-				gr          = run.Group{}
-				ctx, cancel = func() (context.Context, context.CancelFunc) {
-					if cfg.Context == nil {
-						return context.WithCancel(context.Background())
-					}
-					return context.WithCancel(cfg.Context)
-				}()
-				logger = log.NewLogger(
-					log.Name(cfg.Service.Name),
-					log.Level(cfg.Log.Level),
-					log.Pretty(cfg.Log.Pretty),
-					log.Color(cfg.Log.Color),
-					log.File(cfg.Log.File),
-				)
-			)
-			defer cancel()
-
-			e, err := engine.NewOPA(cfg.Engine.Timeout, cfg.Engine)
-			if err != nil {
-				return err
-			}
-
-			{
-				err = grpc.Configure(grpc.GetClientOptions(cfg.GRPCClientTLS)...)
-				if err != nil {
-					return err
-				}
-
-				svc, err := grpc.NewService(
-					grpc.Logger(logger),
-					grpc.TLSEnabled(cfg.GRPC.TLS.Enabled),
-					grpc.TLSCert(
-						cfg.GRPC.TLS.Cert,
-						cfg.GRPC.TLS.Key,
-					),
-					grpc.Name(cfg.Service.Name),
-					grpc.Context(ctx),
-					grpc.Address(cfg.GRPC.Addr),
-					grpc.Namespace(cfg.GRPC.Namespace),
-					grpc.Version(version.GetString()),
-				)
-				if err != nil {
-					return err
-				}
-
-				grpcSvc, err := svcGRPC.New(e)
-				if err != nil {
-					return err
-				}
-
-				if err := svcProtogen.RegisterPoliciesProviderHandler(
-					svc.Server(),
-					grpcSvc,
-				); err != nil {
-					return err
-				}
-
-				gr.Add(svc.Run, func(_ error) {
-					cancel()
-				})
-			}
-
-			{
-				var tlsConf *tls.Config
-
-				if cfg.Events.EnableTLS {
-					var rootCAPool *x509.CertPool
-					if cfg.Events.TLSRootCACertificate != "" {
-						rootCrtFile, err := os.Open(cfg.Events.TLSRootCACertificate)
-						if err != nil {
-							return err
-						}
-
-						rootCAPool, err = ociscrypto.NewCertPoolFromPEM(rootCrtFile)
-						if err != nil {
-							return err
-						}
-						cfg.Events.TLSInsecure = false
-					}
-
-					tlsConf = &tls.Config{
-						RootCAs: rootCAPool,
-					}
-				}
-
-				bus, err := stream.Nats(
-					natsjs.TLSConfig(tlsConf),
-					natsjs.Address(cfg.Events.Endpoint),
-					natsjs.ClusterID(cfg.Events.Cluster),
-				)
-				if err != nil {
-					return err
-				}
-
-				eventSvc, err := svcEvent.New(bus, logger, e, cfg.Postprocessing.Query)
-				if err != nil {
-					return err
-				}
-
-				gr.Add(eventSvc.Run, func(_ error) {
-					cancel()
-				})
-			}
-
-			{
-				server := debug.NewService(
-					debug.Logger(logger),
-					debug.Name(cfg.Service.Name),
-					debug.Version(version.GetString()),
-					debug.Address(cfg.Debug.Addr),
-					debug.Token(cfg.Debug.Token),
-					debug.Pprof(cfg.Debug.Pprof),
-					debug.Zpages(cfg.Debug.Zpages),
-					debug.Health(
-						func(w http.ResponseWriter, r *http.Request) {
-							w.Header().Set("Content-Type", "text/plain")
-							w.WriteHeader(http.StatusOK)
-
-							// TODO: check if services are up and running
-
-							_, err := io.WriteString(w, http.StatusText(http.StatusOK))
-							// io.WriteString should not fail but if it does we want to know.
-							if err != nil {
-								panic(err)
-							}
-						},
-					),
-					debug.Ready(
-						func(w http.ResponseWriter, r *http.Request) {
-							w.Header().Set("Content-Type", "text/plain")
-							w.WriteHeader(http.StatusOK)
-
-							// TODO: check if services are up and running
-
-							_, err := io.WriteString(w, http.StatusText(http.StatusOK))
-							// io.WriteString should not fail but if it does we want to know.
-							if err != nil {
-								panic(err)
-							}
-						},
-					),
-				)
-
-				gr.Add(server.ListenAndServe, func(_ error) {
-					_ = server.Shutdown(ctx)
-					cancel()
-				})
-			}
-
-			return gr.Run()
-		},
-	}
-}
diff --git a/services/policies/pkg/command/version.go b/services/policies/pkg/command/version.go
deleted file mode 100644
index 48cfcfa242b..00000000000
--- a/services/policies/pkg/command/version.go
+++ /dev/null
@@ -1,50 +0,0 @@
-package command
-
-import (
-	"fmt"
-	"os"
-
-	"github.com/owncloud/ocis/v2/ocis-pkg/registry"
-	"github.com/owncloud/ocis/v2/ocis-pkg/version"
-
-	tw "github.com/olekukonko/tablewriter"
-	"github.com/owncloud/ocis/v2/services/policies/pkg/config"
-	"github.com/urfave/cli/v2"
-)
-
-// Version prints the service versions of all running instances.
-func Version(cfg *config.Config) *cli.Command {
-	return &cli.Command{
-		Name:     "version",
-		Usage:    "print the version of this binary and the running service instances",
-		Category: "info",
-		Action: func(c *cli.Context) error {
-			fmt.Println("Version: " + version.GetString())
-			fmt.Printf("Compiled: %s\n", version.Compiled())
-			fmt.Println("")
-
-			reg := registry.GetRegistry()
-			services, err := reg.GetService(cfg.GRPC.Namespace + "." + cfg.Service.Name)
-			if err != nil {
-				fmt.Println(fmt.Errorf("could not get %s services from the registry: %v", cfg.Service.Name, err))
-				return err
-			}
-
-			if len(services) == 0 {
-				fmt.Println("No running " + cfg.Service.Name + " service found.")
-				return nil
-			}
-
-			table := tw.NewWriter(os.Stdout)
-			table.SetHeader([]string{"Version", "Address", "Id"})
-			table.SetAutoFormatHeaders(false)
-			for _, s := range services {
-				for _, n := range s.Nodes {
-					table.Append([]string{s.Version, n.Address, n.Id})
-				}
-			}
-			table.Render()
-			return nil
-		},
-	}
-}
diff --git a/services/policies/pkg/config/config.go b/services/policies/pkg/config/config.go
deleted file mode 100644
index 9e8f15a6970..00000000000
--- a/services/policies/pkg/config/config.go
+++ /dev/null
@@ -1,77 +0,0 @@
-package config
-
-import (
-	"context"
-	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
-	"time"
-)
-
-// Config combines all available configuration parts.
-type Config struct {
-	Commons           *shared.Commons       `yaml:"-"` // don't use this directly as configuration for a service
-	GRPC              GRPC                  `yaml:"grpc"`
-	Service           Service               `yaml:"-"`
-	Debug             Debug                 `yaml:"debug"`
-	TokenManager      *TokenManager         `yaml:"token_manager"`
-	Events            Events                `yaml:"events"`
-	Reva              *shared.Reva          `yaml:"reva"`
-	GRPCClientTLS     *shared.GRPCClientTLS `yaml:"grpc_client_tls"`
-	MachineAuthAPIKey string                `yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;POLICIES_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used to validate internal requests necessary for the access to resources from other services."`
-	Context           context.Context       `yaml:"-"`
-	Log               *Log                  `yaml:"log"`
-	Engine            Engine                `yaml:"engine"`
-	Postprocessing    Postprocessing        `yaml:"postprocessing"`
-}
-
-// Service defines the available service configuration.
-type Service struct {
-	Name string `yaml:"-"`
-}
-
-// GRPC defines the available grpc configuration.
-type GRPC struct {
-	Addr      string                 `ocisConfig:"addr" env:"POLICIES_GRPC_ADDR" desc:"The bind address of the GRPC service."`
-	Namespace string                 `ocisConfig:"-" yaml:"-"`
-	TLS       *shared.GRPCServiceTLS `yaml:"tls"`
-}
-
-// TokenManager is the config for using the reva token manager
-type TokenManager struct {
-	JWTSecret string `yaml:"jwt_secret" env:"OCIS_JWT_SECRET;POLICIES_JWT_SECRET" desc:"The secret to mint and validate jwt tokens."`
-}
-
-// Engine configures the policy engine.
-type Engine struct {
-	Timeout  time.Duration `yaml:"timeout" env:"POLICIES_ENGINE_TIMEOUT" desc:"Sets the timeout the rego expression evaluation can take. The timeout can be set as number followed by a unit identifier like ms, s, etc. Rules default to deny if the timeout was reached."`
-	Policies []string      `yaml:"policies"`
-}
-
-// Postprocessing defines the config options for the postprocessing policy handling.
-type Postprocessing struct {
-	Query string `yaml:"query" env:"POLICIES_POSTPROCESSING_QUERY" desc:"Defines the 'Complete Rules' variable defined in the rego rule set this step uses for its evaluation. Defaults to deny if the variable was not found."`
-}
-
-// Events combines the configuration options for the event bus.
-type Events struct {
-	Endpoint             string `yaml:"endpoint" env:"POLICIES_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."`
-	Cluster              string `yaml:"cluster" env:"POLICIES_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."`
-	TLSInsecure          bool   `yaml:"tls_insecure" env:"OCIS_INSECURE;POLICIES_EVENTS_TLS_INSECURE" desc:"Whether the server should skip the client certificate verification during the TLS handshake."`
-	TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"POLICIES_EVENTS_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided POLICIES_EVENTS_TLS_INSECURE will be seen as false."`
-	EnableTLS            bool   `yaml:"enable_tls" env:"OCIS_EVENTS_ENABLE_TLS;POLICIES_EVENTS_ENABLE_TLS" desc:"Enable TLS for the connection to the events broker. The events broker is the ocis service which receives and delivers events between the services."`
-}
-
-// Log defines the available log configuration.
-type Log struct {
-	Level  string `mapstructure:"level" env:"OCIS_LOG_LEVEL;POLICIES_LOG_LEVEL" desc:"The log level. Valid values are: \"panic\", \"fatal\", \"error\", \"warn\", \"info\", \"debug\", \"trace\"."`
-	Pretty bool   `mapstructure:"pretty" env:"OCIS_LOG_PRETTY;POLICIES_LOG_PRETTY" desc:"Activates pretty log output."`
-	Color  bool   `mapstructure:"color" env:"OCIS_LOG_COLOR;POLICIES_LOG_COLOR" desc:"Activates colorized log output."`
-	File   string `mapstructure:"file" env:"OCIS_LOG_FILE;POLICIES_LOG_FILE" desc:"The path to the log file. Activates logging to this file if set."`
-}
-
-// Debug defines the available debug configuration.
-type Debug struct {
-	Addr   string `yaml:"addr" env:"POLICIES_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
-	Token  string `yaml:"token" env:"POLICIES_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
-	Pprof  bool   `yaml:"pprof" env:"POLICIES_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
-	Zpages bool   `yaml:"zpages" env:"POLICIES_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
-}
diff --git a/services/policies/pkg/config/defaults/defaultconfig.go b/services/policies/pkg/config/defaults/defaultconfig.go
deleted file mode 100644
index 272809b628c..00000000000
--- a/services/policies/pkg/config/defaults/defaultconfig.go
+++ /dev/null
@@ -1,87 +0,0 @@
-package defaults
-
-import (
-	"time"
-
-	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
-	"github.com/owncloud/ocis/v2/ocis-pkg/structs"
-	"github.com/owncloud/ocis/v2/services/policies/pkg/config"
-)
-
-// FullDefaultConfig returns a fully initialized default configuration which is needed for doc generation.
-func FullDefaultConfig() *config.Config {
-	cfg := DefaultConfig()
-	EnsureDefaults(cfg)
-	Sanitize(cfg)
-	return cfg
-}
-
-// DefaultConfig returns the default config
-func DefaultConfig() *config.Config {
-	return &config.Config{
-		Service: config.Service{
-			Name: "policies",
-		},
-		Debug: config.Debug{
-			Addr:   "127.0.0.1:9129",
-			Token:  "",
-			Pprof:  false,
-			Zpages: false,
-		},
-		GRPC: config.GRPC{
-			Addr:      "127.0.0.1:9125",
-			Namespace: "com.owncloud.api",
-		},
-		Reva: shared.DefaultRevaConfig(),
-		Events: config.Events{
-			Endpoint:  "127.0.0.1:9233",
-			Cluster:   "ocis-cluster",
-			EnableTLS: false,
-		},
-		Engine: config.Engine{
-			Timeout: 10 * time.Second,
-		},
-	}
-}
-
-func EnsureDefaults(cfg *config.Config) {
-	if cfg.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
-		cfg.TokenManager = &config.TokenManager{
-			JWTSecret: cfg.Commons.TokenManager.JWTSecret,
-		}
-	} else if cfg.TokenManager == nil {
-		cfg.TokenManager = &config.TokenManager{}
-	}
-	if cfg.MachineAuthAPIKey == "" && cfg.Commons != nil && cfg.Commons.MachineAuthAPIKey != "" {
-		cfg.MachineAuthAPIKey = cfg.Commons.MachineAuthAPIKey
-	}
-
-	if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil {
-		cfg.Reva = &shared.Reva{
-			Address: cfg.Commons.Reva.Address,
-			TLS:     cfg.Commons.Reva.TLS,
-		}
-	} else if cfg.Reva == nil {
-		cfg.Reva = &shared.Reva{}
-	}
-
-	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
-		cfg.Log = &config.Log{
-			Level:  cfg.Commons.Log.Level,
-			Pretty: cfg.Commons.Log.Pretty,
-			Color:  cfg.Commons.Log.Color,
-			File:   cfg.Commons.Log.File,
-		}
-	} else if cfg.Log == nil {
-		cfg.Log = &config.Log{}
-	}
-
-	if cfg.GRPCClientTLS == nil && cfg.Commons != nil {
-		cfg.GRPCClientTLS = structs.CopyOrZeroValue(cfg.Commons.GRPCClientTLS)
-	}
-	if cfg.GRPC.TLS == nil && cfg.Commons != nil {
-		cfg.GRPC.TLS = structs.CopyOrZeroValue(cfg.Commons.GRPCServiceTLS)
-	}
-}
-
-func Sanitize(_ *config.Config) {}
diff --git a/services/policies/pkg/config/parser/parse.go b/services/policies/pkg/config/parser/parse.go
deleted file mode 100644
index 873472671de..00000000000
--- a/services/policies/pkg/config/parser/parse.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package parser
-
-import (
-	"errors"
-
-	ociscfg "github.com/owncloud/ocis/v2/ocis-pkg/config"
-	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
-	"github.com/owncloud/ocis/v2/services/policies/pkg/config"
-	"github.com/owncloud/ocis/v2/services/policies/pkg/config/defaults"
-
-	"github.com/owncloud/ocis/v2/ocis-pkg/config/envdecode"
-)
-
-// ParseConfig loads configuration from known paths.
-func ParseConfig(cfg *config.Config) error {
-	_, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg)
-	if err != nil {
-		return err
-	}
-
-	defaults.EnsureDefaults(cfg)
-
-	// load all env variables relevant to the config in the current context.
-	if err := envdecode.Decode(cfg); err != nil {
-		// no environment variable set for this config is an expected "error"
-		if !errors.Is(err, envdecode.ErrNoTargetFieldsAreSet) {
-			return err
-		}
-	}
-
-	defaults.Sanitize(cfg)
-
-	return Validate(cfg)
-}
-
-func Validate(cfg *config.Config) error {
-	if cfg.TokenManager.JWTSecret == "" {
-		return shared.MissingJWTTokenError(cfg.Service.Name)
-	}
-
-	return nil
-}
diff --git a/services/policies/pkg/engine/engine.go b/services/policies/pkg/engine/engine.go
deleted file mode 100644
index 651f1cbff11..00000000000
--- a/services/policies/pkg/engine/engine.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package engine
-
-import (
-	"context"
-	"encoding/json"
-
-	user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
-	provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
-	"github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/policies/v0"
-	"google.golang.org/protobuf/encoding/protojson"
-)
-
-// Engine defines the granted handlers.
-type Engine interface {
-	Evaluate(ctx context.Context, query string, env Environment) (bool, error)
-}
-
-type (
-	// Stage defines the used auth stage
-	Stage string
-)
-
-var (
-	// StagePP defines the post-processing stage
-	StagePP Stage = "pp"
-
-	// StageHTTP defines the http stage
-	StageHTTP Stage = "http"
-)
-
-// Resource contains resource information and is used as part of the evaluated environment.
-type Resource struct {
-	ID   provider.ResourceId `json:"resource_id"`
-	Name string              `json:"name"`
-	URL  string              `json:"url"`
-	Size uint64              `json:"size"`
-}
-
-// Request contains request information and is used as part of the evaluated environment.
-type Request struct {
-	Method string `json:"method"`
-	Path   string `json:"path"`
-}
-
-// Environment contains every data that is needed to decide if the request should pass or not
-type Environment struct {
-	Stage    Stage     `json:"stage"`
-	User     user.User `json:"user"`
-	Request  Request   `json:"request"`
-	Resource Resource  `json:"resource"`
-}
-
-// NewEnvironmentFromPB converts a PBEnvironment to Environment.
-func NewEnvironmentFromPB(pEnv *v0.Environment) (Environment, error) {
-	env := Environment{}
-
-	rData, err := protojson.Marshal(pEnv)
-	if err != nil {
-		return env, err
-	}
-
-	if err := json.Unmarshal(rData, &env); err != nil {
-		return env, err
-	}
-
-	switch pEnv.Stage {
-	case v0.Stage_STAGE_HTTP:
-		env.Stage = StageHTTP
-	case v0.Stage_STAGE_PP:
-		env.Stage = StagePP
-	}
-
-	return env, nil
-}
diff --git a/services/policies/pkg/engine/opa.go b/services/policies/pkg/engine/opa.go
deleted file mode 100644
index e317fc030f7..00000000000
--- a/services/policies/pkg/engine/opa.go
+++ /dev/null
@@ -1,124 +0,0 @@
-package engine
-
-import (
-	"bytes"
-	"context"
-	"fmt"
-	"net/http"
-	"strings"
-	"time"
-
-	"github.com/cs3org/reva/v2/pkg/rhttp"
-	"github.com/gabriel-vasile/mimetype"
-	"github.com/open-policy-agent/opa/ast"
-	"github.com/open-policy-agent/opa/rego"
-	"github.com/open-policy-agent/opa/types"
-	"github.com/owncloud/ocis/v2/services/policies/pkg/config"
-)
-
-// OPA wraps open policy agent makes it possible to ask if an action is granted.
-type OPA struct {
-	policies []string
-	timeout  time.Duration
-}
-
-// NewOPA returns a ready to use opa engine.
-func NewOPA(timeout time.Duration, conf config.Engine) (OPA, error) {
-	return OPA{
-			policies: conf.Policies,
-			timeout:  timeout,
-		},
-		nil
-}
-
-// Evaluate evaluates the opa policies and returns the result.
-func (o OPA) Evaluate(ctx context.Context, qs string, env Environment) (bool, error) {
-	ctx, cancel := context.WithTimeout(ctx, o.timeout)
-	defer cancel()
-
-	q, err := rego.New(
-		rego.Query(qs),
-		rego.Load(o.policies, nil),
-		GetMimetype,
-		GetResource,
-	).PrepareForEval(ctx)
-	if err != nil {
-		return false, err
-	}
-
-	result, err := q.Eval(ctx, rego.EvalInput(env))
-	if err != nil {
-		return false, err
-	}
-
-	return result.Allowed(), nil
-}
-
-var GetResource = rego.Function1(
-	&rego.Function{
-		Name:             "ocis_get_resource",
-		Decl:             types.NewFunction(types.Args(types.S), types.A),
-		Memoize:          true,
-		Nondeterministic: true,
-	},
-	func(_ rego.BuiltinContext, a *ast.Term) (*ast.Term, error) {
-		var url string
-
-		if err := ast.As(a.Value, &url); err != nil {
-			return nil, err
-		}
-
-		req, err := http.NewRequest(http.MethodGet, url, nil)
-		if err != nil {
-			return nil, err
-		}
-
-		client := rhttp.GetHTTPClient(rhttp.Insecure(true))
-		res, err := client.Do(req)
-		if err != nil {
-			return nil, err
-		}
-		defer res.Body.Close()
-
-		if res.StatusCode != http.StatusOK {
-			return nil, fmt.Errorf("unexpected status code from Download %v", res.StatusCode)
-		}
-
-		buf := new(bytes.Buffer)
-		if _, err := buf.ReadFrom(res.Body); err != nil {
-			return nil, err
-		}
-
-		v, err := ast.InterfaceToValue(buf.Bytes())
-		if err != nil {
-			return nil, err
-		}
-
-		return ast.NewTerm(v), nil
-	},
-)
-
-var GetMimetype = rego.Function1(
-	&rego.Function{
-		Name:             "ocis_get_mimetype",
-		Decl:             types.NewFunction(types.Args(types.A), types.S),
-		Memoize:          true,
-		Nondeterministic: true,
-	},
-	func(_ rego.BuiltinContext, a *ast.Term) (*ast.Term, error) {
-		var body []byte
-
-		if err := ast.As(a.Value, &body); err != nil {
-			return nil, err
-		}
-
-		mimeInfo := mimetype.Detect(body).String()
-		detectedMimetype := strings.Split(mimeInfo, ";")[0]
-		v, err := ast.InterfaceToValue(detectedMimetype)
-		if err != nil {
-			return nil, err
-		}
-
-		return ast.NewTerm(v), nil
-	},
-)
diff --git a/services/policies/pkg/service/event/service.go b/services/policies/pkg/service/event/service.go
deleted file mode 100644
index 054a5397986..00000000000
--- a/services/policies/pkg/service/event/service.go
+++ /dev/null
@@ -1,87 +0,0 @@
-package eventSVC
-
-import (
-	"context"
-	"github.com/cs3org/reva/v2/pkg/events"
-	"github.com/owncloud/ocis/v2/ocis-pkg/log"
-	"github.com/owncloud/ocis/v2/services/policies/pkg/engine"
-)
-
-// Service defines the service handlers.
-type Service struct {
-	query  string
-	log    log.Logger
-	stream events.Stream
-	engine engine.Engine
-}
-
-// New returns a service implementation for Service.
-func New(stream events.Stream, logger log.Logger, engine engine.Engine, query string) (Service, error) {
-	svc := Service{
-		log:    logger,
-		query:  query,
-		engine: engine,
-		stream: stream,
-	}
-
-	return svc, nil
-}
-
-// Run to fulfil Runner interface
-func (s Service) Run() error {
-	ch, err := events.Consume(s.stream, "policies", events.StartPostprocessingStep{})
-	if err != nil {
-		return err
-	}
-
-	for e := range ch {
-		switch ev := e.Event.(type) {
-		case events.StartPostprocessingStep:
-			if ev.StepToStart != "policies" {
-				continue
-			}
-
-			outcome := events.PPOutcomeContinue
-
-			if s.query != "" {
-				env := engine.Environment{
-					Stage: engine.StagePP,
-					Resource: engine.Resource{
-						Name: ev.Filename,
-						URL:  ev.URL,
-						Size: ev.Filesize,
-					},
-				}
-
-				if ev.ExecutingUser != nil {
-					env.User = *ev.ExecutingUser
-				}
-
-				if ev.ResourceID != nil {
-					env.Resource.ID = *ev.ResourceID
-				}
-
-				result, err := s.engine.Evaluate(context.TODO(), s.query, env)
-				if err != nil {
-					s.log.Error().Err(err).Msg("unable evaluate policy")
-				}
-
-				if !result {
-					outcome = events.PPOutcomeDelete
-				}
-			}
-
-			if err := events.Publish(s.stream, events.PostprocessingStepFinished{
-				Outcome:       outcome,
-				UploadID:      ev.UploadID,
-				ExecutingUser: ev.ExecutingUser,
-				Filename:      ev.Filename,
-				FinishedStep:  ev.StepToStart,
-			}); err != nil {
-				return err
-			}
-		}
-	}
-
-	return nil
-}
diff --git a/services/policies/pkg/service/grpc/service.go b/services/policies/pkg/service/grpc/service.go
deleted file mode 100644
index 5a53fe3d03a..00000000000
--- a/services/policies/pkg/service/grpc/service.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package grpcSVC
-
-import (
-	"context"
-
-	"github.com/owncloud/ocis/v2/protogen/gen/ocis/services/policies/v0"
-	"github.com/owncloud/ocis/v2/services/policies/pkg/engine"
-)
-
-// Service defines the service handlers.
-type Service struct {
-	engine engine.Engine
-}
-
-// New returns a service implementation for Service.
-func New(engine engine.Engine) (Service, error) {
-	svc := Service{
-		engine: engine,
-	}
-
-	return svc, nil
-}
-
-// Evaluate exposes the engine policy evaluation.
-func (s Service) Evaluate(ctx context.Context, request *v0.EvaluateRequest, response *v0.EvaluateResponse) error {
-	env, err := engine.NewEnvironmentFromPB(request.Environment)
-	if err != nil {
-		return err
-	}
-
-	result, err := s.engine.Evaluate(ctx, request.Query, env)
-	response.Result = result
-
-	return err
-}
diff --git a/services/postprocessing/pkg/config/config.go b/services/postprocessing/pkg/config/config.go
index b36eb58fcbb..b1fac6a2ea5 100644
--- a/services/postprocessing/pkg/config/config.go
+++ b/services/postprocessing/pkg/config/config.go
@@ -23,7 +23,7 @@ type Config struct {
 // Postprocessing defines the config options for the postprocessing service.
 type Postprocessing struct {
 	Events          Events        `yaml:"events"`
-	Steps           []string      `yaml:"steps" env:"POSTPROCESSING_STEPS" desc:"A comma separated list of postprocessing steps, processed in order of their appearance. Currently supported values by the system are: 'virusscan', 'policies' and 'delay'. Custom steps are allowed. See the documentation for instructions."`
+	Steps           []string      `yaml:"steps" env:"POSTPROCESSING_STEPS" desc:"A comma separated list of postprocessing steps, processed in order of their appearance. Currently supported values by the system are: 'virusscan' and 'delay'. Custom steps are allowed. See the documentation for instructions."`
 	Virusscan       bool          `yaml:"virusscan" env:"POSTPROCESSING_VIRUSSCAN" desc:"After uploading a file but before making it available for download, virus scanning the file can be enabled. Needs as prerequisite the antivirus service to be enabled and configured." deprecationVersion:"master" removalVersion:"master" deprecationInfo:"POSTPROCESSING_VIRUSSCAN is not longer necessary and is replaced by POSTPROCESSING_STEPS which also holds information about the order of steps" deprecationReplacement:"POSTPROCESSING_STEPS"`
 	Delayprocessing time.Duration `yaml:"delayprocessing" env:"POSTPROCESSING_DELAY" desc:"After uploading a file but before making it available for download, a delay step can be added. Intended for developing purposes only. The duration can be set as number followed by a unit identifier like s, m or h. If a duration is set but the keyword 'delay' is not explicitely added to 'POSTPROCESSING_STEPS', the delay step will be processed as last step. In such a case, a log entry will be written on service startup to remind the admin about that situation."`
 }
diff --git a/services/postprocessing/pkg/service/service.go b/services/postprocessing/pkg/service/service.go
index f8a8af0f069..0c286508b96 100644
--- a/services/postprocessing/pkg/service/service.go
+++ b/services/postprocessing/pkg/service/service.go
@@ -23,7 +23,6 @@ func NewPostprocessingService(stream events.Stream, logger log.Logger, c config.
 		events.StartPostprocessingStep{},
 		events.VirusscanFinished{},
 		events.UploadReady{},
-		events.PostprocessingStepFinished{},
 	)
 	if err != nil {
 		return nil, err
diff --git a/services/proxy/pkg/command/server.go b/services/proxy/pkg/command/server.go
index 05a5b718ed8..8c265a5a394 100644
--- a/services/proxy/pkg/command/server.go
+++ b/services/proxy/pkg/command/server.go
@@ -199,6 +199,7 @@ func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config)
 		Logger:            logger,
 		RevaGatewayClient: revaClient,
 	})
+
 	authenticators = append(authenticators, middleware.SignedURLAuthenticator{
 		Logger:             logger,
 		PreSignedURLConfig: cfg.PreSignedURL,
@@ -218,7 +219,9 @@ func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config)
 			cfg.OIDC.RewriteWellKnown,
 			oidcHTTPClient,
 		),
+
 		router.Middleware(cfg.PolicySelector, cfg.Policies, logger),
+
 		middleware.Authentication(
 			authenticators,
 			middleware.CredentialsByUserAgent(cfg.AuthMiddleware.CredentialsByUserAgent),
@@ -234,12 +237,13 @@ func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config)
 			middleware.UserCS3Claim(cfg.UserCS3Claim),
 			middleware.AutoprovisionAccounts(cfg.AutoprovisionAccounts),
 		),
+
 		middleware.SelectorCookie(
 			middleware.Logger(logger),
 			middleware.UserProvider(userProvider),
 			middleware.PolicySelectorConfig(*cfg.PolicySelector),
 		),
-		middleware.Policies(logger, cfg.PoliciesMiddleware.Query),
+
 		// finally, trigger home creation when a user logs in
 		middleware.CreateHome(
 			middleware.Logger(logger),
diff --git a/services/proxy/pkg/config/config.go b/services/proxy/pkg/config/config.go
index 554caebcc2b..d7ac632dd0a 100644
--- a/services/proxy/pkg/config/config.go
+++ b/services/proxy/pkg/config/config.go
@@ -21,22 +21,21 @@ type Config struct {
 	Reva          *shared.Reva          `yaml:"reva"`
 	GRPCClientTLS *shared.GRPCClientTLS `yaml:"grpc_client_tls"`
 
-	RoleQuotas            map[string]uint64  `yaml:"role_quotas"`
-	Policies              []Policy           `yaml:"policies"`
-	OIDC                  OIDC               `yaml:"oidc"`
-	TokenManager          *TokenManager      `mask:"struct" yaml:"token_manager"`
-	PolicySelector        *PolicySelector    `yaml:"policy_selector"`
-	PreSignedURL          PreSignedURL       `yaml:"pre_signed_url"`
-	AccountBackend        string             `yaml:"account_backend" env:"PROXY_ACCOUNT_BACKEND_TYPE" desc:"Account backend the PROXY service should use. Currently only 'cs3' is possible here."`
-	UserOIDCClaim         string             `yaml:"user_oidc_claim" env:"PROXY_USER_OIDC_CLAIM" desc:"The name of an OpenID Connect claim that is used for resolving users with the account backend. The value of the claim must hold a per user unique, stable and non re-assignable identifier. The availability of claims depends on your Identity Provider. There are common claims available for most Identity providers like 'email' or 'preferred_user' but you can also add your own claim."`
-	UserCS3Claim          string             `yaml:"user_cs3_claim" env:"PROXY_USER_CS3_CLAIM" desc:"The name of a CS3 user attribute (claim) that should be mapped to the 'user_oidc_claim'. Supported values are 'username', 'mail' and 'userid'."`
-	MachineAuthAPIKey     string             `mask:"password" yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;PROXY_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used to validate internal requests necessary to access resources from other services."`
-	AutoprovisionAccounts bool               `yaml:"auto_provision_accounts" env:"PROXY_AUTOPROVISION_ACCOUNTS" desc:"Set this to 'true' to automatically provision users that do not yet exist in the users service on-demand upon first sign-in. To use this a write-enabled libregraph user backend needs to be setup an running."`
-	EnableBasicAuth       bool               `yaml:"enable_basic_auth" env:"PROXY_ENABLE_BASIC_AUTH" desc:"Set this to true to enable 'basic authentication' (username/password)."`
-	InsecureBackends      bool               `yaml:"insecure_backends" env:"PROXY_INSECURE_BACKENDS" desc:"Disable TLS certificate validation for all HTTP backend connections."`
-	BackendHTTPSCACert    string             `yaml:"backend_https_cacert" env:"PROXY_HTTPS_CACERT" desc:"Path/File for the root CA certificate used to validate the server’s TLS certificate for https enabled backend services."`
-	AuthMiddleware        AuthMiddleware     `yaml:"auth_middleware"`
-	PoliciesMiddleware    PoliciesMiddleware `yaml:"policies_middleware"`
+	RoleQuotas            map[string]uint64 `yaml:"role_quotas"`
+	Policies              []Policy          `yaml:"policies"`
+	OIDC                  OIDC              `yaml:"oidc"`
+	TokenManager          *TokenManager     `mask:"struct" yaml:"token_manager"`
+	PolicySelector        *PolicySelector   `yaml:"policy_selector"`
+	PreSignedURL          PreSignedURL      `yaml:"pre_signed_url"`
+	AccountBackend        string            `yaml:"account_backend" env:"PROXY_ACCOUNT_BACKEND_TYPE" desc:"Account backend the PROXY service should use. Currently only 'cs3' is possible here."`
+	UserOIDCClaim         string            `yaml:"user_oidc_claim" env:"PROXY_USER_OIDC_CLAIM" desc:"The name of an OpenID Connect claim that is used for resolving users with the account backend. The value of the claim must hold a per user unique, stable and non re-assignable identifier. The availability of claims depends on your Identity Provider. There are common claims available for most Identity providers like 'email' or 'preferred_user' but you can also add your own claim."`
+	UserCS3Claim          string            `yaml:"user_cs3_claim" env:"PROXY_USER_CS3_CLAIM" desc:"The name of a CS3 user attribute (claim) that should be mapped to the 'user_oidc_claim'. Supported values are 'username', 'mail' and 'userid'."`
+	MachineAuthAPIKey     string            `mask:"password" yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;PROXY_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used to validate internal requests necessary to access resources from other services."`
+	AutoprovisionAccounts bool              `yaml:"auto_provision_accounts" env:"PROXY_AUTOPROVISION_ACCOUNTS" desc:"Set this to 'true' to automatically provision users that do not yet exist in the users service on-demand upon first sign-in. To use this a write-enabled libregraph user backend needs to be setup an running."`
+	EnableBasicAuth       bool              `yaml:"enable_basic_auth" env:"PROXY_ENABLE_BASIC_AUTH" desc:"Set this to true to enable 'basic authentication' (username/password)."`
+	InsecureBackends      bool              `yaml:"insecure_backends" env:"PROXY_INSECURE_BACKENDS" desc:"Disable TLS certificate validation for all HTTP backend connections."`
+	BackendHTTPSCACert    string            `yaml:"backend_https_cacert" env:"PROXY_HTTPS_CACERT" desc:"Path/File for the root CA certificate used to validate the server’s TLS certificate for https enabled backend services."`
+	AuthMiddleware        AuthMiddleware    `yaml:"auth_middleware"`
 
 	Context context.Context `yaml:"-" json:"-"`
 }
@@ -85,11 +84,6 @@ type AuthMiddleware struct {
 	CredentialsByUserAgent map[string]string `yaml:"credentials_by_user_agent"`
 }
 
-// PoliciesMiddleware configures the proxy policies middleware.
-type PoliciesMiddleware struct {
-	Query string `yaml:"query" env:"PROXY_POLICIES_QUERY" desc:"Defines the 'Complete Rules' variable defined in the rego rule set this step uses for its evaluation. Rules default to deny if the variable was not found."`
-}
-
 const (
 	AccessTokenVerificationNone = "none"
 	AccessTokenVerificationJWT  = "jwt"
diff --git a/services/proxy/pkg/middleware/policies.go b/services/proxy/pkg/middleware/policies.go
deleted file mode 100644
index 99097cf60aa..00000000000
--- a/services/proxy/pkg/middleware/policies.go
+++ /dev/null
@@ -1,62 +0,0 @@
-package middleware
-
-import (
-	"net/http"
-
-	revactx "github.com/cs3org/reva/v2/pkg/ctx"
-	"github.com/owncloud/ocis/v2/ocis-pkg/log"
-	"github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
-	pMessage "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/policies/v0"
-	pService "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/policies/v0"
-)
-
-// Policies verifies if a request is granted or not.
-func Policies(logger log.Logger, qs string) func(next http.Handler) http.Handler {
-	pClient := pService.NewPoliciesProviderService("com.owncloud.api.policies", grpc.DefaultClient())
-
-	return func(next http.Handler) http.Handler {
-		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-			if qs == "" {
-				next.ServeHTTP(w, r)
-				return
-			}
-
-			req := &pService.EvaluateRequest{
-				Query: qs,
-				Environment: &pMessage.Environment{
-					Request: &pMessage.Request{
-						Method: r.Method,
-						Path:   r.URL.Path,
-					},
-					Stage: pMessage.Stage_STAGE_HTTP,
-				},
-			}
-
-			if user, ok := revactx.ContextGetUser(r.Context()); ok {
-				req.Environment.User = &pMessage.User{
-					Id: &pMessage.User_ID{
-						OpaqueId: user.GetId().GetOpaqueId(),
-					},
-					Username:    user.GetUsername(),
-					Mail:        user.GetMail(),
-					DisplayName: user.GetDisplayName(),
-					Groups:      user.GetGroups(),
-				}
-			}
-
-			rsp, err := pClient.Evaluate(r.Context(), req)
-			if err != nil {
-				logger.Err(err).Msg("error evaluating request")
-				w.WriteHeader(http.StatusInternalServerError)
-				return
-			}
-
-			if !rsp.Result {
-				w.WriteHeader(http.StatusForbidden)
-				return
-			}
-
-			next.ServeHTTP(w, r)
-		})
-	}
-}
diff --git a/services/settings/pkg/config/config.go b/services/settings/pkg/config/config.go
index 031cc7f5dca..f8b7b03b9d2 100644
--- a/services/settings/pkg/config/config.go
+++ b/services/settings/pkg/config/config.go
@@ -32,7 +32,7 @@ type Config struct {
 
 	TokenManager *TokenManager `yaml:"token_manager"`
 
-	SetupDefaultAssignments bool `yaml:"set_default_assignments" env:"SETTINGS_SETUP_DEFAULT_ASSIGNMENTS;ACCOUNTS_DEMO_USERS_AND_GROUPS" desc:"The default role assignments the demo users should be setup."`
+	SetupDefaultAssignments bool `yaml:"set_default_assignments" env:"SETTINGS_SETUP_DEFAULT_ASSIGNMENTS;IDM_CREATE_DEMO_USERS" desc:"The default role assignments the demo users should be setup."`
 
 	Context context.Context `yaml:"-"`
 }
diff --git a/services/settings/pkg/store/defaults/defaults.go b/services/settings/pkg/store/defaults/defaults.go
index 5d852a1c527..63a73dcd180 100644
--- a/services/settings/pkg/store/defaults/defaults.go
+++ b/services/settings/pkg/store/defaults/defaults.go
@@ -653,30 +653,40 @@ var languageSetting = settingsmsg.Setting_SingleChoiceValue{
 
 // DefaultRoleAssignments returns (as one might guess) the default role assignments
 func DefaultRoleAssignments(cfg *config.Config) []*settingsmsg.UserRoleAssignment {
-	return []*settingsmsg.UserRoleAssignment{
-		// default admin users
-		{
+	assignments := []*settingsmsg.UserRoleAssignment{}
+
+	if cfg.SetupDefaultAssignments {
+		assignments = []*settingsmsg.UserRoleAssignment{
+			// default users with role "user"
+			{
+				AccountUuid: "4c510ada-c86b-4815-8820-42cdf82c3d51",
+				RoleId:      BundleUUIDRoleUser,
+			}, {
+				AccountUuid: "f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c",
+				RoleId:      BundleUUIDRoleUser,
+			}, {
+				AccountUuid: "932b4540-8d16-481e-8ef4-588e4b6b151c",
+				RoleId:      BundleUUIDRoleUser,
+			},
+			{
+				// additional admin user
+				AccountUuid: "058bff95-6708-4fe5-91e4-9ea3d377588b", // demo user "moss"
+				RoleId:      BundleUUIDRoleAdmin,
+			}, {
+				// default users with role "spaceadmin"
+				AccountUuid: "534bb038-6f9d-4093-946f-133be61fa4e7",
+				RoleId:      BundleUUIDRoleSpaceAdmin,
+			},
+		}
+	}
+
+	if cfg.AdminUserID != "" {
+		// default admin user
+		assignments = append(assignments, &settingsmsg.UserRoleAssignment{
 			AccountUuid: cfg.AdminUserID,
 			RoleId:      BundleUUIDRoleAdmin,
-		},
-		// default users with role "user"
-		{
-			AccountUuid: "4c510ada-c86b-4815-8820-42cdf82c3d51",
-			RoleId:      BundleUUIDRoleUser,
-		}, {
-			AccountUuid: "f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c",
-			RoleId:      BundleUUIDRoleUser,
-		}, {
-			AccountUuid: "932b4540-8d16-481e-8ef4-588e4b6b151c",
-			RoleId:      BundleUUIDRoleUser,
-		},
-		// default users with role "spaceadmin"
-		{
-			AccountUuid: "058bff95-6708-4fe5-91e4-9ea3d377588b", // demo user "moss"
-			RoleId:      BundleUUIDRoleAdmin,
-		}, {
-			AccountUuid: "534bb038-6f9d-4093-946f-133be61fa4e7",
-			RoleId:      BundleUUIDRoleSpaceAdmin,
-		},
+		})
 	}
+
+	return assignments
 }
diff --git a/services/settings/pkg/store/metadata/store.go b/services/settings/pkg/store/metadata/store.go
index 38a2cb02b82..8081d40cec3 100644
--- a/services/settings/pkg/store/metadata/store.go
+++ b/services/settings/pkg/store/metadata/store.go
@@ -131,11 +131,21 @@ func (s *Store) initMetadataClient(mdc MetadataClient) error {
 			return err
 		}
 
+		assIDs, err := mdc.ReadDir(ctx, accountPath(accountUUID))
+		if err != nil {
+			return err
+		}
+		if len(assIDs) > 0 {
+			// There is already a role assignment for this ID, skip to the next
+			continue
+		}
+
 		ass := &settingsmsg.UserRoleAssignment{
 			Id:          uuid.Must(uuid.NewV4()).String(),
 			AccountUuid: accountUUID,
 			RoleId:      roleID,
 		}
+
 		b, err := json.Marshal(ass)
 		if err != nil {
 			return err
diff --git a/services/userlog/Makefile b/services/userlog/Makefile
index f5a0bb752da..12a1d0a7d60 100644
--- a/services/userlog/Makefile
+++ b/services/userlog/Makefile
@@ -1,10 +1,6 @@
 SHELL := bash
 NAME := userlog
 
-# Where to write the files generated by this makefile.
-OUTPUT_DIR = ./pkg/service/l10n
-TEMPLATE_FILE = ./pkg/service/l10n/locale/userlog.pot
-
 include ../../.make/recursion.mk
 
 ############ tooling ############
@@ -34,26 +30,6 @@ ci-go-generate: $(MOCKERY) # CI runs ci-node-generate automatically before this
 .PHONY: ci-node-generate
 ci-node-generate:
 
-############ translations ########
-.PHONY: l10n-pull
-l10n-pull:
-	cd $(OUTPUT_DIR) && tx pull -a --skip --minimum-perc=75
-
-.PHONY: l10n-push
-l10n-push:
-	cd $(OUTPUT_DIR) && tx push -s --skip
-
-.PHONY: l10n-read
-l10n-read: $(GO_XGETTEXT)
-	go-xgettext -o $(OUTPUT_DIR)/locale/userlog.pot --keyword=Template -s pkg/service/templates.go
-
-.PHONY: l10n-write
-l10n-write:
-
-.PHONY: l10n-clean
-l10n-clean:
-	rm -f $(TEMPLATE_FILE);
-
 ############ licenses ############
 .PHONY: ci-node-check-licenses
 ci-node-check-licenses:
diff --git a/services/userlog/README.md b/services/userlog/README.md
index a9c3476f3f1..352e76fa9c5 100644
--- a/services/userlog/README.md
+++ b/services/userlog/README.md
@@ -31,20 +31,3 @@ The `userlog` service provides an API to retrieve configured events. For now, th
 ## Deleting
 
 To delete events for an user, use a `DELETE` request to `ocs/v2.php/apps/notifications/api/v1/notifications` containing the IDs to delete.
-
-## Translations
-
-The `userlog` service has embedded translations sourced via transifex to provide a basic set of translated languages. These embedded translations are available for all deployment scenarios. In addition, the service supports custom translations, though it is currently not possible to just add custom translations to embedded ones. If custom translations are configured, the embedded ones are not used. To configure custom translations, the `USERLOG_TRANSLATION_PATH` environment variable needs to point to a base folder that will further contain the translation files. This path must be available from all instances of the userlog service, a shared storage is recommended. Translation files must be of type [.po](https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html#PO-Files) or [.mo](https://www.gnu.org/software/gettext/manual/html_node/Binaries.html). For each language, the filename needs to be `userlog.po` (or `userlog.mo`) and stored in a folder structure defining the language code. In general the path/name pattern for a translation file needs to be:
-
-```text
-{USERLOG_TRANSLATION_PATH}/{language-code}/LC_MESSAGES/userlog.po
-```
-
-The language-code pattern is composed as `language[_territory]` where  `language` is the base language and `_territory` is optional defining a country.
-
-As example, for the language `de_DE`, one needs to place the corresponding translation files to `{USERLOG_TRANSLATION_PATH}/de_DE/LC_MESSAGES/userlog.po`.
-
-### Translation Rules
-
-*   If a requested language-code is not available, the service tries to fallback to the base language if available. As example, if `de_DE` is not available, the service tries to fall back to translations in `de` folder.
-*   If the base language is also not available like when the language code is `de_DE` and neither `de_DE` nor the `de` folder is available, the service falls back to the systems default `en`, which is the source of the texts provided by the code.
diff --git a/services/userlog/pkg/config/config.go b/services/userlog/pkg/config/config.go
index c7d18c0056c..04e74cf3bae 100644
--- a/services/userlog/pkg/config/config.go
+++ b/services/userlog/pkg/config/config.go
@@ -22,7 +22,6 @@ type Config struct {
 
 	MachineAuthAPIKey string `yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;USERLOG_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used to validate internal requests necessary to access resources from other services."`
 	RevaGateway       string `yaml:"reva_gateway" env:"REVA_GATEWAY" desc:"CS3 gateway used to look up user metadata"`
-	TranslationPath   string `yaml:"translation_path" env:"USERLOG_TRANSLATION_PATH" desc:"(optional) Set this to a path with custom translations to overwrite the builtin translations. See the documentation for more details."`
 	Events            Events `yaml:"events"`
 	Store             Store  `yaml:"store"`
 
diff --git a/services/userlog/pkg/service/conversion.go b/services/userlog/pkg/service/conversion.go
index 15b6600ef07..a3463508944 100644
--- a/services/userlog/pkg/service/conversion.go
+++ b/services/userlog/pkg/service/conversion.go
@@ -2,32 +2,22 @@ package service
 
 import (
 	"bytes"
-	"context"
-	"embed"
 	"errors"
-	"strings"
 	"text/template"
 	"time"
 
-	gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
 	user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
 	collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
 	storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
 	"github.com/cs3org/reva/v2/pkg/events"
 	"github.com/cs3org/reva/v2/pkg/storagespace"
 	"github.com/cs3org/reva/v2/pkg/utils"
-	"github.com/leonelquinteros/gotext"
 	ehmsg "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/eventhistory/v0"
 )
 
-//go:embed l10n/locale
-var _translationFS embed.FS
-
 var (
 	_resourceTypeSpace = "storagespace"
 	_resourceTypeShare = "share"
-
-	_domain = "userlog"
 )
 
 // OC10Notification is the oc10 style representation of an event
@@ -46,41 +36,9 @@ type OC10Notification struct {
 	MessageDetails map[string]interface{} `json:"messageRichParameters"`
 }
 
-// Converter is responsible for converting eventhistory events to OC10Notifications
-type Converter struct {
-	locale            string
-	gwClient          gateway.GatewayAPIClient
-	machineAuthAPIKey string
-	serviceName       string
-	registeredEvents  map[string]events.Unmarshaller
-	translationPath   string
-
-	// cached within one request not to query other service too much
-	spaces    map[string]*storageprovider.StorageSpace
-	users     map[string]*user.User
-	resources map[string]*storageprovider.ResourceInfo
-	contexts  map[string]context.Context
-}
-
-// NewConverter returns a new Converter
-func NewConverter(loc string, gwc gateway.GatewayAPIClient, machineAuthAPIKey string, name string, translationPath string, registeredEvents map[string]events.Unmarshaller) *Converter {
-	return &Converter{
-		locale:            loc,
-		gwClient:          gwc,
-		machineAuthAPIKey: machineAuthAPIKey,
-		serviceName:       name,
-		registeredEvents:  registeredEvents,
-		translationPath:   translationPath,
-		spaces:            make(map[string]*storageprovider.StorageSpace),
-		users:             make(map[string]*user.User),
-		resources:         make(map[string]*storageprovider.ResourceInfo),
-		contexts:          make(map[string]context.Context),
-	}
-}
-
 // ConvertEvent converts an eventhistory event to an OC10Notification
-func (c *Converter) ConvertEvent(event *ehmsg.Event) (OC10Notification, error) {
-	etype, ok := c.registeredEvents[event.Type]
+func (ul *UserlogService) ConvertEvent(event *ehmsg.Event) (OC10Notification, error) {
+	etype, ok := ul.registeredEvents[event.Type]
 	if !ok {
 		// this should not happen
 		return OC10Notification{}, errors.New("eventtype not registered")
@@ -97,46 +55,50 @@ func (c *Converter) ConvertEvent(event *ehmsg.Event) (OC10Notification, error) {
 		return OC10Notification{}, errors.New("unknown event type")
 	// space related
 	case events.SpaceDisabled:
-		return c.spaceMessage(event.Id, SpaceDisabled, ev.Executant, ev.ID.GetOpaqueId(), ev.Timestamp)
+		return ul.spaceMessage(event.Id, SpaceDisabled, ev.Executant, ev.ID.GetOpaqueId(), ev.Timestamp)
 	case events.SpaceDeleted:
-		return c.spaceDeletedMessage(event.Id, ev.Executant, ev.ID.GetOpaqueId(), ev.SpaceName, ev.Timestamp)
+		return ul.spaceDeletedMessage(event.Id, ev.Executant, ev.ID.GetOpaqueId(), ev.SpaceName, ev.Timestamp)
 	case events.SpaceShared:
-		return c.spaceMessage(event.Id, SpaceShared, ev.Executant, ev.ID.GetOpaqueId(), ev.Timestamp)
+		return ul.spaceMessage(event.Id, SpaceShared, ev.Executant, ev.ID.GetOpaqueId(), ev.Timestamp)
 	case events.SpaceUnshared:
-		return c.spaceMessage(event.Id, SpaceUnshared, ev.Executant, ev.ID.GetOpaqueId(), ev.Timestamp)
+		return ul.spaceMessage(event.Id, SpaceUnshared, ev.Executant, ev.ID.GetOpaqueId(), ev.Timestamp)
 	case events.SpaceMembershipExpired:
-		return c.spaceMessage(event.Id, SpaceMembershipExpired, ev.SpaceOwner, ev.SpaceID.GetOpaqueId(), ev.ExpiredAt)
+		return ul.spaceMessage(event.Id, SpaceMembershipExpired, ev.SpaceOwner, ev.SpaceID.GetOpaqueId(), ev.ExpiredAt)
 
 	// share related
 	case events.ShareCreated:
-		return c.shareMessage(event.Id, ShareCreated, ev.Executant, ev.ItemID, ev.ShareID, utils.TSToTime(ev.CTime))
+		return ul.shareMessage(event.Id, ShareCreated, ev.Executant, ev.ItemID, ev.ShareID, utils.TSToTime(ev.CTime))
 	case events.ShareExpired:
-		return c.shareMessage(event.Id, ShareExpired, ev.ShareOwner, ev.ItemID, ev.ShareID, ev.ExpiredAt)
+		return ul.shareMessage(event.Id, ShareExpired, ev.ShareOwner, ev.ItemID, ev.ShareID, ev.ExpiredAt)
 	case events.ShareRemoved:
-		return c.shareMessage(event.Id, ShareRemoved, ev.Executant, ev.ItemID, ev.ShareID, ev.Timestamp)
+		return ul.shareMessage(event.Id, ShareRemoved, ev.Executant, ev.ItemID, ev.ShareID, ev.Timestamp)
 	}
 }
 
-func (c *Converter) spaceDeletedMessage(eventid string, executant *user.UserId, spaceid string, spacename string, ts time.Time) (OC10Notification, error) {
-	usr, err := c.getUser(context.Background(), executant)
+func (ul *UserlogService) spaceDeletedMessage(eventid string, executant *user.UserId, spaceid string, spacename string, ts time.Time) (OC10Notification, error) {
+	_, user, err := utils.Impersonate(executant, ul.gwClient, ul.cfg.MachineAuthAPIKey)
 	if err != nil {
 		return OC10Notification{}, err
 	}
 
-	subj, subjraw, msg, msgraw, err := composeMessage(SpaceDeleted, c.locale, c.translationPath, map[string]interface{}{
-		"username":  usr.GetDisplayName(),
+	subj, subjraw, msg, msgraw, err := ul.composeMessage(SpaceDeleted, map[string]string{
+		"username":  user.GetDisplayName(),
 		"spacename": spacename,
 	})
 	if err != nil {
 		return OC10Notification{}, err
 	}
 
-	space := &storageprovider.StorageSpace{Id: &storageprovider.StorageSpaceId{OpaqueId: spaceid}, Name: spacename}
+	details := ul.getDetails(user, nil, nil, nil)
+	details["space"] = map[string]string{
+		"id":   spaceid,
+		"name": spacename,
+	}
 
 	return OC10Notification{
 		EventID:        eventid,
-		Service:        c.serviceName,
-		UserName:       usr.GetUsername(),
+		Service:        ul.cfg.Service.Name,
+		UserName:       user.GetUsername(),
 		Timestamp:      ts.Format(time.RFC3339Nano),
 		ResourceID:     spaceid,
 		ResourceType:   _resourceTypeSpace,
@@ -144,28 +106,23 @@ func (c *Converter) spaceDeletedMessage(eventid string, executant *user.UserId,
 		SubjectRaw:     subjraw,
 		Message:        msg,
 		MessageRaw:     msgraw,
-		MessageDetails: generateDetails(usr, space, nil, nil),
+		MessageDetails: details,
 	}, nil
 }
 
-func (c *Converter) spaceMessage(eventid string, nt NotificationTemplate, executant *user.UserId, spaceid string, ts time.Time) (OC10Notification, error) {
-	usr, err := c.getUser(context.Background(), executant)
-	if err != nil {
-		return OC10Notification{}, err
-	}
-
-	ctx, err := c.authenticate(usr)
+func (ul *UserlogService) spaceMessage(eventid string, eventname string, executant *user.UserId, spaceid string, ts time.Time) (OC10Notification, error) {
+	ctx, user, err := utils.Impersonate(executant, ul.gwClient, ul.cfg.MachineAuthAPIKey)
 	if err != nil {
 		return OC10Notification{}, err
 	}
 
-	space, err := c.getSpace(ctx, spaceid)
+	space, err := ul.getSpace(ctx, spaceid)
 	if err != nil {
 		return OC10Notification{}, err
 	}
 
-	subj, subjraw, msg, msgraw, err := composeMessage(nt, c.locale, c.translationPath, map[string]interface{}{
-		"username":  usr.GetDisplayName(),
+	subj, subjraw, msg, msgraw, err := ul.composeMessage(eventname, map[string]string{
+		"username":  user.GetDisplayName(),
 		"spacename": space.GetName(),
 	})
 	if err != nil {
@@ -174,8 +131,8 @@ func (c *Converter) spaceMessage(eventid string, nt NotificationTemplate, execut
 
 	return OC10Notification{
 		EventID:        eventid,
-		Service:        c.serviceName,
-		UserName:       usr.GetUsername(),
+		Service:        ul.cfg.Service.Name,
+		UserName:       user.GetUsername(),
 		Timestamp:      ts.Format(time.RFC3339Nano),
 		ResourceID:     spaceid,
 		ResourceType:   _resourceTypeSpace,
@@ -183,28 +140,23 @@ func (c *Converter) spaceMessage(eventid string, nt NotificationTemplate, execut
 		SubjectRaw:     subjraw,
 		Message:        msg,
 		MessageRaw:     msgraw,
-		MessageDetails: generateDetails(usr, space, nil, nil),
+		MessageDetails: ul.getDetails(user, space, nil, nil),
 	}, nil
 }
 
-func (c *Converter) shareMessage(eventid string, nt NotificationTemplate, executant *user.UserId, resourceid *storageprovider.ResourceId, shareid *collaboration.ShareId, ts time.Time) (OC10Notification, error) {
-	usr, err := c.getUser(context.Background(), executant)
-	if err != nil {
-		return OC10Notification{}, err
-	}
-
-	ctx, err := c.authenticate(usr)
+func (ul *UserlogService) shareMessage(eventid string, eventname string, executant *user.UserId, resourceid *storageprovider.ResourceId, shareid *collaboration.ShareId, ts time.Time) (OC10Notification, error) {
+	ctx, user, err := utils.Impersonate(executant, ul.gwClient, ul.cfg.MachineAuthAPIKey)
 	if err != nil {
 		return OC10Notification{}, err
 	}
 
-	info, err := c.getResource(ctx, resourceid)
+	info, err := ul.getResource(ctx, resourceid)
 	if err != nil {
 		return OC10Notification{}, err
 	}
 
-	subj, subjraw, msg, msgraw, err := composeMessage(nt, c.locale, c.translationPath, map[string]interface{}{
-		"username":     usr.GetDisplayName(),
+	subj, subjraw, msg, msgraw, err := ul.composeMessage(eventname, map[string]string{
+		"username":     user.GetDisplayName(),
 		"resourcename": info.GetName(),
 	})
 	if err != nil {
@@ -213,8 +165,8 @@ func (c *Converter) shareMessage(eventid string, nt NotificationTemplate, execut
 
 	return OC10Notification{
 		EventID:        eventid,
-		Service:        c.serviceName,
-		UserName:       usr.GetUsername(),
+		Service:        ul.cfg.Service.Name,
+		UserName:       user.GetUsername(),
 		Timestamp:      ts.Format(time.RFC3339Nano),
 		ResourceID:     storagespace.FormatResourceID(*info.GetId()),
 		ResourceType:   _resourceTypeShare,
@@ -222,96 +174,37 @@ func (c *Converter) shareMessage(eventid string, nt NotificationTemplate, execut
 		SubjectRaw:     subjraw,
 		Message:        msg,
 		MessageRaw:     msgraw,
-		MessageDetails: generateDetails(usr, nil, info, shareid),
+		MessageDetails: ul.getDetails(user, nil, info, shareid),
 	}, nil
 }
 
-func (c *Converter) authenticate(usr *user.User) (context.Context, error) {
-	if ctx, ok := c.contexts[usr.GetId().GetOpaqueId()]; ok {
-		return ctx, nil
-	}
-	ctx, err := authenticate(usr, c.gwClient, c.machineAuthAPIKey)
-	if err == nil {
-		c.contexts[usr.GetId().GetOpaqueId()] = ctx
-	}
-	return ctx, err
-}
-
-func (c *Converter) getSpace(ctx context.Context, spaceID string) (*storageprovider.StorageSpace, error) {
-	if space, ok := c.spaces[spaceID]; ok {
-		return space, nil
-	}
-	space, err := getSpace(ctx, spaceID, c.gwClient)
-	if err == nil {
-		c.spaces[spaceID] = space
-	}
-	return space, err
-}
-
-func (c *Converter) getResource(ctx context.Context, resourceID *storageprovider.ResourceId) (*storageprovider.ResourceInfo, error) {
-	if r, ok := c.resources[resourceID.GetOpaqueId()]; ok {
-		return r, nil
-	}
-	resource, err := getResource(ctx, resourceID, c.gwClient)
-	if err == nil {
-		c.resources[resourceID.GetOpaqueId()] = resource
-	}
-	return resource, err
-}
-
-func (c *Converter) getUser(ctx context.Context, userID *user.UserId) (*user.User, error) {
-	if u, ok := c.users[userID.GetOpaqueId()]; ok {
-		return u, nil
-	}
-	usr, err := getUser(ctx, userID, c.gwClient)
-	if err == nil {
-		c.users[userID.GetOpaqueId()] = usr
+func (ul *UserlogService) composeMessage(eventname string, vars map[string]string) (string, string, string, string, error) {
+	tpl, ok := _templates[eventname]
+	if !ok {
+		return "", "", "", "", errors.New("unknown template name")
 	}
-	return usr, err
-}
 
-func composeMessage(nt NotificationTemplate, locale string, path string, vars map[string]interface{}) (string, string, string, string, error) {
-	subjectraw, messageraw := loadTemplates(nt, locale, path)
+	subject := ul.executeTemplate(tpl.Subject, vars)
 
-	subject, err := executeTemplate(subjectraw, vars)
-	if err != nil {
-		return "", "", "", "", err
-	}
+	subjectraw := ul.executeTemplate(tpl.Subject, map[string]string{
+		"username":     "{user}",
+		"spacename":    "{space}",
+		"resourcename": "{resource}",
+	})
 
-	message, err := executeTemplate(messageraw, vars)
-	return subject, subjectraw, message, messageraw, err
+	message := ul.executeTemplate(tpl.Message, vars)
 
-}
+	messageraw := ul.executeTemplate(tpl.Message, map[string]string{
+		"username":     "{user}",
+		"spacename":    "{space}",
+		"resourcename": "{resource}",
+	})
 
-func loadTemplates(nt NotificationTemplate, locale string, path string) (string, string) {
-	// Create Locale with library path and language code and load default domain
-	var l *gotext.Locale
-	if path == "" {
-		l = gotext.NewLocaleFS("l10n/locale", locale, _translationFS)
-	} else { // use custom path instead
-		l = gotext.NewLocale(path, locale)
-	}
-	l.AddDomain(_domain) // make domain configurable only if needed
-	return l.Get(nt.Subject), l.Get(nt.Message)
-}
+	return subject, subjectraw, message, messageraw, nil
 
-func executeTemplate(raw string, vars map[string]interface{}) (string, error) {
-	for o, n := range _placeholders {
-		raw = strings.ReplaceAll(raw, o, n)
-	}
-	tpl, err := template.New("").Parse(raw)
-	if err != nil {
-		return "", err
-	}
-	var writer bytes.Buffer
-	if err := tpl.Execute(&writer, vars); err != nil {
-		return "", err
-	}
-
-	return writer.String(), nil
 }
 
-func generateDetails(user *user.User, space *storageprovider.StorageSpace, item *storageprovider.ResourceInfo, shareid *collaboration.ShareId) map[string]interface{} {
+func (ul *UserlogService) getDetails(user *user.User, space *storageprovider.StorageSpace, item *storageprovider.ResourceInfo, shareid *collaboration.ShareId) map[string]interface{} {
 	details := make(map[string]interface{})
 
 	if user != nil {
@@ -344,3 +237,13 @@ func generateDetails(user *user.User, space *storageprovider.StorageSpace, item
 
 	return details
 }
+
+func (ul *UserlogService) executeTemplate(tpl *template.Template, vars map[string]string) string {
+	var writer bytes.Buffer
+	if err := tpl.Execute(&writer, vars); err != nil {
+		ul.log.Error().Err(err).Str("templateName", tpl.Name()).Msg("cannot execute template")
+		return ""
+	}
+
+	return writer.String()
+}
diff --git a/services/userlog/pkg/service/http.go b/services/userlog/pkg/service/http.go
index 7f316cc7847..725275e04d4 100644
--- a/services/userlog/pkg/service/http.go
+++ b/services/userlog/pkg/service/http.go
@@ -7,9 +7,6 @@ import (
 	revactx "github.com/cs3org/reva/v2/pkg/ctx"
 )
 
-// HeaderPreferedLanguage is the header where the client can set the locale
-var HeaderPreferedLanguage = "Prefered-Language"
-
 // ServeHTTP fulfills Handler interface
 func (ul *UserlogService) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	ul.m.ServeHTTP(w, r)
@@ -31,11 +28,9 @@ func (ul *UserlogService) HandleGetEvents(w http.ResponseWriter, r *http.Request
 		return
 	}
 
-	conv := NewConverter(r.Header.Get(HeaderPreferedLanguage), ul.gwClient, ul.cfg.MachineAuthAPIKey, ul.cfg.Service.Name, ul.cfg.TranslationPath, ul.registeredEvents)
-
 	resp := GetEventResponseOC10{}
 	for _, e := range evs {
-		noti, err := conv.ConvertEvent(e)
+		noti, err := ul.ConvertEvent(e)
 		if err != nil {
 			ul.log.Error().Err(err).Str("eventid", e.Id).Str("eventtype", e.Type).Msg("failed to convert event")
 			continue
diff --git a/services/userlog/pkg/service/l10n/.tx/config b/services/userlog/pkg/service/l10n/.tx/config
deleted file mode 100755
index c8380df8df3..00000000000
--- a/services/userlog/pkg/service/l10n/.tx/config
+++ /dev/null
@@ -1,10 +0,0 @@
-[main]
-host = https://www.transifex.com
-
-[o:owncloud-org:p:owncloud:r:ocis-userlog]
-file_filter = locale/<lang>/LC_MESSAGES/userlog.po
-minimum_perc = 0
-source_file = userlog.pot
-source_lang = en
-type = PO
-
diff --git a/services/userlog/pkg/service/l10n/locale/de_DE/LC_MESSAGES/userlog.po b/services/userlog/pkg/service/l10n/locale/de_DE/LC_MESSAGES/userlog.po
deleted file mode 100644
index d38f57feac1..00000000000
--- a/services/userlog/pkg/service/l10n/locale/de_DE/LC_MESSAGES/userlog.po
+++ /dev/null
@@ -1,83 +0,0 @@
-# German translations for  package
-# German translation for .
-# Copyright (C) 2023 THE 'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the  package.
-# Michael Barz <mbarz@owncloud.com>, 2023.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: \n"
-"Report-Msgid-Bugs-To: EMAIL\n"
-"POT-Creation-Date: 2023-03-13 23:36+0100\n"
-"PO-Revision-Date: 2023-03-13 23:36+0100\n"
-"Last-Translator: Michael Barz <mbarz@owncloud.com>\n"
-"Language-Team: German <translation-team-de@lists.sourceforge.net>\n"
-"Language: de\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: pkg/service/templates.go:30
-msgid "Access to Space {space} lost"
-msgstr ""
-
-#: pkg/service/templates.go:45
-msgid "Access to {resource} expired"
-msgstr ""
-
-#: pkg/service/templates.go:29
-msgid "Membership expired"
-msgstr ""
-
-#: pkg/service/templates.go:14
-msgid "Removed from Space"
-msgstr ""
-
-#: pkg/service/templates.go:34
-msgid "Resource shared"
-msgstr ""
-
-#: pkg/service/templates.go:39
-msgid "Resource unshared"
-msgstr ""
-
-#: pkg/service/templates.go:44
-msgid "Share expired"
-msgstr ""
-
-#: pkg/service/templates.go:24
-msgid "Space deleted"
-msgstr ""
-
-#: pkg/service/templates.go:19
-msgid "Space disabled"
-msgstr ""
-
-#: pkg/service/templates.go:9
-msgid "Space shared"
-msgstr ""
-
-#: pkg/service/templates.go:10
-msgid "{user} added you to Space {space}"
-msgstr ""
-
-#: pkg/service/templates.go:25
-msgid "{user} deleted Space {space}"
-msgstr ""
-
-#: pkg/service/templates.go:20
-msgid "{user} disabled Space {space}"
-msgstr ""
-
-#: pkg/service/templates.go:15
-msgid "{user} removed you from Space {space}"
-msgstr ""
-
-#: pkg/service/templates.go:35
-msgid "{user} shared {resource} with you"
-msgstr ""
-
-#: pkg/service/templates.go:40
-msgid "{user} unshared {resource} with you"
-msgstr ""
diff --git a/services/userlog/pkg/service/service.go b/services/userlog/pkg/service/service.go
index 2c6ee2837da..3a8e8559974 100644
--- a/services/userlog/pkg/service/service.go
+++ b/services/userlog/pkg/service/service.go
@@ -12,7 +12,6 @@ import (
 	user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
 	rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
 	storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
-	revactx "github.com/cs3org/reva/v2/pkg/ctx"
 	"github.com/cs3org/reva/v2/pkg/events"
 	"github.com/cs3org/reva/v2/pkg/utils"
 	"github.com/go-chi/chi/v5"
@@ -21,7 +20,6 @@ import (
 	ehsvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/eventhistory/v0"
 	"github.com/owncloud/ocis/v2/services/userlog/pkg/config"
 	"go-micro.dev/v4/store"
-	"google.golang.org/grpc/metadata"
 )
 
 // UserlogService is the service responsible for user activities
@@ -33,7 +31,6 @@ type UserlogService struct {
 	historyClient    ehsvc.EventHistoryService
 	gwClient         gateway.GatewayAPIClient
 	registeredEvents map[string]events.Unmarshaller
-	translationPath  string
 }
 
 // NewUserlogService returns an EventHistory service
@@ -94,7 +91,7 @@ func (ul *UserlogService) MemorizeEvents(ch <-chan events.Event) {
 		case events.SpaceDisabled:
 			users, err = ul.findSpaceMembers(ul.impersonate(e.Executant), e.ID.GetOpaqueId(), viewer)
 		case events.SpaceDeleted:
-			for u := range e.FinalMembers {
+			for u, _ := range e.FinalMembers {
 				users = append(users, u)
 			}
 		case events.SpaceShared:
@@ -254,7 +251,7 @@ func (ul *UserlogService) findSpaceMembers(ctx context.Context, spaceID string,
 		return nil, errors.New("need authenticated context to find space members")
 	}
 
-	space, err := getSpace(ctx, spaceID, ul.gwClient)
+	space, err := ul.getSpace(ctx, spaceID)
 	if err != nil {
 		return nil, err
 	}
@@ -328,7 +325,7 @@ func (ul *UserlogService) resolveID(ctx context.Context, userid *user.UserId, gr
 
 // resolves the users of a group
 func (ul *UserlogService) resolveGroup(ctx context.Context, groupID string) ([]string, error) {
-	grp, err := getGroup(ctx, groupID, ul.gwClient)
+	grp, err := ul.getGroup(ctx, groupID)
 	if err != nil {
 		return nil, err
 	}
@@ -341,51 +338,28 @@ func (ul *UserlogService) resolveGroup(ctx context.Context, groupID string) ([]s
 	return userIDs, nil
 }
 
-func (ul *UserlogService) impersonate(uid *user.UserId) context.Context {
-	if uid == nil {
-		ul.log.Error().Msg("cannot impersonate nil user")
+func (ul *UserlogService) impersonate(u *user.UserId) context.Context {
+	if u == nil {
+		ul.log.Debug().Msg("cannot impersonate nil user")
 		return nil
 	}
 
-	u, err := getUser(context.Background(), uid, ul.gwClient)
+	ctx, _, err := utils.Impersonate(u, ul.gwClient, ul.cfg.MachineAuthAPIKey)
 	if err != nil {
-		ul.log.Error().Err(err).Msg("cannot get user")
-		return nil
-	}
-
-	ctx, err := authenticate(u, ul.gwClient, ul.cfg.MachineAuthAPIKey)
-	if err != nil {
-		ul.log.Error().Err(err).Str("userid", u.GetId().GetOpaqueId()).Msg("failed to impersonate user")
+		ul.log.Error().Err(err).Str("userid", u.GetOpaqueId()).Msg("failed to impersonate user")
 		return nil
 	}
 	return ctx
 }
 
-func authenticate(usr *user.User, gwc gateway.GatewayAPIClient, machineAuthAPIKey string) (context.Context, error) {
-	ctx := revactx.ContextSetUser(context.Background(), usr)
-	authRes, err := gwc.Authenticate(ctx, &gateway.AuthenticateRequest{
-		Type:         "machine",
-		ClientId:     "userid:" + usr.GetId().GetOpaqueId(),
-		ClientSecret: machineAuthAPIKey,
-	})
-	if err != nil {
-		return nil, err
-	}
-	if authRes.GetStatus().GetCode() != rpc.Code_CODE_OK {
-		return nil, fmt.Errorf("error impersonating user: %s", authRes.Status.Message)
-	}
-
-	return metadata.AppendToOutgoingContext(ctx, revactx.TokenHeader, authRes.Token), nil
-}
-
-func getSpace(ctx context.Context, spaceID string, gwc gateway.GatewayAPIClient) (*storageprovider.StorageSpace, error) {
-	res, err := gwc.ListStorageSpaces(ctx, listStorageSpaceRequest(spaceID))
+func (ul *UserlogService) getSpace(ctx context.Context, spaceID string) (*storageprovider.StorageSpace, error) {
+	res, err := ul.gwClient.ListStorageSpaces(ctx, listStorageSpaceRequest(spaceID))
 	if err != nil {
 		return nil, err
 	}
 
 	if res.GetStatus().GetCode() != rpc.Code_CODE_OK {
-		return nil, fmt.Errorf("Error while getting space: (%v) %s", res.GetStatus().GetCode(), res.GetStatus().GetMessage())
+		return nil, fmt.Errorf("Unexpected status code while getting space: %v", res.GetStatus().GetCode())
 	}
 
 	if len(res.StorageSpaces) == 0 {
@@ -395,8 +369,8 @@ func getSpace(ctx context.Context, spaceID string, gwc gateway.GatewayAPIClient)
 	return res.StorageSpaces[0], nil
 }
 
-func getUser(ctx context.Context, userid *user.UserId, gwc gateway.GatewayAPIClient) (*user.User, error) {
-	getUserResponse, err := gwc.GetUser(context.Background(), &user.GetUserRequest{
+func (ul *UserlogService) getUser(ctx context.Context, userid *user.UserId) (*user.User, error) {
+	getUserResponse, err := ul.gwClient.GetUser(context.Background(), &user.GetUserRequest{
 		UserId: userid,
 	})
 	if err != nil {
@@ -410,8 +384,8 @@ func getUser(ctx context.Context, userid *user.UserId, gwc gateway.GatewayAPICli
 	return getUserResponse.GetUser(), nil
 }
 
-func getGroup(ctx context.Context, groupid string, gwc gateway.GatewayAPIClient) (*group.Group, error) {
-	r, err := gwc.GetGroup(ctx, &group.GetGroupRequest{GroupId: &group.GroupId{OpaqueId: groupid}})
+func (ul *UserlogService) getGroup(ctx context.Context, groupid string) (*group.Group, error) {
+	r, err := ul.gwClient.GetGroup(ctx, &group.GetGroupRequest{GroupId: &group.GroupId{OpaqueId: groupid}})
 	if err != nil {
 		return nil, err
 	}
@@ -423,8 +397,8 @@ func getGroup(ctx context.Context, groupid string, gwc gateway.GatewayAPIClient)
 	return r.GetGroup(), nil
 }
 
-func getResource(ctx context.Context, resourceid *storageprovider.ResourceId, gwc gateway.GatewayAPIClient) (*storageprovider.ResourceInfo, error) {
-	res, err := gwc.Stat(ctx, &storageprovider.StatRequest{Ref: &storageprovider.Reference{ResourceId: resourceid}})
+func (ul *UserlogService) getResource(ctx context.Context, resourceid *storageprovider.ResourceId) (*storageprovider.ResourceInfo, error) {
+	res, err := ul.gwClient.Stat(ctx, &storageprovider.StatRequest{Ref: &storageprovider.Reference{ResourceId: resourceid}})
 	if err != nil {
 		return nil, err
 	}
diff --git a/services/userlog/pkg/service/templates.go b/services/userlog/pkg/service/templates.go
index 412b6ee4efb..bc9bf33d2b7 100644
--- a/services/userlog/pkg/service/templates.go
+++ b/services/userlog/pkg/service/templates.go
@@ -1,60 +1,65 @@
 package service
 
-// Template marks the string as a translatable template
-func Template(s string) string { return s }
+import "text/template"
 
 // the available templates
 var (
-	SpaceShared = NotificationTemplate{
-		Subject: Template("Space shared"),
-		Message: Template("{user} added you to Space {space}"),
-	}
+	SpaceShared        = "space-shared"
+	SpaceSharedSubject = "Space shared"
+	SpaceSharedMessage = "{{ .username }} added you to Space {{ .spacename }}"
 
-	SpaceUnshared = NotificationTemplate{
-		Subject: Template("Removed from Space"),
-		Message: Template("{user} removed you from Space {space}"),
-	}
+	SpaceUnshared        = "space-unshared"
+	SpaceUnsharedSubject = "Removed from Space"
+	SpaceUnsharedMessage = "{{ .username }} removed you from Space {{ .spacename }}"
 
-	SpaceDisabled = NotificationTemplate{
-		Subject: Template("Space disabled"),
-		Message: Template("{user} disabled Space {space}"),
-	}
+	SpaceDisabled        = "space-disabled"
+	SpaceDisabledSubject = "Space disabled"
+	SpaceDisabledMessage = "{{ .username }} disabled Space {{ .spacename }}"
 
-	SpaceDeleted = NotificationTemplate{
-		Subject: Template("Space deleted"),
-		Message: Template("{user} deleted Space {space}"),
-	}
+	SpaceDeleted        = "space-deleted"
+	SpaceDeletedSubject = "Space deleted"
+	SpaceDeletedMessage = "{{ .username }} deleted Space {{ .spacename }}"
 
-	SpaceMembershipExpired = NotificationTemplate{
-		Subject: Template("Membership expired"),
-		Message: Template("Access to Space {space} lost"),
-	}
+	SpaceMembershipExpired        = "space-membership-expired"
+	SpaceMembershipExpiredSubject = "Membership expired"
+	SpaceMembershipExpiredMessage = "Access to Space {{ .spacename }} lost"
 
-	ShareCreated = NotificationTemplate{
-		Subject: Template("Resource shared"),
-		Message: Template("{user} shared {resource} with you"),
-	}
+	ShareCreated        = "item-shared"
+	ShareCreatedSubject = "Resource shared"
+	ShareCreatedMessage = "{{ .username }} shared {{ .resourcename }} with you"
 
-	ShareRemoved = NotificationTemplate{
-		Subject: Template("Resource unshared"),
-		Message: Template("{user} unshared {resource} with you"),
-	}
+	ShareRemoved        = "item-unshared"
+	ShareRemovedSubject = "Resource unshared"
+	ShareRemovedMessage = "{{ .username }} unshared {{ .resourcename }} with you"
 
-	ShareExpired = NotificationTemplate{
-		Subject: Template("Share expired"),
-		Message: Template("Access to {resource} expired"),
-	}
+	ShareExpired        = "share-expired"
+	ShareExpiredSubject = "Share expired"
+	ShareExpiredMessage = "Access to {{ .resourcename }} expired"
 )
 
-// holds the information to turn the raw template into a parseable go template
-var _placeholders = map[string]string{
-	"{user}":     "{{ .username }}",
-	"{space}":    "{{ .spacename }}",
-	"{resource}": "{{ .resourcename }}",
-}
+// rendered templates
+var (
+	_templates = map[string]NotificationTemplate{
+		SpaceShared:            notiTmpl(SpaceSharedSubject, SpaceSharedMessage),
+		SpaceUnshared:          notiTmpl(SpaceUnsharedSubject, SpaceUnsharedMessage),
+		SpaceDisabled:          notiTmpl(SpaceDisabledSubject, SpaceDisabledMessage),
+		SpaceDeleted:           notiTmpl(SpaceDeletedSubject, SpaceDeletedMessage),
+		SpaceMembershipExpired: notiTmpl(SpaceMembershipExpiredSubject, SpaceMembershipExpiredMessage),
+		ShareCreated:           notiTmpl(ShareCreatedSubject, ShareCreatedMessage),
+		ShareRemoved:           notiTmpl(ShareRemovedSubject, ShareRemovedMessage),
+		ShareExpired:           notiTmpl(ShareExpiredSubject, ShareExpiredMessage),
+	}
+)
 
 // NotificationTemplate is the data structure for the notifications
 type NotificationTemplate struct {
-	Subject string
-	Message string
+	Subject *template.Template
+	Message *template.Template
+}
+
+func notiTmpl(subjectname string, messagename string) NotificationTemplate {
+	return NotificationTemplate{
+		Subject: template.Must(template.New("").Parse(subjectname)),
+		Message: template.Must(template.New("").Parse(messagename)),
+	}
 }


Test patch:
diff --git a/ocis-pkg/ldap/ldap_test.go b/ocis-pkg/ldap/ldap_test.go
new file mode 100644
index 00000000000..d3ee3152cfb
--- /dev/null
+++ b/ocis-pkg/ldap/ldap_test.go
@@ -0,0 +1,25 @@
+package ldap_test
+
+import (
+	. "github.com/onsi/ginkgo/v2"
+	. "github.com/onsi/gomega"
+	"github.com/owncloud/ocis/v2/ocis-pkg/ldap"
+)
+
+var _ = Describe("ldap", func() {
+	DescribeTable("EscapeDNAttributeValue should escape special characters",
+		func(input, expected string) {
+			escaped := ldap.EscapeDNAttributeValue(input)
+			Expect(escaped).To(Equal(expected))
+		},
+		Entry("normal dn", "foobar", "foobar"),
+		Entry("including comma", "foo,bar", "foo\\,bar"),
+		Entry("including equals", "foo=bar", "foo\\=bar"),
+		Entry("beginning with number sign", "#foobar", "\\#foobar"),
+		Entry("beginning with space", " foobar", "\\ foobar"),
+		Entry("only one space", " ", "\\ "),
+		Entry("two spaces", "  ", "\\ \\ "),
+		Entry("ending with space", "foobar ", "foobar\\ "),
+		Entry("containing multiple special chars", "f+o>o,b<a;r=\"\000", `f\+o\>o\,b\<a\;r\=\\"\00`),
+	)
+})
diff --git a/services/policies/pkg/engine/engine_suite_test.go b/services/policies/pkg/engine/engine_suite_test.go
deleted file mode 100644
index 062fcadb182..00000000000
--- a/services/policies/pkg/engine/engine_suite_test.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package engine_test
-
-import (
-	"testing"
-
-	. "github.com/onsi/ginkgo/v2"
-	. "github.com/onsi/gomega"
-)
-
-func TestEngine(t *testing.T) {
-	RegisterFailHandler(Fail)
-	RunSpecs(t, "Engine Suite")
-}
diff --git a/services/policies/pkg/engine/engine_test.go b/services/policies/pkg/engine/engine_test.go
deleted file mode 100644
index 3ac7c5101f7..00000000000
--- a/services/policies/pkg/engine/engine_test.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package engine_test
-
-import (
-	. "github.com/onsi/ginkgo/v2"
-	. "github.com/onsi/gomega"
-	pMessage "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/policies/v0"
-	"github.com/owncloud/ocis/v2/services/policies/pkg/engine"
-)
-
-var _ = Describe("Engine", func() {
-	DescribeTable("NewEnvironmentFromPB",
-		func(incomingStage pMessage.Stage, outgoinStage engine.Stage) {
-			pEnv := &pMessage.Environment{
-				Stage: incomingStage,
-			}
-
-			env, err := engine.NewEnvironmentFromPB(pEnv)
-			Expect(err).ToNot(HaveOccurred())
-
-			Expect(env.Stage).To(Equal(outgoinStage))
-		},
-		Entry("http stage", pMessage.Stage_STAGE_HTTP, engine.StageHTTP),
-		Entry("pp stage", pMessage.Stage_STAGE_PP, engine.StagePP),
-	)
-})
diff --git a/services/policies/pkg/engine/opa_test.go b/services/policies/pkg/engine/opa_test.go
deleted file mode 100644
index 0e0ff29e0ec..00000000000
--- a/services/policies/pkg/engine/opa_test.go
+++ /dev/null
@@ -1,46 +0,0 @@
-package engine_test
-
-import (
-	"context"
-	"encoding/base64"
-	"net/http"
-	"net/http/httptest"
-
-	. "github.com/onsi/ginkgo/v2"
-	. "github.com/onsi/gomega"
-	"github.com/open-policy-agent/opa/rego"
-	"github.com/owncloud/ocis/v2/services/policies/pkg/engine"
-)
-
-var _ = Describe("Opa", func() {
-	Describe("Custom OPA function", func() {
-		Describe("GetResource", func() {
-			It("loads reva resources", func() {
-				ts := []byte("Lorem Ipsum is simply dummy text of the printing and typesetting")
-				srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-					w.Write(ts)
-				}))
-				defer srv.Close()
-
-				r := rego.New(rego.Query(`ocis_get_resource("`+srv.URL+`")`), engine.GetResource)
-				rs, err := r.Eval(context.Background())
-				Expect(err).ToNot(HaveOccurred())
-
-				data, err := base64.StdEncoding.DecodeString(rs[0].Expressions[0].String())
-				Expect(err).ToNot(HaveOccurred())
-
-				Expect(data).To(Equal(ts))
-
-			})
-		})
-
-		Describe("GetMimetype", func() {
-			It("is defined and returns a mimetype", func() {
-				r := rego.New(rego.Query(`ocis_get_mimetype("")`), engine.GetMimetype)
-				rs, err := r.Eval(context.Background())
-				Expect(err).ToNot(HaveOccurred())
-				Expect(rs[0].Expressions[0].String()).To(Equal("text/plain"))
-			})
-		})
-	})
-})
diff --git a/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md b/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md
index 8a4d6ea595e..c35cff60f80 100644
--- a/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md
+++ b/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md
@@ -108,6 +108,7 @@ The expected failures in this file are from features in the owncloud/ocis repo.
 - [apiGraph/editUser.feature:41](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiGraph/editUser.feature#L41)
 
 #### [Using # in the onPremisesSamAccountName breaks getting users](https://github.com/owncloud/ocis/issues/5755)
+- [apiGraph/editUser.feature:42](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiGraph/editUser.feature#L42)
 - [apiGraph/editUser.feature:44](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiGraph/editUser.feature#L44)
 
 Note: always have an empty line at the end of this file.