diff --git a/design/design.go b/design/design.go
index abce41007ea0e4a0f318f53ea93c190092d77992..3e5bc9fd35b9fe5578ec2ef4bdff0eb9aed77d2d 100644
--- a/design/design.go
+++ b/design/design.go
@@ -21,14 +21,17 @@ var _ = Service("policy", func() {
 	Method("Evaluate", func() {
 		Description("Evaluate executes a policy with the given 'data' as input.")
 		Payload(EvaluateRequest)
-		Result(Any)
+		Result(EvaluateResult)
 		HTTP(func() {
 			POST("/policy/{group}/{policyName}/{version}/evaluation")
 			Header("evaluationID:x-evaluation-id", String, "EvaluationID allows overwriting the randomly generated evaluationID", func() {
 				Example("did:web:example.com")
 			})
 			Body("input")
-			Response(StatusOK)
+			Response(StatusOK, func() {
+				Body("result")
+				Header("ETag")
+			})
 		})
 	})
 
diff --git a/design/types.go b/design/types.go
index ca2d039047465aec00835e953f49b0b2d25adf86..c003fe04928b050c4c31cc88d99414daca1c16b7 100644
--- a/design/types.go
+++ b/design/types.go
@@ -20,7 +20,8 @@ var EvaluateRequest = Type("EvaluateRequest", func() {
 
 var EvaluateResult = Type("EvaluateResult", func() {
 	Field(1, "result", Any, "Arbitrary JSON response.")
-	Required("result")
+	Field(2, "ETag", String, "ETag contains unique identifier of the policy evaluation and can be used to later retrieve the results from Cache.")
+	Required("result", "ETag")
 })
 
 var LockRequest = Type("LockRequest", func() {
diff --git a/gen/http/cli/policy/cli.go b/gen/http/cli/policy/cli.go
index 91de667a21a728f23092a956ff5f4f5255a262b8..1a0dada69c8a50dc8e73a794608b07fbe806f37e 100644
--- a/gen/http/cli/policy/cli.go
+++ b/gen/http/cli/policy/cli.go
@@ -32,7 +32,7 @@ policy (evaluate|lock|unlock)
 // UsageExamples produces an example of a valid invocation of the CLI tool.
 func UsageExamples() string {
 	return os.Args[0] + ` health liveness` + "\n" +
-		os.Args[0] + ` policy evaluate --body "Illum ad assumenda consectetur minima voluptatibus." --group "example" --policy-name "example" --version "1.0" --evaluation-id "Ab accusamus voluptatem et est."` + "\n" +
+		os.Args[0] + ` policy evaluate --body "Id odio aperiam voluptatem molestias corrupti sunt." --group "example" --policy-name "example" --version "1.0" --evaluation-id "Et voluptates."` + "\n" +
 		""
 }
 
@@ -249,7 +249,7 @@ Evaluate executes a policy with the given 'data' as input.
     -evaluation-id STRING: 
 
 Example:
-    %[1]s policy evaluate --body "Illum ad assumenda consectetur minima voluptatibus." --group "example" --policy-name "example" --version "1.0" --evaluation-id "Ab accusamus voluptatem et est."
+    %[1]s policy evaluate --body "Id odio aperiam voluptatem molestias corrupti sunt." --group "example" --policy-name "example" --version "1.0" --evaluation-id "Et voluptates."
 `, os.Args[0])
 }
 
@@ -262,7 +262,7 @@ Lock a policy so that it cannot be evaluated.
     -version STRING: Policy version.
 
 Example:
-    %[1]s policy lock --group "Commodi vitae voluptatem." --policy-name "Similique quisquam optio." --version "Explicabo beatae quisquam officiis libero voluptatibus."
+    %[1]s policy lock --group "Explicabo beatae quisquam officiis libero voluptatibus." --policy-name "Repudiandae dolore quod." --version "Aut ut fuga quae eius minus."
 `, os.Args[0])
 }
 
@@ -275,6 +275,6 @@ Unlock a policy so it can be evaluated again.
     -version STRING: Policy version.
 
 Example:
-    %[1]s policy unlock --group "In illum est et hic." --policy-name "Deleniti non nihil dolor aut sed." --version "Incidunt unde consequatur voluptas dolorem nisi temporibus."
+    %[1]s policy unlock --group "Incidunt unde consequatur voluptas dolorem nisi temporibus." --policy-name "Omnis quasi aut consequuntur." --version "Tempore minus."
 `, os.Args[0])
 }
diff --git a/gen/http/openapi.json b/gen/http/openapi.json
index b87425d258c3be0080a5d16b598585dcfe870853..929e18c02fd206e83548d6434969bb54cd788477 100644
--- a/gen/http/openapi.json
+++ b/gen/http/openapi.json
@@ -1 +1 @@
-{"swagger":"2.0","info":{"title":"Policy Service","description":"The policy service exposes HTTP API for executing policies.","version":""},"host":"localhost:8081","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."}},"schemes":["http"]}},"/policy/{group}/{policyName}/{version}/evaluation":{"post":{"tags":["policy"],"summary":"Evaluate policy","description":"Evaluate executes a policy with the given 'data' as input.","operationId":"policy#Evaluate","parameters":[{"name":"group","in":"path","description":"Policy group.","required":true,"type":"string"},{"name":"policyName","in":"path","description":"Policy name.","required":true,"type":"string"},{"name":"version","in":"path","description":"Policy version.","required":true,"type":"string"},{"name":"x-evaluation-id","in":"header","description":"EvaluationID allows overwriting the randomly generated evaluationID","required":false,"type":"string"},{"name":"any","in":"body","description":"Input data passed to the policy execution runtime.","required":true,"schema":{"type":"string","format":"binary"}}],"responses":{"200":{"description":"OK response.","schema":{"type":"string","format":"binary"}}},"schemes":["http"]}},"/policy/{group}/{policyName}/{version}/lock":{"post":{"tags":["policy"],"summary":"Lock policy","description":"Lock a policy so that it cannot be evaluated.","operationId":"policy#Lock","parameters":[{"name":"group","in":"path","description":"Policy group.","required":true,"type":"string"},{"name":"policyName","in":"path","description":"Policy name.","required":true,"type":"string"},{"name":"version","in":"path","description":"Policy version.","required":true,"type":"string"}],"responses":{"200":{"description":"OK response."}},"schemes":["http"]},"delete":{"tags":["policy"],"summary":"Unlock policy","description":"Unlock a policy so it can be evaluated again.","operationId":"policy#Unlock","parameters":[{"name":"group","in":"path","description":"Policy group.","required":true,"type":"string"},{"name":"policyName","in":"path","description":"Policy name.","required":true,"type":"string"},{"name":"version","in":"path","description":"Policy version.","required":true,"type":"string"}],"responses":{"200":{"description":"OK response."}},"schemes":["http"]}},"/readiness":{"get":{"tags":["health"],"summary":"Readiness health","operationId":"health#Readiness","responses":{"200":{"description":"OK response."}},"schemes":["http"]}}}}
\ No newline at end of file
+{"swagger":"2.0","info":{"title":"Policy Service","description":"The policy service exposes HTTP API for executing policies.","version":""},"host":"localhost:8081","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."}},"schemes":["http"]}},"/policy/{group}/{policyName}/{version}/evaluation":{"post":{"tags":["policy"],"summary":"Evaluate policy","description":"Evaluate executes a policy with the given 'data' as input.","operationId":"policy#Evaluate","parameters":[{"name":"group","in":"path","description":"Policy group.","required":true,"type":"string"},{"name":"policyName","in":"path","description":"Policy name.","required":true,"type":"string"},{"name":"version","in":"path","description":"Policy version.","required":true,"type":"string"},{"name":"x-evaluation-id","in":"header","description":"EvaluationID allows overwriting the randomly generated evaluationID","required":false,"type":"string"},{"name":"any","in":"body","description":"Input data passed to the policy execution runtime.","required":true,"schema":{"type":"string","format":"binary"}}],"responses":{"200":{"description":"OK response.","schema":{"type":"string","format":"binary"},"headers":{"ETag":{"description":"ETag contains unique identifier of the policy evaluation and can be used to later retrieve the results from Cache.","type":"string"}}}},"schemes":["http"]}},"/policy/{group}/{policyName}/{version}/lock":{"post":{"tags":["policy"],"summary":"Lock policy","description":"Lock a policy so that it cannot be evaluated.","operationId":"policy#Lock","parameters":[{"name":"group","in":"path","description":"Policy group.","required":true,"type":"string"},{"name":"policyName","in":"path","description":"Policy name.","required":true,"type":"string"},{"name":"version","in":"path","description":"Policy version.","required":true,"type":"string"}],"responses":{"200":{"description":"OK response."}},"schemes":["http"]},"delete":{"tags":["policy"],"summary":"Unlock policy","description":"Unlock a policy so it can be evaluated again.","operationId":"policy#Unlock","parameters":[{"name":"group","in":"path","description":"Policy group.","required":true,"type":"string"},{"name":"policyName","in":"path","description":"Policy name.","required":true,"type":"string"},{"name":"version","in":"path","description":"Policy version.","required":true,"type":"string"}],"responses":{"200":{"description":"OK response."}},"schemes":["http"]}},"/readiness":{"get":{"tags":["health"],"summary":"Readiness health","operationId":"health#Readiness","responses":{"200":{"description":"OK response."}},"schemes":["http"]}}}}
\ No newline at end of file
diff --git a/gen/http/openapi.yaml b/gen/http/openapi.yaml
index 3552e210a9053c6309155fb89bafad26270d441b..4abd44f0e18a7acc6cc212b53bf305a3690d12b5 100644
--- a/gen/http/openapi.yaml
+++ b/gen/http/openapi.yaml
@@ -65,6 +65,11 @@ paths:
           schema:
             type: string
             format: binary
+          headers:
+            ETag:
+              description: ETag contains unique identifier of the policy evaluation
+                and can be used to later retrieve the results from Cache.
+              type: string
       schemes:
       - http
   /policy/{group}/{policyName}/{version}/lock:
diff --git a/gen/http/openapi3.json b/gen/http/openapi3.json
index ab7d6bd20a75a405353148b5eadf480c81cb12b1..9471ba5faaefea2d67b787a89ff07dcbc4507778 100644
--- a/gen/http/openapi3.json
+++ b/gen/http/openapi3.json
@@ -1 +1 @@
-{"openapi":"3.0.3","info":{"title":"Policy Service","description":"The policy service exposes HTTP API for executing policies.","version":"1.0"},"servers":[{"url":"http://localhost:8081","description":"Policy Server"}],"paths":{"/liveness":{"get":{"tags":["health"],"summary":"Liveness health","operationId":"health#Liveness","responses":{"200":{"description":"OK response."}}}},"/policy/{group}/{policyName}/{version}/evaluation":{"post":{"tags":["policy"],"summary":"Evaluate policy","description":"Evaluate executes a policy with the given 'data' as input.","operationId":"policy#Evaluate","parameters":[{"name":"group","in":"path","description":"Policy group.","required":true,"schema":{"type":"string","description":"Policy group.","example":"example"},"example":"example"},{"name":"policyName","in":"path","description":"Policy name.","required":true,"schema":{"type":"string","description":"Policy name.","example":"example"},"example":"example"},{"name":"version","in":"path","description":"Policy version.","required":true,"schema":{"type":"string","description":"Policy version.","example":"1.0"},"example":"1.0"},{"name":"x-evaluation-id","in":"header","description":"EvaluationID allows overwriting the randomly generated evaluationID","allowEmptyValue":true,"schema":{"type":"string","description":"EvaluationID allows overwriting the randomly generated evaluationID","example":"did:web:example.com"},"example":"did:web:example.com"}],"requestBody":{"description":"Input data passed to the policy execution runtime.","required":true,"content":{"application/json":{"schema":{"type":"string","description":"Input data passed to the policy execution runtime.","example":"Omnis quasi aut consequuntur.","format":"binary"},"example":"Quis quos qui earum velit illum."}}},"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"type":"string","example":"Tempore minus.","format":"binary"},"example":"Aliquam atque voluptatum ut dolorem."}}}}}},"/policy/{group}/{policyName}/{version}/lock":{"delete":{"tags":["policy"],"summary":"Unlock policy","description":"Unlock a policy so it can be evaluated again.","operationId":"policy#Unlock","parameters":[{"name":"group","in":"path","description":"Policy group.","required":true,"schema":{"type":"string","description":"Policy group.","example":"Sint nam voluptatem ea consequatur similique et."},"example":"Non mollitia nesciunt impedit facere."},{"name":"policyName","in":"path","description":"Policy name.","required":true,"schema":{"type":"string","description":"Policy name.","example":"Ut commodi perspiciatis corporis."},"example":"Accusamus autem sequi."},{"name":"version","in":"path","description":"Policy version.","required":true,"schema":{"type":"string","description":"Policy version.","example":"Et nulla."},"example":"In quis nesciunt autem et."}],"responses":{"200":{"description":"OK response."}}},"post":{"tags":["policy"],"summary":"Lock policy","description":"Lock a policy so that it cannot be evaluated.","operationId":"policy#Lock","parameters":[{"name":"group","in":"path","description":"Policy group.","required":true,"schema":{"type":"string","description":"Policy group.","example":"Aut facere veniam repudiandae id."},"example":"Aut minus alias."},{"name":"policyName","in":"path","description":"Policy name.","required":true,"schema":{"type":"string","description":"Policy name.","example":"At eos facilis molestias in voluptas rem."},"example":"Ab accusantium ut ut aliquid sint animi."},{"name":"version","in":"path","description":"Policy version.","required":true,"schema":{"type":"string","description":"Policy version.","example":"Dolorem cumque laborum quis nesciunt."},"example":"Aut voluptas."}],"responses":{"200":{"description":"OK response."}}}},"/readiness":{"get":{"tags":["health"],"summary":"Readiness health","operationId":"health#Readiness","responses":{"200":{"description":"OK response."}}}}},"components":{},"tags":[{"name":"health","description":"Health service provides health check endpoints."},{"name":"policy","description":"Policy Service provides evaluation of policies through Open Policy Agent."}]}
\ No newline at end of file
+{"openapi":"3.0.3","info":{"title":"Policy Service","description":"The policy service exposes HTTP API for executing policies.","version":"1.0"},"servers":[{"url":"http://localhost:8081","description":"Policy Server"}],"paths":{"/liveness":{"get":{"tags":["health"],"summary":"Liveness health","operationId":"health#Liveness","responses":{"200":{"description":"OK response."}}}},"/policy/{group}/{policyName}/{version}/evaluation":{"post":{"tags":["policy"],"summary":"Evaluate policy","description":"Evaluate executes a policy with the given 'data' as input.","operationId":"policy#Evaluate","parameters":[{"name":"group","in":"path","description":"Policy group.","required":true,"schema":{"type":"string","description":"Policy group.","example":"example"},"example":"example"},{"name":"policyName","in":"path","description":"Policy name.","required":true,"schema":{"type":"string","description":"Policy name.","example":"example"},"example":"example"},{"name":"version","in":"path","description":"Policy version.","required":true,"schema":{"type":"string","description":"Policy version.","example":"1.0"},"example":"1.0"},{"name":"x-evaluation-id","in":"header","description":"EvaluationID allows overwriting the randomly generated evaluationID","allowEmptyValue":true,"schema":{"type":"string","description":"EvaluationID allows overwriting the randomly generated evaluationID","example":"did:web:example.com"},"example":"did:web:example.com"}],"requestBody":{"description":"Input data passed to the policy execution runtime.","required":true,"content":{"application/json":{"schema":{"type":"string","description":"Input data passed to the policy execution runtime.","example":"Quis quos qui earum velit illum.","format":"binary"},"example":"Aut facere veniam repudiandae id."}}},"responses":{"200":{"description":"OK response.","headers":{"ETag":{"description":"ETag contains unique identifier of the policy evaluation and can be used to later retrieve the results from Cache.","required":true,"schema":{"type":"string","description":"ETag contains unique identifier of the policy evaluation and can be used to later retrieve the results from Cache.","example":"Aut minus alias."},"example":"At eos facilis molestias in voluptas rem."}},"content":{"application/json":{"schema":{"type":"string","description":"Arbitrary JSON response.","example":"Aliquam atque voluptatum ut dolorem.","format":"binary"},"example":"Ab accusantium ut ut aliquid sint animi."}}}}}},"/policy/{group}/{policyName}/{version}/lock":{"delete":{"tags":["policy"],"summary":"Unlock policy","description":"Unlock a policy so it can be evaluated again.","operationId":"policy#Unlock","parameters":[{"name":"group","in":"path","description":"Policy group.","required":true,"schema":{"type":"string","description":"Policy group.","example":"Et nulla."},"example":"In quis nesciunt autem et."},{"name":"policyName","in":"path","description":"Policy name.","required":true,"schema":{"type":"string","description":"Policy name.","example":"Sunt in et quia cum."},"example":"Commodi nemo fugiat id praesentium accusantium expedita."},{"name":"version","in":"path","description":"Policy version.","required":true,"schema":{"type":"string","description":"Policy version.","example":"Qui non quia."},"example":"Error maxime quasi quia non voluptatibus error."}],"responses":{"200":{"description":"OK response."}}},"post":{"tags":["policy"],"summary":"Lock policy","description":"Lock a policy so that it cannot be evaluated.","operationId":"policy#Lock","parameters":[{"name":"group","in":"path","description":"Policy group.","required":true,"schema":{"type":"string","description":"Policy group.","example":"Dolorem cumque laborum quis nesciunt."},"example":"Aut voluptas."},{"name":"policyName","in":"path","description":"Policy name.","required":true,"schema":{"type":"string","description":"Policy name.","example":"Sint nam voluptatem ea consequatur similique et."},"example":"Non mollitia nesciunt impedit facere."},{"name":"version","in":"path","description":"Policy version.","required":true,"schema":{"type":"string","description":"Policy version.","example":"Ut commodi perspiciatis corporis."},"example":"Accusamus autem sequi."}],"responses":{"200":{"description":"OK response."}}}},"/readiness":{"get":{"tags":["health"],"summary":"Readiness health","operationId":"health#Readiness","responses":{"200":{"description":"OK response."}}}}},"components":{},"tags":[{"name":"health","description":"Health service provides health check endpoints."},{"name":"policy","description":"Policy Service provides evaluation of policies through Open Policy Agent."}]}
\ No newline at end of file
diff --git a/gen/http/openapi3.yaml b/gen/http/openapi3.yaml
index db303ce37efc518726e4239ffdc17e45c41e86ac..843953c8f1c2ebd994eb1769f66cb5417e58fcc8 100644
--- a/gen/http/openapi3.yaml
+++ b/gen/http/openapi3.yaml
@@ -68,19 +68,31 @@ paths:
             schema:
               type: string
               description: Input data passed to the policy execution runtime.
-              example: Omnis quasi aut consequuntur.
+              example: Quis quos qui earum velit illum.
               format: binary
-            example: Quis quos qui earum velit illum.
+            example: Aut facere veniam repudiandae id.
       responses:
         "200":
           description: OK response.
+          headers:
+            ETag:
+              description: ETag contains unique identifier of the policy evaluation
+                and can be used to later retrieve the results from Cache.
+              required: true
+              schema:
+                type: string
+                description: ETag contains unique identifier of the policy evaluation
+                  and can be used to later retrieve the results from Cache.
+                example: Aut minus alias.
+              example: At eos facilis molestias in voluptas rem.
           content:
             application/json:
               schema:
                 type: string
-                example: Tempore minus.
+                description: Arbitrary JSON response.
+                example: Aliquam atque voluptatum ut dolorem.
                 format: binary
-              example: Aliquam atque voluptatum ut dolorem.
+              example: Ab accusantium ut ut aliquid sint animi.
   /policy/{group}/{policyName}/{version}/lock:
     delete:
       tags:
@@ -96,8 +108,8 @@ paths:
         schema:
           type: string
           description: Policy group.
-          example: Sint nam voluptatem ea consequatur similique et.
-        example: Non mollitia nesciunt impedit facere.
+          example: Et nulla.
+        example: In quis nesciunt autem et.
       - name: policyName
         in: path
         description: Policy name.
@@ -105,8 +117,8 @@ paths:
         schema:
           type: string
           description: Policy name.
-          example: Ut commodi perspiciatis corporis.
-        example: Accusamus autem sequi.
+          example: Sunt in et quia cum.
+        example: Commodi nemo fugiat id praesentium accusantium expedita.
       - name: version
         in: path
         description: Policy version.
@@ -114,8 +126,8 @@ paths:
         schema:
           type: string
           description: Policy version.
-          example: Et nulla.
-        example: In quis nesciunt autem et.
+          example: Qui non quia.
+        example: Error maxime quasi quia non voluptatibus error.
       responses:
         "200":
           description: OK response.
@@ -133,8 +145,8 @@ paths:
         schema:
           type: string
           description: Policy group.
-          example: Aut facere veniam repudiandae id.
-        example: Aut minus alias.
+          example: Dolorem cumque laborum quis nesciunt.
+        example: Aut voluptas.
       - name: policyName
         in: path
         description: Policy name.
@@ -142,8 +154,8 @@ paths:
         schema:
           type: string
           description: Policy name.
-          example: At eos facilis molestias in voluptas rem.
-        example: Ab accusantium ut ut aliquid sint animi.
+          example: Sint nam voluptatem ea consequatur similique et.
+        example: Non mollitia nesciunt impedit facere.
       - name: version
         in: path
         description: Policy version.
@@ -151,8 +163,8 @@ paths:
         schema:
           type: string
           description: Policy version.
-          example: Dolorem cumque laborum quis nesciunt.
-        example: Aut voluptas.
+          example: Ut commodi perspiciatis corporis.
+        example: Accusamus autem sequi.
       responses:
         "200":
           description: OK response.
diff --git a/gen/http/policy/client/cli.go b/gen/http/policy/client/cli.go
index 0f885b7a30e6878583c5f23773188cc47a17405b..8f66c95bada522cb67328bec3978efbae30f07ca 100644
--- a/gen/http/policy/client/cli.go
+++ b/gen/http/policy/client/cli.go
@@ -22,7 +22,7 @@ func BuildEvaluatePayload(policyEvaluateBody string, policyEvaluateGroup string,
 	{
 		err = json.Unmarshal([]byte(policyEvaluateBody), &body)
 		if err != nil {
-			return nil, fmt.Errorf("invalid JSON for body, \nerror: %s, \nexample of valid JSON:\n%s", err, "\"Illum ad assumenda consectetur minima voluptatibus.\"")
+			return nil, fmt.Errorf("invalid JSON for body, \nerror: %s, \nexample of valid JSON:\n%s", err, "\"Id odio aperiam voluptatem molestias corrupti sunt.\"")
 		}
 	}
 	var group string
diff --git a/gen/http/policy/client/encode_decode.go b/gen/http/policy/client/encode_decode.go
index 309e2fd62787e93acf767008b248386215d26901..5f2cca5429dbde1f3d823d2f5b96d95dab33c7c4 100644
--- a/gen/http/policy/client/encode_decode.go
+++ b/gen/http/policy/client/encode_decode.go
@@ -16,6 +16,7 @@ import (
 
 	policy "code.vereign.com/gaiax/tsa/policy/gen/policy"
 	goahttp "goa.design/goa/v3/http"
+	goa "goa.design/goa/v3/pkg"
 )
 
 // BuildEvaluateRequest instantiates a HTTP request object with method and path
@@ -94,7 +95,19 @@ func DecodeEvaluateResponse(decoder func(*http.Response) goahttp.Decoder, restor
 			if err != nil {
 				return nil, goahttp.ErrDecodingError("policy", "Evaluate", err)
 			}
-			return body, nil
+			var (
+				eTag string
+			)
+			eTagRaw := resp.Header.Get("Etag")
+			if eTagRaw == "" {
+				err = goa.MergeErrors(err, goa.MissingFieldError("ETag", "header"))
+			}
+			eTag = eTagRaw
+			if err != nil {
+				return nil, goahttp.ErrValidationError("policy", "Evaluate", err)
+			}
+			res := NewEvaluateResultOK(body, eTag)
+			return res, nil
 		default:
 			body, _ := ioutil.ReadAll(resp.Body)
 			return nil, goahttp.ErrInvalidResponse("policy", "Evaluate", resp.StatusCode, string(body))
diff --git a/gen/http/policy/client/types.go b/gen/http/policy/client/types.go
index 770fa2c41568d70efaee163ca48d02f4cdfe910b..56bdc28cd9abc17145f6ce1d11d7481b939f97ad 100644
--- a/gen/http/policy/client/types.go
+++ b/gen/http/policy/client/types.go
@@ -6,3 +6,19 @@
 // $ goa gen code.vereign.com/gaiax/tsa/policy/design
 
 package client
+
+import (
+	policy "code.vereign.com/gaiax/tsa/policy/gen/policy"
+)
+
+// NewEvaluateResultOK builds a "policy" service "Evaluate" endpoint result
+// from a HTTP "OK" response.
+func NewEvaluateResultOK(body interface{}, eTag string) *policy.EvaluateResult {
+	v := body
+	res := &policy.EvaluateResult{
+		Result: v,
+	}
+	res.ETag = eTag
+
+	return res
+}
diff --git a/gen/http/policy/server/encode_decode.go b/gen/http/policy/server/encode_decode.go
index 3bb6113290c5725c435938692e6489b635e2955b..6b7ffabff8b3a70474a43562fbc9850805f3cd95 100644
--- a/gen/http/policy/server/encode_decode.go
+++ b/gen/http/policy/server/encode_decode.go
@@ -12,6 +12,7 @@ import (
 	"io"
 	"net/http"
 
+	policy "code.vereign.com/gaiax/tsa/policy/gen/policy"
 	goahttp "goa.design/goa/v3/http"
 	goa "goa.design/goa/v3/pkg"
 )
@@ -20,9 +21,10 @@ import (
 // policy Evaluate endpoint.
 func EncodeEvaluateResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, interface{}) error {
 	return func(ctx context.Context, w http.ResponseWriter, v interface{}) error {
-		res, _ := v.(interface{})
+		res, _ := v.(*policy.EvaluateResult)
 		enc := encoder(ctx, w)
-		body := res
+		body := res.Result
+		w.Header().Set("Etag", res.ETag)
 		w.WriteHeader(http.StatusOK)
 		return enc.Encode(body)
 	}
diff --git a/gen/policy/client.go b/gen/policy/client.go
index 4543ff51214d584abfe8a3ecaee9d5284cc7b876..554aa783b90015e0836f32342226c7507fc7d3d3 100644
--- a/gen/policy/client.go
+++ b/gen/policy/client.go
@@ -30,13 +30,13 @@ func NewClient(evaluate, lock, unlock goa.Endpoint) *Client {
 }
 
 // Evaluate calls the "Evaluate" endpoint of the "policy" service.
-func (c *Client) Evaluate(ctx context.Context, p *EvaluateRequest) (res interface{}, err error) {
+func (c *Client) Evaluate(ctx context.Context, p *EvaluateRequest) (res *EvaluateResult, err error) {
 	var ires interface{}
 	ires, err = c.EvaluateEndpoint(ctx, p)
 	if err != nil {
 		return
 	}
-	return ires.(interface{}), nil
+	return ires.(*EvaluateResult), nil
 }
 
 // Lock calls the "Lock" endpoint of the "policy" service.
diff --git a/gen/policy/service.go b/gen/policy/service.go
index 4abb1bcdcde12ad0b54ddfbc412308a536c131f4..11c7536b0ad4399f3526678b18e5aa451befa31e 100644
--- a/gen/policy/service.go
+++ b/gen/policy/service.go
@@ -14,7 +14,7 @@ import (
 // Policy Service provides evaluation of policies through Open Policy Agent.
 type Service interface {
 	// Evaluate executes a policy with the given 'data' as input.
-	Evaluate(context.Context, *EvaluateRequest) (res interface{}, err error)
+	Evaluate(context.Context, *EvaluateRequest) (res *EvaluateResult, err error)
 	// Lock a policy so that it cannot be evaluated.
 	Lock(context.Context, *LockRequest) (err error)
 	// Unlock a policy so it can be evaluated again.
@@ -46,6 +46,15 @@ type EvaluateRequest struct {
 	EvaluationID *string
 }
 
+// EvaluateResult is the result type of the policy service Evaluate method.
+type EvaluateResult struct {
+	// Arbitrary JSON response.
+	Result interface{}
+	// ETag contains unique identifier of the policy evaluation and can be used to
+	// later retrieve the results from Cache.
+	ETag string
+}
+
 // LockRequest is the payload type of the policy service Lock method.
 type LockRequest struct {
 	// Policy group.
diff --git a/internal/service/policy/service.go b/internal/service/policy/service.go
index 605722b503e732b0e9829470ec00b8951991719a..7d90e62b2e00023ac1f95d9b934cf8f6036a276c 100644
--- a/internal/service/policy/service.go
+++ b/internal/service/policy/service.go
@@ -59,7 +59,7 @@ func New(storage Storage, queryCache RegoCache, cache Cache, logger *zap.Logger)
 // Evaluating the URL: `.../policies/mygroup/example/1.0/evaluation` will
 // return results correctly, only if the package declaration inside the policy is:
 // `package mygroup.example`.
-func (s *Service) Evaluate(ctx context.Context, req *policy.EvaluateRequest) (interface{}, error) {
+func (s *Service) Evaluate(ctx context.Context, req *policy.EvaluateRequest) (*policy.EvaluateResult, error) {
 	var evaluationID string
 	if req.EvaluationID != nil && *req.EvaluationID != "" {
 		evaluationID = *req.EvaluationID
@@ -107,12 +107,24 @@ func (s *Service) Evaluate(ctx context.Context, req *policy.EvaluateRequest) (in
 		return nil, errors.New("error storing policy result in cache")
 	}
 
-	result := map[string]interface{}{
-		"evaluationID": evaluationID,
-		"result":       resultSet[0].Expressions[0].Value,
+	// If there is only a single result from the policy evaluation and it was assigned to an empty
+	// variable, then we'll return a custom response containing only the value of the empty variable
+	// without any mapping.
+	result := resultSet[0].Expressions[0].Value
+	if resultMap, ok := result.(map[string]interface{}); ok {
+		if len(resultMap) == 1 {
+			for k, v := range resultMap {
+				if k == "$0" {
+					result = v
+				}
+			}
+		}
 	}
 
-	return result, nil
+	return &policy.EvaluateResult{
+		Result: result,
+		ETag:   evaluationID,
+	}, nil
 }
 
 // Lock a policy so that it cannot be evaluated.
diff --git a/internal/service/policy/service_test.go b/internal/service/policy/service_test.go
index 69c25d3c5694e39221706fcf5c08b4fed7b01ea3..ca5b4db7214c4c49889228c4804e6803fbffce15 100644
--- a/internal/service/policy/service_test.go
+++ b/internal/service/policy/service_test.go
@@ -23,12 +23,17 @@ func TestNew(t *testing.T) {
 
 func TestService_Evaluate(t *testing.T) {
 	// prepare test policy source code that will be evaluated
-	testPolicy := `package testgroup.example allow { input.msg == "yes" }`
+	testPolicy := `package testgroup.example default allow = false allow { input.msg == "yes" }`
+
+	// prepare test policy source code for the case when policy result must contain only the
+	// value of a blank variable assignment
+	testPolicyBlankAssignment := `package testgroup.example _ = {"hello":"world"}`
 
 	// prepare test query that can be retrieved from rego queryCache
 	testQuery, err := rego.New(
 		rego.Module("example.rego", testPolicy),
 		rego.Query("data.testgroup.example"),
+		rego.StrictBuiltinErrors(true),
 	).PrepareForEval(context.Background())
 	assert.NoError(t, err)
 
@@ -50,7 +55,7 @@ func TestService_Evaluate(t *testing.T) {
 		regocache policy.RegoCache
 		cache     policy.Cache
 		// expected result
-		res     interface{}
+		res     *goapolicy.EvaluateResult
 		errkind errors.Kind
 		errtext string
 	}{
@@ -68,7 +73,9 @@ func TestService_Evaluate(t *testing.T) {
 					return nil
 				},
 			},
-			res: map[string]interface{}{"allow": true},
+			res: &goapolicy.EvaluateResult{
+				Result: map[string]interface{}{"allow": true},
+			},
 		},
 		{
 			name: "policy is not found",
@@ -146,7 +153,9 @@ func TestService_Evaluate(t *testing.T) {
 					return nil
 				},
 			},
-			res: map[string]interface{}{"allow": true},
+			res: &goapolicy.EvaluateResult{
+				Result: map[string]interface{}{"allow": true},
+			},
 		},
 		{
 			name: "policy is executed successfully, but storing the result in cache fails",
@@ -176,6 +185,35 @@ func TestService_Evaluate(t *testing.T) {
 			errkind: errors.Unknown,
 			errtext: "error storing policy result in cache",
 		},
+		{
+			name: "policy with blank variable assignment is evaluated successfully",
+			req:  testReq(),
+			regocache: &policyfakes.FakeRegoCache{
+				GetStub: func(key string) (*rego.PreparedEvalQuery, bool) {
+					return nil, false
+				},
+			},
+			storage: &policyfakes.FakeStorage{
+				PolicyStub: func(ctx context.Context, s string, s2 string, s3 string) (*storage.Policy, error) {
+					return &storage.Policy{
+						Name:       "example",
+						Group:      "testgroup",
+						Version:    "1.0",
+						Rego:       testPolicyBlankAssignment,
+						Locked:     false,
+						LastUpdate: time.Now(),
+					}, nil
+				},
+			},
+			cache: &policyfakes.FakeCache{
+				SetStub: func(ctx context.Context, s string, s2 string, s3 string, bytes []byte) error {
+					return nil
+				},
+			},
+			res: &goapolicy.EvaluateResult{
+				Result: map[string]interface{}{"hello": "world"},
+			},
+		},
 	}
 
 	for _, test := range tests {
@@ -186,10 +224,8 @@ func TestService_Evaluate(t *testing.T) {
 				assert.Empty(t, test.errtext)
 				assert.NotNil(t, res)
 
-				result, ok := res.(map[string]interface{})
-				assert.True(t, ok)
-				assert.Equal(t, test.res, result["result"])
-				assert.NotEmpty(t, result["evaluationID"])
+				assert.Equal(t, test.res.Result, res.Result)
+				assert.NotEmpty(t, res.ETag)
 			} else {
 				e, ok := err.(*errors.Error)
 				assert.True(t, ok)