diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 7ba775a534d64291955648e24da611f3c5a3cd99..c92e8694f8f984638f7769e9cf29d719ff1b6adf 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -14,7 +14,7 @@ linters:
     - golangci-lint run
 
 unit tests:
-  image: golang:1.21.3
+  image: golang:1.21.5
   stage: test
   script:
     - go version
@@ -23,7 +23,7 @@ unit tests:
   coverage: '/total:\s+\(statements\)\s+(\d+.\d+\%)/'
 
 govulncheck:
-  image: golang:1.21.3
+  image: golang:1.21.5
   stage: test
   script:
     - go version
diff --git a/deployment/ci/Dockerfile b/deployment/ci/Dockerfile
index 60f9b8210b56c843e3e73c46004f0ee0c57647ab..346b141a62289f11e1bcedf9da75f140ab43c7d5 100644
--- a/deployment/ci/Dockerfile
+++ b/deployment/ci/Dockerfile
@@ -1,4 +1,4 @@
-FROM golang:1.21.3-alpine3.17 as builder
+FROM golang:1.21.5-alpine3.17 as builder
 
 RUN apk add git
 
diff --git a/deployment/compose/Dockerfile b/deployment/compose/Dockerfile
index e9d3baeaf73b41a653953d21efab82ca482ce244..b57e8bd82a58c31dd728367293b58ff2186d67f4 100644
--- a/deployment/compose/Dockerfile
+++ b/deployment/compose/Dockerfile
@@ -1,4 +1,4 @@
-FROM golang:1.21.3
+FROM golang:1.21.5
 
 RUN go install github.com/ysmood/kit/cmd/guard@v0.25.11
 
