diff --git a/cmd/policy/main.go b/cmd/policy/main.go
index cd489f786f0bdd81dd3ecdfbaf5fb3cbdb36fae3..cc3e4e16e33642ce8e15ffe44dcf6e3bbfa54962 100644
--- a/cmd/policy/main.go
+++ b/cmd/policy/main.go
@@ -107,7 +107,7 @@ func main() {
 	}
 
 	// create policy changes notifier
-	notifier := notify.New(events, httpClient, storage, logger)
+	notifier := notify.New(events, storage, httpClient, logger)
 
 	// subscribe the cache for policy data changes
 	storage.AddPolicyChangeSubscribers(regocache, notifier)
diff --git a/design/design.go b/design/design.go
index 971fdbf748bdffdcef01d051eb75384ead902fd5..fc540a8c99ff58bdf281611440624c1147a8dc94 100644
--- a/design/design.go
+++ b/design/design.go
@@ -78,9 +78,9 @@ var _ = Service("policy", func() {
 		})
 	})
 
-	Method("Webhooks", func() {
-		Description("Gives ability to user to subscribe for policy change via webhooks")
-		Payload(WebhooksRequest)
+	Method("SubscribeForPolicyChange", func() {
+		Description("Subscribe for policy change notifications by registering webhook callbacks which the policy service will call.")
+		Payload(SubscribeRequest)
 		Result(Any)
 		HTTP(func() {
 			POST("/policy/{group}/{policyname}/{version}/notifychange")
diff --git a/design/types.go b/design/types.go
index 8d47f542be96ae79d1d56eb091387e65bdd3ae77..c02856228bd56741cfcb4e1d17d17fe96a2246c1 100644
--- a/design/types.go
+++ b/design/types.go
@@ -65,11 +65,16 @@ var PoliciesResult = Type("PoliciesResult", func() {
 	Required("policies")
 })
 
-var WebhooksRequest = Type("WebHooksRequest", func() {
-	Field(1, "webhook_url", String, "Subscriber webhook url.")
-	Field(2, "subscriber", String, "Name of the subscriber for policy.")
+var SubscribeRequest = Type("WebHooksRequest", func() {
+	Field(1, "webhook_url", String, "Subscriber webhook url.", func() {
+		Format(FormatURI)
+	})
+	Field(2, "subscriber", String, "Name of the subscriber for policy.", func() {
+		MinLength(3)
+		MaxLength(100)
+	})
 	Field(3, "policyname", String, "Policy name.")
 	Field(4, "group", String, "Policy group.")
 	Field(5, "version", String, "Policy version.")
-	Required("webhook_url", "subscriber", "group", "policyname", "version")
+	Required("webhook_url", "subscriber", "policyname", "group", "version")
 })
diff --git a/gen/http/cli/policy/cli.go b/gen/http/cli/policy/cli.go
index 0ef0f3fe48e6c1275204613abd12a128c2eeed76..2a50902b75f8c53b881500bfadbb1b50b74645fb 100644
--- a/gen/http/cli/policy/cli.go
+++ b/gen/http/cli/policy/cli.go
@@ -24,14 +24,14 @@ import (
 //	command (subcommand1|subcommand2|...)
 func UsageCommands() string {
 	return `health (liveness|readiness)
-policy (evaluate|lock|unlock|list-policies|webhooks)
+policy (evaluate|lock|unlock|list-policies|subscribe-for-policy-change)
 `
 }
 
 // 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 "Earum velit illum quia aliquam atque voluptatum." --group "example" --policy-name "example" --version "1.0" --evaluation-id "Omnis quasi aut consequuntur." --ttl 2830259876533307070` + "\n" +
+		os.Args[0] + ` policy evaluate --body "Voluptas dolorem cumque laborum." --group "example" --policy-name "example" --version "1.0" --evaluation-id "At eos facilis molestias in voluptas rem." --ttl 6456224539272509278` + "\n" +
 		""
 }
 
@@ -77,11 +77,11 @@ func ParseEndpoint(
 		policyListPoliciesDataFlag       = policyListPoliciesFlags.String("data", "", "")
 		policyListPoliciesDataConfigFlag = policyListPoliciesFlags.String("data-config", "", "")
 
-		policyWebhooksFlags          = flag.NewFlagSet("webhooks", flag.ExitOnError)
-		policyWebhooksBodyFlag       = policyWebhooksFlags.String("body", "REQUIRED", "")
-		policyWebhooksGroupFlag      = policyWebhooksFlags.String("group", "REQUIRED", "Policy group.")
-		policyWebhooksPolicynameFlag = policyWebhooksFlags.String("policyname", "REQUIRED", "Policy name.")
-		policyWebhooksVersionFlag    = policyWebhooksFlags.String("version", "REQUIRED", "Policy version.")
+		policySubscribeForPolicyChangeFlags          = flag.NewFlagSet("subscribe-for-policy-change", flag.ExitOnError)
+		policySubscribeForPolicyChangeBodyFlag       = policySubscribeForPolicyChangeFlags.String("body", "REQUIRED", "")
+		policySubscribeForPolicyChangeGroupFlag      = policySubscribeForPolicyChangeFlags.String("group", "REQUIRED", "Policy group.")
+		policySubscribeForPolicyChangePolicynameFlag = policySubscribeForPolicyChangeFlags.String("policyname", "REQUIRED", "Policy name.")
+		policySubscribeForPolicyChangeVersionFlag    = policySubscribeForPolicyChangeFlags.String("version", "REQUIRED", "Policy version.")
 	)
 	healthFlags.Usage = healthUsage
 	healthLivenessFlags.Usage = healthLivenessUsage
@@ -92,7 +92,7 @@ func ParseEndpoint(
 	policyLockFlags.Usage = policyLockUsage
 	policyUnlockFlags.Usage = policyUnlockUsage
 	policyListPoliciesFlags.Usage = policyListPoliciesUsage
-	policyWebhooksFlags.Usage = policyWebhooksUsage
+	policySubscribeForPolicyChangeFlags.Usage = policySubscribeForPolicyChangeUsage
 
 	if err := flag.CommandLine.Parse(os.Args[1:]); err != nil {
 		return nil, nil, err
@@ -152,8 +152,8 @@ func ParseEndpoint(
 			case "list-policies":
 				epf = policyListPoliciesFlags
 
-			case "webhooks":
-				epf = policyWebhooksFlags
+			case "subscribe-for-policy-change":
+				epf = policySubscribeForPolicyChangeFlags
 
 			}
 
@@ -202,9 +202,9 @@ func ParseEndpoint(
 			case "list-policies":
 				endpoint = c.ListPolicies()
 				data, err = policyc.BuildListPoliciesPayload(*policyListPoliciesLockedFlag, *policyListPoliciesRegoFlag, *policyListPoliciesDataFlag, *policyListPoliciesDataConfigFlag)
-			case "webhooks":
-				endpoint = c.Webhooks()
-				data, err = policyc.BuildWebhooksPayload(*policyWebhooksBodyFlag, *policyWebhooksGroupFlag, *policyWebhooksPolicynameFlag, *policyWebhooksVersionFlag)
+			case "subscribe-for-policy-change":
+				endpoint = c.SubscribeForPolicyChange()
+				data, err = policyc.BuildSubscribeForPolicyChangePayload(*policySubscribeForPolicyChangeBodyFlag, *policySubscribeForPolicyChangeGroupFlag, *policySubscribeForPolicyChangePolicynameFlag, *policySubscribeForPolicyChangeVersionFlag)
 			}
 		}
 	}
@@ -260,7 +260,7 @@ COMMAND:
     lock: Lock a policy so that it cannot be evaluated.
     unlock: Unlock a policy so it can be evaluated again.
     list-policies: List policies from storage with optional filters.
-    webhooks: Gives ability to user to subscribe for policy change via webhooks
+    subscribe-for-policy-change: Subscribe for policy change notifications by registering webhook callbacks which the policy service will call.
 
 Additional help:
     %[1]s policy COMMAND --help
@@ -278,7 +278,7 @@ Evaluate executes a policy with the given 'data' as input.
     -ttl INT: 
 
 Example:
-    %[1]s policy evaluate --body "Earum velit illum quia aliquam atque voluptatum." --group "example" --policy-name "example" --version "1.0" --evaluation-id "Omnis quasi aut consequuntur." --ttl 2830259876533307070
+    %[1]s policy evaluate --body "Voluptas dolorem cumque laborum." --group "example" --policy-name "example" --version "1.0" --evaluation-id "At eos facilis molestias in voluptas rem." --ttl 6456224539272509278
 `, os.Args[0])
 }
 
@@ -291,7 +291,7 @@ Lock a policy so that it cannot be evaluated.
     -version STRING: Policy version.
 
 Example:
-    %[1]s policy lock --group "Aut voluptas." --policy-name "Sint nam voluptatem ea consequatur similique et." --version "Non mollitia nesciunt impedit facere."
+    %[1]s policy lock --group "Sunt in et quia cum." --policy-name "Commodi nemo fugiat id praesentium accusantium expedita." --version "Qui non quia."
 `, os.Args[0])
 }
 
@@ -304,7 +304,7 @@ Unlock a policy so it can be evaluated again.
     -version STRING: Policy version.
 
 Example:
-    %[1]s policy unlock --group "In quis nesciunt autem et." --policy-name "Sunt in et quia cum." --version "Commodi nemo fugiat id praesentium accusantium expedita."
+    %[1]s policy unlock --group "Ut amet." --policy-name "Accusamus enim." --version "Recusandae est rerum corrupti quia."
 `, os.Args[0])
 }
 
@@ -318,23 +318,23 @@ List policies from storage with optional filters.
     -data-config BOOL: 
 
 Example:
-    %[1]s policy list-policies --locked false --rego true --data false --data-config true
+    %[1]s policy list-policies --locked true --rego true --data false --data-config false
 `, os.Args[0])
 }
 
-func policyWebhooksUsage() {
-	fmt.Fprintf(os.Stderr, `%[1]s [flags] policy webhooks -body JSON -group STRING -policyname STRING -version STRING
+func policySubscribeForPolicyChangeUsage() {
+	fmt.Fprintf(os.Stderr, `%[1]s [flags] policy subscribe-for-policy-change -body JSON -group STRING -policyname STRING -version STRING
 
-Gives ability to user to subscribe for policy change via webhooks
+Subscribe for policy change notifications by registering webhook callbacks which the policy service will call.
     -body JSON: 
     -group STRING: Policy group.
     -policyname STRING: Policy name.
     -version STRING: Policy version.
 
 Example:
-    %[1]s policy webhooks --body '{
-      "subscriber": "Est totam officia necessitatibus tempore.",
-      "webhook_url": "Ad ab perspiciatis voluptatem pariatur corporis est."
-   }' --group "Animi consequuntur consequatur vel rerum." --policyname "Ipsam nam." --version "Vitae dolores quas et aperiam dolores reiciendis."
+    %[1]s policy subscribe-for-policy-change --body '{
+      "subscriber": "iyv",
+      "webhook_url": "http://boehmohara.org/estelle_kuhic"
+   }' --group "Sunt dolorem ea architecto iure est." --policyname "Architecto id." --version "Ut est ut molestias sint ipsam."
 `, os.Args[0])
 }
diff --git a/gen/http/openapi.json b/gen/http/openapi.json
index f8384375ce127787df963daa5ec7895db7726367..c80676fa92cb2817b2ab438b8327be2691b6df2c 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":{"get":{"tags":["policy"],"summary":"Evaluate policy","description":"Evaluate executes a policy with the given 'data' as input.","operationId":"policy#Evaluate#1","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":"x-cache-ttl","in":"header","description":"Policy result cache TTL in seconds","required":false,"type":"integer"},{"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"]},"post":{"tags":["policy"],"summary":"Evaluate policy","description":"Evaluate executes a policy with the given 'data' as input.","operationId":"policy#Evaluate#2","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":"x-cache-ttl","in":"header","description":"Policy result cache TTL in seconds","required":false,"type":"integer"},{"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}/evaluation/did.json":{"get":{"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":"x-cache-ttl","in":"header","description":"Policy result cache TTL in seconds","required":false,"type":"integer"},{"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"]}},"/policy/{group}/{policyname}/{version}/notifychange":{"post":{"tags":["policy"],"summary":"Webhooks policy","description":"Gives ability to user to subscribe for policy change via webhooks","operationId":"policy#Webhooks","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":"WebhooksRequestBody","in":"body","required":true,"schema":{"$ref":"#/definitions/PolicyWebhooksRequestBody","required":["webhook_url","subscriber"]}}],"responses":{"200":{"description":"OK response.","schema":{"type":"string","format":"binary"}}},"schemes":["http"]}},"/readiness":{"get":{"tags":["health"],"summary":"Readiness health","operationId":"health#Readiness","responses":{"200":{"description":"OK response."}},"schemes":["http"]}},"/v1/policies":{"get":{"tags":["policy"],"summary":"ListPolicies policy","description":"List policies from storage with optional filters.","operationId":"policy#ListPolicies","parameters":[{"name":"locked","in":"query","description":"Filter to return locked/unlocked policies (optional).","required":false,"type":"boolean"},{"name":"rego","in":"query","description":"Include policy source code in results (optional).","required":false,"type":"boolean"},{"name":"data","in":"query","description":"Include policy static data in results (optional). ","required":false,"type":"boolean"},{"name":"dataConfig","in":"query","description":"Include static data config (optional).","required":false,"type":"boolean"}],"responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/PolicyListPoliciesResponseBody","required":["policies"]}}},"schemes":["http"]}}},"definitions":{"PolicyListPoliciesResponseBody":{"title":"PolicyListPoliciesResponseBody","type":"object","properties":{"policies":{"type":"array","items":{"$ref":"#/definitions/PolicyResponseBody"},"description":"JSON array of policies.","example":[{"data":"Accusamus enim.","dataConfig":"Recusandae est rerum corrupti quia.","group":"Optio quia et laborum.","lastUpdate":1029654258457164464,"locked":true,"policyName":"Error maxime quasi quia non voluptatibus error.","rego":"Ut amet.","version":"In libero perspiciatis voluptatum ut soluta."},{"data":"Accusamus enim.","dataConfig":"Recusandae est rerum corrupti quia.","group":"Optio quia et laborum.","lastUpdate":1029654258457164464,"locked":true,"policyName":"Error maxime quasi quia non voluptatibus error.","rego":"Ut amet.","version":"In libero perspiciatis voluptatum ut soluta."},{"data":"Accusamus enim.","dataConfig":"Recusandae est rerum corrupti quia.","group":"Optio quia et laborum.","lastUpdate":1029654258457164464,"locked":true,"policyName":"Error maxime quasi quia non voluptatibus error.","rego":"Ut amet.","version":"In libero perspiciatis voluptatum ut soluta."}]}},"example":{"policies":[{"data":"Accusamus enim.","dataConfig":"Recusandae est rerum corrupti quia.","group":"Optio quia et laborum.","lastUpdate":1029654258457164464,"locked":true,"policyName":"Error maxime quasi quia non voluptatibus error.","rego":"Ut amet.","version":"In libero perspiciatis voluptatum ut soluta."},{"data":"Accusamus enim.","dataConfig":"Recusandae est rerum corrupti quia.","group":"Optio quia et laborum.","lastUpdate":1029654258457164464,"locked":true,"policyName":"Error maxime quasi quia non voluptatibus error.","rego":"Ut amet.","version":"In libero perspiciatis voluptatum ut soluta."},{"data":"Accusamus enim.","dataConfig":"Recusandae est rerum corrupti quia.","group":"Optio quia et laborum.","lastUpdate":1029654258457164464,"locked":true,"policyName":"Error maxime quasi quia non voluptatibus error.","rego":"Ut amet.","version":"In libero perspiciatis voluptatum ut soluta."},{"data":"Accusamus enim.","dataConfig":"Recusandae est rerum corrupti quia.","group":"Optio quia et laborum.","lastUpdate":1029654258457164464,"locked":true,"policyName":"Error maxime quasi quia non voluptatibus error.","rego":"Ut amet.","version":"In libero perspiciatis voluptatum ut soluta."}]},"required":["policies"]},"PolicyResponseBody":{"title":"PolicyResponseBody","type":"object","properties":{"data":{"type":"string","description":"Policy static data.","example":"Ipsa ad voluptatum maxime ut."},"dataConfig":{"type":"string","description":"Policy static data optional configuration.","example":"Aut asperiores."},"group":{"type":"string","description":"Policy group.","example":"Veritatis quam qui nostrum eaque."},"lastUpdate":{"type":"integer","description":"Last update (Unix timestamp).","example":1131015782715696616,"format":"int64"},"locked":{"type":"boolean","description":"Locked specifies if the policy is locked or allowed to execute.","example":false},"policyName":{"type":"string","description":"Policy name.","example":"Maiores et minus."},"rego":{"type":"string","description":"Policy rego source code.","example":"Delectus rerum molestiae possimus cum laboriosam."},"version":{"type":"string","description":"Policy version.","example":"Et dolores."}},"example":{"data":"Similique architecto.","dataConfig":"Sunt ut est ut molestias.","group":"Error minus vel voluptate quasi.","lastUpdate":2308837710267791288,"locked":true,"policyName":"Omnis molestiae tempora sed repellendus.","rego":"Vel sunt dolorem ea architecto iure.","version":"Debitis consectetur."},"required":["group","policyName","version","locked","lastUpdate"]},"PolicyWebhooksRequestBody":{"title":"PolicyWebhooksRequestBody","type":"object","properties":{"subscriber":{"type":"string","description":"Name of the subscriber for policy.","example":"Dolorum suscipit quae."},"webhook_url":{"type":"string","description":"Subscriber webhook url.","example":"Dolore laborum aperiam aut."}},"example":{"subscriber":"Accusamus et voluptatibus cupiditate ea.","webhook_url":"Et unde rerum dolore."},"required":["webhook_url","subscriber"]}}}
\ 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":{"get":{"tags":["policy"],"summary":"Evaluate policy","description":"Evaluate executes a policy with the given 'data' as input.","operationId":"policy#Evaluate#1","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":"x-cache-ttl","in":"header","description":"Policy result cache TTL in seconds","required":false,"type":"integer"},{"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"]},"post":{"tags":["policy"],"summary":"Evaluate policy","description":"Evaluate executes a policy with the given 'data' as input.","operationId":"policy#Evaluate#2","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":"x-cache-ttl","in":"header","description":"Policy result cache TTL in seconds","required":false,"type":"integer"},{"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}/evaluation/did.json":{"get":{"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":"x-cache-ttl","in":"header","description":"Policy result cache TTL in seconds","required":false,"type":"integer"},{"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"]}},"/policy/{group}/{policyname}/{version}/notifychange":{"post":{"tags":["policy"],"summary":"SubscribeForPolicyChange policy","description":"Subscribe for policy change notifications by registering webhook callbacks which the policy service will call.","operationId":"policy#SubscribeForPolicyChange","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":"SubscribeForPolicyChangeRequestBody","in":"body","required":true,"schema":{"$ref":"#/definitions/PolicySubscribeForPolicyChangeRequestBody","required":["webhook_url","subscriber"]}}],"responses":{"200":{"description":"OK response.","schema":{"type":"string","format":"binary"}}},"schemes":["http"]}},"/readiness":{"get":{"tags":["health"],"summary":"Readiness health","operationId":"health#Readiness","responses":{"200":{"description":"OK response."}},"schemes":["http"]}},"/v1/policies":{"get":{"tags":["policy"],"summary":"ListPolicies policy","description":"List policies from storage with optional filters.","operationId":"policy#ListPolicies","parameters":[{"name":"locked","in":"query","description":"Filter to return locked/unlocked policies (optional).","required":false,"type":"boolean"},{"name":"rego","in":"query","description":"Include policy source code in results (optional).","required":false,"type":"boolean"},{"name":"data","in":"query","description":"Include policy static data in results (optional). ","required":false,"type":"boolean"},{"name":"dataConfig","in":"query","description":"Include static data config (optional).","required":false,"type":"boolean"}],"responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/PolicyListPoliciesResponseBody","required":["policies"]}}},"schemes":["http"]}}},"definitions":{"PolicyListPoliciesResponseBody":{"title":"PolicyListPoliciesResponseBody","type":"object","properties":{"policies":{"type":"array","items":{"$ref":"#/definitions/PolicyResponseBody"},"description":"JSON array of policies.","example":[{"data":"Totam officia necessitatibus tempore nulla animi.","dataConfig":"Consequatur vel rerum rem ipsam nam.","group":"Recusandae dolorum nisi distinctio vitae ad.","lastUpdate":1724369781608544610,"locked":true,"policyName":"Voluptatum voluptas ad corporis adipisci inventore ipsum.","rego":"Corporis est rem.","version":"Perspiciatis voluptatem."},{"data":"Totam officia necessitatibus tempore nulla animi.","dataConfig":"Consequatur vel rerum rem ipsam nam.","group":"Recusandae dolorum nisi distinctio vitae ad.","lastUpdate":1724369781608544610,"locked":true,"policyName":"Voluptatum voluptas ad corporis adipisci inventore ipsum.","rego":"Corporis est rem.","version":"Perspiciatis voluptatem."},{"data":"Totam officia necessitatibus tempore nulla animi.","dataConfig":"Consequatur vel rerum rem ipsam nam.","group":"Recusandae dolorum nisi distinctio vitae ad.","lastUpdate":1724369781608544610,"locked":true,"policyName":"Voluptatum voluptas ad corporis adipisci inventore ipsum.","rego":"Corporis est rem.","version":"Perspiciatis voluptatem."},{"data":"Totam officia necessitatibus tempore nulla animi.","dataConfig":"Consequatur vel rerum rem ipsam nam.","group":"Recusandae dolorum nisi distinctio vitae ad.","lastUpdate":1724369781608544610,"locked":true,"policyName":"Voluptatum voluptas ad corporis adipisci inventore ipsum.","rego":"Corporis est rem.","version":"Perspiciatis voluptatem."}]}},"example":{"policies":[{"data":"Totam officia necessitatibus tempore nulla animi.","dataConfig":"Consequatur vel rerum rem ipsam nam.","group":"Recusandae dolorum nisi distinctio vitae ad.","lastUpdate":1724369781608544610,"locked":true,"policyName":"Voluptatum voluptas ad corporis adipisci inventore ipsum.","rego":"Corporis est rem.","version":"Perspiciatis voluptatem."},{"data":"Totam officia necessitatibus tempore nulla animi.","dataConfig":"Consequatur vel rerum rem ipsam nam.","group":"Recusandae dolorum nisi distinctio vitae ad.","lastUpdate":1724369781608544610,"locked":true,"policyName":"Voluptatum voluptas ad corporis adipisci inventore ipsum.","rego":"Corporis est rem.","version":"Perspiciatis voluptatem."},{"data":"Totam officia necessitatibus tempore nulla animi.","dataConfig":"Consequatur vel rerum rem ipsam nam.","group":"Recusandae dolorum nisi distinctio vitae ad.","lastUpdate":1724369781608544610,"locked":true,"policyName":"Voluptatum voluptas ad corporis adipisci inventore ipsum.","rego":"Corporis est rem.","version":"Perspiciatis voluptatem."}]},"required":["policies"]},"PolicyResponseBody":{"title":"PolicyResponseBody","type":"object","properties":{"data":{"type":"string","description":"Policy static data.","example":"Ut quibusdam."},"dataConfig":{"type":"string","description":"Policy static data optional configuration.","example":"Eaque fugiat et."},"group":{"type":"string","description":"Policy group.","example":"Dolore ducimus accusamus et voluptatibus cupiditate."},"lastUpdate":{"type":"integer","description":"Last update (Unix timestamp).","example":1036142546592891419,"format":"int64"},"locked":{"type":"boolean","description":"Locked specifies if the policy is locked or allowed to execute.","example":true},"policyName":{"type":"string","description":"Policy name.","example":"Quae et et unde."},"rego":{"type":"string","description":"Policy rego source code.","example":"Nisi vitae iure fugiat sed sit dolores."},"version":{"type":"string","description":"Policy version.","example":"Repellat inventore ut doloremque recusandae earum et."}},"example":{"data":"Consequatur ut suscipit.","dataConfig":"Neque et sed modi accusantium.","group":"Totam voluptatem.","lastUpdate":6143850218805975874,"locked":true,"policyName":"Quo ut molestias rerum sunt eaque omnis.","rego":"Est impedit.","version":"Sapiente architecto et enim omnis."},"required":["group","policyName","version","locked","lastUpdate"]},"PolicySubscribeForPolicyChangeRequestBody":{"title":"PolicySubscribeForPolicyChangeRequestBody","type":"object","properties":{"subscriber":{"type":"string","description":"Name of the subscriber for policy.","example":"it3","minLength":3,"maxLength":100},"webhook_url":{"type":"string","description":"Subscriber webhook url.","example":"http://brekkeemmerich.info/marco","format":"uri"}},"example":{"subscriber":"3s8","webhook_url":"http://funk.com/mattie"},"required":["webhook_url","subscriber"]}}}
\ No newline at end of file
diff --git a/gen/http/openapi.yaml b/gen/http/openapi.yaml
index 3f9c608a1b6d489fe057feca0e33bca839ae4c4f..02f70b96ef9b07dfaf99099890fea5e9c5463b1a 100644
--- a/gen/http/openapi.yaml
+++ b/gen/http/openapi.yaml
@@ -238,9 +238,9 @@ paths:
         post:
             tags:
                 - policy
-            summary: Webhooks policy
-            description: Gives ability to user to subscribe for policy change via webhooks
-            operationId: policy#Webhooks
+            summary: SubscribeForPolicyChange policy
+            description: Subscribe for policy change notifications by registering webhook callbacks which the policy service will call.
+            operationId: policy#SubscribeForPolicyChange
             parameters:
                 - name: group
                   in: path
@@ -257,11 +257,11 @@ paths:
                   description: Policy version.
                   required: true
                   type: string
-                - name: WebhooksRequestBody
+                - name: SubscribeForPolicyChangeRequestBody
                   in: body
                   required: true
                   schema:
-                    $ref: '#/definitions/PolicyWebhooksRequestBody'
+                    $ref: '#/definitions/PolicySubscribeForPolicyChangeRequestBody'
                     required:
                         - webhook_url
                         - subscriber
@@ -332,64 +332,64 @@ definitions:
                     $ref: '#/definitions/PolicyResponseBody'
                 description: JSON array of policies.
                 example:
-                    - data: Accusamus enim.
-                      dataConfig: Recusandae est rerum corrupti quia.
-                      group: Optio quia et laborum.
-                      lastUpdate: 1029654258457164464
+                    - data: Totam officia necessitatibus tempore nulla animi.
+                      dataConfig: Consequatur vel rerum rem ipsam nam.
+                      group: Recusandae dolorum nisi distinctio vitae ad.
+                      lastUpdate: 1724369781608544610
                       locked: true
-                      policyName: Error maxime quasi quia non voluptatibus error.
-                      rego: Ut amet.
-                      version: In libero perspiciatis voluptatum ut soluta.
-                    - data: Accusamus enim.
-                      dataConfig: Recusandae est rerum corrupti quia.
-                      group: Optio quia et laborum.
-                      lastUpdate: 1029654258457164464
+                      policyName: Voluptatum voluptas ad corporis adipisci inventore ipsum.
+                      rego: Corporis est rem.
+                      version: Perspiciatis voluptatem.
+                    - data: Totam officia necessitatibus tempore nulla animi.
+                      dataConfig: Consequatur vel rerum rem ipsam nam.
+                      group: Recusandae dolorum nisi distinctio vitae ad.
+                      lastUpdate: 1724369781608544610
                       locked: true
-                      policyName: Error maxime quasi quia non voluptatibus error.
-                      rego: Ut amet.
-                      version: In libero perspiciatis voluptatum ut soluta.
-                    - data: Accusamus enim.
-                      dataConfig: Recusandae est rerum corrupti quia.
-                      group: Optio quia et laborum.
-                      lastUpdate: 1029654258457164464
+                      policyName: Voluptatum voluptas ad corporis adipisci inventore ipsum.
+                      rego: Corporis est rem.
+                      version: Perspiciatis voluptatem.
+                    - data: Totam officia necessitatibus tempore nulla animi.
+                      dataConfig: Consequatur vel rerum rem ipsam nam.
+                      group: Recusandae dolorum nisi distinctio vitae ad.
+                      lastUpdate: 1724369781608544610
                       locked: true
-                      policyName: Error maxime quasi quia non voluptatibus error.
-                      rego: Ut amet.
-                      version: In libero perspiciatis voluptatum ut soluta.
+                      policyName: Voluptatum voluptas ad corporis adipisci inventore ipsum.
+                      rego: Corporis est rem.
+                      version: Perspiciatis voluptatem.
+                    - data: Totam officia necessitatibus tempore nulla animi.
+                      dataConfig: Consequatur vel rerum rem ipsam nam.
+                      group: Recusandae dolorum nisi distinctio vitae ad.
+                      lastUpdate: 1724369781608544610
+                      locked: true
+                      policyName: Voluptatum voluptas ad corporis adipisci inventore ipsum.
+                      rego: Corporis est rem.
+                      version: Perspiciatis voluptatem.
         example:
             policies:
-                - data: Accusamus enim.
-                  dataConfig: Recusandae est rerum corrupti quia.
-                  group: Optio quia et laborum.
-                  lastUpdate: 1029654258457164464
-                  locked: true
-                  policyName: Error maxime quasi quia non voluptatibus error.
-                  rego: Ut amet.
-                  version: In libero perspiciatis voluptatum ut soluta.
-                - data: Accusamus enim.
-                  dataConfig: Recusandae est rerum corrupti quia.
-                  group: Optio quia et laborum.
-                  lastUpdate: 1029654258457164464
+                - data: Totam officia necessitatibus tempore nulla animi.
+                  dataConfig: Consequatur vel rerum rem ipsam nam.
+                  group: Recusandae dolorum nisi distinctio vitae ad.
+                  lastUpdate: 1724369781608544610
                   locked: true
-                  policyName: Error maxime quasi quia non voluptatibus error.
-                  rego: Ut amet.
-                  version: In libero perspiciatis voluptatum ut soluta.
-                - data: Accusamus enim.
-                  dataConfig: Recusandae est rerum corrupti quia.
-                  group: Optio quia et laborum.
-                  lastUpdate: 1029654258457164464
+                  policyName: Voluptatum voluptas ad corporis adipisci inventore ipsum.
+                  rego: Corporis est rem.
+                  version: Perspiciatis voluptatem.
+                - data: Totam officia necessitatibus tempore nulla animi.
+                  dataConfig: Consequatur vel rerum rem ipsam nam.
+                  group: Recusandae dolorum nisi distinctio vitae ad.
+                  lastUpdate: 1724369781608544610
                   locked: true
-                  policyName: Error maxime quasi quia non voluptatibus error.
-                  rego: Ut amet.
-                  version: In libero perspiciatis voluptatum ut soluta.
-                - data: Accusamus enim.
-                  dataConfig: Recusandae est rerum corrupti quia.
-                  group: Optio quia et laborum.
-                  lastUpdate: 1029654258457164464
+                  policyName: Voluptatum voluptas ad corporis adipisci inventore ipsum.
+                  rego: Corporis est rem.
+                  version: Perspiciatis voluptatem.
+                - data: Totam officia necessitatibus tempore nulla animi.
+                  dataConfig: Consequatur vel rerum rem ipsam nam.
+                  group: Recusandae dolorum nisi distinctio vitae ad.
+                  lastUpdate: 1724369781608544610
                   locked: true
-                  policyName: Error maxime quasi quia non voluptatibus error.
-                  rego: Ut amet.
-                  version: In libero perspiciatis voluptatum ut soluta.
+                  policyName: Voluptatum voluptas ad corporis adipisci inventore ipsum.
+                  rego: Corporis est rem.
+                  version: Perspiciatis voluptatem.
         required:
             - policies
     PolicyResponseBody:
@@ -399,66 +399,69 @@ definitions:
             data:
                 type: string
                 description: Policy static data.
-                example: Ipsa ad voluptatum maxime ut.
+                example: Ut quibusdam.
             dataConfig:
                 type: string
                 description: Policy static data optional configuration.
-                example: Aut asperiores.
+                example: Eaque fugiat et.
             group:
                 type: string
                 description: Policy group.
-                example: Veritatis quam qui nostrum eaque.
+                example: Dolore ducimus accusamus et voluptatibus cupiditate.
             lastUpdate:
                 type: integer
                 description: Last update (Unix timestamp).
-                example: 1131015782715696616
+                example: 1036142546592891419
                 format: int64
             locked:
                 type: boolean
                 description: Locked specifies if the policy is locked or allowed to execute.
-                example: false
+                example: true
             policyName:
                 type: string
                 description: Policy name.
-                example: Maiores et minus.
+                example: Quae et et unde.
             rego:
                 type: string
                 description: Policy rego source code.
-                example: Delectus rerum molestiae possimus cum laboriosam.
+                example: Nisi vitae iure fugiat sed sit dolores.
             version:
                 type: string
                 description: Policy version.
-                example: Et dolores.
+                example: Repellat inventore ut doloremque recusandae earum et.
         example:
-            data: Similique architecto.
-            dataConfig: Sunt ut est ut molestias.
-            group: Error minus vel voluptate quasi.
-            lastUpdate: 2308837710267791288
+            data: Consequatur ut suscipit.
+            dataConfig: Neque et sed modi accusantium.
+            group: Totam voluptatem.
+            lastUpdate: 6143850218805975874
             locked: true
-            policyName: Omnis molestiae tempora sed repellendus.
-            rego: Vel sunt dolorem ea architecto iure.
-            version: Debitis consectetur.
+            policyName: Quo ut molestias rerum sunt eaque omnis.
+            rego: Est impedit.
+            version: Sapiente architecto et enim omnis.
         required:
             - group
             - policyName
             - version
             - locked
             - lastUpdate
-    PolicyWebhooksRequestBody:
-        title: PolicyWebhooksRequestBody
+    PolicySubscribeForPolicyChangeRequestBody:
+        title: PolicySubscribeForPolicyChangeRequestBody
         type: object
         properties:
             subscriber:
                 type: string
                 description: Name of the subscriber for policy.
-                example: Dolorum suscipit quae.
+                example: it3
+                minLength: 3
+                maxLength: 100
             webhook_url:
                 type: string
                 description: Subscriber webhook url.
-                example: Dolore laborum aperiam aut.
+                example: http://brekkeemmerich.info/marco
+                format: uri
         example:
-            subscriber: Accusamus et voluptatibus cupiditate ea.
-            webhook_url: Et unde rerum dolore.
+            subscriber: 3s8
+            webhook_url: http://funk.com/mattie
         required:
             - webhook_url
             - subscriber
diff --git a/gen/http/openapi3.json b/gen/http/openapi3.json
index dce151929456b7701c7b8f384d1f2591995077c2..2dab40f06d7e1cd8d55f3b34b4d241184b1f34c4 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":{"get":{"tags":["policy"],"summary":"Evaluate policy","description":"Evaluate executes a policy with the given 'data' as input.","operationId":"policy#Evaluate#1","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"},{"name":"x-cache-ttl","in":"header","description":"Policy result cache TTL in seconds","allowEmptyValue":true,"schema":{"type":"integer","description":"Policy result cache TTL in seconds","example":60,"format":"int64"},"example":60}],"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":"Inventore ut doloremque recusandae.","format":"binary"},"example":"Aut accusantium in."}}},"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":"Culpa deserunt voluptatem culpa."},"example":"Cupiditate qui quo."}},"content":{"application/json":{"schema":{"type":"string","description":"Arbitrary JSON response.","example":"Et quis nisi vitae iure.","format":"binary"},"example":"Dignissimos enim."}}}}},"post":{"tags":["policy"],"summary":"Evaluate policy","description":"Evaluate executes a policy with the given 'data' as input.","operationId":"policy#Evaluate#2","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"},{"name":"x-cache-ttl","in":"header","description":"Policy result cache TTL in seconds","allowEmptyValue":true,"schema":{"type":"integer","description":"Policy result cache TTL in seconds","example":60,"format":"int64"},"example":60}],"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":"Inventore ut doloremque recusandae.","format":"binary"},"example":"Error et sunt maxime aperiam."}}},"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":"Et sit qui fugit enim labore."},"example":"Molestiae fugiat harum quia corporis ullam natus."}},"content":{"application/json":{"schema":{"type":"string","description":"Arbitrary JSON response.","example":"Et quis nisi vitae iure.","format":"binary"},"example":"Animi omnis minima fuga numquam."}}}}}},"/policy/{group}/{policyName}/{version}/evaluation/did.json":{"get":{"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"},{"name":"x-cache-ttl","in":"header","description":"Policy result cache TTL in seconds","allowEmptyValue":true,"schema":{"type":"integer","description":"Policy result cache TTL in seconds","example":60,"format":"int64"},"example":60}],"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":"Inventore ut doloremque recusandae.","format":"binary"},"example":"Laborum dolor dolorem modi aut."}}},"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":"Veritatis impedit rerum recusandae eligendi in."},"example":"Sapiente unde doloremque quae ullam qui optio."}},"content":{"application/json":{"schema":{"type":"string","description":"Arbitrary JSON response.","example":"Et quis nisi vitae iure.","format":"binary"},"example":"Iure rerum non cumque sapiente laborum voluptas."}}}}}},"/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":"Consequatur aut ipsam."},"example":"Aut provident ducimus vero adipisci nemo."},{"name":"policyName","in":"path","description":"Policy name.","required":true,"schema":{"type":"string","description":"Policy name.","example":"Itaque laborum."},"example":"Quos saepe dolorum qui tenetur aut."},{"name":"version","in":"path","description":"Policy version.","required":true,"schema":{"type":"string","description":"Policy version.","example":"Iusto mollitia rerum quis ut et."},"example":"Ipsam est alias officiis."}],"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":"Ipsum explicabo assumenda delectus."},"example":"Eius sed."},{"name":"policyName","in":"path","description":"Policy name.","required":true,"schema":{"type":"string","description":"Policy name.","example":"Rerum saepe dolores laborum odio."},"example":"Eos nemo repudiandae."},{"name":"version","in":"path","description":"Policy version.","required":true,"schema":{"type":"string","description":"Policy version.","example":"Eveniet voluptas rerum."},"example":"Facilis tempora dolor consectetur."}],"responses":{"200":{"description":"OK response."}}}},"/policy/{group}/{policyname}/{version}/notifychange":{"post":{"tags":["policy"],"summary":"Webhooks policy","description":"Gives ability to user to subscribe for policy change via webhooks","operationId":"policy#Webhooks","parameters":[{"name":"group","in":"path","description":"Policy group.","required":true,"schema":{"type":"string","description":"Policy group.","example":"Aut quas eos qui minima."},"example":"Est non."},{"name":"policyname","in":"path","description":"Policy name.","required":true,"schema":{"type":"string","description":"Policy name.","example":"Minima aut in quis et qui."},"example":"Deleniti natus eos cumque asperiores."},{"name":"version","in":"path","description":"Policy version.","required":true,"schema":{"type":"string","description":"Policy version.","example":"Commodi illo quidem omnis eveniet et."},"example":"Adipisci harum."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhooksRequestBody"},"example":{"subscriber":"Est totam officia necessitatibus tempore.","webhook_url":"Ad ab perspiciatis voluptatem pariatur corporis est."}}}},"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"type":"string","example":"Ut reiciendis fugit dolorum cupiditate.","format":"binary"},"example":"Ratione sit numquam non cupiditate sed omnis."}}}}}},"/readiness":{"get":{"tags":["health"],"summary":"Readiness health","operationId":"health#Readiness","responses":{"200":{"description":"OK response."}}}},"/v1/policies":{"get":{"tags":["policy"],"summary":"ListPolicies policy","description":"List policies from storage with optional filters.","operationId":"policy#ListPolicies","parameters":[{"name":"locked","in":"query","description":"Filter to return locked/unlocked policies (optional).","allowEmptyValue":true,"schema":{"type":"boolean","description":"Filter to return locked/unlocked policies (optional).","example":false},"example":false},{"name":"rego","in":"query","description":"Include policy source code in results (optional).","allowEmptyValue":true,"schema":{"type":"boolean","description":"Include policy source code in results (optional).","example":false},"example":false},{"name":"data","in":"query","description":"Include policy static data in results (optional). ","allowEmptyValue":true,"schema":{"type":"boolean","description":"Include policy static data in results (optional). ","example":true},"example":true},{"name":"dataConfig","in":"query","description":"Include static data config (optional).","allowEmptyValue":true,"schema":{"type":"boolean","description":"Include static data config (optional).","example":true},"example":true}],"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PoliciesResult"},"example":{"policies":[{"data":"Accusamus enim.","dataConfig":"Recusandae est rerum corrupti quia.","group":"Optio quia et laborum.","lastUpdate":1029654258457164464,"locked":true,"policyName":"Error maxime quasi quia non voluptatibus error.","rego":"Ut amet.","version":"In libero perspiciatis voluptatum ut soluta."},{"data":"Accusamus enim.","dataConfig":"Recusandae est rerum corrupti quia.","group":"Optio quia et laborum.","lastUpdate":1029654258457164464,"locked":true,"policyName":"Error maxime quasi quia non voluptatibus error.","rego":"Ut amet.","version":"In libero perspiciatis voluptatum ut soluta."},{"data":"Accusamus enim.","dataConfig":"Recusandae est rerum corrupti quia.","group":"Optio quia et laborum.","lastUpdate":1029654258457164464,"locked":true,"policyName":"Error maxime quasi quia non voluptatibus error.","rego":"Ut amet.","version":"In libero perspiciatis voluptatum ut soluta."},{"data":"Accusamus enim.","dataConfig":"Recusandae est rerum corrupti quia.","group":"Optio quia et laborum.","lastUpdate":1029654258457164464,"locked":true,"policyName":"Error maxime quasi quia non voluptatibus error.","rego":"Ut amet.","version":"In libero perspiciatis voluptatum ut soluta."}]}}}}}}}},"components":{"schemas":{"PoliciesResult":{"type":"object","properties":{"policies":{"type":"array","items":{"$ref":"#/components/schemas/Policy"},"description":"JSON array of policies.","example":[{"data":"Accusamus enim.","dataConfig":"Recusandae est rerum corrupti quia.","group":"Optio quia et laborum.","lastUpdate":1029654258457164464,"locked":true,"policyName":"Error maxime quasi quia non voluptatibus error.","rego":"Ut amet.","version":"In libero perspiciatis voluptatum ut soluta."},{"data":"Accusamus enim.","dataConfig":"Recusandae est rerum corrupti quia.","group":"Optio quia et laborum.","lastUpdate":1029654258457164464,"locked":true,"policyName":"Error maxime quasi quia non voluptatibus error.","rego":"Ut amet.","version":"In libero perspiciatis voluptatum ut soluta."}]}},"example":{"policies":[{"data":"Accusamus enim.","dataConfig":"Recusandae est rerum corrupti quia.","group":"Optio quia et laborum.","lastUpdate":1029654258457164464,"locked":true,"policyName":"Error maxime quasi quia non voluptatibus error.","rego":"Ut amet.","version":"In libero perspiciatis voluptatum ut soluta."},{"data":"Accusamus enim.","dataConfig":"Recusandae est rerum corrupti quia.","group":"Optio quia et laborum.","lastUpdate":1029654258457164464,"locked":true,"policyName":"Error maxime quasi quia non voluptatibus error.","rego":"Ut amet.","version":"In libero perspiciatis voluptatum ut soluta."}]},"required":["policies"]},"Policy":{"type":"object","properties":{"data":{"type":"string","description":"Policy static data.","example":"Non quo ut molestias rerum sunt."},"dataConfig":{"type":"string","description":"Policy static data optional configuration.","example":"Omnis dolores totam voluptatem rerum."},"group":{"type":"string","description":"Policy group.","example":"Iusto ut."},"lastUpdate":{"type":"integer","description":"Last update (Unix timestamp).","example":3092150594834775360,"format":"int64"},"locked":{"type":"boolean","description":"Locked specifies if the policy is locked or allowed to execute.","example":false},"policyName":{"type":"string","description":"Policy name.","example":"Sed sit."},"rego":{"type":"string","description":"Policy rego source code.","example":"Et mollitia."},"version":{"type":"string","description":"Policy version.","example":"Et eaque."}},"example":{"data":"Rerum asperiores nulla.","dataConfig":"Tenetur rerum necessitatibus fugit.","group":"Est impedit.","lastUpdate":2958895584654309878,"locked":false,"policyName":"Enim omnis.","rego":"Neque et sed modi accusantium.","version":"Consequatur ut suscipit."},"required":["group","policyName","version","locked","lastUpdate"]},"WebhooksRequestBody":{"type":"object","properties":{"subscriber":{"type":"string","description":"Name of the subscriber for policy.","example":"Harum voluptate et ut similique doloremque quis."},"webhook_url":{"type":"string","description":"Subscriber webhook url.","example":"Repellendus quis rem et occaecati quam tempora."}},"example":{"subscriber":"Vel saepe nisi et.","webhook_url":"Expedita ipsum minus ipsam."},"required":["webhook_url","subscriber"]}}},"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":{"get":{"tags":["policy"],"summary":"Evaluate policy","description":"Evaluate executes a policy with the given 'data' as input.","operationId":"policy#Evaluate#1","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"},{"name":"x-cache-ttl","in":"header","description":"Policy result cache TTL in seconds","allowEmptyValue":true,"schema":{"type":"integer","description":"Policy result cache TTL in seconds","example":60,"format":"int64"},"example":60}],"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":"Tenetur dignissimos enim.","format":"binary"},"example":"Eius culpa velit est."}}},"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":"Et numquam non rerum."},"example":"Rerum exercitationem odit tempora ab in aliquid."}},"content":{"application/json":{"schema":{"type":"string","description":"Arbitrary JSON response.","example":"Error et sunt maxime aperiam.","format":"binary"},"example":"Deleniti odit dolor et et."}}}}},"post":{"tags":["policy"],"summary":"Evaluate policy","description":"Evaluate executes a policy with the given 'data' as input.","operationId":"policy#Evaluate#2","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"},{"name":"x-cache-ttl","in":"header","description":"Policy result cache TTL in seconds","allowEmptyValue":true,"schema":{"type":"integer","description":"Policy result cache TTL in seconds","example":60,"format":"int64"},"example":60}],"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":"Tenetur dignissimos enim.","format":"binary"},"example":"Libero sed a at."}}},"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":"Qui delectus."},"example":"Qui et sit maiores architecto alias."}},"content":{"application/json":{"schema":{"type":"string","description":"Arbitrary JSON response.","example":"Error et sunt maxime aperiam.","format":"binary"},"example":"Nesciunt labore voluptatibus."}}}}}},"/policy/{group}/{policyName}/{version}/evaluation/did.json":{"get":{"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"},{"name":"x-cache-ttl","in":"header","description":"Policy result cache TTL in seconds","allowEmptyValue":true,"schema":{"type":"integer","description":"Policy result cache TTL in seconds","example":60,"format":"int64"},"example":60}],"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":"Tenetur dignissimos enim.","format":"binary"},"example":"Repudiandae delectus facere."}}},"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":"Temporibus commodi."},"example":"Dolore nostrum animi omnis qui nihil."}},"content":{"application/json":{"schema":{"type":"string","description":"Arbitrary JSON response.","example":"Error et sunt maxime aperiam.","format":"binary"},"example":"Quibusdam rem voluptatum dolor provident dolorum nihil."}}}}}},"/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":"Consequatur totam reiciendis molestiae itaque qui."},"example":"Illo temporibus."},{"name":"policyName","in":"path","description":"Policy name.","required":true,"schema":{"type":"string","description":"Policy name.","example":"Nam atque."},"example":"Atque quo nihil incidunt ipsam eum quia."},{"name":"version","in":"path","description":"Policy version.","required":true,"schema":{"type":"string","description":"Policy version.","example":"Qui earum."},"example":"Placeat aliquid consectetur dignissimos ea id est."}],"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":"Quia et deserunt expedita facilis maiores."},"example":"Quos autem aut in est."},{"name":"policyName","in":"path","description":"Policy name.","required":true,"schema":{"type":"string","description":"Policy name.","example":"Iusto porro rerum qui."},"example":"Quis qui perferendis provident corrupti rerum exercitationem."},{"name":"version","in":"path","description":"Policy version.","required":true,"schema":{"type":"string","description":"Policy version.","example":"Est debitis."},"example":"Voluptas qui quisquam magnam aut."}],"responses":{"200":{"description":"OK response."}}}},"/policy/{group}/{policyname}/{version}/notifychange":{"post":{"tags":["policy"],"summary":"SubscribeForPolicyChange policy","description":"Subscribe for policy change notifications by registering webhook callbacks which the policy service will call.","operationId":"policy#SubscribeForPolicyChange","parameters":[{"name":"group","in":"path","description":"Policy group.","required":true,"schema":{"type":"string","description":"Policy group.","example":"Doloremque aut quis ducimus est quisquam sapiente."},"example":"Dignissimos molestiae ullam totam nihil."},{"name":"policyname","in":"path","description":"Policy name.","required":true,"schema":{"type":"string","description":"Policy name.","example":"Eum rem."},"example":"Dolorem asperiores quia."},{"name":"version","in":"path","description":"Policy version.","required":true,"schema":{"type":"string","description":"Policy version.","example":"Atque labore nobis modi."},"example":"Quis eaque voluptatem explicabo."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscribeForPolicyChangeRequestBody"},"example":{"subscriber":"iyv","webhook_url":"http://boehmohara.org/estelle_kuhic"}}}},"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"type":"string","example":"Esse ut.","format":"binary"},"example":"Voluptatem autem exercitationem nobis voluptas."}}}}}},"/readiness":{"get":{"tags":["health"],"summary":"Readiness health","operationId":"health#Readiness","responses":{"200":{"description":"OK response."}}}},"/v1/policies":{"get":{"tags":["policy"],"summary":"ListPolicies policy","description":"List policies from storage with optional filters.","operationId":"policy#ListPolicies","parameters":[{"name":"locked","in":"query","description":"Filter to return locked/unlocked policies (optional).","allowEmptyValue":true,"schema":{"type":"boolean","description":"Filter to return locked/unlocked policies (optional).","example":false},"example":true},{"name":"rego","in":"query","description":"Include policy source code in results (optional).","allowEmptyValue":true,"schema":{"type":"boolean","description":"Include policy source code in results (optional).","example":false},"example":true},{"name":"data","in":"query","description":"Include policy static data in results (optional). ","allowEmptyValue":true,"schema":{"type":"boolean","description":"Include policy static data in results (optional). ","example":false},"example":true},{"name":"dataConfig","in":"query","description":"Include static data config (optional).","allowEmptyValue":true,"schema":{"type":"boolean","description":"Include static data config (optional).","example":false},"example":true}],"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PoliciesResult"},"example":{"policies":[{"data":"Totam officia necessitatibus tempore nulla animi.","dataConfig":"Consequatur vel rerum rem ipsam nam.","group":"Recusandae dolorum nisi distinctio vitae ad.","lastUpdate":1724369781608544610,"locked":true,"policyName":"Voluptatum voluptas ad corporis adipisci inventore ipsum.","rego":"Corporis est rem.","version":"Perspiciatis voluptatem."},{"data":"Totam officia necessitatibus tempore nulla animi.","dataConfig":"Consequatur vel rerum rem ipsam nam.","group":"Recusandae dolorum nisi distinctio vitae ad.","lastUpdate":1724369781608544610,"locked":true,"policyName":"Voluptatum voluptas ad corporis adipisci inventore ipsum.","rego":"Corporis est rem.","version":"Perspiciatis voluptatem."},{"data":"Totam officia necessitatibus tempore nulla animi.","dataConfig":"Consequatur vel rerum rem ipsam nam.","group":"Recusandae dolorum nisi distinctio vitae ad.","lastUpdate":1724369781608544610,"locked":true,"policyName":"Voluptatum voluptas ad corporis adipisci inventore ipsum.","rego":"Corporis est rem.","version":"Perspiciatis voluptatem."}]}}}}}}}},"components":{"schemas":{"PoliciesResult":{"type":"object","properties":{"policies":{"type":"array","items":{"$ref":"#/components/schemas/Policy"},"description":"JSON array of policies.","example":[{"data":"Totam officia necessitatibus tempore nulla animi.","dataConfig":"Consequatur vel rerum rem ipsam nam.","group":"Recusandae dolorum nisi distinctio vitae ad.","lastUpdate":1724369781608544610,"locked":true,"policyName":"Voluptatum voluptas ad corporis adipisci inventore ipsum.","rego":"Corporis est rem.","version":"Perspiciatis voluptatem."},{"data":"Totam officia necessitatibus tempore nulla animi.","dataConfig":"Consequatur vel rerum rem ipsam nam.","group":"Recusandae dolorum nisi distinctio vitae ad.","lastUpdate":1724369781608544610,"locked":true,"policyName":"Voluptatum voluptas ad corporis adipisci inventore ipsum.","rego":"Corporis est rem.","version":"Perspiciatis voluptatem."},{"data":"Totam officia necessitatibus tempore nulla animi.","dataConfig":"Consequatur vel rerum rem ipsam nam.","group":"Recusandae dolorum nisi distinctio vitae ad.","lastUpdate":1724369781608544610,"locked":true,"policyName":"Voluptatum voluptas ad corporis adipisci inventore ipsum.","rego":"Corporis est rem.","version":"Perspiciatis voluptatem."},{"data":"Totam officia necessitatibus tempore nulla animi.","dataConfig":"Consequatur vel rerum rem ipsam nam.","group":"Recusandae dolorum nisi distinctio vitae ad.","lastUpdate":1724369781608544610,"locked":true,"policyName":"Voluptatum voluptas ad corporis adipisci inventore ipsum.","rego":"Corporis est rem.","version":"Perspiciatis voluptatem."}]}},"example":{"policies":[{"data":"Totam officia necessitatibus tempore nulla animi.","dataConfig":"Consequatur vel rerum rem ipsam nam.","group":"Recusandae dolorum nisi distinctio vitae ad.","lastUpdate":1724369781608544610,"locked":true,"policyName":"Voluptatum voluptas ad corporis adipisci inventore ipsum.","rego":"Corporis est rem.","version":"Perspiciatis voluptatem."},{"data":"Totam officia necessitatibus tempore nulla animi.","dataConfig":"Consequatur vel rerum rem ipsam nam.","group":"Recusandae dolorum nisi distinctio vitae ad.","lastUpdate":1724369781608544610,"locked":true,"policyName":"Voluptatum voluptas ad corporis adipisci inventore ipsum.","rego":"Corporis est rem.","version":"Perspiciatis voluptatem."},{"data":"Totam officia necessitatibus tempore nulla animi.","dataConfig":"Consequatur vel rerum rem ipsam nam.","group":"Recusandae dolorum nisi distinctio vitae ad.","lastUpdate":1724369781608544610,"locked":true,"policyName":"Voluptatum voluptas ad corporis adipisci inventore ipsum.","rego":"Corporis est rem.","version":"Perspiciatis voluptatem."}]},"required":["policies"]},"Policy":{"type":"object","properties":{"data":{"type":"string","description":"Policy static data.","example":"Ipsum explicabo assumenda delectus."},"dataConfig":{"type":"string","description":"Policy static data optional configuration.","example":"Eius sed."},"group":{"type":"string","description":"Policy group.","example":"Et exercitationem perspiciatis quidem accusamus."},"lastUpdate":{"type":"integer","description":"Last update (Unix timestamp).","example":4992260150389358954,"format":"int64"},"locked":{"type":"boolean","description":"Locked specifies if the policy is locked or allowed to execute.","example":true},"policyName":{"type":"string","description":"Policy name.","example":"Et sit qui fugit enim labore."},"rego":{"type":"string","description":"Policy rego source code.","example":"Animi omnis minima fuga numquam."},"version":{"type":"string","description":"Policy version.","example":"Molestiae fugiat harum quia corporis ullam natus."}},"example":{"data":"Consequatur aut ipsam.","dataConfig":"Aut provident ducimus vero adipisci nemo.","group":"Voluptas eos nemo.","lastUpdate":5753045449869824649,"locked":false,"policyName":"Dolores laborum.","rego":"Facilis tempora dolor consectetur.","version":"Vel eveniet voluptas rerum."},"required":["group","policyName","version","locked","lastUpdate"]},"SubscribeForPolicyChangeRequestBody":{"type":"object","properties":{"subscriber":{"type":"string","description":"Name of the subscriber for policy.","example":"4ur","minLength":3,"maxLength":100},"webhook_url":{"type":"string","description":"Subscriber webhook url.","example":"http://wisozk.info/jesus","format":"uri"}},"example":{"subscriber":"wox","webhook_url":"http://kassulke.name/dexter"},"required":["webhook_url","subscriber"]}}},"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 2e47c1a30d9321501ff5d251f769147b509c0878..bb769355682023b2abd613beb91ddb51f7ad843f 100644
--- a/gen/http/openapi3.yaml
+++ b/gen/http/openapi3.yaml
@@ -78,9 +78,9 @@ paths:
                         schema:
                             type: string
                             description: Input data passed to the policy execution runtime.
-                            example: Inventore ut doloremque recusandae.
+                            example: Tenetur dignissimos enim.
                             format: binary
-                        example: Aut accusantium in.
+                        example: Eius culpa velit est.
             responses:
                 "200":
                     description: OK response.
@@ -91,16 +91,16 @@ paths:
                             schema:
                                 type: string
                                 description: ETag contains unique identifier of the policy evaluation and can be used to later retrieve the results from Cache.
-                                example: Culpa deserunt voluptatem culpa.
-                            example: Cupiditate qui quo.
+                                example: Et numquam non rerum.
+                            example: Rerum exercitationem odit tempora ab in aliquid.
                     content:
                         application/json:
                             schema:
                                 type: string
                                 description: Arbitrary JSON response.
-                                example: Et quis nisi vitae iure.
+                                example: Error et sunt maxime aperiam.
                                 format: binary
-                            example: Dignissimos enim.
+                            example: Deleniti odit dolor et et.
         post:
             tags:
                 - policy
@@ -162,9 +162,9 @@ paths:
                         schema:
                             type: string
                             description: Input data passed to the policy execution runtime.
-                            example: Inventore ut doloremque recusandae.
+                            example: Tenetur dignissimos enim.
                             format: binary
-                        example: Error et sunt maxime aperiam.
+                        example: Libero sed a at.
             responses:
                 "200":
                     description: OK response.
@@ -175,16 +175,16 @@ paths:
                             schema:
                                 type: string
                                 description: ETag contains unique identifier of the policy evaluation and can be used to later retrieve the results from Cache.
-                                example: Et sit qui fugit enim labore.
-                            example: Molestiae fugiat harum quia corporis ullam natus.
+                                example: Qui delectus.
+                            example: Qui et sit maiores architecto alias.
                     content:
                         application/json:
                             schema:
                                 type: string
                                 description: Arbitrary JSON response.
-                                example: Et quis nisi vitae iure.
+                                example: Error et sunt maxime aperiam.
                                 format: binary
-                            example: Animi omnis minima fuga numquam.
+                            example: Nesciunt labore voluptatibus.
     /policy/{group}/{policyName}/{version}/evaluation/did.json:
         get:
             tags:
@@ -247,9 +247,9 @@ paths:
                         schema:
                             type: string
                             description: Input data passed to the policy execution runtime.
-                            example: Inventore ut doloremque recusandae.
+                            example: Tenetur dignissimos enim.
                             format: binary
-                        example: Laborum dolor dolorem modi aut.
+                        example: Repudiandae delectus facere.
             responses:
                 "200":
                     description: OK response.
@@ -260,16 +260,16 @@ paths:
                             schema:
                                 type: string
                                 description: ETag contains unique identifier of the policy evaluation and can be used to later retrieve the results from Cache.
-                                example: Veritatis impedit rerum recusandae eligendi in.
-                            example: Sapiente unde doloremque quae ullam qui optio.
+                                example: Temporibus commodi.
+                            example: Dolore nostrum animi omnis qui nihil.
                     content:
                         application/json:
                             schema:
                                 type: string
                                 description: Arbitrary JSON response.
-                                example: Et quis nisi vitae iure.
+                                example: Error et sunt maxime aperiam.
                                 format: binary
-                            example: Iure rerum non cumque sapiente laborum voluptas.
+                            example: Quibusdam rem voluptatum dolor provident dolorum nihil.
     /policy/{group}/{policyName}/{version}/lock:
         delete:
             tags:
@@ -285,8 +285,8 @@ paths:
                   schema:
                     type: string
                     description: Policy group.
-                    example: Consequatur aut ipsam.
-                  example: Aut provident ducimus vero adipisci nemo.
+                    example: Consequatur totam reiciendis molestiae itaque qui.
+                  example: Illo temporibus.
                 - name: policyName
                   in: path
                   description: Policy name.
@@ -294,8 +294,8 @@ paths:
                   schema:
                     type: string
                     description: Policy name.
-                    example: Itaque laborum.
-                  example: Quos saepe dolorum qui tenetur aut.
+                    example: Nam atque.
+                  example: Atque quo nihil incidunt ipsam eum quia.
                 - name: version
                   in: path
                   description: Policy version.
@@ -303,8 +303,8 @@ paths:
                   schema:
                     type: string
                     description: Policy version.
-                    example: Iusto mollitia rerum quis ut et.
-                  example: Ipsam est alias officiis.
+                    example: Qui earum.
+                  example: Placeat aliquid consectetur dignissimos ea id est.
             responses:
                 "200":
                     description: OK response.
@@ -322,8 +322,8 @@ paths:
                   schema:
                     type: string
                     description: Policy group.
-                    example: Ipsum explicabo assumenda delectus.
-                  example: Eius sed.
+                    example: Quia et deserunt expedita facilis maiores.
+                  example: Quos autem aut in est.
                 - name: policyName
                   in: path
                   description: Policy name.
@@ -331,8 +331,8 @@ paths:
                   schema:
                     type: string
                     description: Policy name.
-                    example: Rerum saepe dolores laborum odio.
-                  example: Eos nemo repudiandae.
+                    example: Iusto porro rerum qui.
+                  example: Quis qui perferendis provident corrupti rerum exercitationem.
                 - name: version
                   in: path
                   description: Policy version.
@@ -340,8 +340,8 @@ paths:
                   schema:
                     type: string
                     description: Policy version.
-                    example: Eveniet voluptas rerum.
-                  example: Facilis tempora dolor consectetur.
+                    example: Est debitis.
+                  example: Voluptas qui quisquam magnam aut.
             responses:
                 "200":
                     description: OK response.
@@ -349,9 +349,9 @@ paths:
         post:
             tags:
                 - policy
-            summary: Webhooks policy
-            description: Gives ability to user to subscribe for policy change via webhooks
-            operationId: policy#Webhooks
+            summary: SubscribeForPolicyChange policy
+            description: Subscribe for policy change notifications by registering webhook callbacks which the policy service will call.
+            operationId: policy#SubscribeForPolicyChange
             parameters:
                 - name: group
                   in: path
@@ -360,8 +360,8 @@ paths:
                   schema:
                     type: string
                     description: Policy group.
-                    example: Aut quas eos qui minima.
-                  example: Est non.
+                    example: Doloremque aut quis ducimus est quisquam sapiente.
+                  example: Dignissimos molestiae ullam totam nihil.
                 - name: policyname
                   in: path
                   description: Policy name.
@@ -369,8 +369,8 @@ paths:
                   schema:
                     type: string
                     description: Policy name.
-                    example: Minima aut in quis et qui.
-                  example: Deleniti natus eos cumque asperiores.
+                    example: Eum rem.
+                  example: Dolorem asperiores quia.
                 - name: version
                   in: path
                   description: Policy version.
@@ -378,17 +378,17 @@ paths:
                   schema:
                     type: string
                     description: Policy version.
-                    example: Commodi illo quidem omnis eveniet et.
-                  example: Adipisci harum.
+                    example: Atque labore nobis modi.
+                  example: Quis eaque voluptatem explicabo.
             requestBody:
                 required: true
                 content:
                     application/json:
                         schema:
-                            $ref: '#/components/schemas/WebhooksRequestBody'
+                            $ref: '#/components/schemas/SubscribeForPolicyChangeRequestBody'
                         example:
-                            subscriber: Est totam officia necessitatibus tempore.
-                            webhook_url: Ad ab perspiciatis voluptatem pariatur corporis est.
+                            subscriber: iyv
+                            webhook_url: http://boehmohara.org/estelle_kuhic
             responses:
                 "200":
                     description: OK response.
@@ -396,9 +396,9 @@ paths:
                         application/json:
                             schema:
                                 type: string
-                                example: Ut reiciendis fugit dolorum cupiditate.
+                                example: Esse ut.
                                 format: binary
-                            example: Ratione sit numquam non cupiditate sed omnis.
+                            example: Voluptatem autem exercitationem nobis voluptas.
     /readiness:
         get:
             tags:
@@ -424,7 +424,7 @@ paths:
                     type: boolean
                     description: Filter to return locked/unlocked policies (optional).
                     example: false
-                  example: false
+                  example: true
                 - name: rego
                   in: query
                   description: Include policy source code in results (optional).
@@ -433,7 +433,7 @@ paths:
                     type: boolean
                     description: Include policy source code in results (optional).
                     example: false
-                  example: false
+                  example: true
                 - name: data
                   in: query
                   description: 'Include policy static data in results (optional). '
@@ -441,7 +441,7 @@ paths:
                   schema:
                     type: boolean
                     description: 'Include policy static data in results (optional). '
-                    example: true
+                    example: false
                   example: true
                 - name: dataConfig
                   in: query
@@ -450,7 +450,7 @@ paths:
                   schema:
                     type: boolean
                     description: Include static data config (optional).
-                    example: true
+                    example: false
                   example: true
             responses:
                 "200":
@@ -461,38 +461,30 @@ paths:
                                 $ref: '#/components/schemas/PoliciesResult'
                             example:
                                 policies:
-                                    - data: Accusamus enim.
-                                      dataConfig: Recusandae est rerum corrupti quia.
-                                      group: Optio quia et laborum.
-                                      lastUpdate: 1029654258457164464
+                                    - data: Totam officia necessitatibus tempore nulla animi.
+                                      dataConfig: Consequatur vel rerum rem ipsam nam.
+                                      group: Recusandae dolorum nisi distinctio vitae ad.
+                                      lastUpdate: 1724369781608544610
                                       locked: true
-                                      policyName: Error maxime quasi quia non voluptatibus error.
-                                      rego: Ut amet.
-                                      version: In libero perspiciatis voluptatum ut soluta.
-                                    - data: Accusamus enim.
-                                      dataConfig: Recusandae est rerum corrupti quia.
-                                      group: Optio quia et laborum.
-                                      lastUpdate: 1029654258457164464
+                                      policyName: Voluptatum voluptas ad corporis adipisci inventore ipsum.
+                                      rego: Corporis est rem.
+                                      version: Perspiciatis voluptatem.
+                                    - data: Totam officia necessitatibus tempore nulla animi.
+                                      dataConfig: Consequatur vel rerum rem ipsam nam.
+                                      group: Recusandae dolorum nisi distinctio vitae ad.
+                                      lastUpdate: 1724369781608544610
                                       locked: true
-                                      policyName: Error maxime quasi quia non voluptatibus error.
-                                      rego: Ut amet.
-                                      version: In libero perspiciatis voluptatum ut soluta.
-                                    - data: Accusamus enim.
-                                      dataConfig: Recusandae est rerum corrupti quia.
-                                      group: Optio quia et laborum.
-                                      lastUpdate: 1029654258457164464
+                                      policyName: Voluptatum voluptas ad corporis adipisci inventore ipsum.
+                                      rego: Corporis est rem.
+                                      version: Perspiciatis voluptatem.
+                                    - data: Totam officia necessitatibus tempore nulla animi.
+                                      dataConfig: Consequatur vel rerum rem ipsam nam.
+                                      group: Recusandae dolorum nisi distinctio vitae ad.
+                                      lastUpdate: 1724369781608544610
                                       locked: true
-                                      policyName: Error maxime quasi quia non voluptatibus error.
-                                      rego: Ut amet.
-                                      version: In libero perspiciatis voluptatum ut soluta.
-                                    - data: Accusamus enim.
-                                      dataConfig: Recusandae est rerum corrupti quia.
-                                      group: Optio quia et laborum.
-                                      lastUpdate: 1029654258457164464
-                                      locked: true
-                                      policyName: Error maxime quasi quia non voluptatibus error.
-                                      rego: Ut amet.
-                                      version: In libero perspiciatis voluptatum ut soluta.
+                                      policyName: Voluptatum voluptas ad corporis adipisci inventore ipsum.
+                                      rego: Corporis est rem.
+                                      version: Perspiciatis voluptatem.
 components:
     schemas:
         PoliciesResult:
@@ -504,40 +496,64 @@ components:
                         $ref: '#/components/schemas/Policy'
                     description: JSON array of policies.
                     example:
-                        - data: Accusamus enim.
-                          dataConfig: Recusandae est rerum corrupti quia.
-                          group: Optio quia et laborum.
-                          lastUpdate: 1029654258457164464
+                        - data: Totam officia necessitatibus tempore nulla animi.
+                          dataConfig: Consequatur vel rerum rem ipsam nam.
+                          group: Recusandae dolorum nisi distinctio vitae ad.
+                          lastUpdate: 1724369781608544610
+                          locked: true
+                          policyName: Voluptatum voluptas ad corporis adipisci inventore ipsum.
+                          rego: Corporis est rem.
+                          version: Perspiciatis voluptatem.
+                        - data: Totam officia necessitatibus tempore nulla animi.
+                          dataConfig: Consequatur vel rerum rem ipsam nam.
+                          group: Recusandae dolorum nisi distinctio vitae ad.
+                          lastUpdate: 1724369781608544610
                           locked: true
-                          policyName: Error maxime quasi quia non voluptatibus error.
-                          rego: Ut amet.
-                          version: In libero perspiciatis voluptatum ut soluta.
-                        - data: Accusamus enim.
-                          dataConfig: Recusandae est rerum corrupti quia.
-                          group: Optio quia et laborum.
-                          lastUpdate: 1029654258457164464
+                          policyName: Voluptatum voluptas ad corporis adipisci inventore ipsum.
+                          rego: Corporis est rem.
+                          version: Perspiciatis voluptatem.
+                        - data: Totam officia necessitatibus tempore nulla animi.
+                          dataConfig: Consequatur vel rerum rem ipsam nam.
+                          group: Recusandae dolorum nisi distinctio vitae ad.
+                          lastUpdate: 1724369781608544610
                           locked: true
-                          policyName: Error maxime quasi quia non voluptatibus error.
-                          rego: Ut amet.
-                          version: In libero perspiciatis voluptatum ut soluta.
+                          policyName: Voluptatum voluptas ad corporis adipisci inventore ipsum.
+                          rego: Corporis est rem.
+                          version: Perspiciatis voluptatem.
+                        - data: Totam officia necessitatibus tempore nulla animi.
+                          dataConfig: Consequatur vel rerum rem ipsam nam.
+                          group: Recusandae dolorum nisi distinctio vitae ad.
+                          lastUpdate: 1724369781608544610
+                          locked: true
+                          policyName: Voluptatum voluptas ad corporis adipisci inventore ipsum.
+                          rego: Corporis est rem.
+                          version: Perspiciatis voluptatem.
             example:
                 policies:
-                    - data: Accusamus enim.
-                      dataConfig: Recusandae est rerum corrupti quia.
-                      group: Optio quia et laborum.
-                      lastUpdate: 1029654258457164464
+                    - data: Totam officia necessitatibus tempore nulla animi.
+                      dataConfig: Consequatur vel rerum rem ipsam nam.
+                      group: Recusandae dolorum nisi distinctio vitae ad.
+                      lastUpdate: 1724369781608544610
+                      locked: true
+                      policyName: Voluptatum voluptas ad corporis adipisci inventore ipsum.
+                      rego: Corporis est rem.
+                      version: Perspiciatis voluptatem.
+                    - data: Totam officia necessitatibus tempore nulla animi.
+                      dataConfig: Consequatur vel rerum rem ipsam nam.
+                      group: Recusandae dolorum nisi distinctio vitae ad.
+                      lastUpdate: 1724369781608544610
                       locked: true
-                      policyName: Error maxime quasi quia non voluptatibus error.
-                      rego: Ut amet.
-                      version: In libero perspiciatis voluptatum ut soluta.
-                    - data: Accusamus enim.
-                      dataConfig: Recusandae est rerum corrupti quia.
-                      group: Optio quia et laborum.
-                      lastUpdate: 1029654258457164464
+                      policyName: Voluptatum voluptas ad corporis adipisci inventore ipsum.
+                      rego: Corporis est rem.
+                      version: Perspiciatis voluptatem.
+                    - data: Totam officia necessitatibus tempore nulla animi.
+                      dataConfig: Consequatur vel rerum rem ipsam nam.
+                      group: Recusandae dolorum nisi distinctio vitae ad.
+                      lastUpdate: 1724369781608544610
                       locked: true
-                      policyName: Error maxime quasi quia non voluptatibus error.
-                      rego: Ut amet.
-                      version: In libero perspiciatis voluptatum ut soluta.
+                      policyName: Voluptatum voluptas ad corporis adipisci inventore ipsum.
+                      rego: Corporis est rem.
+                      version: Perspiciatis voluptatem.
             required:
                 - policies
         Policy:
@@ -546,65 +562,68 @@ components:
                 data:
                     type: string
                     description: Policy static data.
-                    example: Non quo ut molestias rerum sunt.
+                    example: Ipsum explicabo assumenda delectus.
                 dataConfig:
                     type: string
                     description: Policy static data optional configuration.
-                    example: Omnis dolores totam voluptatem rerum.
+                    example: Eius sed.
                 group:
                     type: string
                     description: Policy group.
-                    example: Iusto ut.
+                    example: Et exercitationem perspiciatis quidem accusamus.
                 lastUpdate:
                     type: integer
                     description: Last update (Unix timestamp).
-                    example: 3092150594834775360
+                    example: 4992260150389358954
                     format: int64
                 locked:
                     type: boolean
                     description: Locked specifies if the policy is locked or allowed to execute.
-                    example: false
+                    example: true
                 policyName:
                     type: string
                     description: Policy name.
-                    example: Sed sit.
+                    example: Et sit qui fugit enim labore.
                 rego:
                     type: string
                     description: Policy rego source code.
-                    example: Et mollitia.
+                    example: Animi omnis minima fuga numquam.
                 version:
                     type: string
                     description: Policy version.
-                    example: Et eaque.
+                    example: Molestiae fugiat harum quia corporis ullam natus.
             example:
-                data: Rerum asperiores nulla.
-                dataConfig: Tenetur rerum necessitatibus fugit.
-                group: Est impedit.
-                lastUpdate: 2958895584654309878
+                data: Consequatur aut ipsam.
+                dataConfig: Aut provident ducimus vero adipisci nemo.
+                group: Voluptas eos nemo.
+                lastUpdate: 5753045449869824649
                 locked: false
-                policyName: Enim omnis.
-                rego: Neque et sed modi accusantium.
-                version: Consequatur ut suscipit.
+                policyName: Dolores laborum.
+                rego: Facilis tempora dolor consectetur.
+                version: Vel eveniet voluptas rerum.
             required:
                 - group
                 - policyName
                 - version
                 - locked
                 - lastUpdate
-        WebhooksRequestBody:
+        SubscribeForPolicyChangeRequestBody:
             type: object
             properties:
                 subscriber:
                     type: string
                     description: Name of the subscriber for policy.
-                    example: Harum voluptate et ut similique doloremque quis.
+                    example: 4ur
+                    minLength: 3
+                    maxLength: 100
                 webhook_url:
                     type: string
                     description: Subscriber webhook url.
-                    example: Repellendus quis rem et occaecati quam tempora.
+                    example: http://wisozk.info/jesus
+                    format: uri
             example:
-                subscriber: Vel saepe nisi et.
-                webhook_url: Expedita ipsum minus ipsam.
+                subscriber: wox
+                webhook_url: http://kassulke.name/dexter
             required:
                 - webhook_url
                 - subscriber
diff --git a/gen/http/policy/client/cli.go b/gen/http/policy/client/cli.go
index fbd0d51da31d090091af5598c4d0c55ab21109e9..6a1a7bc8ea8cf51f083fe3653b0b974684a1a38a 100644
--- a/gen/http/policy/client/cli.go
+++ b/gen/http/policy/client/cli.go
@@ -11,8 +11,10 @@ import (
 	"encoding/json"
 	"fmt"
 	"strconv"
+	"unicode/utf8"
 
 	policy "gitlab.eclipse.org/eclipse/xfsc/tsa/policy/gen/policy"
+	goa "goa.design/goa/v3/pkg"
 )
 
 // BuildEvaluatePayload builds the payload for the policy Evaluate endpoint
@@ -23,7 +25,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, "\"Earum velit illum quia aliquam atque voluptatum.\"")
+			return nil, fmt.Errorf("invalid JSON for body, \nerror: %s, \nexample of valid JSON:\n%s", err, "\"Voluptas dolorem cumque laborum.\"")
 		}
 	}
 	var group string
@@ -172,28 +174,38 @@ func BuildListPoliciesPayload(policyListPoliciesLocked string, policyListPolicie
 	return v, nil
 }
 
-// BuildWebhooksPayload builds the payload for the policy Webhooks endpoint
-// from CLI flags.
-func BuildWebhooksPayload(policyWebhooksBody string, policyWebhooksGroup string, policyWebhooksPolicyname string, policyWebhooksVersion string) (*policy.WebHooksRequest, error) {
+// BuildSubscribeForPolicyChangePayload builds the payload for the policy
+// SubscribeForPolicyChange endpoint from CLI flags.
+func BuildSubscribeForPolicyChangePayload(policySubscribeForPolicyChangeBody string, policySubscribeForPolicyChangeGroup string, policySubscribeForPolicyChangePolicyname string, policySubscribeForPolicyChangeVersion string) (*policy.WebHooksRequest, error) {
 	var err error
-	var body WebhooksRequestBody
+	var body SubscribeForPolicyChangeRequestBody
 	{
-		err = json.Unmarshal([]byte(policyWebhooksBody), &body)
+		err = json.Unmarshal([]byte(policySubscribeForPolicyChangeBody), &body)
+		if err != nil {
+			return nil, fmt.Errorf("invalid JSON for body, \nerror: %s, \nexample of valid JSON:\n%s", err, "'{\n      \"subscriber\": \"iyv\",\n      \"webhook_url\": \"http://boehmohara.org/estelle_kuhic\"\n   }'")
+		}
+		err = goa.MergeErrors(err, goa.ValidateFormat("body.webhook_url", body.WebhookURL, goa.FormatURI))
+		if utf8.RuneCountInString(body.Subscriber) < 3 {
+			err = goa.MergeErrors(err, goa.InvalidLengthError("body.subscriber", body.Subscriber, utf8.RuneCountInString(body.Subscriber), 3, true))
+		}
+		if utf8.RuneCountInString(body.Subscriber) > 100 {
+			err = goa.MergeErrors(err, goa.InvalidLengthError("body.subscriber", body.Subscriber, utf8.RuneCountInString(body.Subscriber), 100, false))
+		}
 		if err != nil {
-			return nil, fmt.Errorf("invalid JSON for body, \nerror: %s, \nexample of valid JSON:\n%s", err, "'{\n      \"subscriber\": \"Est totam officia necessitatibus tempore.\",\n      \"webhook_url\": \"Ad ab perspiciatis voluptatem pariatur corporis est.\"\n   }'")
+			return nil, err
 		}
 	}
 	var group string
 	{
-		group = policyWebhooksGroup
+		group = policySubscribeForPolicyChangeGroup
 	}
 	var policyname string
 	{
-		policyname = policyWebhooksPolicyname
+		policyname = policySubscribeForPolicyChangePolicyname
 	}
 	var version string
 	{
-		version = policyWebhooksVersion
+		version = policySubscribeForPolicyChangeVersion
 	}
 	v := &policy.WebHooksRequest{
 		WebhookURL: body.WebhookURL,
diff --git a/gen/http/policy/client/client.go b/gen/http/policy/client/client.go
index 435cb3eb4fc22beb5429130272e604b6fd84876f..59591dc295b8641019eaae50f990b68cb4b1136c 100644
--- a/gen/http/policy/client/client.go
+++ b/gen/http/policy/client/client.go
@@ -31,9 +31,9 @@ type Client struct {
 	// ListPolicies endpoint.
 	ListPoliciesDoer goahttp.Doer
 
-	// Webhooks Doer is the HTTP client used to make requests to the Webhooks
-	// endpoint.
-	WebhooksDoer goahttp.Doer
+	// SubscribeForPolicyChange Doer is the HTTP client used to make requests to
+	// the SubscribeForPolicyChange endpoint.
+	SubscribeForPolicyChangeDoer goahttp.Doer
 
 	// RestoreResponseBody controls whether the response bodies are reset after
 	// decoding so they can be read again.
@@ -55,16 +55,16 @@ func NewClient(
 	restoreBody bool,
 ) *Client {
 	return &Client{
-		EvaluateDoer:        doer,
-		LockDoer:            doer,
-		UnlockDoer:          doer,
-		ListPoliciesDoer:    doer,
-		WebhooksDoer:        doer,
-		RestoreResponseBody: restoreBody,
-		scheme:              scheme,
-		host:                host,
-		decoder:             dec,
-		encoder:             enc,
+		EvaluateDoer:                 doer,
+		LockDoer:                     doer,
+		UnlockDoer:                   doer,
+		ListPoliciesDoer:             doer,
+		SubscribeForPolicyChangeDoer: doer,
+		RestoreResponseBody:          restoreBody,
+		scheme:                       scheme,
+		host:                         host,
+		decoder:                      dec,
+		encoder:                      enc,
 	}
 }
 
@@ -154,15 +154,15 @@ func (c *Client) ListPolicies() goa.Endpoint {
 	}
 }
 
-// Webhooks returns an endpoint that makes HTTP requests to the policy service
-// Webhooks server.
-func (c *Client) Webhooks() goa.Endpoint {
+// SubscribeForPolicyChange returns an endpoint that makes HTTP requests to the
+// policy service SubscribeForPolicyChange server.
+func (c *Client) SubscribeForPolicyChange() goa.Endpoint {
 	var (
-		encodeRequest  = EncodeWebhooksRequest(c.encoder)
-		decodeResponse = DecodeWebhooksResponse(c.decoder, c.RestoreResponseBody)
+		encodeRequest  = EncodeSubscribeForPolicyChangeRequest(c.encoder)
+		decodeResponse = DecodeSubscribeForPolicyChangeResponse(c.decoder, c.RestoreResponseBody)
 	)
 	return func(ctx context.Context, v any) (any, error) {
-		req, err := c.BuildWebhooksRequest(ctx, v)
+		req, err := c.BuildSubscribeForPolicyChangeRequest(ctx, v)
 		if err != nil {
 			return nil, err
 		}
@@ -170,9 +170,9 @@ func (c *Client) Webhooks() goa.Endpoint {
 		if err != nil {
 			return nil, err
 		}
-		resp, err := c.WebhooksDoer.Do(req)
+		resp, err := c.SubscribeForPolicyChangeDoer.Do(req)
 		if err != nil {
-			return nil, goahttp.ErrRequestError("policy", "Webhooks", err)
+			return nil, goahttp.ErrRequestError("policy", "SubscribeForPolicyChange", err)
 		}
 		return decodeResponse(resp)
 	}
diff --git a/gen/http/policy/client/encode_decode.go b/gen/http/policy/client/encode_decode.go
index 8f864fb47dcd31ef495a11c203d9a1036dbfbebf..d9e8e6cbaf7194bde3d37355ab9ab36833132b11 100644
--- a/gen/http/policy/client/encode_decode.go
+++ b/gen/http/policy/client/encode_decode.go
@@ -315,9 +315,10 @@ func DecodeListPoliciesResponse(decoder func(*http.Response) goahttp.Decoder, re
 	}
 }
 
-// BuildWebhooksRequest instantiates a HTTP request object with method and path
-// set to call the "policy" service "Webhooks" endpoint
-func (c *Client) BuildWebhooksRequest(ctx context.Context, v any) (*http.Request, error) {
+// BuildSubscribeForPolicyChangeRequest instantiates a HTTP request object with
+// method and path set to call the "policy" service "SubscribeForPolicyChange"
+// endpoint
+func (c *Client) BuildSubscribeForPolicyChangeRequest(ctx context.Context, v any) (*http.Request, error) {
 	var (
 		group      string
 		policyname string
@@ -326,16 +327,16 @@ func (c *Client) BuildWebhooksRequest(ctx context.Context, v any) (*http.Request
 	{
 		p, ok := v.(*policy.WebHooksRequest)
 		if !ok {
-			return nil, goahttp.ErrInvalidType("policy", "Webhooks", "*policy.WebHooksRequest", v)
+			return nil, goahttp.ErrInvalidType("policy", "SubscribeForPolicyChange", "*policy.WebHooksRequest", v)
 		}
 		group = p.Group
 		policyname = p.Policyname
 		version = p.Version
 	}
-	u := &url.URL{Scheme: c.scheme, Host: c.host, Path: WebhooksPolicyPath(group, policyname, version)}
+	u := &url.URL{Scheme: c.scheme, Host: c.host, Path: SubscribeForPolicyChangePolicyPath(group, policyname, version)}
 	req, err := http.NewRequest("POST", u.String(), nil)
 	if err != nil {
-		return nil, goahttp.ErrInvalidURL("policy", "Webhooks", u.String(), err)
+		return nil, goahttp.ErrInvalidURL("policy", "SubscribeForPolicyChange", u.String(), err)
 	}
 	if ctx != nil {
 		req = req.WithContext(ctx)
@@ -344,26 +345,26 @@ func (c *Client) BuildWebhooksRequest(ctx context.Context, v any) (*http.Request
 	return req, nil
 }
 
-// EncodeWebhooksRequest returns an encoder for requests sent to the policy
-// Webhooks server.
-func EncodeWebhooksRequest(encoder func(*http.Request) goahttp.Encoder) func(*http.Request, any) error {
+// EncodeSubscribeForPolicyChangeRequest returns an encoder for requests sent
+// to the policy SubscribeForPolicyChange server.
+func EncodeSubscribeForPolicyChangeRequest(encoder func(*http.Request) goahttp.Encoder) func(*http.Request, any) error {
 	return func(req *http.Request, v any) error {
 		p, ok := v.(*policy.WebHooksRequest)
 		if !ok {
-			return goahttp.ErrInvalidType("policy", "Webhooks", "*policy.WebHooksRequest", v)
+			return goahttp.ErrInvalidType("policy", "SubscribeForPolicyChange", "*policy.WebHooksRequest", v)
 		}
-		body := NewWebhooksRequestBody(p)
+		body := NewSubscribeForPolicyChangeRequestBody(p)
 		if err := encoder(req).Encode(&body); err != nil {
-			return goahttp.ErrEncodingError("policy", "Webhooks", err)
+			return goahttp.ErrEncodingError("policy", "SubscribeForPolicyChange", err)
 		}
 		return nil
 	}
 }
 
-// DecodeWebhooksResponse returns a decoder for responses returned by the
-// policy Webhooks endpoint. restoreBody controls whether the response body
-// should be restored after having been read.
-func DecodeWebhooksResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (any, error) {
+// DecodeSubscribeForPolicyChangeResponse returns a decoder for responses
+// returned by the policy SubscribeForPolicyChange endpoint. restoreBody
+// controls whether the response body should be restored after having been read.
+func DecodeSubscribeForPolicyChangeResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (any, error) {
 	return func(resp *http.Response) (any, error) {
 		if restoreBody {
 			b, err := io.ReadAll(resp.Body)
@@ -385,12 +386,12 @@ func DecodeWebhooksResponse(decoder func(*http.Response) goahttp.Decoder, restor
 			)
 			err = decoder(resp).Decode(&body)
 			if err != nil {
-				return nil, goahttp.ErrDecodingError("policy", "Webhooks", err)
+				return nil, goahttp.ErrDecodingError("policy", "SubscribeForPolicyChange", err)
 			}
 			return body, nil
 		default:
 			body, _ := io.ReadAll(resp.Body)
-			return nil, goahttp.ErrInvalidResponse("policy", "Webhooks", resp.StatusCode, string(body))
+			return nil, goahttp.ErrInvalidResponse("policy", "SubscribeForPolicyChange", resp.StatusCode, string(body))
 		}
 	}
 }
diff --git a/gen/http/policy/client/paths.go b/gen/http/policy/client/paths.go
index 06a7d6be4315a562a788f5d8418b78268ffeceb7..12f361cf8f4154062aa66d6ccbd4ff10352815e3 100644
--- a/gen/http/policy/client/paths.go
+++ b/gen/http/policy/client/paths.go
@@ -41,7 +41,7 @@ func ListPoliciesPolicyPath() string {
 	return "/v1/policies"
 }
 
-// WebhooksPolicyPath returns the URL path to the policy service Webhooks HTTP endpoint.
-func WebhooksPolicyPath(group string, policyname string, version string) string {
+// SubscribeForPolicyChangePolicyPath returns the URL path to the policy service SubscribeForPolicyChange HTTP endpoint.
+func SubscribeForPolicyChangePolicyPath(group string, policyname string, version string) string {
 	return fmt.Sprintf("/policy/%v/%v/%v/notifychange", group, policyname, version)
 }
diff --git a/gen/http/policy/client/types.go b/gen/http/policy/client/types.go
index f17e6ed9c0ad0a3a5cf312f4cd2848d7d76765be..5a9090d3a04b4a1125361e86f406f86a9510c0bd 100644
--- a/gen/http/policy/client/types.go
+++ b/gen/http/policy/client/types.go
@@ -12,9 +12,9 @@ import (
 	goa "goa.design/goa/v3/pkg"
 )
 
-// WebhooksRequestBody is the type of the "policy" service "Webhooks" endpoint
-// HTTP request body.
-type WebhooksRequestBody struct {
+// SubscribeForPolicyChangeRequestBody is the type of the "policy" service
+// "SubscribeForPolicyChange" endpoint HTTP request body.
+type SubscribeForPolicyChangeRequestBody struct {
 	// Subscriber webhook url.
 	WebhookURL string `form:"webhook_url" json:"webhook_url" xml:"webhook_url"`
 	// Name of the subscriber for policy.
@@ -48,10 +48,10 @@ type PolicyResponseBody struct {
 	LastUpdate *int64 `form:"lastUpdate,omitempty" json:"lastUpdate,omitempty" xml:"lastUpdate,omitempty"`
 }
 
-// NewWebhooksRequestBody builds the HTTP request body from the payload of the
-// "Webhooks" endpoint of the "policy" service.
-func NewWebhooksRequestBody(p *policy.WebHooksRequest) *WebhooksRequestBody {
-	body := &WebhooksRequestBody{
+// NewSubscribeForPolicyChangeRequestBody builds the HTTP request body from the
+// payload of the "SubscribeForPolicyChange" endpoint of the "policy" service.
+func NewSubscribeForPolicyChangeRequestBody(p *policy.WebHooksRequest) *SubscribeForPolicyChangeRequestBody {
+	body := &SubscribeForPolicyChangeRequestBody{
 		WebhookURL: p.WebhookURL,
 		Subscriber: p.Subscriber,
 	}
diff --git a/gen/http/policy/server/encode_decode.go b/gen/http/policy/server/encode_decode.go
index d37f26d769134a4a9973a04c934dfe5f43360033..e6828ab0223b83c809b6527db79e6bf14646c044 100644
--- a/gen/http/policy/server/encode_decode.go
+++ b/gen/http/policy/server/encode_decode.go
@@ -214,9 +214,9 @@ func DecodeListPoliciesRequest(mux goahttp.Muxer, decoder func(*http.Request) go
 	}
 }
 
-// EncodeWebhooksResponse returns an encoder for responses returned by the
-// policy Webhooks endpoint.
-func EncodeWebhooksResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, any) error {
+// EncodeSubscribeForPolicyChangeResponse returns an encoder for responses
+// returned by the policy SubscribeForPolicyChange endpoint.
+func EncodeSubscribeForPolicyChangeResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, any) error {
 	return func(ctx context.Context, w http.ResponseWriter, v any) error {
 		res, _ := v.(any)
 		enc := encoder(ctx, w)
@@ -226,12 +226,12 @@ func EncodeWebhooksResponse(encoder func(context.Context, http.ResponseWriter) g
 	}
 }
 
-// DecodeWebhooksRequest returns a decoder for requests sent to the policy
-// Webhooks endpoint.
-func DecodeWebhooksRequest(mux goahttp.Muxer, decoder func(*http.Request) goahttp.Decoder) func(*http.Request) (any, error) {
+// DecodeSubscribeForPolicyChangeRequest returns a decoder for requests sent to
+// the policy SubscribeForPolicyChange endpoint.
+func DecodeSubscribeForPolicyChangeRequest(mux goahttp.Muxer, decoder func(*http.Request) goahttp.Decoder) func(*http.Request) (any, error) {
 	return func(r *http.Request) (any, error) {
 		var (
-			body WebhooksRequestBody
+			body SubscribeForPolicyChangeRequestBody
 			err  error
 		)
 		err = decoder(r).Decode(&body)
@@ -241,7 +241,7 @@ func DecodeWebhooksRequest(mux goahttp.Muxer, decoder func(*http.Request) goahtt
 			}
 			return nil, goa.DecodePayloadError(err.Error())
 		}
-		err = ValidateWebhooksRequestBody(&body)
+		err = ValidateSubscribeForPolicyChangeRequestBody(&body)
 		if err != nil {
 			return nil, err
 		}
@@ -256,7 +256,7 @@ func DecodeWebhooksRequest(mux goahttp.Muxer, decoder func(*http.Request) goahtt
 		group = params["group"]
 		policyname = params["policyname"]
 		version = params["version"]
-		payload := NewWebhooksWebHooksRequest(&body, group, policyname, version)
+		payload := NewSubscribeForPolicyChangeWebHooksRequest(&body, group, policyname, version)
 
 		return payload, nil
 	}
diff --git a/gen/http/policy/server/paths.go b/gen/http/policy/server/paths.go
index 8e398de2d13d4091bdcc65cc9f0f2c1fc02b9330..95cd607f1ed07e97995a3b9dcf7f5909d928ec15 100644
--- a/gen/http/policy/server/paths.go
+++ b/gen/http/policy/server/paths.go
@@ -41,7 +41,7 @@ func ListPoliciesPolicyPath() string {
 	return "/v1/policies"
 }
 
-// WebhooksPolicyPath returns the URL path to the policy service Webhooks HTTP endpoint.
-func WebhooksPolicyPath(group string, policyname string, version string) string {
+// SubscribeForPolicyChangePolicyPath returns the URL path to the policy service SubscribeForPolicyChange HTTP endpoint.
+func SubscribeForPolicyChangePolicyPath(group string, policyname string, version string) string {
 	return fmt.Sprintf("/policy/%v/%v/%v/notifychange", group, policyname, version)
 }
diff --git a/gen/http/policy/server/server.go b/gen/http/policy/server/server.go
index e93b79a7e18d3edeb0bf627a4756cb7bc8a49e48..d2b365399cf612f1a2e36099e8b1401de33e0b5c 100644
--- a/gen/http/policy/server/server.go
+++ b/gen/http/policy/server/server.go
@@ -18,12 +18,12 @@ import (
 
 // Server lists the policy service endpoint HTTP handlers.
 type Server struct {
-	Mounts       []*MountPoint
-	Evaluate     http.Handler
-	Lock         http.Handler
-	Unlock       http.Handler
-	ListPolicies http.Handler
-	Webhooks     http.Handler
+	Mounts                   []*MountPoint
+	Evaluate                 http.Handler
+	Lock                     http.Handler
+	Unlock                   http.Handler
+	ListPolicies             http.Handler
+	SubscribeForPolicyChange http.Handler
 }
 
 // MountPoint holds information about the mounted endpoints.
@@ -59,13 +59,13 @@ func New(
 			{"Lock", "POST", "/policy/{group}/{policyName}/{version}/lock"},
 			{"Unlock", "DELETE", "/policy/{group}/{policyName}/{version}/lock"},
 			{"ListPolicies", "GET", "/v1/policies"},
-			{"Webhooks", "POST", "/policy/{group}/{policyname}/{version}/notifychange"},
+			{"SubscribeForPolicyChange", "POST", "/policy/{group}/{policyname}/{version}/notifychange"},
 		},
-		Evaluate:     NewEvaluateHandler(e.Evaluate, mux, decoder, encoder, errhandler, formatter),
-		Lock:         NewLockHandler(e.Lock, mux, decoder, encoder, errhandler, formatter),
-		Unlock:       NewUnlockHandler(e.Unlock, mux, decoder, encoder, errhandler, formatter),
-		ListPolicies: NewListPoliciesHandler(e.ListPolicies, mux, decoder, encoder, errhandler, formatter),
-		Webhooks:     NewWebhooksHandler(e.Webhooks, mux, decoder, encoder, errhandler, formatter),
+		Evaluate:                 NewEvaluateHandler(e.Evaluate, mux, decoder, encoder, errhandler, formatter),
+		Lock:                     NewLockHandler(e.Lock, mux, decoder, encoder, errhandler, formatter),
+		Unlock:                   NewUnlockHandler(e.Unlock, mux, decoder, encoder, errhandler, formatter),
+		ListPolicies:             NewListPoliciesHandler(e.ListPolicies, mux, decoder, encoder, errhandler, formatter),
+		SubscribeForPolicyChange: NewSubscribeForPolicyChangeHandler(e.SubscribeForPolicyChange, mux, decoder, encoder, errhandler, formatter),
 	}
 }
 
@@ -78,7 +78,7 @@ func (s *Server) Use(m func(http.Handler) http.Handler) {
 	s.Lock = m(s.Lock)
 	s.Unlock = m(s.Unlock)
 	s.ListPolicies = m(s.ListPolicies)
-	s.Webhooks = m(s.Webhooks)
+	s.SubscribeForPolicyChange = m(s.SubscribeForPolicyChange)
 }
 
 // MethodNames returns the methods served.
@@ -90,7 +90,7 @@ func Mount(mux goahttp.Muxer, h *Server) {
 	MountLockHandler(mux, h.Lock)
 	MountUnlockHandler(mux, h.Unlock)
 	MountListPoliciesHandler(mux, h.ListPolicies)
-	MountWebhooksHandler(mux, h.Webhooks)
+	MountSubscribeForPolicyChangeHandler(mux, h.SubscribeForPolicyChange)
 }
 
 // Mount configures the mux to serve the policy endpoints.
@@ -304,9 +304,9 @@ func NewListPoliciesHandler(
 	})
 }
 
-// MountWebhooksHandler configures the mux to serve the "policy" service
-// "Webhooks" endpoint.
-func MountWebhooksHandler(mux goahttp.Muxer, h http.Handler) {
+// MountSubscribeForPolicyChangeHandler configures the mux to serve the
+// "policy" service "SubscribeForPolicyChange" endpoint.
+func MountSubscribeForPolicyChangeHandler(mux goahttp.Muxer, h http.Handler) {
 	f, ok := h.(http.HandlerFunc)
 	if !ok {
 		f = func(w http.ResponseWriter, r *http.Request) {
@@ -316,9 +316,10 @@ func MountWebhooksHandler(mux goahttp.Muxer, h http.Handler) {
 	mux.Handle("POST", "/policy/{group}/{policyname}/{version}/notifychange", f)
 }
 
-// NewWebhooksHandler creates a HTTP handler which loads the HTTP request and
-// calls the "policy" service "Webhooks" endpoint.
-func NewWebhooksHandler(
+// NewSubscribeForPolicyChangeHandler creates a HTTP handler which loads the
+// HTTP request and calls the "policy" service "SubscribeForPolicyChange"
+// endpoint.
+func NewSubscribeForPolicyChangeHandler(
 	endpoint goa.Endpoint,
 	mux goahttp.Muxer,
 	decoder func(*http.Request) goahttp.Decoder,
@@ -327,13 +328,13 @@ func NewWebhooksHandler(
 	formatter func(ctx context.Context, err error) goahttp.Statuser,
 ) http.Handler {
 	var (
-		decodeRequest  = DecodeWebhooksRequest(mux, decoder)
-		encodeResponse = EncodeWebhooksResponse(encoder)
+		decodeRequest  = DecodeSubscribeForPolicyChangeRequest(mux, decoder)
+		encodeResponse = EncodeSubscribeForPolicyChangeResponse(encoder)
 		encodeError    = goahttp.ErrorEncoder(encoder, formatter)
 	)
 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		ctx := context.WithValue(r.Context(), goahttp.AcceptTypeKey, r.Header.Get("Accept"))
-		ctx = context.WithValue(ctx, goa.MethodKey, "Webhooks")
+		ctx = context.WithValue(ctx, goa.MethodKey, "SubscribeForPolicyChange")
 		ctx = context.WithValue(ctx, goa.ServiceKey, "policy")
 		payload, err := decodeRequest(r)
 		if err != nil {
diff --git a/gen/http/policy/server/types.go b/gen/http/policy/server/types.go
index 5b878ce0066eddccb820c2bad7800f69e1b85d88..a64411480b7837686fdc4bf106d7ff7e06ae25aa 100644
--- a/gen/http/policy/server/types.go
+++ b/gen/http/policy/server/types.go
@@ -8,13 +8,15 @@
 package server
 
 import (
+	"unicode/utf8"
+
 	policy "gitlab.eclipse.org/eclipse/xfsc/tsa/policy/gen/policy"
 	goa "goa.design/goa/v3/pkg"
 )
 
-// WebhooksRequestBody is the type of the "policy" service "Webhooks" endpoint
-// HTTP request body.
-type WebhooksRequestBody struct {
+// SubscribeForPolicyChangeRequestBody is the type of the "policy" service
+// "SubscribeForPolicyChange" endpoint HTTP request body.
+type SubscribeForPolicyChangeRequestBody struct {
 	// Subscriber webhook url.
 	WebhookURL *string `form:"webhook_url,omitempty" json:"webhook_url,omitempty" xml:"webhook_url,omitempty"`
 	// Name of the subscriber for policy.
@@ -110,8 +112,9 @@ func NewListPoliciesPoliciesRequest(locked *bool, rego *bool, data *bool, dataCo
 	return v
 }
 
-// NewWebhooksWebHooksRequest builds a policy service Webhooks endpoint payload.
-func NewWebhooksWebHooksRequest(body *WebhooksRequestBody, group string, policyname string, version string) *policy.WebHooksRequest {
+// NewSubscribeForPolicyChangeWebHooksRequest builds a policy service
+// SubscribeForPolicyChange endpoint payload.
+func NewSubscribeForPolicyChangeWebHooksRequest(body *SubscribeForPolicyChangeRequestBody, group string, policyname string, version string) *policy.WebHooksRequest {
 	v := &policy.WebHooksRequest{
 		WebhookURL: *body.WebhookURL,
 		Subscriber: *body.Subscriber,
@@ -123,14 +126,27 @@ func NewWebhooksWebHooksRequest(body *WebhooksRequestBody, group string, policyn
 	return v
 }
 
-// ValidateWebhooksRequestBody runs the validations defined on
-// WebhooksRequestBody
-func ValidateWebhooksRequestBody(body *WebhooksRequestBody) (err error) {
+// ValidateSubscribeForPolicyChangeRequestBody runs the validations defined on
+// SubscribeForPolicyChangeRequestBody
+func ValidateSubscribeForPolicyChangeRequestBody(body *SubscribeForPolicyChangeRequestBody) (err error) {
 	if body.WebhookURL == nil {
 		err = goa.MergeErrors(err, goa.MissingFieldError("webhook_url", "body"))
 	}
 	if body.Subscriber == nil {
 		err = goa.MergeErrors(err, goa.MissingFieldError("subscriber", "body"))
 	}
+	if body.WebhookURL != nil {
+		err = goa.MergeErrors(err, goa.ValidateFormat("body.webhook_url", *body.WebhookURL, goa.FormatURI))
+	}
+	if body.Subscriber != nil {
+		if utf8.RuneCountInString(*body.Subscriber) < 3 {
+			err = goa.MergeErrors(err, goa.InvalidLengthError("body.subscriber", *body.Subscriber, utf8.RuneCountInString(*body.Subscriber), 3, true))
+		}
+	}
+	if body.Subscriber != nil {
+		if utf8.RuneCountInString(*body.Subscriber) > 100 {
+			err = goa.MergeErrors(err, goa.InvalidLengthError("body.subscriber", *body.Subscriber, utf8.RuneCountInString(*body.Subscriber), 100, false))
+		}
+	}
 	return
 }
diff --git a/gen/policy/client.go b/gen/policy/client.go
index 26088b1527348298ff3636a986370e9e762cb135..903e7ebd9db811ac3f60391c44242590e67f5cfe 100644
--- a/gen/policy/client.go
+++ b/gen/policy/client.go
@@ -15,21 +15,21 @@ import (
 
 // Client is the "policy" service client.
 type Client struct {
-	EvaluateEndpoint     goa.Endpoint
-	LockEndpoint         goa.Endpoint
-	UnlockEndpoint       goa.Endpoint
-	ListPoliciesEndpoint goa.Endpoint
-	WebhooksEndpoint     goa.Endpoint
+	EvaluateEndpoint                 goa.Endpoint
+	LockEndpoint                     goa.Endpoint
+	UnlockEndpoint                   goa.Endpoint
+	ListPoliciesEndpoint             goa.Endpoint
+	SubscribeForPolicyChangeEndpoint goa.Endpoint
 }
 
 // NewClient initializes a "policy" service client given the endpoints.
-func NewClient(evaluate, lock, unlock, listPolicies, webhooks goa.Endpoint) *Client {
+func NewClient(evaluate, lock, unlock, listPolicies, subscribeForPolicyChange goa.Endpoint) *Client {
 	return &Client{
-		EvaluateEndpoint:     evaluate,
-		LockEndpoint:         lock,
-		UnlockEndpoint:       unlock,
-		ListPoliciesEndpoint: listPolicies,
-		WebhooksEndpoint:     webhooks,
+		EvaluateEndpoint:                 evaluate,
+		LockEndpoint:                     lock,
+		UnlockEndpoint:                   unlock,
+		ListPoliciesEndpoint:             listPolicies,
+		SubscribeForPolicyChangeEndpoint: subscribeForPolicyChange,
 	}
 }
 
@@ -65,10 +65,11 @@ func (c *Client) ListPolicies(ctx context.Context, p *PoliciesRequest) (res *Pol
 	return ires.(*PoliciesResult), nil
 }
 
-// Webhooks calls the "Webhooks" endpoint of the "policy" service.
-func (c *Client) Webhooks(ctx context.Context, p *WebHooksRequest) (res any, err error) {
+// SubscribeForPolicyChange calls the "SubscribeForPolicyChange" endpoint of
+// the "policy" service.
+func (c *Client) SubscribeForPolicyChange(ctx context.Context, p *WebHooksRequest) (res any, err error) {
 	var ires any
-	ires, err = c.WebhooksEndpoint(ctx, p)
+	ires, err = c.SubscribeForPolicyChangeEndpoint(ctx, p)
 	if err != nil {
 		return
 	}
diff --git a/gen/policy/endpoints.go b/gen/policy/endpoints.go
index 7b2afbe9474495eaceee08f254d1812b14f1e600..885b9fbac26fa62abd8f11294f0ada9f99f538c5 100644
--- a/gen/policy/endpoints.go
+++ b/gen/policy/endpoints.go
@@ -15,21 +15,21 @@ import (
 
 // Endpoints wraps the "policy" service endpoints.
 type Endpoints struct {
-	Evaluate     goa.Endpoint
-	Lock         goa.Endpoint
-	Unlock       goa.Endpoint
-	ListPolicies goa.Endpoint
-	Webhooks     goa.Endpoint
+	Evaluate                 goa.Endpoint
+	Lock                     goa.Endpoint
+	Unlock                   goa.Endpoint
+	ListPolicies             goa.Endpoint
+	SubscribeForPolicyChange goa.Endpoint
 }
 
 // NewEndpoints wraps the methods of the "policy" service with endpoints.
 func NewEndpoints(s Service) *Endpoints {
 	return &Endpoints{
-		Evaluate:     NewEvaluateEndpoint(s),
-		Lock:         NewLockEndpoint(s),
-		Unlock:       NewUnlockEndpoint(s),
-		ListPolicies: NewListPoliciesEndpoint(s),
-		Webhooks:     NewWebhooksEndpoint(s),
+		Evaluate:                 NewEvaluateEndpoint(s),
+		Lock:                     NewLockEndpoint(s),
+		Unlock:                   NewUnlockEndpoint(s),
+		ListPolicies:             NewListPoliciesEndpoint(s),
+		SubscribeForPolicyChange: NewSubscribeForPolicyChangeEndpoint(s),
 	}
 }
 
@@ -39,7 +39,7 @@ func (e *Endpoints) Use(m func(goa.Endpoint) goa.Endpoint) {
 	e.Lock = m(e.Lock)
 	e.Unlock = m(e.Unlock)
 	e.ListPolicies = m(e.ListPolicies)
-	e.Webhooks = m(e.Webhooks)
+	e.SubscribeForPolicyChange = m(e.SubscribeForPolicyChange)
 }
 
 // NewEvaluateEndpoint returns an endpoint function that calls the method
@@ -78,11 +78,11 @@ func NewListPoliciesEndpoint(s Service) goa.Endpoint {
 	}
 }
 
-// NewWebhooksEndpoint returns an endpoint function that calls the method
-// "Webhooks" of service "policy".
-func NewWebhooksEndpoint(s Service) goa.Endpoint {
+// NewSubscribeForPolicyChangeEndpoint returns an endpoint function that calls
+// the method "SubscribeForPolicyChange" of service "policy".
+func NewSubscribeForPolicyChangeEndpoint(s Service) goa.Endpoint {
 	return func(ctx context.Context, req any) (any, error) {
 		p := req.(*WebHooksRequest)
-		return s.Webhooks(ctx, p)
+		return s.SubscribeForPolicyChange(ctx, p)
 	}
 }
diff --git a/gen/policy/service.go b/gen/policy/service.go
index 7f05e1b38eba0796490fa157fabd2a94963449f9..d9dcf756677e179392e620d299182bdf85872558 100644
--- a/gen/policy/service.go
+++ b/gen/policy/service.go
@@ -21,8 +21,9 @@ type Service interface {
 	Unlock(context.Context, *UnlockRequest) (err error)
 	// List policies from storage with optional filters.
 	ListPolicies(context.Context, *PoliciesRequest) (res *PoliciesResult, err error)
-	// Gives ability to user to subscribe for policy change via webhooks
-	Webhooks(context.Context, *WebHooksRequest) (res any, err error)
+	// Subscribe for policy change notifications by registering webhook callbacks
+	// which the policy service will call.
+	SubscribeForPolicyChange(context.Context, *WebHooksRequest) (res any, err error)
 }
 
 // ServiceName is the name of the service as defined in the design. This is the
@@ -33,7 +34,7 @@ const ServiceName = "policy"
 // MethodNames lists the service method names as defined in the design. These
 // are the same values that are set in the endpoint request contexts under the
 // MethodKey key.
-var MethodNames = [5]string{"Evaluate", "Lock", "Unlock", "ListPolicies", "Webhooks"}
+var MethodNames = [5]string{"Evaluate", "Lock", "Unlock", "ListPolicies", "SubscribeForPolicyChange"}
 
 // EvaluateRequest is the payload type of the policy service Evaluate method.
 type EvaluateRequest struct {
@@ -115,7 +116,8 @@ type UnlockRequest struct {
 	Version string
 }
 
-// WebHooksRequest is the payload type of the policy service Webhooks method.
+// WebHooksRequest is the payload type of the policy service
+// SubscribeForPolicyChange method.
 type WebHooksRequest struct {
 	// Subscriber webhook url.
 	WebhookURL string
diff --git a/go.mod b/go.mod
index 5ca7ccbef8284e794ed656f2a0b4bba9505f8390..1f424a340a6ab071651ddd858b32d214f782eae6 100644
--- a/go.mod
+++ b/go.mod
@@ -19,6 +19,7 @@ require (
 )
 
 require (
+	github.com/google/flatbuffers v2.0.8+incompatible // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
 	github.com/minio/highwayhash v1.0.2 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
diff --git a/go.sum b/go.sum
index bcd93762d3ed27aca057d268aae713071d0e37b6..d9e84fad5348e1e0fd225fa0787daa62d3916a2f 100644
--- a/go.sum
+++ b/go.sum
@@ -59,7 +59,8 @@ github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu
 github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
 github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw=
+github.com/google/flatbuffers v2.0.8+incompatible h1:ivUb1cGomAB101ZM1T0nOiWz9pSrTMoa9+EiY7igmkM=
+github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
 github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
diff --git a/internal/notify/notify.go b/internal/notify/notify.go
index 6417cfed9f4f7f64226e854de40b7fb92d116871..9edeb233e9c0ff083ff5a68e05d02725b0d2cdaa 100644
--- a/internal/notify/notify.go
+++ b/internal/notify/notify.go
@@ -4,11 +4,13 @@ import (
 	"bytes"
 	"context"
 	"encoding/json"
+	"errors"
 	"fmt"
 	"net/http"
 
-	"gitlab.eclipse.org/eclipse/xfsc/tsa/policy/internal/storage"
 	"go.uber.org/zap"
+
+	"gitlab.eclipse.org/eclipse/xfsc/tsa/policy/internal/storage"
 )
 
 //go:generate counterfeiter . Events
@@ -19,7 +21,7 @@ type Events interface {
 }
 
 type Storage interface {
-	FindAllSubscribed(ctx context.Context, policyName, policyGroup, policyVersion string) ([]*storage.Subscriber, error)
+	PolicyChangeSubscribers(ctx context.Context, policyName, policyGroup, policyVersion string) ([]*storage.Subscriber, error)
 }
 
 type Notifier struct {
@@ -37,59 +39,71 @@ type EventPolicyChange struct {
 
 // New creates a policy change notifier for interested subscribers.
 // It can notify for policy changes both via MessageQueue or Web hooks.
-func New(events Events, client *http.Client, storage Storage, logger *zap.Logger) *Notifier {
-	return &Notifier{events: events, client: client, storage: storage, logger: logger}
+func New(events Events, storage Storage, client *http.Client, logger *zap.Logger) *Notifier {
+	return &Notifier{events: events, storage: storage, client: client, logger: logger}
 }
 
 // PolicyDataChange is called when the policies source code or data are updated
 // in storage. The function will notify subscribers of the given changes.
 func (n *Notifier) PolicyDataChange(ctx context.Context, policyName, policyGroup, policyVersion string) error {
-	data := &EventPolicyChange{Name: policyName, Version: policyVersion, Group: policyGroup}
+	logger := n.logger.With(
+		zap.String("operation", "PolicyDataChange"),
+	)
+
+	event := &EventPolicyChange{Name: policyName, Version: policyVersion, Group: policyGroup}
+	var joinedErrors error
+
+	responseData, err := json.Marshal(event)
+	if err != nil {
+		logger.Error("error while marshal the evet", zap.Error(err))
+		joinedErrors = errors.Join(joinedErrors, err)
+	}
+
+	subscribers, err := n.storage.PolicyChangeSubscribers(ctx, event.Name, event.Group, event.Version)
+	if err != nil {
+		logger.Error("error while getting subscribers", zap.Error(err))
+		joinedErrors = errors.Join(err)
+	}
+
+	for _, subscriber := range subscribers {
+		n.notifySubscribers(ctx, subscriber, event, responseData)
+	}
 
-	n.notifySubscribers(ctx, data)
+	err = n.events.Send(ctx, event)
+	if err != nil {
+		joinedErrors = errors.Join(joinedErrors, err)
+	}
 
-	return n.events.Send(ctx, data)
+	return joinedErrors
 }
 
-func (n *Notifier) notifySubscribers(ctx context.Context, data *EventPolicyChange) {
+func (n *Notifier) notifySubscribers(ctx context.Context, subscriber *storage.Subscriber, event *EventPolicyChange, responseData []byte) {
 	logger := n.logger.With(
 		zap.String("operation", "notifySubscribers"),
-		zap.String("group", data.Group),
-		zap.String("policy", data.Name),
-		zap.String("version", data.Version),
+		zap.String("group", event.Group),
+		zap.String("policy", event.Name),
+		zap.String("version", event.Version),
 	)
 
-	byteData, err := json.Marshal(data)
+	req, err := http.NewRequestWithContext(ctx, http.MethodPost, subscriber.WebhookURL, bytes.NewBuffer(responseData))
 	if err != nil {
-		logger.Error("error while marshal the data", zap.Error(err))
+		err = fmt.Errorf("error while creating request for sending data to subscriber: %s with URL: %s: %w", subscriber.Name, subscriber.WebhookURL, err)
+		logger.Error("error creating request", zap.Error(err))
 	}
+	req.Header.Set("Content-Type", "application/json")
 
-	subscribers, err := n.storage.FindAllSubscribed(ctx, data.Name, data.Group, data.Version)
+	res, err := n.client.Do(req)
 	if err != nil {
-		logger.Error("error while getting subscribers", zap.Error(err))
+		err = fmt.Errorf("error while trying to send data to subscriber: %s with URL: %s: %w", subscriber.Name, subscriber.WebhookURL, err)
+		logger.Error("error sending data", zap.Error(err))
 	}
 
-	for _, subscriber := range subscribers {
-		req, err := http.NewRequestWithContext(ctx, http.MethodPost, subscriber.WebhookURL, bytes.NewBuffer(byteData))
-		if err != nil {
-			err = fmt.Errorf("error while creating request for sending data to subscriber: %s with URL: %s: %w", subscriber.Name, subscriber.WebhookURL, err)
-			logger.Error("error creating request", zap.Error(err))
-		}
-		req.Header.Set("Content-Type", "application/json")
-
-		res, err := n.client.Do(req)
-		if err != nil {
-			err = fmt.Errorf("error while trying to send data to subscriber: %s with URL: %s: %w", subscriber.Name, subscriber.WebhookURL, err)
-			logger.Error("error sending data", zap.Error(err))
-		}
-
-		if res != nil {
-			defer res.Body.Close()
+	if res != nil {
+		defer res.Body.Close()
 
-			if res.StatusCode >= http.StatusBadRequest {
-				err = fmt.Errorf("error: subscriber %s with URL %s didn't respond with status code %d: %w", subscriber.Name, subscriber.WebhookURL, res.StatusCode, err)
-				logger.Error("client did not respond", zap.Error(err))
-			}
+		if res.StatusCode >= http.StatusBadRequest {
+			err = fmt.Errorf("error: subscriber %s with URL %s didn't respond with status code %d: %w", subscriber.Name, subscriber.WebhookURL, res.StatusCode, err)
+			logger.Error("client did not respond", zap.Error(err))
 		}
 	}
 }
diff --git a/internal/notify/notify_test.go b/internal/notify/notify_test.go
index 2b81e0f73fb3089ab28e203854c44166c35fe08a..5947118d1c98c221f2686dba78de42adf02d9af1 100644
--- a/internal/notify/notify_test.go
+++ b/internal/notify/notify_test.go
@@ -25,7 +25,7 @@ func TestNotify_PolicyDataChange(t *testing.T) {
 		{
 			name:              "error when sending event",
 			eventPolicyChange: &notify.EventPolicyChange{Name: "exampleName", Version: "exampleVersion", Group: "exampleGroup"},
-			storage: &notifyfakes.FakeStorage{FindAllSubscribedStub: func(ctx context.Context, s1, s2, s3 string) ([]*storage.Subscriber, error) {
+			storage: &notifyfakes.FakeStorage{PolicyChangeSubscribersStub: func(ctx context.Context, s1, s2, s3 string) ([]*storage.Subscriber, error) {
 				return []*storage.Subscriber{}, nil
 			}},
 			events: &notifyfakes.FakeEvents{SendStub: func(ctx context.Context, a any) error {
@@ -38,7 +38,7 @@ func TestNotify_PolicyDataChange(t *testing.T) {
 		{
 			name:              "sending event is successful",
 			eventPolicyChange: &notify.EventPolicyChange{Name: "exampleName", Version: "exampleVersion", Group: "exampleGroup"},
-			storage: &notifyfakes.FakeStorage{FindAllSubscribedStub: func(ctx context.Context, s1, s2, s3 string) ([]*storage.Subscriber, error) {
+			storage: &notifyfakes.FakeStorage{PolicyChangeSubscribersStub: func(ctx context.Context, s1, s2, s3 string) ([]*storage.Subscriber, error) {
 				return []*storage.Subscriber{}, nil
 			}},
 			events: &notifyfakes.FakeEvents{SendStub: func(ctx context.Context, a any) error {
@@ -49,7 +49,7 @@ func TestNotify_PolicyDataChange(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
-			notifier := notify.New(test.events, http.DefaultClient, test.storage, zap.NewNop())
+			notifier := notify.New(test.events, test.storage, http.DefaultClient, zap.NewNop())
 			err := notifier.PolicyDataChange(context.Background(), test.eventPolicyChange.Name, test.eventPolicyChange.Group, test.eventPolicyChange.Version)
 			if test.errText != "" {
 				assert.ErrorContains(t, err, test.errText)
diff --git a/internal/notify/notifyfakes/fake_storage.go b/internal/notify/notifyfakes/fake_storage.go
index c42f298c057048ad2173177993b48f7bfd63c448..890147999ff4603f9dcb8625adf72bc3ad8da2c0 100644
--- a/internal/notify/notifyfakes/fake_storage.go
+++ b/internal/notify/notifyfakes/fake_storage.go
@@ -10,19 +10,19 @@ import (
 )
 
 type FakeStorage struct {
-	FindAllSubscribedStub        func(context.Context, string, string, string) ([]*storage.Subscriber, error)
-	findAllSubscribedMutex       sync.RWMutex
-	findAllSubscribedArgsForCall []struct {
+	PolicyChangeSubscribersStub        func(context.Context, string, string, string) ([]*storage.Subscriber, error)
+	policyChangeSubscribersMutex       sync.RWMutex
+	policyChangeSubscribersArgsForCall []struct {
 		arg1 context.Context
 		arg2 string
 		arg3 string
 		arg4 string
 	}
-	findAllSubscribedReturns struct {
+	policyChangeSubscribersReturns struct {
 		result1 []*storage.Subscriber
 		result2 error
 	}
-	findAllSubscribedReturnsOnCall map[int]struct {
+	policyChangeSubscribersReturnsOnCall map[int]struct {
 		result1 []*storage.Subscriber
 		result2 error
 	}
@@ -30,19 +30,19 @@ type FakeStorage struct {
 	invocationsMutex sync.RWMutex
 }
 
-func (fake *FakeStorage) FindAllSubscribed(arg1 context.Context, arg2 string, arg3 string, arg4 string) ([]*storage.Subscriber, error) {
-	fake.findAllSubscribedMutex.Lock()
-	ret, specificReturn := fake.findAllSubscribedReturnsOnCall[len(fake.findAllSubscribedArgsForCall)]
-	fake.findAllSubscribedArgsForCall = append(fake.findAllSubscribedArgsForCall, struct {
+func (fake *FakeStorage) PolicyChangeSubscribers(arg1 context.Context, arg2 string, arg3 string, arg4 string) ([]*storage.Subscriber, error) {
+	fake.policyChangeSubscribersMutex.Lock()
+	ret, specificReturn := fake.policyChangeSubscribersReturnsOnCall[len(fake.policyChangeSubscribersArgsForCall)]
+	fake.policyChangeSubscribersArgsForCall = append(fake.policyChangeSubscribersArgsForCall, struct {
 		arg1 context.Context
 		arg2 string
 		arg3 string
 		arg4 string
 	}{arg1, arg2, arg3, arg4})
-	stub := fake.FindAllSubscribedStub
-	fakeReturns := fake.findAllSubscribedReturns
-	fake.recordInvocation("FindAllSubscribed", []interface{}{arg1, arg2, arg3, arg4})
-	fake.findAllSubscribedMutex.Unlock()
+	stub := fake.PolicyChangeSubscribersStub
+	fakeReturns := fake.policyChangeSubscribersReturns
+	fake.recordInvocation("PolicyChangeSubscribers", []interface{}{arg1, arg2, arg3, arg4})
+	fake.policyChangeSubscribersMutex.Unlock()
 	if stub != nil {
 		return stub(arg1, arg2, arg3, arg4)
 	}
@@ -52,46 +52,46 @@ func (fake *FakeStorage) FindAllSubscribed(arg1 context.Context, arg2 string, ar
 	return fakeReturns.result1, fakeReturns.result2
 }
 
-func (fake *FakeStorage) FindAllSubscribedCallCount() int {
-	fake.findAllSubscribedMutex.RLock()
-	defer fake.findAllSubscribedMutex.RUnlock()
-	return len(fake.findAllSubscribedArgsForCall)
+func (fake *FakeStorage) PolicyChangeSubscribersCallCount() int {
+	fake.policyChangeSubscribersMutex.RLock()
+	defer fake.policyChangeSubscribersMutex.RUnlock()
+	return len(fake.policyChangeSubscribersArgsForCall)
 }
 
-func (fake *FakeStorage) FindAllSubscribedCalls(stub func(context.Context, string, string, string) ([]*storage.Subscriber, error)) {
-	fake.findAllSubscribedMutex.Lock()
-	defer fake.findAllSubscribedMutex.Unlock()
-	fake.FindAllSubscribedStub = stub
+func (fake *FakeStorage) PolicyChangeSubscribersCalls(stub func(context.Context, string, string, string) ([]*storage.Subscriber, error)) {
+	fake.policyChangeSubscribersMutex.Lock()
+	defer fake.policyChangeSubscribersMutex.Unlock()
+	fake.PolicyChangeSubscribersStub = stub
 }
 
-func (fake *FakeStorage) FindAllSubscribedArgsForCall(i int) (context.Context, string, string, string) {
-	fake.findAllSubscribedMutex.RLock()
-	defer fake.findAllSubscribedMutex.RUnlock()
-	argsForCall := fake.findAllSubscribedArgsForCall[i]
+func (fake *FakeStorage) PolicyChangeSubscribersArgsForCall(i int) (context.Context, string, string, string) {
+	fake.policyChangeSubscribersMutex.RLock()
+	defer fake.policyChangeSubscribersMutex.RUnlock()
+	argsForCall := fake.policyChangeSubscribersArgsForCall[i]
 	return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4
 }
 
-func (fake *FakeStorage) FindAllSubscribedReturns(result1 []*storage.Subscriber, result2 error) {
-	fake.findAllSubscribedMutex.Lock()
-	defer fake.findAllSubscribedMutex.Unlock()
-	fake.FindAllSubscribedStub = nil
-	fake.findAllSubscribedReturns = struct {
+func (fake *FakeStorage) PolicyChangeSubscribersReturns(result1 []*storage.Subscriber, result2 error) {
+	fake.policyChangeSubscribersMutex.Lock()
+	defer fake.policyChangeSubscribersMutex.Unlock()
+	fake.PolicyChangeSubscribersStub = nil
+	fake.policyChangeSubscribersReturns = struct {
 		result1 []*storage.Subscriber
 		result2 error
 	}{result1, result2}
 }
 
-func (fake *FakeStorage) FindAllSubscribedReturnsOnCall(i int, result1 []*storage.Subscriber, result2 error) {
-	fake.findAllSubscribedMutex.Lock()
-	defer fake.findAllSubscribedMutex.Unlock()
-	fake.FindAllSubscribedStub = nil
-	if fake.findAllSubscribedReturnsOnCall == nil {
-		fake.findAllSubscribedReturnsOnCall = make(map[int]struct {
+func (fake *FakeStorage) PolicyChangeSubscribersReturnsOnCall(i int, result1 []*storage.Subscriber, result2 error) {
+	fake.policyChangeSubscribersMutex.Lock()
+	defer fake.policyChangeSubscribersMutex.Unlock()
+	fake.PolicyChangeSubscribersStub = nil
+	if fake.policyChangeSubscribersReturnsOnCall == nil {
+		fake.policyChangeSubscribersReturnsOnCall = make(map[int]struct {
 			result1 []*storage.Subscriber
 			result2 error
 		})
 	}
-	fake.findAllSubscribedReturnsOnCall[i] = struct {
+	fake.policyChangeSubscribersReturnsOnCall[i] = struct {
 		result1 []*storage.Subscriber
 		result2 error
 	}{result1, result2}
@@ -100,8 +100,8 @@ func (fake *FakeStorage) FindAllSubscribedReturnsOnCall(i int, result1 []*storag
 func (fake *FakeStorage) Invocations() map[string][][]interface{} {
 	fake.invocationsMutex.RLock()
 	defer fake.invocationsMutex.RUnlock()
-	fake.findAllSubscribedMutex.RLock()
-	defer fake.findAllSubscribedMutex.RUnlock()
+	fake.policyChangeSubscribersMutex.RLock()
+	defer fake.policyChangeSubscribersMutex.RUnlock()
 	copiedInvocations := map[string][][]interface{}{}
 	for key, value := range fake.invocations {
 		copiedInvocations[key] = value
diff --git a/internal/service/policy/policyfakes/fake_storage.go b/internal/service/policy/policyfakes/fake_storage.go
index da008faa9c5cb5fcfd18e65df24bcedf3073f6d0..bb43a39ca7785a99eca1da6c2a403dac53bc71b9 100644
--- a/internal/service/policy/policyfakes/fake_storage.go
+++ b/internal/service/policy/policyfakes/fake_storage.go
@@ -10,32 +10,18 @@ import (
 )
 
 type FakeStorage struct {
-	CreateSubscriberStub        func(context.Context, *storage.Subscriber) error
+	CreateSubscriberStub        func(context.Context, *storage.Subscriber) (*storage.Subscriber, error)
 	createSubscriberMutex       sync.RWMutex
 	createSubscriberArgsForCall []struct {
 		arg1 context.Context
 		arg2 *storage.Subscriber
 	}
 	createSubscriberReturns struct {
-		result1 error
-	}
-	createSubscriberReturnsOnCall map[int]struct {
-		result1 error
-	}
-	FindAllSubscribedStub        func(context.Context, string, string, string) ([]*storage.Subscriber, error)
-	findAllSubscribedMutex       sync.RWMutex
-	findAllSubscribedArgsForCall []struct {
-		arg1 context.Context
-		arg2 string
-		arg3 string
-		arg4 string
-	}
-	findAllSubscribedReturns struct {
-		result1 []*storage.Subscriber
+		result1 *storage.Subscriber
 		result2 error
 	}
-	findAllSubscribedReturnsOnCall map[int]struct {
-		result1 []*storage.Subscriber
+	createSubscriberReturnsOnCall map[int]struct {
+		result1 *storage.Subscriber
 		result2 error
 	}
 	GetPoliciesStub        func(context.Context, *bool) ([]*storage.Policy, error)
@@ -87,7 +73,7 @@ type FakeStorage struct {
 	invocationsMutex sync.RWMutex
 }
 
-func (fake *FakeStorage) CreateSubscriber(arg1 context.Context, arg2 *storage.Subscriber) error {
+func (fake *FakeStorage) CreateSubscriber(arg1 context.Context, arg2 *storage.Subscriber) (*storage.Subscriber, error) {
 	fake.createSubscriberMutex.Lock()
 	ret, specificReturn := fake.createSubscriberReturnsOnCall[len(fake.createSubscriberArgsForCall)]
 	fake.createSubscriberArgsForCall = append(fake.createSubscriberArgsForCall, struct {
@@ -102,9 +88,9 @@ func (fake *FakeStorage) CreateSubscriber(arg1 context.Context, arg2 *storage.Su
 		return stub(arg1, arg2)
 	}
 	if specificReturn {
-		return ret.result1
+		return ret.result1, ret.result2
 	}
-	return fakeReturns.result1
+	return fakeReturns.result1, fakeReturns.result2
 }
 
 func (fake *FakeStorage) CreateSubscriberCallCount() int {
@@ -113,7 +99,7 @@ func (fake *FakeStorage) CreateSubscriberCallCount() int {
 	return len(fake.createSubscriberArgsForCall)
 }
 
-func (fake *FakeStorage) CreateSubscriberCalls(stub func(context.Context, *storage.Subscriber) error) {
+func (fake *FakeStorage) CreateSubscriberCalls(stub func(context.Context, *storage.Subscriber) (*storage.Subscriber, error)) {
 	fake.createSubscriberMutex.Lock()
 	defer fake.createSubscriberMutex.Unlock()
 	fake.CreateSubscriberStub = stub
@@ -126,92 +112,28 @@ func (fake *FakeStorage) CreateSubscriberArgsForCall(i int) (context.Context, *s
 	return argsForCall.arg1, argsForCall.arg2
 }
 
-func (fake *FakeStorage) CreateSubscriberReturns(result1 error) {
+func (fake *FakeStorage) CreateSubscriberReturns(result1 *storage.Subscriber, result2 error) {
 	fake.createSubscriberMutex.Lock()
 	defer fake.createSubscriberMutex.Unlock()
 	fake.CreateSubscriberStub = nil
 	fake.createSubscriberReturns = struct {
-		result1 error
-	}{result1}
+		result1 *storage.Subscriber
+		result2 error
+	}{result1, result2}
 }
 
-func (fake *FakeStorage) CreateSubscriberReturnsOnCall(i int, result1 error) {
+func (fake *FakeStorage) CreateSubscriberReturnsOnCall(i int, result1 *storage.Subscriber, result2 error) {
 	fake.createSubscriberMutex.Lock()
 	defer fake.createSubscriberMutex.Unlock()
 	fake.CreateSubscriberStub = nil
 	if fake.createSubscriberReturnsOnCall == nil {
 		fake.createSubscriberReturnsOnCall = make(map[int]struct {
-			result1 error
-		})
-	}
-	fake.createSubscriberReturnsOnCall[i] = struct {
-		result1 error
-	}{result1}
-}
-
-func (fake *FakeStorage) FindAllSubscribed(arg1 context.Context, arg2 string, arg3 string, arg4 string) ([]*storage.Subscriber, error) {
-	fake.findAllSubscribedMutex.Lock()
-	ret, specificReturn := fake.findAllSubscribedReturnsOnCall[len(fake.findAllSubscribedArgsForCall)]
-	fake.findAllSubscribedArgsForCall = append(fake.findAllSubscribedArgsForCall, struct {
-		arg1 context.Context
-		arg2 string
-		arg3 string
-		arg4 string
-	}{arg1, arg2, arg3, arg4})
-	stub := fake.FindAllSubscribedStub
-	fakeReturns := fake.findAllSubscribedReturns
-	fake.recordInvocation("FindAllSubscribed", []interface{}{arg1, arg2, arg3, arg4})
-	fake.findAllSubscribedMutex.Unlock()
-	if stub != nil {
-		return stub(arg1, arg2, arg3, arg4)
-	}
-	if specificReturn {
-		return ret.result1, ret.result2
-	}
-	return fakeReturns.result1, fakeReturns.result2
-}
-
-func (fake *FakeStorage) FindAllSubscribedCallCount() int {
-	fake.findAllSubscribedMutex.RLock()
-	defer fake.findAllSubscribedMutex.RUnlock()
-	return len(fake.findAllSubscribedArgsForCall)
-}
-
-func (fake *FakeStorage) FindAllSubscribedCalls(stub func(context.Context, string, string, string) ([]*storage.Subscriber, error)) {
-	fake.findAllSubscribedMutex.Lock()
-	defer fake.findAllSubscribedMutex.Unlock()
-	fake.FindAllSubscribedStub = stub
-}
-
-func (fake *FakeStorage) FindAllSubscribedArgsForCall(i int) (context.Context, string, string, string) {
-	fake.findAllSubscribedMutex.RLock()
-	defer fake.findAllSubscribedMutex.RUnlock()
-	argsForCall := fake.findAllSubscribedArgsForCall[i]
-	return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4
-}
-
-func (fake *FakeStorage) FindAllSubscribedReturns(result1 []*storage.Subscriber, result2 error) {
-	fake.findAllSubscribedMutex.Lock()
-	defer fake.findAllSubscribedMutex.Unlock()
-	fake.FindAllSubscribedStub = nil
-	fake.findAllSubscribedReturns = struct {
-		result1 []*storage.Subscriber
-		result2 error
-	}{result1, result2}
-}
-
-func (fake *FakeStorage) FindAllSubscribedReturnsOnCall(i int, result1 []*storage.Subscriber, result2 error) {
-	fake.findAllSubscribedMutex.Lock()
-	defer fake.findAllSubscribedMutex.Unlock()
-	fake.FindAllSubscribedStub = nil
-	if fake.findAllSubscribedReturnsOnCall == nil {
-		fake.findAllSubscribedReturnsOnCall = make(map[int]struct {
-			result1 []*storage.Subscriber
+			result1 *storage.Subscriber
 			result2 error
 		})
 	}
-	fake.findAllSubscribedReturnsOnCall[i] = struct {
-		result1 []*storage.Subscriber
+	fake.createSubscriberReturnsOnCall[i] = struct {
+		result1 *storage.Subscriber
 		result2 error
 	}{result1, result2}
 }
@@ -418,8 +340,6 @@ func (fake *FakeStorage) Invocations() map[string][][]interface{} {
 	defer fake.invocationsMutex.RUnlock()
 	fake.createSubscriberMutex.RLock()
 	defer fake.createSubscriberMutex.RUnlock()
-	fake.findAllSubscribedMutex.RLock()
-	defer fake.findAllSubscribedMutex.RUnlock()
 	fake.getPoliciesMutex.RLock()
 	defer fake.getPoliciesMutex.RUnlock()
 	fake.policyMutex.RLock()
diff --git a/internal/service/policy/service.go b/internal/service/policy/service.go
index ed8355d2e9f2e55204ee72282c85fde29d71c5c4..c18868ad57789d416434a168836fed1e8d45a882 100644
--- a/internal/service/policy/service.go
+++ b/internal/service/policy/service.go
@@ -30,7 +30,7 @@ type Storage interface {
 	Policy(ctx context.Context, group, name, version string) (*storage.Policy, error)
 	SetPolicyLock(ctx context.Context, group, name, version string, lock bool) error
 	GetPolicies(ctx context.Context, locked *bool) ([]*storage.Policy, error)
-	CreateSubscriber(ctx context.Context, subscriber *storage.Subscriber) error
+	CreateSubscriber(ctx context.Context, subscriber *storage.Subscriber) (*storage.Subscriber, error)
 }
 
 type RegoCache interface {
@@ -242,8 +242,8 @@ func (s *Service) ListPolicies(ctx context.Context, req *policy.PoliciesRequest)
 	return &policy.PoliciesResult{Policies: policiesResult}, nil
 }
 
-func (s *Service) Webhooks(ctx context.Context, req *policy.WebHooksRequest) (any, error) {
-	err := s.storage.CreateSubscriber(ctx, &storage.Subscriber{
+func (s *Service) SubscribeForPolicyChange(ctx context.Context, req *policy.WebHooksRequest) (any, error) {
+	subscriber, err := s.storage.CreateSubscriber(ctx, &storage.Subscriber{
 		Name:          req.Subscriber,
 		WebhookURL:    req.WebhookURL,
 		PolicyName:    req.Policyname,
@@ -254,7 +254,7 @@ func (s *Service) Webhooks(ctx context.Context, req *policy.WebHooksRequest) (an
 		return nil, err
 	}
 
-	return nil, nil
+	return subscriber, nil
 }
 
 // prepareQuery tries to get a prepared query from the regocache.
diff --git a/internal/storage/subscribers.go b/internal/storage/subscribers.go
index 5ddf9b9402aeea5a88cb208fe7ec0544e1b7cdf6..986476c226c25c017d80201546df9a4d75ebd975 100644
--- a/internal/storage/subscribers.go
+++ b/internal/storage/subscribers.go
@@ -2,10 +2,13 @@ package storage
 
 import (
 	"context"
+	"errors"
+	"fmt"
 	"time"
 
 	"go.mongodb.org/mongo-driver/bson"
 	"go.mongodb.org/mongo-driver/bson/primitive"
+	"go.mongodb.org/mongo-driver/mongo"
 )
 
 type Subscriber struct {
@@ -17,38 +20,78 @@ type Subscriber struct {
 	PolicyVersion string
 	CreatedAt     time.Time
 	UpdatedAt     time.Time
-	DeletedAt     *time.Time
 }
 
-func (s *Storage) CreateSubscriber(ctx context.Context, subscriber *Subscriber) error {
+func (s *Storage) CreateSubscriber(ctx context.Context, subscriber *Subscriber) (*Subscriber, error) {
 	subscriber.CreatedAt = time.Now()
 	subscriber.UpdatedAt = time.Now()
 	subscriber.ID = primitive.NewObjectID()
 
-	_, err := s.subscriber.InsertOne(ctx, subscriber)
+	_, err := s.isPolicyExist(ctx, subscriber.PolicyName, subscriber.PolicyGroup, subscriber.PolicyVersion)
 	if err != nil {
-		return err
+		return nil, err
+	}
+
+	subscriberExist, err := s.isSubscriberExist(ctx, subscriber)
+	if err != nil {
+		return nil, err
+	}
+
+	if subscriberExist {
+		return nil, fmt.Errorf("subscriber already exists")
+	}
+
+	_, err = s.subscriber.InsertOne(ctx, subscriber)
+	if err != nil {
+		return nil, err
 	}
 
-	return nil
+	return subscriber, nil
 }
 
-func (s *Storage) FindAllSubscribed(ctx context.Context, policyName, policyGroup, policyVersion string) ([]*Subscriber, error) {
+func (s *Storage) PolicyChangeSubscribers(ctx context.Context, policyName, policyGroup, policyVersion string) ([]*Subscriber, error) {
 	cursor, err := s.subscriber.Find(ctx, bson.M{
 		"policyname":    policyName,
 		"policygroup":   policyGroup,
 		"policyversion": policyVersion,
 	})
-
 	if err != nil {
 		return nil, err
 	}
 
 	subscribers := []*Subscriber{}
-
 	if err := cursor.All(ctx, &subscribers); err != nil {
 		return nil, err
 	}
 
 	return subscribers, nil
 }
+
+func (s *Storage) isSubscriberExist(ctx context.Context, subscriber *Subscriber) (bool, error) {
+	err := s.subscriber.FindOne(ctx, bson.M{
+		"name":          subscriber.Name,
+		"webhookurl":    subscriber.WebhookURL,
+		"policyname":    subscriber.PolicyName,
+		"policygroup":   subscriber.PolicyGroup,
+		"policyversion": subscriber.PolicyVersion,
+	}).Err()
+	if err != nil {
+		if errors.Is(err, mongo.ErrNoDocuments) {
+			return false, nil
+		}
+		return false, err
+	}
+	return true, nil
+}
+
+func (s *Storage) isPolicyExist(ctx context.Context, name, group, version string) (bool, error) {
+	err := s.policy.FindOne(ctx, bson.M{
+		"name":    name,
+		"group":   group,
+		"version": version,
+	}).Err()
+	if err != nil {
+		return false, err
+	}
+	return true, nil
+}