diff --git a/design/design.go b/design/design.go
index 470b6a6e27c714cd3524267766e900f15f042233..28fc20acae40eba9df4a35c6fab6a451a49aef92 100644
--- a/design/design.go
+++ b/design/design.go
@@ -56,7 +56,13 @@ var _ = Service("cache", func() {
 				Example("Login")
 			})
 			Header("scope:x-cache-scope", String, "Cache entry scope", func() {
-				Example("administration")
+				Example("multiple scopes", "administration,user")
+				Example("default", "administration")
+			})
+			Header("strategy:x-cache-flatten-strategy", String, "Flatten strategy.", func() {
+				Example("first key value only", "first")
+				Example("last key value only", "last")
+				Example("default", "merge")
 			})
 
 			Response(StatusOK, func() {
diff --git a/design/types.go b/design/types.go
index eee0825d85ed07a661c979e8a5d8ea51edcc2740..bf8bd71bf9c0baa88a2ee57bcb0bcd53718f0348 100644
--- a/design/types.go
+++ b/design/types.go
@@ -6,7 +6,8 @@ import . "goa.design/goa/v3/dsl"
 var CacheGetRequest = Type("CacheGetRequest", func() {
 	Field(1, "key", String)
 	Field(2, "namespace", String)
-	Field(3, "scope", String) // Initial implementation with a single scope
+	Field(3, "scope", String)
+	Field(4, "strategy", String)
 	Required("key")
 })
 
diff --git a/gen/cache/service.go b/gen/cache/service.go
index 74f41d961927e3fdc1c77b37a1df1f31fd4c37b7..9d0f802dd1dc90f4c44a0fc6db58b06083d0dcd7 100644
--- a/gen/cache/service.go
+++ b/gen/cache/service.go
@@ -36,6 +36,7 @@ type CacheGetRequest struct {
 	Key       string
 	Namespace *string
 	Scope     *string
+	Strategy  *string
 }
 
 // CacheSetRequest is the payload type of the cache service Set method.
diff --git a/gen/http/cache/client/cli.go b/gen/http/cache/client/cli.go
index 4f75bd46a479ad1a576bbd0fac478d8a3298f7ba..31684f60e89eea3f76b436fbd1791e0c66d5437b 100644
--- a/gen/http/cache/client/cli.go
+++ b/gen/http/cache/client/cli.go
@@ -16,7 +16,7 @@ import (
 )
 
 // BuildGetPayload builds the payload for the cache Get endpoint from CLI flags.
-func BuildGetPayload(cacheGetKey string, cacheGetNamespace string, cacheGetScope string) (*cache.CacheGetRequest, error) {
+func BuildGetPayload(cacheGetKey string, cacheGetNamespace string, cacheGetScope string, cacheGetStrategy string) (*cache.CacheGetRequest, error) {
 	var key string
 	{
 		key = cacheGetKey
@@ -33,10 +33,17 @@ func BuildGetPayload(cacheGetKey string, cacheGetNamespace string, cacheGetScope
 			scope = &cacheGetScope
 		}
 	}
+	var strategy *string
+	{
+		if cacheGetStrategy != "" {
+			strategy = &cacheGetStrategy
+		}
+	}
 	v := &cache.CacheGetRequest{}
 	v.Key = key
 	v.Namespace = namespace
 	v.Scope = scope
+	v.Strategy = strategy
 
 	return v, nil
 }
@@ -48,7 +55,7 @@ func BuildSetPayload(cacheSetBody string, cacheSetKey string, cacheSetNamespace
 	{
 		err = json.Unmarshal([]byte(cacheSetBody), &body)
 		if err != nil {
-			return nil, fmt.Errorf("invalid JSON for body, \nerror: %s, \nexample of valid JSON:\n%s", err, "\"Dolorem et quam et illum.\"")
+			return nil, fmt.Errorf("invalid JSON for body, \nerror: %s, \nexample of valid JSON:\n%s", err, "\"Enim vel.\"")
 		}
 	}
 	var key string
@@ -99,7 +106,7 @@ func BuildSetExternalPayload(cacheSetExternalBody string, cacheSetExternalKey st
 	{
 		err = json.Unmarshal([]byte(cacheSetExternalBody), &body)
 		if err != nil {
-			return nil, fmt.Errorf("invalid JSON for body, \nerror: %s, \nexample of valid JSON:\n%s", err, "\"Quis rerum velit sunt rerum dignissimos at.\"")
+			return nil, fmt.Errorf("invalid JSON for body, \nerror: %s, \nexample of valid JSON:\n%s", err, "\"Sint ipsa fugiat et id rem.\"")
 		}
 	}
 	var key string
diff --git a/gen/http/cache/client/encode_decode.go b/gen/http/cache/client/encode_decode.go
index db80d155308f960f911ccd572d55cac8666449a4..793256a4178a693a2515773d657f701e72d09827 100644
--- a/gen/http/cache/client/encode_decode.go
+++ b/gen/http/cache/client/encode_decode.go
@@ -54,6 +54,10 @@ func EncodeGetRequest(encoder func(*http.Request) goahttp.Encoder) func(*http.Re
 			head := *p.Scope
 			req.Header.Set("x-cache-scope", head)
 		}
+		if p.Strategy != nil {
+			head := *p.Strategy
+			req.Header.Set("x-cache-flatten-strategy", head)
+		}
 		return nil
 	}
 }
diff --git a/gen/http/cache/server/encode_decode.go b/gen/http/cache/server/encode_decode.go
index 44aee8d8ef7da8d78fdaa596d533af1a57edd0d7..f8d56c06ec04bc970610f12da13fe9cbd177c404 100644
--- a/gen/http/cache/server/encode_decode.go
+++ b/gen/http/cache/server/encode_decode.go
@@ -38,6 +38,7 @@ func DecodeGetRequest(mux goahttp.Muxer, decoder func(*http.Request) goahttp.Dec
 			key       string
 			namespace *string
 			scope     *string
+			strategy  *string
 			err       error
 		)
 		key = r.Header.Get("x-cache-key")
@@ -52,10 +53,14 @@ func DecodeGetRequest(mux goahttp.Muxer, decoder func(*http.Request) goahttp.Dec
 		if scopeRaw != "" {
 			scope = &scopeRaw
 		}
+		strategyRaw := r.Header.Get("x-cache-flatten-strategy")
+		if strategyRaw != "" {
+			strategy = &strategyRaw
+		}
 		if err != nil {
 			return nil, err
 		}
-		payload := NewGetCacheGetRequest(key, namespace, scope)
+		payload := NewGetCacheGetRequest(key, namespace, scope, strategy)
 
 		return payload, nil
 	}
diff --git a/gen/http/cache/server/types.go b/gen/http/cache/server/types.go
index 56803f12967d47936b136a77a6500fc4cb48e5bf..1e458783ec6e1f57a977e0de4449c6849f8a0351 100644
--- a/gen/http/cache/server/types.go
+++ b/gen/http/cache/server/types.go
@@ -12,11 +12,12 @@ import (
 )
 
 // NewGetCacheGetRequest builds a cache service Get endpoint payload.
-func NewGetCacheGetRequest(key string, namespace *string, scope *string) *cache.CacheGetRequest {
+func NewGetCacheGetRequest(key string, namespace *string, scope *string, strategy *string) *cache.CacheGetRequest {
 	v := &cache.CacheGetRequest{}
 	v.Key = key
 	v.Namespace = namespace
 	v.Scope = scope
+	v.Strategy = strategy
 
 	return v
 }
diff --git a/gen/http/cli/cache/cli.go b/gen/http/cli/cache/cli.go
index 44fb882cbf558eca3f57bf7e8d0ffe88a836ddaf..518b2114a59d7f17162845ee0c88a43fa3a7f585 100644
--- a/gen/http/cli/cache/cli.go
+++ b/gen/http/cli/cache/cli.go
@@ -30,7 +30,7 @@ health (liveness|readiness)
 
 // UsageExamples produces an example of a valid invocation of the CLI tool.
 func UsageExamples() string {
-	return os.Args[0] + ` cache get --key "Voluptatum modi tenetur tempore quia est ratione." --namespace "Corrupti sunt dolores." --scope "Repellat omnis id ex."` + "\n" +
+	return os.Args[0] + ` cache get --key "Iusto consequatur voluptatem eligendi et eligendi." --namespace "Optio natus." --scope "Ratione quasi perspiciatis qui." --strategy "Animi non alias occaecati esse."` + "\n" +
 		os.Args[0] + ` health liveness` + "\n" +
 		""
 }
@@ -51,6 +51,7 @@ func ParseEndpoint(
 		cacheGetKeyFlag       = cacheGetFlags.String("key", "REQUIRED", "")
 		cacheGetNamespaceFlag = cacheGetFlags.String("namespace", "", "")
 		cacheGetScopeFlag     = cacheGetFlags.String("scope", "", "")
+		cacheGetStrategyFlag  = cacheGetFlags.String("strategy", "", "")
 
 		cacheSetFlags         = flag.NewFlagSet("set", flag.ExitOnError)
 		cacheSetBodyFlag      = cacheSetFlags.String("body", "REQUIRED", "")
@@ -163,7 +164,7 @@ func ParseEndpoint(
 			switch epn {
 			case "get":
 				endpoint = c.Get()
-				data, err = cachec.BuildGetPayload(*cacheGetKeyFlag, *cacheGetNamespaceFlag, *cacheGetScopeFlag)
+				data, err = cachec.BuildGetPayload(*cacheGetKeyFlag, *cacheGetNamespaceFlag, *cacheGetScopeFlag, *cacheGetStrategyFlag)
 			case "set":
 				endpoint = c.Set()
 				data, err = cachec.BuildSetPayload(*cacheSetBodyFlag, *cacheSetKeyFlag, *cacheSetNamespaceFlag, *cacheSetScopeFlag, *cacheSetTTLFlag)
@@ -206,15 +207,16 @@ Additional help:
 `, os.Args[0])
 }
 func cacheGetUsage() {
-	fmt.Fprintf(os.Stderr, `%[1]s [flags] cache get -key STRING -namespace STRING -scope STRING
+	fmt.Fprintf(os.Stderr, `%[1]s [flags] cache get -key STRING -namespace STRING -scope STRING -strategy STRING
 
 Get JSON value from the cache.
     -key STRING: 
     -namespace STRING: 
     -scope STRING: 
+    -strategy STRING: 
 
 Example:
-    %[1]s cache get --key "Voluptatum modi tenetur tempore quia est ratione." --namespace "Corrupti sunt dolores." --scope "Repellat omnis id ex."
+    %[1]s cache get --key "Iusto consequatur voluptatem eligendi et eligendi." --namespace "Optio natus." --scope "Ratione quasi perspiciatis qui." --strategy "Animi non alias occaecati esse."
 `, os.Args[0])
 }
 
@@ -229,7 +231,7 @@ Set a JSON value in the cache.
     -ttl INT: 
 
 Example:
-    %[1]s cache set --body "Dolorem et quam et illum." --key "Esse inventore ullam placeat aut." --namespace "Omnis itaque." --scope "Quasi ut." --ttl 3100652887298323449
+    %[1]s cache set --body "Enim vel." --key "Ut in." --namespace "Ab dolores distinctio quis." --scope "Optio aliquam error nam." --ttl 2227603043401673122
 `, os.Args[0])
 }
 
@@ -244,7 +246,7 @@ Set an external JSON value in the cache and provide an event for the input.
     -ttl INT: 
 
 Example:
-    %[1]s cache set-external --body "Quis rerum velit sunt rerum dignissimos at." --key "Optio aliquam error nam." --namespace "Recusandae illo." --scope "Placeat veniam veritatis doloribus." --ttl 5137048679846705449
+    %[1]s cache set-external --body "Sint ipsa fugiat et id rem." --key "Molestiae minima." --namespace "Quia dolores rem." --scope "Est illum." --ttl 6207033275224297400
 `, os.Args[0])
 }
 
diff --git a/gen/http/openapi.json b/gen/http/openapi.json
index febee9e13843c7696b10226d473cbc0aeeb535e8..81d8d61561c393db3717cdf66bbcfad496db6da6 100644
--- a/gen/http/openapi.json
+++ b/gen/http/openapi.json
@@ -1 +1 @@
-{"swagger":"2.0","info":{"title":"Cache Service","description":"The cache service exposes interface for working with Redis.","version":""},"host":"localhost:8083","consumes":["application/json","application/xml","application/gob"],"produces":["application/json","application/xml","application/gob"],"paths":{"/liveness":{"get":{"tags":["health"],"summary":"Liveness health","operationId":"health#Liveness","responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/HealthLivenessResponseBody","required":["service","status","version"]}}},"schemes":["http"]}},"/readiness":{"get":{"tags":["health"],"summary":"Readiness health","operationId":"health#Readiness","responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/HealthReadinessResponseBody","required":["service","status","version"]}}},"schemes":["http"]}},"/v1/cache":{"get":{"tags":["cache"],"summary":"Get cache","description":"Get JSON value from the cache.","operationId":"cache#Get","produces":["application/json"],"parameters":[{"name":"x-cache-key","in":"header","description":"Cache entry key","required":true,"type":"string"},{"name":"x-cache-namespace","in":"header","description":"Cache entry namespace","required":false,"type":"string"},{"name":"x-cache-scope","in":"header","description":"Cache entry scope","required":false,"type":"string"}],"responses":{"200":{"description":"OK response.","schema":{"type":"string","format":"binary"}}},"schemes":["http"]},"post":{"tags":["cache"],"summary":"Set cache","description":"Set a JSON value in the cache.","operationId":"cache#Set","parameters":[{"name":"x-cache-key","in":"header","description":"Cache entry key","required":true,"type":"string"},{"name":"x-cache-namespace","in":"header","description":"Cache entry namespace","required":false,"type":"string"},{"name":"x-cache-scope","in":"header","description":"Cache entry scope","required":false,"type":"string"},{"name":"x-cache-ttl","in":"header","description":"Cache entry TTL in seconds","required":false,"type":"integer"},{"name":"any","in":"body","required":true,"schema":{"type":"string","format":"binary"}}],"responses":{"201":{"description":"Created response."}},"schemes":["http"]}},"/v1/external/cache":{"post":{"tags":["cache"],"summary":"SetExternal cache","description":"Set an external JSON value in the cache and provide an event for the input.","operationId":"cache#SetExternal","parameters":[{"name":"x-cache-key","in":"header","description":"Cache entry key","required":true,"type":"string"},{"name":"x-cache-namespace","in":"header","description":"Cache entry namespace","required":false,"type":"string"},{"name":"x-cache-scope","in":"header","description":"Cache entry scope","required":false,"type":"string"},{"name":"x-cache-ttl","in":"header","description":"Cache entry TTL in seconds","required":false,"type":"integer"},{"name":"any","in":"body","required":true,"schema":{"type":"string","format":"binary"}}],"responses":{"200":{"description":"OK response."}},"schemes":["http"]}}},"definitions":{"HealthLivenessResponseBody":{"title":"HealthLivenessResponseBody","type":"object","properties":{"service":{"type":"string","description":"Service name.","example":"Laborum reprehenderit rerum est et ut dolores."},"status":{"type":"string","description":"Status message.","example":"Consequatur porro qui est dolor a."},"version":{"type":"string","description":"Service runtime version.","example":"Ad dolor."}},"example":{"service":"Fugiat voluptatem vel et.","status":"Sint tempore est nam iusto.","version":"Ipsam quidem aut velit vitae est."},"required":["service","status","version"]},"HealthReadinessResponseBody":{"title":"HealthReadinessResponseBody","type":"object","properties":{"service":{"type":"string","description":"Service name.","example":"Repellat qui totam et recusandae."},"status":{"type":"string","description":"Status message.","example":"Dolores at qui aliquam ullam."},"version":{"type":"string","description":"Service runtime version.","example":"Omnis ex fugit corporis."}},"example":{"service":"Minima sed et.","status":"Veniam optio qui.","version":"Suscipit velit aliquid et."},"required":["service","status","version"]}}}
\ No newline at end of file
+{"swagger":"2.0","info":{"title":"Cache Service","description":"The cache service exposes interface for working with Redis.","version":""},"host":"localhost:8083","consumes":["application/json","application/xml","application/gob"],"produces":["application/json","application/xml","application/gob"],"paths":{"/liveness":{"get":{"tags":["health"],"summary":"Liveness health","operationId":"health#Liveness","responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/HealthLivenessResponseBody","required":["service","status","version"]}}},"schemes":["http"]}},"/readiness":{"get":{"tags":["health"],"summary":"Readiness health","operationId":"health#Readiness","responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/HealthReadinessResponseBody","required":["service","status","version"]}}},"schemes":["http"]}},"/v1/cache":{"get":{"tags":["cache"],"summary":"Get cache","description":"Get JSON value from the cache.","operationId":"cache#Get","produces":["application/json"],"parameters":[{"name":"x-cache-key","in":"header","description":"Cache entry key","required":true,"type":"string"},{"name":"x-cache-namespace","in":"header","description":"Cache entry namespace","required":false,"type":"string"},{"name":"x-cache-scope","in":"header","description":"Cache entry scope","required":false,"type":"string"},{"name":"x-cache-flatten-strategy","in":"header","description":"Flatten strategy.","required":false,"type":"string"}],"responses":{"200":{"description":"OK response.","schema":{"type":"string","format":"binary"}}},"schemes":["http"]},"post":{"tags":["cache"],"summary":"Set cache","description":"Set a JSON value in the cache.","operationId":"cache#Set","parameters":[{"name":"x-cache-key","in":"header","description":"Cache entry key","required":true,"type":"string"},{"name":"x-cache-namespace","in":"header","description":"Cache entry namespace","required":false,"type":"string"},{"name":"x-cache-scope","in":"header","description":"Cache entry scope","required":false,"type":"string"},{"name":"x-cache-ttl","in":"header","description":"Cache entry TTL in seconds","required":false,"type":"integer"},{"name":"any","in":"body","required":true,"schema":{"type":"string","format":"binary"}}],"responses":{"201":{"description":"Created response."}},"schemes":["http"]}},"/v1/external/cache":{"post":{"tags":["cache"],"summary":"SetExternal cache","description":"Set an external JSON value in the cache and provide an event for the input.","operationId":"cache#SetExternal","parameters":[{"name":"x-cache-key","in":"header","description":"Cache entry key","required":true,"type":"string"},{"name":"x-cache-namespace","in":"header","description":"Cache entry namespace","required":false,"type":"string"},{"name":"x-cache-scope","in":"header","description":"Cache entry scope","required":false,"type":"string"},{"name":"x-cache-ttl","in":"header","description":"Cache entry TTL in seconds","required":false,"type":"integer"},{"name":"any","in":"body","required":true,"schema":{"type":"string","format":"binary"}}],"responses":{"200":{"description":"OK response."}},"schemes":["http"]}}},"definitions":{"HealthLivenessResponseBody":{"title":"HealthLivenessResponseBody","type":"object","properties":{"service":{"type":"string","description":"Service name.","example":"Repellat qui totam et recusandae."},"status":{"type":"string","description":"Status message.","example":"Dolores at qui aliquam ullam."},"version":{"type":"string","description":"Service runtime version.","example":"Omnis ex fugit corporis."}},"example":{"service":"Minima sed et.","status":"Veniam optio qui.","version":"Suscipit velit aliquid et."},"required":["service","status","version"]},"HealthReadinessResponseBody":{"title":"HealthReadinessResponseBody","type":"object","properties":{"service":{"type":"string","description":"Service name.","example":"Rerum et qui alias qui."},"status":{"type":"string","description":"Status message.","example":"Beatae commodi."},"version":{"type":"string","description":"Service runtime version.","example":"Fuga voluptas explicabo et libero."}},"example":{"service":"Illum nam ratione nisi.","status":"Labore vel.","version":"Aut illum."},"required":["service","status","version"]}}}
\ No newline at end of file
diff --git a/gen/http/openapi.yaml b/gen/http/openapi.yaml
index 3648e0c82368173c51c7c1ff87e89388b3fb8042..0e5f69ccd6b890c8890e333e74e95dcbfc35654d 100644
--- a/gen/http/openapi.yaml
+++ b/gen/http/openapi.yaml
@@ -72,6 +72,11 @@ paths:
                   description: Cache entry scope
                   required: false
                   type: string
+                - name: x-cache-flatten-strategy
+                  in: header
+                  description: Flatten strategy.
+                  required: false
+                  type: string
             responses:
                 "200":
                     description: OK response.
@@ -165,19 +170,19 @@ definitions:
             service:
                 type: string
                 description: Service name.
-                example: Laborum reprehenderit rerum est et ut dolores.
+                example: Repellat qui totam et recusandae.
             status:
                 type: string
                 description: Status message.
-                example: Consequatur porro qui est dolor a.
+                example: Dolores at qui aliquam ullam.
             version:
                 type: string
                 description: Service runtime version.
-                example: Ad dolor.
+                example: Omnis ex fugit corporis.
         example:
-            service: Fugiat voluptatem vel et.
-            status: Sint tempore est nam iusto.
-            version: Ipsam quidem aut velit vitae est.
+            service: Minima sed et.
+            status: Veniam optio qui.
+            version: Suscipit velit aliquid et.
         required:
             - service
             - status
@@ -189,19 +194,19 @@ definitions:
             service:
                 type: string
                 description: Service name.
-                example: Repellat qui totam et recusandae.
+                example: Rerum et qui alias qui.
             status:
                 type: string
                 description: Status message.
-                example: Dolores at qui aliquam ullam.
+                example: Beatae commodi.
             version:
                 type: string
                 description: Service runtime version.
-                example: Omnis ex fugit corporis.
+                example: Fuga voluptas explicabo et libero.
         example:
-            service: Minima sed et.
-            status: Veniam optio qui.
-            version: Suscipit velit aliquid et.
+            service: Illum nam ratione nisi.
+            status: Labore vel.
+            version: Aut illum.
         required:
             - service
             - status
diff --git a/gen/http/openapi3.json b/gen/http/openapi3.json
index 605856bfa27850eb6f1bf81f1b1101d5742ed5ec..c1681f1cf9ebc5972cbe0c9343c8bd787eb0e75a 100644
--- a/gen/http/openapi3.json
+++ b/gen/http/openapi3.json
@@ -1 +1 @@
-{"openapi":"3.0.3","info":{"title":"Cache Service","description":"The cache service exposes interface for working with Redis.","version":"1.0"},"servers":[{"url":"http://localhost:8083","description":"Cache Server"}],"paths":{"/liveness":{"get":{"tags":["health"],"summary":"Liveness health","operationId":"health#Liveness","responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"},"example":{"service":"Molestiae minima.","status":"Quia dolores rem.","version":"Est illum."}}}}}}},"/readiness":{"get":{"tags":["health"],"summary":"Readiness health","operationId":"health#Readiness","responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"},"example":{"service":"Repellendus quo.","status":"Cumque aut.","version":"Sit sint ipsa fugiat et id rem."}}}}}}},"/v1/cache":{"get":{"tags":["cache"],"summary":"Get cache","description":"Get JSON value from the cache.","operationId":"cache#Get","parameters":[{"name":"x-cache-key","in":"header","description":"Cache entry key","allowEmptyValue":true,"required":true,"schema":{"type":"string","description":"Cache entry key","example":"did:web:example.com"},"example":"did:web:example.com"},{"name":"x-cache-namespace","in":"header","description":"Cache entry namespace","allowEmptyValue":true,"schema":{"type":"string","description":"Cache entry namespace","example":"Login"},"example":"Login"},{"name":"x-cache-scope","in":"header","description":"Cache entry scope","allowEmptyValue":true,"schema":{"type":"string","description":"Cache entry scope","example":"administration"},"example":"administration"}],"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"type":"string","example":"Rerum et qui alias qui.","format":"binary"},"example":"Accusamus ratione voluptatibus."}}}}},"post":{"tags":["cache"],"summary":"Set cache","description":"Set a JSON value in the cache.","operationId":"cache#Set","parameters":[{"name":"x-cache-key","in":"header","description":"Cache entry key","allowEmptyValue":true,"required":true,"schema":{"type":"string","description":"Cache entry key","example":"did:web:example.com"},"example":"did:web:example.com"},{"name":"x-cache-namespace","in":"header","description":"Cache entry namespace","allowEmptyValue":true,"schema":{"type":"string","description":"Cache entry namespace","example":"Login"},"example":"Login"},{"name":"x-cache-scope","in":"header","description":"Cache entry scope","allowEmptyValue":true,"schema":{"type":"string","description":"Cache entry scope","example":"administration"},"example":"administration"},{"name":"x-cache-ttl","in":"header","description":"Cache entry TTL in seconds","allowEmptyValue":true,"schema":{"type":"integer","description":"Cache entry TTL in seconds","example":60,"format":"int64"},"example":60}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"string","example":"Beatae commodi.","format":"binary"},"example":"Quae minus maiores nulla deleniti ipsa."}}},"responses":{"201":{"description":"Created response."}}}},"/v1/external/cache":{"post":{"tags":["cache"],"summary":"SetExternal cache","description":"Set an external JSON value in the cache and provide an event for the input.","operationId":"cache#SetExternal","parameters":[{"name":"x-cache-key","in":"header","description":"Cache entry key","allowEmptyValue":true,"required":true,"schema":{"type":"string","description":"Cache entry key","example":"did:web:example.com"},"example":"did:web:example.com"},{"name":"x-cache-namespace","in":"header","description":"Cache entry namespace","allowEmptyValue":true,"schema":{"type":"string","description":"Cache entry namespace","example":"Login"},"example":"Login"},{"name":"x-cache-scope","in":"header","description":"Cache entry scope","allowEmptyValue":true,"schema":{"type":"string","description":"Cache entry scope","example":"administration"},"example":"administration"},{"name":"x-cache-ttl","in":"header","description":"Cache entry TTL in seconds","allowEmptyValue":true,"schema":{"type":"integer","description":"Cache entry TTL in seconds","example":60,"format":"int64"},"example":60}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"string","example":"Fuga voluptas explicabo et libero.","format":"binary"},"example":"Quidem nihil quis tempore."}}},"responses":{"200":{"description":"OK response."}}}}},"components":{"schemas":{"HealthResponse":{"type":"object","properties":{"service":{"type":"string","description":"Service name.","example":"Illum nam ratione nisi."},"status":{"type":"string","description":"Status message.","example":"Labore vel."},"version":{"type":"string","description":"Service runtime version.","example":"Aut illum."}},"example":{"service":"Itaque vel.","status":"Itaque enim aut consequatur beatae ut.","version":"Et atque impedit nostrum perspiciatis ipsum."},"required":["service","status","version"]}}},"tags":[{"name":"cache","description":"Cache service allows storing and retrieving data from distributed cache."},{"name":"health","description":"Health service provides health check endpoints."}]}
\ No newline at end of file
+{"openapi":"3.0.3","info":{"title":"Cache Service","description":"The cache service exposes interface for working with Redis.","version":"1.0"},"servers":[{"url":"http://localhost:8083","description":"Cache Server"}],"paths":{"/liveness":{"get":{"tags":["health"],"summary":"Liveness health","operationId":"health#Liveness","responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"},"example":{"service":"Laborum reprehenderit rerum est et ut dolores.","status":"Consequatur porro qui est dolor a.","version":"Ad dolor."}}}}}}},"/readiness":{"get":{"tags":["health"],"summary":"Readiness health","operationId":"health#Readiness","responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"},"example":{"service":"Fugiat voluptatem vel et.","status":"Sint tempore est nam iusto.","version":"Ipsam quidem aut velit vitae est."}}}}}}},"/v1/cache":{"get":{"tags":["cache"],"summary":"Get cache","description":"Get JSON value from the cache.","operationId":"cache#Get","parameters":[{"name":"x-cache-key","in":"header","description":"Cache entry key","allowEmptyValue":true,"required":true,"schema":{"type":"string","description":"Cache entry key","example":"did:web:example.com"},"example":"did:web:example.com"},{"name":"x-cache-namespace","in":"header","description":"Cache entry namespace","allowEmptyValue":true,"schema":{"type":"string","description":"Cache entry namespace","example":"Login"},"example":"Login"},{"name":"x-cache-scope","in":"header","description":"Cache entry scope","allowEmptyValue":true,"schema":{"type":"string","description":"Cache entry scope","example":"administration"},"examples":{"default":{"summary":"default","value":"administration"},"multiple scopes":{"summary":"multiple scopes","value":"administration,user"}}},{"name":"x-cache-flatten-strategy","in":"header","description":"Flatten strategy.","allowEmptyValue":true,"schema":{"type":"string","description":"Flatten strategy.","example":"merge"},"examples":{"default":{"summary":"default","value":"merge"},"first key value only":{"summary":"first key value only","value":"first"},"last key value only":{"summary":"last key value only","value":"last"}}}],"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"type":"string","example":"Itaque vel.","format":"binary"},"example":"Amet atque cupiditate."}}}}},"post":{"tags":["cache"],"summary":"Set cache","description":"Set a JSON value in the cache.","operationId":"cache#Set","parameters":[{"name":"x-cache-key","in":"header","description":"Cache entry key","allowEmptyValue":true,"required":true,"schema":{"type":"string","description":"Cache entry key","example":"did:web:example.com"},"example":"did:web:example.com"},{"name":"x-cache-namespace","in":"header","description":"Cache entry namespace","allowEmptyValue":true,"schema":{"type":"string","description":"Cache entry namespace","example":"Login"},"example":"Login"},{"name":"x-cache-scope","in":"header","description":"Cache entry scope","allowEmptyValue":true,"schema":{"type":"string","description":"Cache entry scope","example":"administration"},"example":"administration"},{"name":"x-cache-ttl","in":"header","description":"Cache entry TTL in seconds","allowEmptyValue":true,"schema":{"type":"integer","description":"Cache entry TTL in seconds","example":60,"format":"int64"},"example":60}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"string","example":"Itaque enim aut consequatur beatae ut.","format":"binary"},"example":"Minus nostrum eaque."}}},"responses":{"201":{"description":"Created response."}}}},"/v1/external/cache":{"post":{"tags":["cache"],"summary":"SetExternal cache","description":"Set an external JSON value in the cache and provide an event for the input.","operationId":"cache#SetExternal","parameters":[{"name":"x-cache-key","in":"header","description":"Cache entry key","allowEmptyValue":true,"required":true,"schema":{"type":"string","description":"Cache entry key","example":"did:web:example.com"},"example":"did:web:example.com"},{"name":"x-cache-namespace","in":"header","description":"Cache entry namespace","allowEmptyValue":true,"schema":{"type":"string","description":"Cache entry namespace","example":"Login"},"example":"Login"},{"name":"x-cache-scope","in":"header","description":"Cache entry scope","allowEmptyValue":true,"schema":{"type":"string","description":"Cache entry scope","example":"administration"},"example":"administration"},{"name":"x-cache-ttl","in":"header","description":"Cache entry TTL in seconds","allowEmptyValue":true,"schema":{"type":"integer","description":"Cache entry TTL in seconds","example":60,"format":"int64"},"example":60}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"string","example":"Et atque impedit nostrum perspiciatis ipsum.","format":"binary"},"example":"Eligendi magni qui porro beatae porro."}}},"responses":{"200":{"description":"OK response."}}}}},"components":{"schemas":{"HealthResponse":{"type":"object","properties":{"service":{"type":"string","description":"Service name.","example":"Accusamus ratione voluptatibus."},"status":{"type":"string","description":"Status message.","example":"Quae minus maiores nulla deleniti ipsa."},"version":{"type":"string","description":"Service runtime version.","example":"Quidem nihil quis tempore."}},"example":{"service":"Vel quis doloremque iure eius reiciendis.","status":"Perferendis porro laborum autem dolorem aut nesciunt.","version":"Sed eius qui placeat sed."},"required":["service","status","version"]}}},"tags":[{"name":"cache","description":"Cache service allows storing and retrieving data from distributed cache."},{"name":"health","description":"Health service provides health check endpoints."}]}
\ No newline at end of file
diff --git a/gen/http/openapi3.yaml b/gen/http/openapi3.yaml
index 61ccd2d10543d218a16fb87c715c17cafe1d589b..0c90f30cff57af6c76a7c5fd2d97f938e245c63d 100644
--- a/gen/http/openapi3.yaml
+++ b/gen/http/openapi3.yaml
@@ -21,9 +21,9 @@ paths:
                             schema:
                                 $ref: '#/components/schemas/HealthResponse'
                             example:
-                                service: Molestiae minima.
-                                status: Quia dolores rem.
-                                version: Est illum.
+                                service: Laborum reprehenderit rerum est et ut dolores.
+                                status: Consequatur porro qui est dolor a.
+                                version: Ad dolor.
     /readiness:
         get:
             tags:
@@ -38,9 +38,9 @@ paths:
                             schema:
                                 $ref: '#/components/schemas/HealthResponse'
                             example:
-                                service: Repellendus quo.
-                                status: Cumque aut.
-                                version: Sit sint ipsa fugiat et id rem.
+                                service: Fugiat voluptatem vel et.
+                                status: Sint tempore est nam iusto.
+                                version: Ipsam quidem aut velit vitae est.
     /v1/cache:
         get:
             tags:
@@ -76,7 +76,31 @@ paths:
                     type: string
                     description: Cache entry scope
                     example: administration
-                  example: administration
+                  examples:
+                    default:
+                        summary: default
+                        value: administration
+                    multiple scopes:
+                        summary: multiple scopes
+                        value: administration,user
+                - name: x-cache-flatten-strategy
+                  in: header
+                  description: Flatten strategy.
+                  allowEmptyValue: true
+                  schema:
+                    type: string
+                    description: Flatten strategy.
+                    example: merge
+                  examples:
+                    default:
+                        summary: default
+                        value: merge
+                    first key value only:
+                        summary: first key value only
+                        value: first
+                    last key value only:
+                        summary: last key value only
+                        value: last
             responses:
                 "200":
                     description: OK response.
@@ -84,9 +108,9 @@ paths:
                         application/json:
                             schema:
                                 type: string
-                                example: Rerum et qui alias qui.
+                                example: Itaque vel.
                                 format: binary
-                            example: Accusamus ratione voluptatibus.
+                            example: Amet atque cupiditate.
         post:
             tags:
                 - cache
@@ -138,9 +162,9 @@ paths:
                     application/json:
                         schema:
                             type: string
-                            example: Beatae commodi.
+                            example: Itaque enim aut consequatur beatae ut.
                             format: binary
-                        example: Quae minus maiores nulla deleniti ipsa.
+                        example: Minus nostrum eaque.
             responses:
                 "201":
                     description: Created response.
@@ -196,9 +220,9 @@ paths:
                     application/json:
                         schema:
                             type: string
-                            example: Fuga voluptas explicabo et libero.
+                            example: Et atque impedit nostrum perspiciatis ipsum.
                             format: binary
-                        example: Quidem nihil quis tempore.
+                        example: Eligendi magni qui porro beatae porro.
             responses:
                 "200":
                     description: OK response.
@@ -210,19 +234,19 @@ components:
                 service:
                     type: string
                     description: Service name.
-                    example: Illum nam ratione nisi.
+                    example: Accusamus ratione voluptatibus.
                 status:
                     type: string
                     description: Status message.
-                    example: Labore vel.
+                    example: Quae minus maiores nulla deleniti ipsa.
                 version:
                     type: string
                     description: Service runtime version.
-                    example: Aut illum.
+                    example: Quidem nihil quis tempore.
             example:
-                service: Itaque vel.
-                status: Itaque enim aut consequatur beatae ut.
-                version: Et atque impedit nostrum perspiciatis ipsum.
+                service: Vel quis doloremque iure eius reiciendis.
+                status: Perferendis porro laborum autem dolorem aut nesciunt.
+                version: Sed eius qui placeat sed.
             required:
                 - service
                 - status
diff --git a/internal/service/cache/service.go b/internal/service/cache/service.go
index 9fdb01cc111e18143c9e1f968c3bdf0a1b4b9662..22de0e16543250a5a3c129c28dfa8ef4a849721e 100644
--- a/internal/service/cache/service.go
+++ b/internal/service/cache/service.go
@@ -3,6 +3,8 @@ package cache
 import (
 	"context"
 	"encoding/json"
+	"fmt"
+	"strings"
 	"time"
 
 	"go.uber.org/zap"
@@ -45,21 +47,19 @@ func (s *Service) Get(ctx context.Context, req *cache.CacheGetRequest) (interfac
 		return nil, errors.New(errors.BadRequest, "missing key")
 	}
 
-	// create key from the input fields
-	key := makeCacheKey(req.Key, req.Namespace, req.Scope)
-	data, err := s.cache.Get(ctx, key)
-	if err != nil {
-		logger.Error("error getting value from cache", zap.String("key", key), zap.Error(err))
-		if errors.Is(errors.NotFound, err) {
-			return nil, errors.New("key not found in cache", err)
-		}
-		return nil, errors.New("error getting value from cache", err)
+	var scopes []string
+	if req.Scope != nil {
+		scopes = strings.Split(*req.Scope, ",")
 	}
 
-	var decodedValue interface{}
-	if err := json.Unmarshal(data, &decodedValue); err != nil {
-		logger.Error("cannot decode json value from cache", zap.Error(err))
-		return nil, errors.New("cannot decode json value from cache", err)
+	if len(scopes) > 1 {
+		return s.getWithMultipleScopes(ctx, req, scopes)
+	}
+
+	decodedValue, err := s.get(ctx, req.Key, req.Namespace, req.Scope)
+	if err != nil {
+		logger.Error("error getting value from cache", zap.Error(err))
+		return nil, err
 	}
 
 	return decodedValue, nil
@@ -128,3 +128,112 @@ func makeCacheKey(key string, namespace, scope *string) string {
 	}
 	return k
 }
+
+func (s *Service) getWithMultipleScopes(ctx context.Context, req *cache.CacheGetRequest, scopes []string) (map[string]interface{}, error) {
+	keyValues := map[string][]interface{}{}
+	result := map[string]interface{}{}
+
+	for _, scope := range scopes {
+		scope := strings.TrimSpace(scope)
+		decodedValue, err := s.get(ctx, req.Key, req.Namespace, &scope)
+		if err != nil {
+			if errors.Is(errors.NotFound, err) {
+				s.logger.Warn(err.Error())
+				continue
+			}
+			return nil, err
+		}
+
+		switch d := decodedValue.(type) {
+		case map[string]interface{}:
+			addValue(d, keyValues)
+		case []map[string]interface{}:
+			for _, data := range d {
+				addValue(data, keyValues)
+			}
+		default:
+			s.logger.Warn("decode value is of unknown type")
+			continue
+		}
+	}
+
+	switch {
+	case req.Strategy == nil || *req.Strategy == "merge":
+		result = mergeAll(keyValues)
+
+	case *req.Strategy == "first":
+		for key, value := range keyValues {
+			result[key] = value[0]
+		}
+
+	case *req.Strategy == "last":
+		for key, value := range keyValues {
+			result[key] = value[len(value)-1]
+		}
+	}
+
+	return result, nil
+}
+
+func addValue(decodedValue map[string]interface{}, des map[string][]interface{}) {
+	for k, v := range decodedValue {
+		if dataArr, contains := des[k]; contains {
+			dataArr = append(dataArr, v)
+			des[k] = dataArr
+			continue
+		}
+
+		des[k] = []interface{}{v}
+	}
+}
+
+// mergeAll merges all values for a key if more than one value is available.
+func mergeAll(data map[string][]interface{}) map[string]interface{} {
+	result := map[string]interface{}{}
+	for key, value := range data {
+		if len(value) == 1 {
+			result[key] = value[0]
+			continue
+		}
+
+		for i, v := range value {
+			index := fmt.Sprintf("%s_%d", key, i+1)
+			result[index] = v
+		}
+	}
+	return result
+}
+
+func (s *Service) get(ctx context.Context, key string, namespace *string, scope *string) (interface{}, error) {
+	// create key from the input fields
+	cacheKey := makeCacheKey(key, namespace, scope)
+	data, err := s.cache.Get(ctx, cacheKey)
+	if err != nil {
+		if errors.Is(errors.NotFound, err) {
+			return nil, errors.New(errors.NotFound, "key not found in cache", err)
+		}
+		return nil, errors.New("error getting value from cache", err)
+	}
+
+	decodedValue, err := unmarshalCacheData(data)
+	if err != nil {
+		return nil, errors.New("cannot decode json value from cache", err)
+	}
+
+	return decodedValue, nil
+}
+
+func unmarshalCacheData(data []byte) (interface{}, error) {
+	var keyValueArray []map[string]interface{}
+	var keyValue map[string]interface{}
+
+	err := json.Unmarshal(data, &keyValue)
+	if err != nil {
+		err := json.Unmarshal(data, &keyValueArray)
+		if err != nil {
+			return nil, err
+		}
+		return keyValueArray, nil
+	}
+	return keyValue, nil
+}
diff --git a/internal/service/cache/service_test.go b/internal/service/cache/service_test.go
index 530d9bfe6e7dd5a406baf37f12bda81784a77b60..1d87d4df67a3a304000aa22bbf6a06ec21df9274 100644
--- a/internal/service/cache/service_test.go
+++ b/internal/service/cache/service_test.go
@@ -2,11 +2,13 @@ package cache_test
 
 import (
 	"context"
+	"fmt"
 	"testing"
 	"time"
 
 	"github.com/stretchr/testify/assert"
 	"go.uber.org/zap"
+	"go.uber.org/zap/zaptest/observer"
 
 	goacache "gitlab.eclipse.org/eclipse/xfsc/tsa/cache/gen/cache"
 	"gitlab.eclipse.org/eclipse/xfsc/tsa/cache/internal/service/cache"
@@ -21,14 +23,18 @@ func TestNew(t *testing.T) {
 }
 
 func TestService_Get(t *testing.T) {
+	const key1 = "key,namespace,scope"
+	const key2 = "key,namespace,scope2"
+
 	tests := []struct {
 		name  string
 		cache *cachefakes.FakeCache
 		req   *goacache.CacheGetRequest
 
-		res     interface{}
-		errkind errors.Kind
-		errtext string
+		res        interface{}
+		errkind    errors.Kind
+		errtext    string
+		loggerText string
 	}{
 		{
 			name:    "missing cache key",
@@ -96,12 +102,136 @@ func TestService_Get(t *testing.T) {
 			res:     map[string]interface{}{"test": "value"},
 			errtext: "",
 		},
+		{
+			name: "multiple scope cache return error",
+			req: &goacache.CacheGetRequest{
+				Key:       "key",
+				Namespace: ptr.String("namespace"),
+				Scope:     ptr.String("scope,scope2"),
+				Strategy:  ptr.String("last"),
+			},
+			cache: &cachefakes.FakeCache{
+				GetStub: func(ctx context.Context, key string) ([]byte, error) {
+					if key == key1 {
+						return nil, fmt.Errorf("some error")
+					}
+					return []byte(`{"test":"value2"}`), nil
+				},
+			},
+			errtext: "error getting value from cache",
+		},
+		{
+			name: "multiple scope with merge flatten strategy",
+			req: &goacache.CacheGetRequest{
+				Key:       "key",
+				Namespace: ptr.String("namespace"),
+				Scope:     ptr.String("scope,scope2"),
+				Strategy:  ptr.String("merge"),
+			},
+			cache: &cachefakes.FakeCache{
+				GetStub: func(ctx context.Context, key string) ([]byte, error) {
+					if key == key1 {
+						return []byte(`{"test":"value"}`), nil
+					}
+					return []byte(`{"test":"value2"}`), nil
+				},
+			},
+			res:     map[string]interface{}{"test_1": "value", "test_2": "value2"},
+			errtext: "",
+		},
+		{
+			name: "multiple scope with first flatten strategy",
+			req: &goacache.CacheGetRequest{
+				Key:       "key",
+				Namespace: ptr.String("namespace"),
+				Scope:     ptr.String("scope,scope2"),
+				Strategy:  ptr.String("first"),
+			},
+			cache: &cachefakes.FakeCache{
+				GetStub: func(ctx context.Context, key string) ([]byte, error) {
+					if key == key1 {
+						return []byte(`{"test":"value"}`), nil
+					}
+					return []byte(`{"test":"value2"}`), nil
+				},
+			},
+			res:     map[string]interface{}{"test": "value"},
+			errtext: "",
+		},
+		{
+			name: "multiple scope with last flatten strategy",
+			req: &goacache.CacheGetRequest{
+				Key:       "key",
+				Namespace: ptr.String("namespace"),
+				Scope:     ptr.String("scope,not_existed_scope,scope2"),
+				Strategy:  ptr.String("last"),
+			},
+			cache: &cachefakes.FakeCache{
+				GetStub: func(ctx context.Context, key string) ([]byte, error) {
+					if key == key1 {
+						return []byte(`{"test":"value"}`), nil
+					}
+					return []byte(`{"test":"value2"}`), nil
+				},
+			},
+			res:     map[string]interface{}{"test": "value2"},
+			errtext: "",
+		},
+		{
+			name: "multiple scope with last flatten strategy",
+			req: &goacache.CacheGetRequest{
+				Key:       "key",
+				Namespace: ptr.String("namespace"),
+				Scope:     ptr.String("scope,scope2"),
+				Strategy:  ptr.String("last"),
+			},
+			cache: &cachefakes.FakeCache{
+				GetStub: func(ctx context.Context, key string) ([]byte, error) {
+					if key == key1 {
+						return []byte(`{"test":"value"}`), nil
+					}
+					return []byte(`{"test":"value2"}`), nil
+				},
+			},
+			res:     map[string]interface{}{"test": "value2"},
+			errtext: "",
+		},
+		{
+			name: "multiple scope return warn if the key doesn't exist",
+			req: &goacache.CacheGetRequest{
+				Key:       "key",
+				Namespace: ptr.String("namespace"),
+				Scope:     ptr.String("scope,scope2"),
+				Strategy:  ptr.String("last"),
+			},
+			cache: &cachefakes.FakeCache{
+				GetStub: func(ctx context.Context, key string) ([]byte, error) {
+					if key == key1 {
+						return []byte(`{"test":"value"}`), nil
+					}
+					if key == key2 {
+						return []byte(`{"test":"value2"}`), nil
+					}
+					return nil, errors.New(errors.NotFound, "some error")
+				},
+			},
+			res:        map[string]interface{}{"test": "value2"},
+			loggerText: "key not found in cache",
+		},
 	}
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
-			svc := cache.New(test.cache, nil, zap.NewNop())
+			core, logs := observer.New(zap.WarnLevel)
+			logger := zap.New(core)
+
+			svc := cache.New(test.cache, nil, logger)
 			res, err := svc.Get(context.Background(), test.req)
+
+			if test.loggerText != "" && logs.Len() >= 1 {
+				assert.Contains(t, logs.All()[0].Message, test.loggerText)
+			}
+
 			if err == nil {
 				assert.Empty(t, test.errtext)
 				assert.Equal(t, test.res, res)
diff --git a/vendor/go.uber.org/zap/zaptest/observer/logged_entry.go b/vendor/go.uber.org/zap/zaptest/observer/logged_entry.go
new file mode 100644
index 0000000000000000000000000000000000000000..a4ea7ec36c1e4162f9a56e17183d78be218c4147
Binary files /dev/null and b/vendor/go.uber.org/zap/zaptest/observer/logged_entry.go differ
diff --git a/vendor/go.uber.org/zap/zaptest/observer/observer.go b/vendor/go.uber.org/zap/zaptest/observer/observer.go
new file mode 100644
index 0000000000000000000000000000000000000000..f77f1308baf29fa3699df5d3cb0eb07763f50d9b
Binary files /dev/null and b/vendor/go.uber.org/zap/zaptest/observer/observer.go differ
diff --git a/vendor/modules.txt b/vendor/modules.txt
index ffa5dce85532a46fe8dc891429ca72e3eb6cbf3f..489d9cc44ec0130d660153efea671ef669dd4f01 100644
Binary files a/vendor/modules.txt and b/vendor/modules.txt differ