diff --git a/manifests/automationservice.yaml b/manifests/automationservice.yaml
deleted file mode 120000
index 5e8d3c1c82db0c03119f29865e2a7edabcdfb0eb..0000000000000000000000000000000000000000
--- a/manifests/automationservice.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../src/automation/target/kubernetes/kubernetes.yml
\ No newline at end of file
diff --git a/manifests/automationservice.yaml b/manifests/automationservice.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..4dacf3998c3991a441dc374ca6c6abc29e8d3b80
--- /dev/null
+++ b/manifests/automationservice.yaml
@@ -0,0 +1,98 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+---
+apiVersion: v1
+kind: Service
+metadata:
+  annotations:
+    app.quarkus.io/build-timestamp: 2022-09-19 - 10:48:18 +0000
+  labels:
+    app.kubernetes.io/name: automationservice
+    app: automationservice
+  name: automationservice
+spec:
+  ports:
+    - name: grpc
+      port: 5050
+      targetPort: 5050
+    - name: http
+      port: 8080
+      targetPort: 8080
+  selector:
+    app.kubernetes.io/name: automationservice
+  type: ClusterIP
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  annotations:
+    app.quarkus.io/build-timestamp: 2022-09-19 - 10:48:18 +0000
+  labels:
+    app: automationservice
+    app.kubernetes.io/name: automationservice
+  name: automationservice
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: automationservice
+  template:
+    metadata:
+      annotations:
+        app.quarkus.io/build-timestamp: 2022-09-19 - 10:48:18 +0000
+      labels:
+        app: automationservice
+        app.kubernetes.io/name: automationservice
+    spec:
+      containers:
+        - env:
+            - name: KUBERNETES_NAMESPACE
+              valueFrom:
+                fieldRef:
+                  fieldPath: metadata.namespace
+            - name: CONTEXT_SERVICE_HOST
+              value: contextservice
+            - name: DEVICE_SERVICE_HOST
+              value: deviceservice
+          image: labs.etsi.org:5050/tfs/controller/automation:0.2.0
+          imagePullPolicy: Always
+          livenessProbe:
+            failureThreshold: 3
+            httpGet:
+              path: /q/health/live
+              port: 8080
+              scheme: HTTP
+            initialDelaySeconds: 2
+            periodSeconds: 10
+            successThreshold: 1
+            timeoutSeconds: 10
+          name: automationservice
+          ports:
+            - containerPort: 5050
+              name: grpc
+              protocol: TCP
+            - containerPort: 8080
+              name: http
+              protocol: TCP
+          readinessProbe:
+            failureThreshold: 3
+            httpGet:
+              path: /q/health/ready
+              port: 8080
+              scheme: HTTP
+            initialDelaySeconds: 2
+            periodSeconds: 10
+            successThreshold: 1
+            timeoutSeconds: 10
diff --git a/manifests/policyservice.yaml b/manifests/policyservice.yaml
deleted file mode 120000
index bb28f6e2cff4c6b50e44f049dec6a53d31922e86..0000000000000000000000000000000000000000
--- a/manifests/policyservice.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../src/policy/target/kubernetes/kubernetes.yml
\ No newline at end of file
diff --git a/manifests/policyservice.yaml b/manifests/policyservice.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..40516e5cc3fdd1fb993a1248ad36ea7551edfc40
--- /dev/null
+++ b/manifests/policyservice.yaml
@@ -0,0 +1,103 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+---
+apiVersion: v1
+kind: Service
+metadata:
+  annotations:
+    app.quarkus.io/commit-id: e369fc6b4de63303f91e1fd3de0b6a591a86c0f5
+    app.quarkus.io/build-timestamp: 2022-11-18 - 12:56:37 +0000
+  labels:
+    app.kubernetes.io/name: policyservice
+    app: policyservice
+  name: policyservice
+spec:
+  ports:
+    - name: http
+      port: 8080
+      targetPort: 8080
+    - name: grpc
+      port: 6060
+      targetPort: 6060
+  selector:
+    app.kubernetes.io/name: policyservice
+  type: ClusterIP
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  annotations:
+    app.quarkus.io/commit-id: e369fc6b4de63303f91e1fd3de0b6a591a86c0f5
+    app.quarkus.io/build-timestamp: 2022-11-22 - 14:10:01 +0000
+  labels:
+    app: policyservice
+    app.kubernetes.io/name: policyservice
+  name: policyservice
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: policyservice
+  template:
+    metadata:
+      annotations:
+        app.quarkus.io/commit-id: e369fc6b4de63303f91e1fd3de0b6a591a86c0f5
+        app.quarkus.io/build-timestamp: 2022-11-22 - 14:10:01 +0000
+      labels:
+        app: policyservice
+        app.kubernetes.io/name: policyservice
+    spec:
+      containers:
+        - env:
+            - name: KUBERNETES_NAMESPACE
+              valueFrom:
+                fieldRef:
+                  fieldPath: metadata.namespace
+            - name: MONITORING_SERVICE_HOST
+              value: monitoringservice
+            - name: CONTEXT_SERVICE_HOST
+              value: contextservice
+            - name: SERVICE_SERVICE_HOST
+              value: serviceservice
+          image: labs.etsi.org:5050/tfs/controller/policy:0.1.0
+          imagePullPolicy: Always
+          livenessProbe:
+            failureThreshold: 3
+            httpGet:
+              path: /q/health/live
+              port: 8080
+              scheme: HTTP
+            initialDelaySeconds: 2
+            periodSeconds: 10
+            successThreshold: 1
+            timeoutSeconds: 10
+          name: policyservice
+          ports:
+            - containerPort: 8080
+              name: http
+              protocol: TCP
+            - containerPort: 6060
+              name: grpc
+              protocol: TCP
+          readinessProbe:
+            failureThreshold: 3
+            httpGet:
+              path: /q/health/ready
+              port: 8080
+              scheme: HTTP
+            initialDelaySeconds: 2
+            periodSeconds: 10
+            successThreshold: 1
+            timeoutSeconds: 10
diff --git a/src/automation/Dockerfile b/src/automation/Dockerfile
deleted file mode 120000
index eec732273e12372d1a11fef9d958b124e9d8df1f..0000000000000000000000000000000000000000
--- a/src/automation/Dockerfile
+++ /dev/null
@@ -1 +0,0 @@
-src/main/docker/Dockerfile.multistage.jvm
\ No newline at end of file
diff --git a/src/automation/Dockerfile b/src/automation/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..43fef96b4f72497c26ae9b3f457791b357249e81
--- /dev/null
+++ b/src/automation/Dockerfile
@@ -0,0 +1,67 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Multi-stage Docker image build
+
+# Stage 1
+FROM maven:3-jdk-11 AS builder
+
+# Define working directory
+WORKDIR /app
+
+# Copy every file in working directory, as defined in .dockerignore file
+COPY ./pom.xml pom.xml
+COPY ./src src/
+COPY ./target/generated-sources/ target/generated-sources/
+RUN mvn --errors --batch-mode package -Dmaven.test.skip=true
+
+# Stage 2
+FROM builder AS unit-test
+
+RUN mvn --errors --batch-mode -Pgenerate-consolidated-coverage verify
+
+# Stage 3
+FROM registry.access.redhat.com/ubi8/ubi-minimal:8.4 AS release
+
+ARG JAVA_PACKAGE=java-11-openjdk-headless
+ARG RUN_JAVA_VERSION=1.3.8
+ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
+# Install java and the run-java script
+# Also set up permissions for user `1001`
+RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \
+    && microdnf update \
+    && microdnf clean all \
+    && mkdir /deployments \
+    && chown 1001 /deployments \
+    && chmod "g+rwX" /deployments \
+    && chown 1001:root /deployments \
+    && curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \
+    && chown 1001 /deployments/run-java.sh \
+    && chmod 540 /deployments/run-java.sh \
+    && echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/conf/security/java.security
+
+# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
+ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
+# We make four distinct layers so if there are application changes the library layers can be re-used
+COPY --from=builder --chown=1001 /app/target/quarkus-app/lib/ /deployments/lib/
+COPY --from=builder --chown=1001 /app/target/quarkus-app/*.jar /deployments/
+COPY --from=builder --chown=1001 /app/target/quarkus-app/app/ /deployments/app/
+COPY --from=builder --chown=1001 /app/target/quarkus-app/quarkus/ /deployments/quarkus/
+
+EXPOSE 8080
+EXPOSE 5050
+USER 1001
+
+ENTRYPOINT [ "/deployments/run-java.sh" ]
+
diff --git a/src/automation/src/main/proto/acl.proto b/src/automation/src/main/proto/acl.proto
deleted file mode 120000
index 158ae78eb5bdea534ba7008114c2b97ed6dffed8..0000000000000000000000000000000000000000
--- a/src/automation/src/main/proto/acl.proto
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../proto/acl.proto
\ No newline at end of file
diff --git a/src/automation/src/main/proto/acl.proto b/src/automation/src/main/proto/acl.proto
new file mode 100644
index 0000000000000000000000000000000000000000..3dba735dccf44d584a998eb02b4835bac7ceddd1
--- /dev/null
+++ b/src/automation/src/main/proto/acl.proto
@@ -0,0 +1,69 @@
+// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+package acl;
+
+enum AclRuleTypeEnum {
+  ACLRULETYPE_UNDEFINED = 0;
+  ACLRULETYPE_IPV4      = 1;
+  ACLRULETYPE_IPV6      = 2;
+  ACLRULETYPE_L2        = 3;
+  ACLRULETYPE_MPLS      = 4;
+  ACLRULETYPE_MIXED     = 5;
+}
+
+enum AclForwardActionEnum {
+  ACLFORWARDINGACTION_UNDEFINED = 0;
+  ACLFORWARDINGACTION_DROP      = 1;
+  ACLFORWARDINGACTION_ACCEPT    = 2;
+  ACLFORWARDINGACTION_REJECT    = 3;
+}
+
+enum AclLogActionEnum {
+  ACLLOGACTION_UNDEFINED = 0;
+  ACLLOGACTION_NOLOG     = 1;
+  ACLLOGACTION_SYSLOG    = 2;
+}
+
+message AclMatch {
+  uint32 dscp             = 1;
+  uint32 protocol         = 2;
+  string src_address      = 3;
+  string dst_address      = 4;
+  uint32 src_port         = 5;
+  uint32 dst_port         = 6;
+  uint32 start_mpls_label = 7;
+  uint32 end_mpls_label   = 8;
+}
+
+message AclAction {
+  AclForwardActionEnum forward_action = 1;
+  AclLogActionEnum     log_action     = 2;
+}
+
+message AclEntry {
+  uint32    sequence_id = 1;
+  string    description = 2;
+  AclMatch  match       = 3;
+  AclAction action      = 4;
+}
+
+message AclRuleSet {
+  string             name        = 1;
+  AclRuleTypeEnum    type        = 2;
+  string             description = 3;
+  string             user_id     = 4;
+  repeated AclEntry  entries     = 5;
+}
diff --git a/src/automation/src/main/proto/automation.proto b/src/automation/src/main/proto/automation.proto
deleted file mode 120000
index afef7a8e47ec5688ec46498c2197bc345e6c5e92..0000000000000000000000000000000000000000
--- a/src/automation/src/main/proto/automation.proto
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../proto/automation.proto
\ No newline at end of file
diff --git a/src/automation/src/main/proto/automation.proto b/src/automation/src/main/proto/automation.proto
new file mode 100644
index 0000000000000000000000000000000000000000..e2dbe33223566c4065ecb0086fbd8231a56834d4
--- /dev/null
+++ b/src/automation/src/main/proto/automation.proto
@@ -0,0 +1,69 @@
+// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+package automation;
+
+import "context.proto";
+
+service AutomationService {
+  rpc ZtpGetDeviceRole(DeviceRoleId) returns (DeviceRole) {}
+  rpc ZtpGetDeviceRolesByDeviceId(context.DeviceId) returns (DeviceRoleList) {}
+  rpc ZtpAdd(DeviceRole) returns (DeviceRoleState) {}
+  rpc ZtpUpdate(DeviceRoleConfig) returns (DeviceRoleState) {}
+  rpc ZtpDelete(DeviceRole) returns (DeviceRoleState) {}
+  rpc ZtpDeleteAll(context.Empty) returns (DeviceDeletionResult) {}
+}
+
+enum DeviceRoleType {
+  NONE = 0;
+  DEV_OPS = 1;
+  DEV_CONF = 2;
+  PIPELINE_CONF = 3;
+}
+
+message DeviceRoleId {
+  context.Uuid devRoleId = 1;
+  context.DeviceId devId = 2;
+}
+
+message DeviceRole {
+  DeviceRoleId devRoleId = 1;
+  DeviceRoleType devRoleType = 2;
+}
+
+message DeviceRoleConfig {
+  DeviceRole devRole = 1;
+  context.DeviceConfig devConfig = 2;
+}
+
+message DeviceRoleList {
+  repeated DeviceRole devRole = 1;
+}
+
+message DeviceRoleState {
+  DeviceRoleId devRoleId = 1;
+  ZtpDeviceState devRoleState = 2;
+}
+
+message DeviceDeletionResult {
+  repeated string deleted = 1;
+}
+
+enum ZtpDeviceState {
+  ZTP_DEV_STATE_UNDEFINED = 0;
+  ZTP_DEV_STATE_CREATED  = 1;
+  ZTP_DEV_STATE_UPDATED  = 2;
+  ZTP_DEV_STATE_DELETED  = 3;
+}
diff --git a/src/automation/src/main/proto/context.proto b/src/automation/src/main/proto/context.proto
deleted file mode 120000
index 7f33c4bc783bd20d031d94ab3b2e94f0d76ecd95..0000000000000000000000000000000000000000
--- a/src/automation/src/main/proto/context.proto
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../proto/context.proto
\ No newline at end of file
diff --git a/src/automation/src/main/proto/context.proto b/src/automation/src/main/proto/context.proto
new file mode 100644
index 0000000000000000000000000000000000000000..e403c4a22f2df62f695041c094cc1c6e6a193d5f
--- /dev/null
+++ b/src/automation/src/main/proto/context.proto
@@ -0,0 +1,554 @@
+// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+package context;
+
+import "acl.proto";
+import "kpi_sample_types.proto";
+
+service ContextService {
+  rpc ListContextIds     (Empty         ) returns (       ContextIdList   ) {}
+  rpc ListContexts       (Empty         ) returns (       ContextList     ) {}
+  rpc GetContext         (ContextId     ) returns (       Context         ) {}
+  rpc SetContext         (Context       ) returns (       ContextId       ) {}
+  rpc RemoveContext      (ContextId     ) returns (       Empty           ) {}
+  rpc GetContextEvents   (Empty         ) returns (stream ContextEvent    ) {}
+
+  rpc ListTopologyIds    (ContextId     ) returns (       TopologyIdList  ) {}
+  rpc ListTopologies     (ContextId     ) returns (       TopologyList    ) {}
+  rpc GetTopology        (TopologyId    ) returns (       Topology        ) {}
+  rpc GetTopologyDetails (TopologyId    ) returns (       TopologyDetails ) {}
+  rpc SetTopology        (Topology      ) returns (       TopologyId      ) {}
+  rpc RemoveTopology     (TopologyId    ) returns (       Empty           ) {}
+  rpc GetTopologyEvents  (Empty         ) returns (stream TopologyEvent   ) {}
+
+  rpc ListDeviceIds      (Empty         ) returns (       DeviceIdList    ) {}
+  rpc ListDevices        (Empty         ) returns (       DeviceList      ) {}
+  rpc GetDevice          (DeviceId      ) returns (       Device          ) {}
+  rpc SetDevice          (Device        ) returns (       DeviceId        ) {}
+  rpc RemoveDevice       (DeviceId      ) returns (       Empty           ) {}
+  rpc GetDeviceEvents    (Empty         ) returns (stream DeviceEvent     ) {}
+
+  rpc ListEndPointNames  (EndPointIdList) returns (       EndPointNameList) {}
+
+  rpc ListLinkIds        (Empty         ) returns (       LinkIdList      ) {}
+  rpc ListLinks          (Empty         ) returns (       LinkList        ) {}
+  rpc GetLink            (LinkId        ) returns (       Link            ) {}
+  rpc SetLink            (Link          ) returns (       LinkId          ) {}
+  rpc RemoveLink         (LinkId        ) returns (       Empty           ) {}
+  rpc GetLinkEvents      (Empty         ) returns (stream LinkEvent       ) {}
+
+  rpc ListServiceIds     (ContextId     ) returns (       ServiceIdList   ) {}
+  rpc ListServices       (ContextId     ) returns (       ServiceList     ) {}
+  rpc GetService         (ServiceId     ) returns (       Service         ) {}
+  rpc SetService         (Service       ) returns (       ServiceId       ) {}
+  rpc UnsetService       (Service       ) returns (       ServiceId       ) {}
+  rpc RemoveService      (ServiceId     ) returns (       Empty           ) {}
+  rpc GetServiceEvents   (Empty         ) returns (stream ServiceEvent    ) {}
+
+  rpc ListSliceIds       (ContextId     ) returns (       SliceIdList     ) {}
+  rpc ListSlices         (ContextId     ) returns (       SliceList       ) {}
+  rpc GetSlice           (SliceId       ) returns (       Slice           ) {}
+  rpc SetSlice           (Slice         ) returns (       SliceId         ) {}
+  rpc UnsetSlice         (Slice         ) returns (       SliceId         ) {}
+  rpc RemoveSlice        (SliceId       ) returns (       Empty           ) {}
+  rpc GetSliceEvents     (Empty         ) returns (stream SliceEvent      ) {}
+
+  rpc ListConnectionIds  (ServiceId     ) returns (       ConnectionIdList) {}
+  rpc ListConnections    (ServiceId     ) returns (       ConnectionList  ) {}
+  rpc GetConnection      (ConnectionId  ) returns (       Connection      ) {}
+  rpc SetConnection      (Connection    ) returns (       ConnectionId    ) {}
+  rpc RemoveConnection   (ConnectionId  ) returns (       Empty           ) {}
+  rpc GetConnectionEvents(Empty         ) returns (stream ConnectionEvent ) {}
+}
+
+// ----- Generic -------------------------------------------------------------------------------------------------------
+message Empty {}
+
+message Uuid {
+  string uuid = 1;
+}
+
+enum EventTypeEnum {
+  EVENTTYPE_UNDEFINED = 0;
+  EVENTTYPE_CREATE = 1;
+  EVENTTYPE_UPDATE = 2;
+  EVENTTYPE_REMOVE = 3;
+}
+
+message Timestamp {
+  double timestamp = 1;
+}
+
+message Event {
+  Timestamp timestamp = 1;
+  EventTypeEnum event_type = 2;
+}
+
+// ----- Context -------------------------------------------------------------------------------------------------------
+message ContextId {
+  Uuid context_uuid = 1;
+}
+
+message Context {
+  ContextId context_id = 1;
+  string name = 2;
+  repeated TopologyId topology_ids = 3;
+  repeated ServiceId service_ids = 4;
+  repeated SliceId slice_ids = 5;
+  TeraFlowController controller = 6;
+}
+
+message ContextIdList {
+  repeated ContextId context_ids = 1;
+}
+
+message ContextList {
+  repeated Context contexts = 1;
+}
+
+message ContextEvent {
+  Event event = 1;
+  ContextId context_id = 2;
+}
+
+
+// ----- Topology ------------------------------------------------------------------------------------------------------
+message TopologyId {
+  ContextId context_id = 1;
+  Uuid topology_uuid = 2;
+}
+
+message Topology {
+  TopologyId topology_id = 1;
+  string name = 2;
+  repeated DeviceId device_ids = 3;
+  repeated LinkId link_ids = 4;
+}
+
+message TopologyDetails {
+  TopologyId topology_id = 1;
+  string name = 2;
+  repeated Device devices = 3;
+  repeated Link links = 4;
+}
+
+message TopologyIdList {
+  repeated TopologyId topology_ids = 1;
+}
+
+message TopologyList {
+  repeated Topology topologies = 1;
+}
+
+message TopologyEvent {
+  Event event = 1;
+  TopologyId topology_id = 2;
+}
+
+
+// ----- Device --------------------------------------------------------------------------------------------------------
+message DeviceId {
+  Uuid device_uuid = 1;
+}
+
+message Device {
+  DeviceId device_id = 1;
+  string name = 2;
+  string device_type = 3;
+  DeviceConfig device_config = 4;
+  DeviceOperationalStatusEnum device_operational_status = 5;
+  repeated DeviceDriverEnum device_drivers = 6;
+  repeated EndPoint device_endpoints = 7;
+  repeated Component component = 8; // Used for inventory
+}
+
+message Component {
+  repeated string comp_string = 1;
+}
+
+message DeviceConfig {
+  repeated ConfigRule config_rules = 1;
+}
+
+enum DeviceDriverEnum {
+  DEVICEDRIVER_UNDEFINED = 0; // also used for emulated
+  DEVICEDRIVER_OPENCONFIG = 1;
+  DEVICEDRIVER_TRANSPORT_API = 2;
+  DEVICEDRIVER_P4 = 3;
+  DEVICEDRIVER_IETF_NETWORK_TOPOLOGY = 4;
+  DEVICEDRIVER_ONF_TR_352 = 5;
+  DEVICEDRIVER_XR = 6;
+}
+
+enum DeviceOperationalStatusEnum {
+  DEVICEOPERATIONALSTATUS_UNDEFINED = 0;
+  DEVICEOPERATIONALSTATUS_DISABLED = 1;
+  DEVICEOPERATIONALSTATUS_ENABLED = 2;
+}
+
+message DeviceIdList {
+  repeated DeviceId device_ids = 1;
+}
+
+message DeviceList {
+  repeated Device devices = 1;
+}
+
+message DeviceEvent {
+  Event event = 1;
+  DeviceId device_id = 2;
+  DeviceConfig device_config = 3;
+}
+
+
+// ----- Link ----------------------------------------------------------------------------------------------------------
+message LinkId {
+  Uuid link_uuid = 1;
+}
+
+message Link {
+  LinkId link_id = 1;
+  string name = 2;
+  repeated EndPointId link_endpoint_ids = 3;
+}
+
+message LinkIdList {
+  repeated LinkId link_ids = 1;
+}
+
+message LinkList {
+  repeated Link links = 1;
+}
+
+message LinkEvent {
+  Event event = 1;
+  LinkId link_id = 2;
+}
+
+
+// ----- Service -------------------------------------------------------------------------------------------------------
+message ServiceId {
+  ContextId context_id = 1;
+  Uuid service_uuid = 2;
+}
+
+message Service {
+  ServiceId service_id = 1;
+  string name = 2;
+  ServiceTypeEnum service_type = 3;
+  repeated EndPointId service_endpoint_ids = 4;
+  repeated Constraint service_constraints = 5;
+  ServiceStatus service_status = 6;
+  ServiceConfig service_config = 7;
+  Timestamp timestamp = 8;
+}
+
+enum ServiceTypeEnum {
+  SERVICETYPE_UNKNOWN = 0;
+  SERVICETYPE_L3NM = 1;
+  SERVICETYPE_L2NM = 2;
+  SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 3;
+}
+
+enum ServiceStatusEnum {
+  SERVICESTATUS_UNDEFINED = 0;
+  SERVICESTATUS_PLANNED = 1;
+  SERVICESTATUS_ACTIVE =  2;
+  SERVICESTATUS_PENDING_REMOVAL = 3;
+  SERVICESTATUS_SLA_VIOLATED = 4;
+}
+
+message ServiceStatus {
+  ServiceStatusEnum service_status = 1;
+}
+
+message ServiceConfig {
+  repeated ConfigRule config_rules = 1;
+}
+
+message ServiceIdList {
+  repeated ServiceId service_ids = 1;
+}
+
+message ServiceList {
+  repeated Service services = 1;
+}
+
+message ServiceEvent {
+  Event event = 1;
+  ServiceId service_id = 2;
+}
+
+// ----- Slice ---------------------------------------------------------------------------------------------------------
+message SliceId {
+  ContextId context_id = 1;
+  Uuid slice_uuid = 2;
+}
+
+message Slice {
+  SliceId slice_id = 1;
+  string name = 2;
+  repeated EndPointId slice_endpoint_ids = 3;
+  repeated Constraint slice_constraints = 4;
+  repeated ServiceId slice_service_ids = 5;
+  repeated SliceId slice_subslice_ids = 6;
+  SliceStatus slice_status = 7;
+  SliceConfig slice_config = 8;
+  SliceOwner slice_owner = 9;
+  Timestamp timestamp = 10;
+}
+
+message SliceOwner {
+  Uuid owner_uuid = 1;
+  string owner_string = 2;
+}
+
+enum SliceStatusEnum {
+  SLICESTATUS_UNDEFINED    = 0;
+  SLICESTATUS_PLANNED      = 1;
+  SLICESTATUS_INIT         = 2;
+  SLICESTATUS_ACTIVE       = 3;
+  SLICESTATUS_DEINIT       = 4;
+  SLICESTATUS_SLA_VIOLATED = 5;
+}
+
+message SliceStatus {
+  SliceStatusEnum slice_status = 1;
+}
+
+message SliceConfig {
+  repeated ConfigRule config_rules = 1;
+}
+
+message SliceIdList {
+  repeated SliceId slice_ids = 1;
+}
+
+message SliceList {
+  repeated Slice slices = 1;
+}
+
+message SliceEvent {
+  Event event = 1;
+  SliceId slice_id = 2;
+}
+
+// ----- Connection ----------------------------------------------------------------------------------------------------
+message ConnectionId {
+  Uuid connection_uuid = 1;
+}
+
+message ConnectionSettings_L0 {
+  string lsp_symbolic_name = 1;
+}
+
+message ConnectionSettings_L2 {
+  string src_mac_address = 1;
+  string dst_mac_address = 2;
+  uint32 ether_type = 3;
+  uint32 vlan_id = 4;
+  uint32 mpls_label = 5;
+  uint32 mpls_traffic_class = 6;
+}
+
+message ConnectionSettings_L3 {
+  string src_ip_address = 1;
+  string dst_ip_address = 2;
+  uint32 dscp = 3;
+  uint32 protocol = 4;
+  uint32 ttl = 5;
+}
+
+message ConnectionSettings_L4 {
+  uint32 src_port = 1;
+  uint32 dst_port = 2;
+  uint32 tcp_flags = 3;
+  uint32 ttl = 4;
+}
+
+message ConnectionSettings {
+  ConnectionSettings_L0 l0 = 1;
+  ConnectionSettings_L2 l2 = 2;
+  ConnectionSettings_L3 l3 = 3;
+  ConnectionSettings_L4 l4 = 4;
+}
+
+message Connection {
+  ConnectionId connection_id = 1;
+  ServiceId service_id = 2;
+  repeated EndPointId path_hops_endpoint_ids = 3;
+  repeated ServiceId sub_service_ids = 4;
+  ConnectionSettings settings = 5;
+}
+
+message ConnectionIdList {
+  repeated ConnectionId connection_ids = 1;
+}
+
+message ConnectionList {
+  repeated Connection connections = 1;
+}
+
+message ConnectionEvent {
+  Event event = 1;
+  ConnectionId connection_id = 2;
+}
+
+
+// ----- Endpoint ------------------------------------------------------------------------------------------------------
+message EndPointId {
+  TopologyId topology_id = 1;
+  DeviceId device_id = 2;
+  Uuid endpoint_uuid = 3;
+}
+
+message EndPoint {
+  EndPointId endpoint_id = 1;
+  string name = 2;
+  string endpoint_type = 3;
+  repeated kpi_sample_types.KpiSampleType kpi_sample_types = 4;
+  Location endpoint_location = 5;
+}
+
+message EndPointName {
+  EndPointId endpoint_id = 1;
+  string device_name = 2;
+  string endpoint_name = 3;
+  string endpoint_type = 4;
+}
+
+message EndPointIdList {
+  repeated EndPointId endpoint_ids = 1;
+}
+
+message EndPointNameList {
+  repeated EndPointName endpoint_names = 1;
+}
+
+
+// ----- Configuration -------------------------------------------------------------------------------------------------
+enum ConfigActionEnum {
+  CONFIGACTION_UNDEFINED = 0;
+  CONFIGACTION_SET       = 1;
+  CONFIGACTION_DELETE    = 2;
+}
+
+message ConfigRule_Custom {
+  string resource_key = 1;
+  string resource_value = 2;
+}
+
+message ConfigRule_ACL {
+  EndPointId endpoint_id = 1;
+  acl.AclRuleSet rule_set = 2;
+}
+
+message ConfigRule {
+  ConfigActionEnum action = 1;
+  oneof config_rule {
+    ConfigRule_Custom custom = 2;
+    ConfigRule_ACL acl = 3;
+  }
+}
+
+
+// ----- Constraint ----------------------------------------------------------------------------------------------------
+message Constraint_Custom {
+  string constraint_type = 1;
+  string constraint_value = 2;
+}
+
+message Constraint_Schedule {
+  float start_timestamp = 1;
+  float duration_days = 2;
+}
+
+message GPS_Position {
+  float latitude = 1;
+  float longitude = 2;
+}
+
+message Location {
+  oneof location {
+    string region = 1;
+    GPS_Position gps_position = 2;
+  }
+}
+
+message Constraint_EndPointLocation {
+  EndPointId endpoint_id = 1;
+  Location location = 2;
+}
+
+message Constraint_EndPointPriority {
+  EndPointId endpoint_id = 1;
+  uint32 priority = 2;
+}
+
+message Constraint_SLA_Latency {
+  float e2e_latency_ms = 1;
+}
+
+message Constraint_SLA_Capacity {
+  float capacity_gbps = 1;
+}
+
+message Constraint_SLA_Availability {
+  uint32 num_disjoint_paths = 1;
+  bool all_active = 2;
+}
+
+enum IsolationLevelEnum {
+  NO_ISOLATION = 0;
+  PHYSICAL_ISOLATION = 1;
+  LOGICAL_ISOLATION = 2;
+  PROCESS_ISOLATION = 3;
+  PHYSICAL_MEMORY_ISOLATION = 4;
+  PHYSICAL_NETWORK_ISOLATION = 5;
+  VIRTUAL_RESOURCE_ISOLATION = 6;
+  NETWORK_FUNCTIONS_ISOLATION = 7;
+  SERVICE_ISOLATION = 8;
+}
+
+message Constraint_SLA_Isolation_level {
+  repeated IsolationLevelEnum isolation_level = 1;
+}
+
+message Constraint {
+  oneof constraint {
+    Constraint_Custom custom = 1;
+    Constraint_Schedule schedule = 2;
+    Constraint_EndPointLocation endpoint_location = 3;
+    Constraint_EndPointPriority endpoint_priority = 4;
+    Constraint_SLA_Capacity sla_capacity = 5;
+    Constraint_SLA_Latency sla_latency = 6;
+    Constraint_SLA_Availability sla_availability = 7;
+    Constraint_SLA_Isolation_level sla_isolation = 8;
+  }
+}
+
+
+// ----- Miscellaneous -------------------------------------------------------------------------------------------------
+message TeraFlowController {
+  ContextId context_id = 1;
+  string ip_address = 2;
+  uint32 port = 3;
+}
+
+message AuthenticationResult {
+  ContextId context_id = 1;
+  bool authenticated = 2;
+}
diff --git a/src/automation/src/main/proto/device.proto b/src/automation/src/main/proto/device.proto
deleted file mode 120000
index ad6e7c47eb9fb50c5cc8a7b3562caaf933ba0469..0000000000000000000000000000000000000000
--- a/src/automation/src/main/proto/device.proto
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../proto/device.proto
\ No newline at end of file
diff --git a/src/automation/src/main/proto/device.proto b/src/automation/src/main/proto/device.proto
new file mode 100644
index 0000000000000000000000000000000000000000..30e60079db6c1eb8641d10115f6f43840eabf39c
--- /dev/null
+++ b/src/automation/src/main/proto/device.proto
@@ -0,0 +1,34 @@
+// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+package device;
+
+import "context.proto";
+import "monitoring.proto";
+
+service DeviceService {
+  rpc AddDevice       (context.Device    ) returns (context.DeviceId    ) {}
+  rpc ConfigureDevice (context.Device    ) returns (context.DeviceId    ) {}
+  rpc DeleteDevice    (context.DeviceId  ) returns (context.Empty       ) {}
+  rpc GetInitialConfig(context.DeviceId  ) returns (context.DeviceConfig) {}
+  rpc MonitorDeviceKpi(MonitoringSettings) returns (context.Empty       ) {}
+}
+
+message MonitoringSettings {
+  monitoring.KpiId kpi_id = 1;
+  monitoring.KpiDescriptor kpi_descriptor = 2;
+  float sampling_duration_s = 3;
+  float sampling_interval_s = 4;
+}
diff --git a/src/automation/src/main/proto/kpi_sample_types.proto b/src/automation/src/main/proto/kpi_sample_types.proto
deleted file mode 120000
index 98e748bbf4fbadbc04c3657f458d733f1bc7bdb8..0000000000000000000000000000000000000000
--- a/src/automation/src/main/proto/kpi_sample_types.proto
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../proto/kpi_sample_types.proto
\ No newline at end of file
diff --git a/src/automation/src/main/proto/kpi_sample_types.proto b/src/automation/src/main/proto/kpi_sample_types.proto
new file mode 100644
index 0000000000000000000000000000000000000000..1ade4d69bf5a6c23d993cd37ed731eee10d7374e
--- /dev/null
+++ b/src/automation/src/main/proto/kpi_sample_types.proto
@@ -0,0 +1,34 @@
+// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+package kpi_sample_types;
+
+enum KpiSampleType {
+    KPISAMPLETYPE_UNKNOWN                       = 0;
+    KPISAMPLETYPE_PACKETS_TRANSMITTED           = 101;
+    KPISAMPLETYPE_PACKETS_RECEIVED              = 102;
+    KPISAMPLETYPE_PACKETS_DROPPED               = 103;
+    KPISAMPLETYPE_BYTES_TRANSMITTED             = 201;
+    KPISAMPLETYPE_BYTES_RECEIVED                = 202;
+    KPISAMPLETYPE_BYTES_DROPPED                 = 203;
+    KPISAMPLETYPE_ML_CONFIDENCE                 = 401;  //. can be used by both optical and L3 without any issue
+    KPISAMPLETYPE_OPTICAL_SECURITY_STATUS       = 501;  //. can be used by both optical and L3 without any issue
+    KPISAMPLETYPE_L3_UNIQUE_ATTACK_CONNS        = 601;
+    KPISAMPLETYPE_L3_TOTAL_DROPPED_PACKTS       = 602;
+    KPISAMPLETYPE_L3_UNIQUE_ATTACKERS           = 603;
+    KPISAMPLETYPE_L3_UNIQUE_COMPROMISED_CLIENTS = 604;
+    KPISAMPLETYPE_L3_SECURITY_STATUS_CRYPTO     = 605;
+    KPISAMPLETYPE_SERVICE_LATENCY_MS            = 701;
+}
diff --git a/src/automation/src/main/proto/monitoring.proto b/src/automation/src/main/proto/monitoring.proto
deleted file mode 120000
index aceaa7328099fe736163be048ee1ad21a61d79a2..0000000000000000000000000000000000000000
--- a/src/automation/src/main/proto/monitoring.proto
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../proto/monitoring.proto
\ No newline at end of file
diff --git a/src/automation/src/main/proto/monitoring.proto b/src/automation/src/main/proto/monitoring.proto
new file mode 100644
index 0000000000000000000000000000000000000000..3862973e056d6267d8defc68e77cbf3c8a10ebee
--- /dev/null
+++ b/src/automation/src/main/proto/monitoring.proto
@@ -0,0 +1,173 @@
+// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+package monitoring;
+
+import "context.proto";
+import "kpi_sample_types.proto";
+
+service MonitoringService {
+  rpc SetKpi                (KpiDescriptor      ) returns (KpiId               ) {} // Stable not final
+  rpc DeleteKpi             (KpiId              ) returns (context.Empty       ) {} // Stable and final
+  rpc GetKpiDescriptor      (KpiId              ) returns (KpiDescriptor       ) {} // Stable and final
+  rpc GetKpiDescriptorList  (context.Empty      ) returns (KpiDescriptorList   ) {} // Stable and final
+  rpc IncludeKpi            (Kpi                ) returns (context.Empty       ) {} // Stable and final
+  rpc MonitorKpi            (MonitorKpiRequest  ) returns (context.Empty       ) {} // Stable and final
+  rpc QueryKpiData          (KpiQuery           ) returns (RawKpiTable         ) {} // Not implemented
+  rpc SetKpiSubscription    (SubsDescriptor     ) returns (stream SubsResponse ) {} // Stable not final
+  rpc GetSubsDescriptor     (SubscriptionID     ) returns (SubsDescriptor      ) {} // Stable and final
+  rpc GetSubscriptions      (context.Empty      ) returns (SubsList            ) {} // Stable and final
+  rpc DeleteSubscription    (SubscriptionID     ) returns (context.Empty       ) {} // Stable and final
+  rpc SetKpiAlarm           (AlarmDescriptor    ) returns (AlarmID             ) {} // Stable not final
+  rpc GetAlarms             (context.Empty      ) returns (AlarmList           ) {} // Stable and final
+  rpc GetAlarmDescriptor    (AlarmID            ) returns (AlarmDescriptor     ) {} // Stable and final
+  rpc GetAlarmResponseStream(AlarmSubscription  ) returns (stream AlarmResponse) {} // Not Stable not final
+  rpc DeleteAlarm           (AlarmID            ) returns (context.Empty       ) {} // Stable and final
+  rpc GetStreamKpi          (KpiId              ) returns (stream Kpi          ) {} // Stable not final
+  rpc GetInstantKpi         (KpiId              ) returns (Kpi                 ) {} // Stable not final
+}
+
+message KpiDescriptor {
+  KpiId                          kpi_id          = 1;
+  string                         kpi_description = 2;
+  repeated KpiId                 kpi_id_list     = 3;
+  kpi_sample_types.KpiSampleType kpi_sample_type = 4;
+  context.DeviceId               device_id       = 5;
+  context.EndPointId             endpoint_id     = 6;
+  context.ServiceId              service_id      = 7;
+  context.SliceId                slice_id        = 8;
+  context.ConnectionId           connection_id   = 9;
+}
+
+message MonitorKpiRequest {
+  KpiId kpi_id              = 1;
+  float monitoring_window_s = 2;
+  float sampling_rate_s     = 3;
+  // Pending add field to reflect Available Device Protocols
+}
+
+message KpiQuery {
+  repeated KpiId    kpi_ids             = 1;
+  float             monitoring_window_s = 2;
+  uint32            last_n_samples      = 3;  // used when you want something like "get the last N many samples
+  context.Timestamp start_timestamp     = 4;  // used when you want something like "get the samples since X date/time"
+  context.Timestamp end_timestamp       = 5;  // used when you want something like "get the samples until X date/time"
+}
+
+
+message RawKpi { // cell
+  context.Timestamp timestamp = 1;
+  KpiValue          kpi_value = 2;
+}
+
+message RawKpiList { // column
+  KpiId           kpi_id    = 1;
+  repeated RawKpi raw_kpis  = 2;
+}
+
+message RawKpiTable { // table
+  repeated RawKpiList raw_kpi_lists = 1;
+}
+
+message KpiId {
+  context.Uuid kpi_id = 1;
+}
+
+message Kpi {
+  KpiId             kpi_id    = 1;
+  context.Timestamp timestamp = 2;
+  KpiValue          kpi_value = 3;
+}
+
+message KpiValueRange {
+  KpiValue  kpiMinValue     = 1;
+  KpiValue  kpiMaxValue     = 2;
+  bool      inRange         = 3;  // by default True
+  bool      includeMinValue = 4;  // False is outside the interval
+  bool      includeMaxValue = 5;  // False is outside the interval
+}
+
+message KpiValue {
+  oneof value {
+    int32  int32Val  = 1;
+    uint32 uint32Val = 2;
+    int64  int64Val  = 3;
+    uint64 uint64Val = 4;
+    float  floatVal  = 5;
+    string stringVal = 6;
+    bool   boolVal   = 7;
+  }
+}
+
+
+message KpiList {
+  repeated Kpi kpi = 1;
+}
+
+message KpiDescriptorList {
+  repeated KpiDescriptor kpi_descriptor_list = 1;
+}
+
+message SubsDescriptor{
+  SubscriptionID    subs_id             = 1;
+  KpiId             kpi_id              = 2;
+  float             sampling_duration_s = 3;
+  float             sampling_interval_s = 4;
+  context.Timestamp start_timestamp     = 5;  // used when you want something like "get the samples since X date/time"
+  context.Timestamp end_timestamp       = 6;  // used when you want something like "get the samples until X date/time"
+  // Pending add field to reflect Available Device Protocols
+}
+
+message SubscriptionID {
+  context.Uuid subs_id = 1;
+}
+
+message SubsResponse {
+  SubscriptionID   subs_id  = 1;
+  KpiList          kpi_list = 2;
+}
+
+message SubsList {
+  repeated SubsDescriptor subs_descriptor = 1;
+}
+
+message AlarmDescriptor {
+  AlarmID                     alarm_id              = 1;
+  string                      alarm_description     = 2;
+  string                      name                  = 3;
+  KpiId                       kpi_id                = 4;
+  KpiValueRange               kpi_value_range       = 5;
+  context.Timestamp           timestamp             = 6;
+}
+
+message AlarmID{
+  context.Uuid alarm_id = 1;
+}
+
+message AlarmSubscription{
+  AlarmID alarm_id                  = 1;
+  float   subscription_timeout_s    = 2;
+  float   subscription_frequency_ms = 3;
+}
+
+message AlarmResponse {
+  AlarmID           alarm_id  = 1;
+  string            text      = 2;
+  KpiList           kpi_list  = 3;
+}
+
+message AlarmList {
+    repeated AlarmDescriptor alarm_descriptor = 1;
+}
diff --git a/src/device/service/DeviceServiceServicerImpl.py b/src/device/service/DeviceServiceServicerImpl.py
index 1987be15ddef49f1756909ce9203d1aaa574d6f0..0258380a14df03204a7cb77c5a2d8b39aa3c64cc 100644
--- a/src/device/service/DeviceServiceServicerImpl.py
+++ b/src/device/service/DeviceServiceServicerImpl.py
@@ -22,13 +22,14 @@ from common.proto.device_pb2_grpc import DeviceServiceServicer
 from common.tools.context_queries.Device import get_device
 from common.tools.mutex_queues.MutexQueues import MutexQueues
 from context.client.ContextClient import ContextClient
-from device.service.Errors import ERROR_MISSING_DRIVER, ERROR_MISSING_KPI
 from .driver_api._Driver import _Driver
 from .driver_api.DriverInstanceCache import DriverInstanceCache, get_driver
 from .monitoring.MonitoringLoops import MonitoringLoops
+from .ErrorMessages import ERROR_MISSING_DRIVER, ERROR_MISSING_KPI
 from .Tools import (
     check_connect_rules, check_no_endpoints, compute_rules_to_add_delete, configure_rules, deconfigure_rules,
-    populate_config_rules, populate_endpoint_monitoring_resources, populate_endpoints, populate_initial_config_rules, subscribe_kpi, unsubscribe_kpi, update_endpoints)
+    populate_config_rules, populate_endpoint_monitoring_resources, populate_endpoints, populate_initial_config_rules,
+    subscribe_kpi, unsubscribe_kpi, update_endpoints)
 
 LOGGER = logging.getLogger(__name__)
 
@@ -110,7 +111,7 @@ class DeviceServiceServicerImpl(DeviceServiceServicer):
 
             driver : _Driver = self.driver_instance_cache.get(device_uuid)
             if driver is None:
-                msg = ERROR_MISSING_DRIVER.format(str(device_uuid))
+                msg = ERROR_MISSING_DRIVER.format(device_uuid=str(device_uuid))
                 raise OperationFailedException('ConfigureDevice', extra_details=msg)
 
             if DeviceDriverEnum.DEVICEDRIVER_P4 in device.device_drivers:
@@ -164,7 +165,7 @@ class DeviceServiceServicerImpl(DeviceServiceServicer):
         try:
             driver : _Driver = self.driver_instance_cache.get(device_uuid)
             if driver is None:
-                msg = ERROR_MISSING_DRIVER.format(str(device_uuid))
+                msg = ERROR_MISSING_DRIVER.format(device_uuid=str(device_uuid))
                 raise OperationFailedException('GetInitialConfig', extra_details=msg)
 
             device_config = DeviceConfig()
@@ -190,7 +191,7 @@ class DeviceServiceServicerImpl(DeviceServiceServicer):
             kpi_uuid = request.kpi_id.kpi_id.uuid
             kpi_details = self.monitoring_loops.get_kpi_by_uuid(kpi_uuid)
             if kpi_details is None:
-                msg = ERROR_MISSING_KPI.format(str(kpi_uuid))
+                msg = ERROR_MISSING_KPI.format(kpi_uuid=str(kpi_uuid))
                 raise OperationFailedException('MonitorDeviceKpi', extra_details=msg)
             device_uuid = kpi_details[0]
 
@@ -198,7 +199,7 @@ class DeviceServiceServicerImpl(DeviceServiceServicer):
         try:
             driver : _Driver = self.driver_instance_cache.get(device_uuid)
             if driver is None:
-                msg = ERROR_MISSING_DRIVER.format(str(device_uuid))
+                msg = ERROR_MISSING_DRIVER.format(device_uuid=str(device_uuid))
                 raise OperationFailedException('MonitorDeviceKpi', extra_details=msg)
 
             errors = manage_kpi_method(request, driver, self.monitoring_loops)
diff --git a/src/device/service/ErrorMessages.py b/src/device/service/ErrorMessages.py
new file mode 100644
index 0000000000000000000000000000000000000000..1fbea721fdc52bdf759581c0525b30b1206ae844
--- /dev/null
+++ b/src/device/service/ErrorMessages.py
@@ -0,0 +1,39 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+_DEVICE_ID          = 'DeviceId({device_uuid:s})'
+_ENDPOINT_ID        = 'EndpointId({endpoint_uuid:s})'
+_ENDPOINT_DATA      = 'EndpointId({endpoint_data:s})'
+_KPI                = 'Kpi({kpi_uuid:s})'
+_DEVICE_ENDPOINT_ID = _DEVICE_ID + '/' + _ENDPOINT_ID
+_RESOURCE_KEY       = 'Resource(key={resource_key:s})'
+_RESOURCE_KEY_VALUE = 'Resource(key={resource_key:s}, value={resource_value:s})'
+_SUBSCRIPTION       = 'Subscription(key={subscr_key:s}, duration={subscr_duration:s}, interval={subscr_interval:s})'
+_SAMPLE_TYPE        = 'SampleType({sample_type_id:s}/{sample_type_name:s})'
+_ERROR              = 'Error({error:s})'
+
+ERROR_MISSING_DRIVER = _DEVICE_ID + ' has not been added to this Device instance'
+ERROR_MISSING_KPI    = _KPI + ' not found'
+
+ERROR_BAD_ENDPOINT   = _DEVICE_ID + ': GetConfig retrieved malformed ' + _ENDPOINT_DATA
+
+ERROR_GET            = _DEVICE_ID + ': Unable to Get ' + _RESOURCE_KEY + '; ' + _ERROR
+ERROR_GET_INIT       = _DEVICE_ID + ': Unable to Get Initial ' + _RESOURCE_KEY + '; ' + _ERROR
+ERROR_DELETE         = _DEVICE_ID + ': Unable to Delete ' + _RESOURCE_KEY_VALUE + '; ' + _ERROR
+ERROR_SET            = _DEVICE_ID + ': Unable to Set ' + _RESOURCE_KEY_VALUE + '; ' + _ERROR
+
+ERROR_SAMPLETYPE     = _DEVICE_ENDPOINT_ID + ': ' + _SAMPLE_TYPE + ' not supported'
+
+ERROR_SUBSCRIBE      = _DEVICE_ID + ': Unable to Subscribe ' + _SUBSCRIPTION + '; ' + _ERROR
+ERROR_UNSUBSCRIBE    = _DEVICE_ID + ': Unable to Unsubscribe ' + _SUBSCRIPTION + '; ' + _ERROR
diff --git a/src/device/service/Errors.py b/src/device/service/Errors.py
deleted file mode 100644
index a29a70f05a79ba1517d0bd305dd94afa76703cac..0000000000000000000000000000000000000000
--- a/src/device/service/Errors.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-ERROR_MISSING_DRIVER = 'Device({:s}) has not been added to this Device instance'
-ERROR_MISSING_KPI    = 'Kpi({:s}) not found'
-
-ERROR_BAD_ENDPOINT   = 'Device({:s}): GetConfig retrieved malformed Endpoint({:s})'
-
-ERROR_GET            = 'Device({:s}): Unable to Get resource(key={:s}); error({:s})'
-ERROR_GET_INIT       = 'Device({:s}): Unable to Get Initial resource(key={:s}); error({:s})'
-ERROR_DELETE         = 'Device({:s}): Unable to Delete resource(key={:s}, value={:s}); error({:s})'
-ERROR_SET            = 'Device({:s}): Unable to Set resource(key={:s}, value={:s}); error({:s})'
-
-ERROR_SAMPLETYPE     = 'Device({:s})/EndPoint({:s}): SampleType({:s}/{:s}) not supported'
-
-ERROR_SUBSCRIBE      = 'Device({:s}): Unable to Subscribe subscription(key={:s}, duration={:s}, interval={:s}); '+\
-                       'error({:s})'
-ERROR_UNSUBSCRIBE    = 'Device({:s}): Unable to Unsubscribe subscription(key={:s}, duration={:s}, interval={:s}); '+\
-                       'error({:s})'
diff --git a/src/device/service/Tools.py b/src/device/service/Tools.py
index 7dd61085b0f492d7a1d7873a9e1fe3f73a7b407c..571e8acdab7fc243c22923a69202c89db88c8ce3 100644
--- a/src/device/service/Tools.py
+++ b/src/device/service/Tools.py
@@ -23,9 +23,10 @@ from common.tools.grpc.ConfigRules import update_config_rule_custom
 from common.tools.grpc.Tools import grpc_message_to_json
 from .driver_api._Driver import _Driver, RESOURCE_ENDPOINTS
 from .monitoring.MonitoringLoops import MonitoringLoops
-from .Errors import (
+from .ErrorMessages import (
     ERROR_BAD_ENDPOINT, ERROR_DELETE, ERROR_GET, ERROR_GET_INIT, ERROR_MISSING_KPI, ERROR_SAMPLETYPE, ERROR_SET,
-    ERROR_SUBSCRIBE, ERROR_UNSUBSCRIBE)
+    ERROR_SUBSCRIBE, ERROR_UNSUBSCRIBE
+)
 
 LOGGER = logging.getLogger(__name__)
 
@@ -85,12 +86,13 @@ def populate_endpoints(device : Device, driver : _Driver, monitoring_loops : Mon
     errors : List[str] = list()
     for endpoint in results_getconfig:
         if len(endpoint) != 2:
-            errors.append(ERROR_BAD_ENDPOINT.format(device_uuid, str(endpoint)))
+            errors.append(ERROR_BAD_ENDPOINT.format(device_uuid=device_uuid, endpoint_data=str(endpoint)))
             continue
 
         resource_key, resource_value = endpoint
         if isinstance(resource_value, Exception):
-            errors.append(ERROR_GET.format(device_uuid, str(resource_key), str(resource_value)))
+            errors.append(ERROR_GET.format(
+                device_uuid=device_uuid, resource_key=str(resource_key), error=str(resource_value)))
             continue
         if resource_value is None:
             continue
@@ -134,7 +136,9 @@ def _raw_config_rules_to_grpc(
 
     for resource_key, resource_value in raw_config_rules:
         if isinstance(resource_value, Exception):
-            errors.append(error_template.format(device_uuid, str(resource_key), str(resource_value)))
+            errors.append(error_template.format(
+                device_uuid=device_uuid, resource_key=str(resource_key), resource_value=str(resource_value),
+                error=str(resource_value)))
             continue
 
         if resource_value is None: continue
@@ -223,7 +227,8 @@ def subscribe_kpi(request : MonitoringSettings, driver : _Driver, monitoring_loo
     if resource_key is None:
         kpi_sample_type_name = KpiSampleType.Name(kpi_sample_type).upper().replace('KPISAMPLETYPE_', '')
         MSG = ERROR_SAMPLETYPE.format(
-            str(device_uuid), str(endpoint_uuid), str(kpi_sample_type), str(kpi_sample_type_name)
+            device_uuid=str(device_uuid), endpoint_uuid=str(endpoint_uuid), sample_type_id=str(kpi_sample_type),
+            sample_type_name=str(kpi_sample_type_name)
         )
         LOGGER.warning('{:s} Supported Device-Endpoint-KpiSampleType items: {:s}'.format(
             MSG, str(monitoring_loops.get_all_resource_keys())))
@@ -239,7 +244,8 @@ def subscribe_kpi(request : MonitoringSettings, driver : _Driver, monitoring_loo
     for (resource_key, duration, interval), result in zip(resources_to_subscribe, results_subscribestate):
         if isinstance(result, Exception):
             errors.append(ERROR_SUBSCRIBE.format(
-                str(device_uuid), str(resource_key), str(duration), str(interval), str(result)
+                device_uuid=str(device_uuid), subscr_key=str(resource_key), subscr_duration=str(duration),
+                subscr_interval=str(interval), error=str(result)
             ))
             continue
 
@@ -253,7 +259,7 @@ def unsubscribe_kpi(request : MonitoringSettings, driver : _Driver, monitoring_l
 
     kpi_details = monitoring_loops.get_kpi_by_uuid(kpi_uuid)
     if kpi_details is None:
-        return [ERROR_MISSING_KPI.format(str(kpi_uuid))]
+        return [ERROR_MISSING_KPI.format(kpi_uuid=str(kpi_uuid))]
 
     device_uuid, resource_key, sampling_duration, sampling_interval = kpi_details
 
@@ -264,7 +270,9 @@ def unsubscribe_kpi(request : MonitoringSettings, driver : _Driver, monitoring_l
     for (resource_key, duration, interval), result in zip(resources_to_unsubscribe, results_unsubscribestate):
         if isinstance(result, Exception):
             errors.append(ERROR_UNSUBSCRIBE.format(
-                device_uuid, str(resource_key), str(duration), str(interval), str(result)))
+                device_uuid=str(device_uuid), subscr_key=str(resource_key), subscr_duration=str(duration),
+                subscr_interval=str(interval), error=str(result)
+            ))
             continue
 
     monitoring_loops.remove_kpi(kpi_uuid)
diff --git a/src/policy/Dockerfile b/src/policy/Dockerfile
deleted file mode 120000
index eec732273e12372d1a11fef9d958b124e9d8df1f..0000000000000000000000000000000000000000
--- a/src/policy/Dockerfile
+++ /dev/null
@@ -1 +0,0 @@
-src/main/docker/Dockerfile.multistage.jvm
\ No newline at end of file
diff --git a/src/policy/Dockerfile b/src/policy/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..2c6412d0766558edf3bb469b17c7f2b6a1c7dd08
--- /dev/null
+++ b/src/policy/Dockerfile
@@ -0,0 +1,66 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Multi-stage Docker image build
+
+# Stage 1
+FROM maven:3-jdk-11 AS builder
+
+# Define working directory
+WORKDIR /app
+
+# Copy every file in working directory, as defined in .dockerignore file
+COPY ./pom.xml pom.xml
+COPY ./src src/
+COPY ./target/generated-sources/ target/generated-sources/
+RUN mvn --errors --batch-mode package -Dmaven.test.skip=true
+
+# Stage 2
+FROM builder AS unit-test
+
+RUN mvn --errors --batch-mode -Pgenerate-consolidated-coverage verify
+
+# Stage 3
+FROM registry.access.redhat.com/ubi8/ubi-minimal:8.4 AS release
+
+ARG JAVA_PACKAGE=java-11-openjdk-headless
+ARG RUN_JAVA_VERSION=1.3.8
+ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
+# Install java and the run-java script
+# Also set up permissions for user `1001`
+RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \
+    && microdnf update \
+    && microdnf clean all \
+    && mkdir /deployments \
+    && chown 1001 /deployments \
+    && chmod "g+rwX" /deployments \
+    && chown 1001:root /deployments \
+    && curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \
+    && chown 1001 /deployments/run-java.sh \
+    && chmod 540 /deployments/run-java.sh \
+    && echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/conf/security/java.security
+
+# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
+ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
+# We make four distinct layers so if there are application changes the library layers can be re-used
+COPY --from=builder --chown=1001 /app/target/quarkus-app/lib/ /deployments/lib/
+COPY --from=builder --chown=1001 /app/target/quarkus-app/*.jar /deployments/
+COPY --from=builder --chown=1001 /app/target/quarkus-app/app/ /deployments/app/
+COPY --from=builder --chown=1001 /app/target/quarkus-app/quarkus/ /deployments/quarkus/
+
+EXPOSE 8080
+EXPOSE 6060
+USER 1001
+
+ENTRYPOINT [ "/deployments/run-java.sh" ]
diff --git a/src/policy/src/main/proto/acl.proto b/src/policy/src/main/proto/acl.proto
deleted file mode 120000
index 158ae78eb5bdea534ba7008114c2b97ed6dffed8..0000000000000000000000000000000000000000
--- a/src/policy/src/main/proto/acl.proto
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../proto/acl.proto
\ No newline at end of file
diff --git a/src/policy/src/main/proto/acl.proto b/src/policy/src/main/proto/acl.proto
new file mode 100644
index 0000000000000000000000000000000000000000..3dba735dccf44d584a998eb02b4835bac7ceddd1
--- /dev/null
+++ b/src/policy/src/main/proto/acl.proto
@@ -0,0 +1,69 @@
+// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+package acl;
+
+enum AclRuleTypeEnum {
+  ACLRULETYPE_UNDEFINED = 0;
+  ACLRULETYPE_IPV4      = 1;
+  ACLRULETYPE_IPV6      = 2;
+  ACLRULETYPE_L2        = 3;
+  ACLRULETYPE_MPLS      = 4;
+  ACLRULETYPE_MIXED     = 5;
+}
+
+enum AclForwardActionEnum {
+  ACLFORWARDINGACTION_UNDEFINED = 0;
+  ACLFORWARDINGACTION_DROP      = 1;
+  ACLFORWARDINGACTION_ACCEPT    = 2;
+  ACLFORWARDINGACTION_REJECT    = 3;
+}
+
+enum AclLogActionEnum {
+  ACLLOGACTION_UNDEFINED = 0;
+  ACLLOGACTION_NOLOG     = 1;
+  ACLLOGACTION_SYSLOG    = 2;
+}
+
+message AclMatch {
+  uint32 dscp             = 1;
+  uint32 protocol         = 2;
+  string src_address      = 3;
+  string dst_address      = 4;
+  uint32 src_port         = 5;
+  uint32 dst_port         = 6;
+  uint32 start_mpls_label = 7;
+  uint32 end_mpls_label   = 8;
+}
+
+message AclAction {
+  AclForwardActionEnum forward_action = 1;
+  AclLogActionEnum     log_action     = 2;
+}
+
+message AclEntry {
+  uint32    sequence_id = 1;
+  string    description = 2;
+  AclMatch  match       = 3;
+  AclAction action      = 4;
+}
+
+message AclRuleSet {
+  string             name        = 1;
+  AclRuleTypeEnum    type        = 2;
+  string             description = 3;
+  string             user_id     = 4;
+  repeated AclEntry  entries     = 5;
+}
diff --git a/src/policy/src/main/proto/context.proto b/src/policy/src/main/proto/context.proto
deleted file mode 120000
index 7f33c4bc783bd20d031d94ab3b2e94f0d76ecd95..0000000000000000000000000000000000000000
--- a/src/policy/src/main/proto/context.proto
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../proto/context.proto
\ No newline at end of file
diff --git a/src/policy/src/main/proto/context.proto b/src/policy/src/main/proto/context.proto
new file mode 100644
index 0000000000000000000000000000000000000000..e403c4a22f2df62f695041c094cc1c6e6a193d5f
--- /dev/null
+++ b/src/policy/src/main/proto/context.proto
@@ -0,0 +1,554 @@
+// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+package context;
+
+import "acl.proto";
+import "kpi_sample_types.proto";
+
+service ContextService {
+  rpc ListContextIds     (Empty         ) returns (       ContextIdList   ) {}
+  rpc ListContexts       (Empty         ) returns (       ContextList     ) {}
+  rpc GetContext         (ContextId     ) returns (       Context         ) {}
+  rpc SetContext         (Context       ) returns (       ContextId       ) {}
+  rpc RemoveContext      (ContextId     ) returns (       Empty           ) {}
+  rpc GetContextEvents   (Empty         ) returns (stream ContextEvent    ) {}
+
+  rpc ListTopologyIds    (ContextId     ) returns (       TopologyIdList  ) {}
+  rpc ListTopologies     (ContextId     ) returns (       TopologyList    ) {}
+  rpc GetTopology        (TopologyId    ) returns (       Topology        ) {}
+  rpc GetTopologyDetails (TopologyId    ) returns (       TopologyDetails ) {}
+  rpc SetTopology        (Topology      ) returns (       TopologyId      ) {}
+  rpc RemoveTopology     (TopologyId    ) returns (       Empty           ) {}
+  rpc GetTopologyEvents  (Empty         ) returns (stream TopologyEvent   ) {}
+
+  rpc ListDeviceIds      (Empty         ) returns (       DeviceIdList    ) {}
+  rpc ListDevices        (Empty         ) returns (       DeviceList      ) {}
+  rpc GetDevice          (DeviceId      ) returns (       Device          ) {}
+  rpc SetDevice          (Device        ) returns (       DeviceId        ) {}
+  rpc RemoveDevice       (DeviceId      ) returns (       Empty           ) {}
+  rpc GetDeviceEvents    (Empty         ) returns (stream DeviceEvent     ) {}
+
+  rpc ListEndPointNames  (EndPointIdList) returns (       EndPointNameList) {}
+
+  rpc ListLinkIds        (Empty         ) returns (       LinkIdList      ) {}
+  rpc ListLinks          (Empty         ) returns (       LinkList        ) {}
+  rpc GetLink            (LinkId        ) returns (       Link            ) {}
+  rpc SetLink            (Link          ) returns (       LinkId          ) {}
+  rpc RemoveLink         (LinkId        ) returns (       Empty           ) {}
+  rpc GetLinkEvents      (Empty         ) returns (stream LinkEvent       ) {}
+
+  rpc ListServiceIds     (ContextId     ) returns (       ServiceIdList   ) {}
+  rpc ListServices       (ContextId     ) returns (       ServiceList     ) {}
+  rpc GetService         (ServiceId     ) returns (       Service         ) {}
+  rpc SetService         (Service       ) returns (       ServiceId       ) {}
+  rpc UnsetService       (Service       ) returns (       ServiceId       ) {}
+  rpc RemoveService      (ServiceId     ) returns (       Empty           ) {}
+  rpc GetServiceEvents   (Empty         ) returns (stream ServiceEvent    ) {}
+
+  rpc ListSliceIds       (ContextId     ) returns (       SliceIdList     ) {}
+  rpc ListSlices         (ContextId     ) returns (       SliceList       ) {}
+  rpc GetSlice           (SliceId       ) returns (       Slice           ) {}
+  rpc SetSlice           (Slice         ) returns (       SliceId         ) {}
+  rpc UnsetSlice         (Slice         ) returns (       SliceId         ) {}
+  rpc RemoveSlice        (SliceId       ) returns (       Empty           ) {}
+  rpc GetSliceEvents     (Empty         ) returns (stream SliceEvent      ) {}
+
+  rpc ListConnectionIds  (ServiceId     ) returns (       ConnectionIdList) {}
+  rpc ListConnections    (ServiceId     ) returns (       ConnectionList  ) {}
+  rpc GetConnection      (ConnectionId  ) returns (       Connection      ) {}
+  rpc SetConnection      (Connection    ) returns (       ConnectionId    ) {}
+  rpc RemoveConnection   (ConnectionId  ) returns (       Empty           ) {}
+  rpc GetConnectionEvents(Empty         ) returns (stream ConnectionEvent ) {}
+}
+
+// ----- Generic -------------------------------------------------------------------------------------------------------
+message Empty {}
+
+message Uuid {
+  string uuid = 1;
+}
+
+enum EventTypeEnum {
+  EVENTTYPE_UNDEFINED = 0;
+  EVENTTYPE_CREATE = 1;
+  EVENTTYPE_UPDATE = 2;
+  EVENTTYPE_REMOVE = 3;
+}
+
+message Timestamp {
+  double timestamp = 1;
+}
+
+message Event {
+  Timestamp timestamp = 1;
+  EventTypeEnum event_type = 2;
+}
+
+// ----- Context -------------------------------------------------------------------------------------------------------
+message ContextId {
+  Uuid context_uuid = 1;
+}
+
+message Context {
+  ContextId context_id = 1;
+  string name = 2;
+  repeated TopologyId topology_ids = 3;
+  repeated ServiceId service_ids = 4;
+  repeated SliceId slice_ids = 5;
+  TeraFlowController controller = 6;
+}
+
+message ContextIdList {
+  repeated ContextId context_ids = 1;
+}
+
+message ContextList {
+  repeated Context contexts = 1;
+}
+
+message ContextEvent {
+  Event event = 1;
+  ContextId context_id = 2;
+}
+
+
+// ----- Topology ------------------------------------------------------------------------------------------------------
+message TopologyId {
+  ContextId context_id = 1;
+  Uuid topology_uuid = 2;
+}
+
+message Topology {
+  TopologyId topology_id = 1;
+  string name = 2;
+  repeated DeviceId device_ids = 3;
+  repeated LinkId link_ids = 4;
+}
+
+message TopologyDetails {
+  TopologyId topology_id = 1;
+  string name = 2;
+  repeated Device devices = 3;
+  repeated Link links = 4;
+}
+
+message TopologyIdList {
+  repeated TopologyId topology_ids = 1;
+}
+
+message TopologyList {
+  repeated Topology topologies = 1;
+}
+
+message TopologyEvent {
+  Event event = 1;
+  TopologyId topology_id = 2;
+}
+
+
+// ----- Device --------------------------------------------------------------------------------------------------------
+message DeviceId {
+  Uuid device_uuid = 1;
+}
+
+message Device {
+  DeviceId device_id = 1;
+  string name = 2;
+  string device_type = 3;
+  DeviceConfig device_config = 4;
+  DeviceOperationalStatusEnum device_operational_status = 5;
+  repeated DeviceDriverEnum device_drivers = 6;
+  repeated EndPoint device_endpoints = 7;
+  repeated Component component = 8; // Used for inventory
+}
+
+message Component {
+  repeated string comp_string = 1;
+}
+
+message DeviceConfig {
+  repeated ConfigRule config_rules = 1;
+}
+
+enum DeviceDriverEnum {
+  DEVICEDRIVER_UNDEFINED = 0; // also used for emulated
+  DEVICEDRIVER_OPENCONFIG = 1;
+  DEVICEDRIVER_TRANSPORT_API = 2;
+  DEVICEDRIVER_P4 = 3;
+  DEVICEDRIVER_IETF_NETWORK_TOPOLOGY = 4;
+  DEVICEDRIVER_ONF_TR_352 = 5;
+  DEVICEDRIVER_XR = 6;
+}
+
+enum DeviceOperationalStatusEnum {
+  DEVICEOPERATIONALSTATUS_UNDEFINED = 0;
+  DEVICEOPERATIONALSTATUS_DISABLED = 1;
+  DEVICEOPERATIONALSTATUS_ENABLED = 2;
+}
+
+message DeviceIdList {
+  repeated DeviceId device_ids = 1;
+}
+
+message DeviceList {
+  repeated Device devices = 1;
+}
+
+message DeviceEvent {
+  Event event = 1;
+  DeviceId device_id = 2;
+  DeviceConfig device_config = 3;
+}
+
+
+// ----- Link ----------------------------------------------------------------------------------------------------------
+message LinkId {
+  Uuid link_uuid = 1;
+}
+
+message Link {
+  LinkId link_id = 1;
+  string name = 2;
+  repeated EndPointId link_endpoint_ids = 3;
+}
+
+message LinkIdList {
+  repeated LinkId link_ids = 1;
+}
+
+message LinkList {
+  repeated Link links = 1;
+}
+
+message LinkEvent {
+  Event event = 1;
+  LinkId link_id = 2;
+}
+
+
+// ----- Service -------------------------------------------------------------------------------------------------------
+message ServiceId {
+  ContextId context_id = 1;
+  Uuid service_uuid = 2;
+}
+
+message Service {
+  ServiceId service_id = 1;
+  string name = 2;
+  ServiceTypeEnum service_type = 3;
+  repeated EndPointId service_endpoint_ids = 4;
+  repeated Constraint service_constraints = 5;
+  ServiceStatus service_status = 6;
+  ServiceConfig service_config = 7;
+  Timestamp timestamp = 8;
+}
+
+enum ServiceTypeEnum {
+  SERVICETYPE_UNKNOWN = 0;
+  SERVICETYPE_L3NM = 1;
+  SERVICETYPE_L2NM = 2;
+  SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 3;
+}
+
+enum ServiceStatusEnum {
+  SERVICESTATUS_UNDEFINED = 0;
+  SERVICESTATUS_PLANNED = 1;
+  SERVICESTATUS_ACTIVE =  2;
+  SERVICESTATUS_PENDING_REMOVAL = 3;
+  SERVICESTATUS_SLA_VIOLATED = 4;
+}
+
+message ServiceStatus {
+  ServiceStatusEnum service_status = 1;
+}
+
+message ServiceConfig {
+  repeated ConfigRule config_rules = 1;
+}
+
+message ServiceIdList {
+  repeated ServiceId service_ids = 1;
+}
+
+message ServiceList {
+  repeated Service services = 1;
+}
+
+message ServiceEvent {
+  Event event = 1;
+  ServiceId service_id = 2;
+}
+
+// ----- Slice ---------------------------------------------------------------------------------------------------------
+message SliceId {
+  ContextId context_id = 1;
+  Uuid slice_uuid = 2;
+}
+
+message Slice {
+  SliceId slice_id = 1;
+  string name = 2;
+  repeated EndPointId slice_endpoint_ids = 3;
+  repeated Constraint slice_constraints = 4;
+  repeated ServiceId slice_service_ids = 5;
+  repeated SliceId slice_subslice_ids = 6;
+  SliceStatus slice_status = 7;
+  SliceConfig slice_config = 8;
+  SliceOwner slice_owner = 9;
+  Timestamp timestamp = 10;
+}
+
+message SliceOwner {
+  Uuid owner_uuid = 1;
+  string owner_string = 2;
+}
+
+enum SliceStatusEnum {
+  SLICESTATUS_UNDEFINED    = 0;
+  SLICESTATUS_PLANNED      = 1;
+  SLICESTATUS_INIT         = 2;
+  SLICESTATUS_ACTIVE       = 3;
+  SLICESTATUS_DEINIT       = 4;
+  SLICESTATUS_SLA_VIOLATED = 5;
+}
+
+message SliceStatus {
+  SliceStatusEnum slice_status = 1;
+}
+
+message SliceConfig {
+  repeated ConfigRule config_rules = 1;
+}
+
+message SliceIdList {
+  repeated SliceId slice_ids = 1;
+}
+
+message SliceList {
+  repeated Slice slices = 1;
+}
+
+message SliceEvent {
+  Event event = 1;
+  SliceId slice_id = 2;
+}
+
+// ----- Connection ----------------------------------------------------------------------------------------------------
+message ConnectionId {
+  Uuid connection_uuid = 1;
+}
+
+message ConnectionSettings_L0 {
+  string lsp_symbolic_name = 1;
+}
+
+message ConnectionSettings_L2 {
+  string src_mac_address = 1;
+  string dst_mac_address = 2;
+  uint32 ether_type = 3;
+  uint32 vlan_id = 4;
+  uint32 mpls_label = 5;
+  uint32 mpls_traffic_class = 6;
+}
+
+message ConnectionSettings_L3 {
+  string src_ip_address = 1;
+  string dst_ip_address = 2;
+  uint32 dscp = 3;
+  uint32 protocol = 4;
+  uint32 ttl = 5;
+}
+
+message ConnectionSettings_L4 {
+  uint32 src_port = 1;
+  uint32 dst_port = 2;
+  uint32 tcp_flags = 3;
+  uint32 ttl = 4;
+}
+
+message ConnectionSettings {
+  ConnectionSettings_L0 l0 = 1;
+  ConnectionSettings_L2 l2 = 2;
+  ConnectionSettings_L3 l3 = 3;
+  ConnectionSettings_L4 l4 = 4;
+}
+
+message Connection {
+  ConnectionId connection_id = 1;
+  ServiceId service_id = 2;
+  repeated EndPointId path_hops_endpoint_ids = 3;
+  repeated ServiceId sub_service_ids = 4;
+  ConnectionSettings settings = 5;
+}
+
+message ConnectionIdList {
+  repeated ConnectionId connection_ids = 1;
+}
+
+message ConnectionList {
+  repeated Connection connections = 1;
+}
+
+message ConnectionEvent {
+  Event event = 1;
+  ConnectionId connection_id = 2;
+}
+
+
+// ----- Endpoint ------------------------------------------------------------------------------------------------------
+message EndPointId {
+  TopologyId topology_id = 1;
+  DeviceId device_id = 2;
+  Uuid endpoint_uuid = 3;
+}
+
+message EndPoint {
+  EndPointId endpoint_id = 1;
+  string name = 2;
+  string endpoint_type = 3;
+  repeated kpi_sample_types.KpiSampleType kpi_sample_types = 4;
+  Location endpoint_location = 5;
+}
+
+message EndPointName {
+  EndPointId endpoint_id = 1;
+  string device_name = 2;
+  string endpoint_name = 3;
+  string endpoint_type = 4;
+}
+
+message EndPointIdList {
+  repeated EndPointId endpoint_ids = 1;
+}
+
+message EndPointNameList {
+  repeated EndPointName endpoint_names = 1;
+}
+
+
+// ----- Configuration -------------------------------------------------------------------------------------------------
+enum ConfigActionEnum {
+  CONFIGACTION_UNDEFINED = 0;
+  CONFIGACTION_SET       = 1;
+  CONFIGACTION_DELETE    = 2;
+}
+
+message ConfigRule_Custom {
+  string resource_key = 1;
+  string resource_value = 2;
+}
+
+message ConfigRule_ACL {
+  EndPointId endpoint_id = 1;
+  acl.AclRuleSet rule_set = 2;
+}
+
+message ConfigRule {
+  ConfigActionEnum action = 1;
+  oneof config_rule {
+    ConfigRule_Custom custom = 2;
+    ConfigRule_ACL acl = 3;
+  }
+}
+
+
+// ----- Constraint ----------------------------------------------------------------------------------------------------
+message Constraint_Custom {
+  string constraint_type = 1;
+  string constraint_value = 2;
+}
+
+message Constraint_Schedule {
+  float start_timestamp = 1;
+  float duration_days = 2;
+}
+
+message GPS_Position {
+  float latitude = 1;
+  float longitude = 2;
+}
+
+message Location {
+  oneof location {
+    string region = 1;
+    GPS_Position gps_position = 2;
+  }
+}
+
+message Constraint_EndPointLocation {
+  EndPointId endpoint_id = 1;
+  Location location = 2;
+}
+
+message Constraint_EndPointPriority {
+  EndPointId endpoint_id = 1;
+  uint32 priority = 2;
+}
+
+message Constraint_SLA_Latency {
+  float e2e_latency_ms = 1;
+}
+
+message Constraint_SLA_Capacity {
+  float capacity_gbps = 1;
+}
+
+message Constraint_SLA_Availability {
+  uint32 num_disjoint_paths = 1;
+  bool all_active = 2;
+}
+
+enum IsolationLevelEnum {
+  NO_ISOLATION = 0;
+  PHYSICAL_ISOLATION = 1;
+  LOGICAL_ISOLATION = 2;
+  PROCESS_ISOLATION = 3;
+  PHYSICAL_MEMORY_ISOLATION = 4;
+  PHYSICAL_NETWORK_ISOLATION = 5;
+  VIRTUAL_RESOURCE_ISOLATION = 6;
+  NETWORK_FUNCTIONS_ISOLATION = 7;
+  SERVICE_ISOLATION = 8;
+}
+
+message Constraint_SLA_Isolation_level {
+  repeated IsolationLevelEnum isolation_level = 1;
+}
+
+message Constraint {
+  oneof constraint {
+    Constraint_Custom custom = 1;
+    Constraint_Schedule schedule = 2;
+    Constraint_EndPointLocation endpoint_location = 3;
+    Constraint_EndPointPriority endpoint_priority = 4;
+    Constraint_SLA_Capacity sla_capacity = 5;
+    Constraint_SLA_Latency sla_latency = 6;
+    Constraint_SLA_Availability sla_availability = 7;
+    Constraint_SLA_Isolation_level sla_isolation = 8;
+  }
+}
+
+
+// ----- Miscellaneous -------------------------------------------------------------------------------------------------
+message TeraFlowController {
+  ContextId context_id = 1;
+  string ip_address = 2;
+  uint32 port = 3;
+}
+
+message AuthenticationResult {
+  ContextId context_id = 1;
+  bool authenticated = 2;
+}
diff --git a/src/policy/src/main/proto/context_policy.proto b/src/policy/src/main/proto/context_policy.proto
deleted file mode 120000
index d41593ddeb8b8b89878587e4fb389c94394ab340..0000000000000000000000000000000000000000
--- a/src/policy/src/main/proto/context_policy.proto
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../proto/context_policy.proto
\ No newline at end of file
diff --git a/src/policy/src/main/proto/context_policy.proto b/src/policy/src/main/proto/context_policy.proto
new file mode 100644
index 0000000000000000000000000000000000000000..f6dae48306e2ef7fe8a0682185ec46e1f2ad637e
--- /dev/null
+++ b/src/policy/src/main/proto/context_policy.proto
@@ -0,0 +1,28 @@
+// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+package context_policy;
+
+import "context.proto";
+import "policy.proto";
+
+// created as a separate service to prevent import-loops in context and policy
+service ContextPolicyService {
+  rpc ListPolicyRuleIds(context.Empty         ) returns (policy.PolicyRuleIdList) {}
+  rpc ListPolicyRules  (context.Empty         ) returns (policy.PolicyRuleList  ) {}
+  rpc GetPolicyRule    (policy.PolicyRuleId   ) returns (policy.PolicyRule      ) {}
+  rpc SetPolicyRule    (policy.PolicyRule     ) returns (policy.PolicyRuleId    ) {}
+  rpc RemovePolicyRule (policy.PolicyRuleId   ) returns (context.Empty          ) {}
+}
diff --git a/src/policy/src/main/proto/device.proto b/src/policy/src/main/proto/device.proto
deleted file mode 120000
index ad6e7c47eb9fb50c5cc8a7b3562caaf933ba0469..0000000000000000000000000000000000000000
--- a/src/policy/src/main/proto/device.proto
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../proto/device.proto
\ No newline at end of file
diff --git a/src/policy/src/main/proto/device.proto b/src/policy/src/main/proto/device.proto
new file mode 100644
index 0000000000000000000000000000000000000000..30e60079db6c1eb8641d10115f6f43840eabf39c
--- /dev/null
+++ b/src/policy/src/main/proto/device.proto
@@ -0,0 +1,34 @@
+// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+package device;
+
+import "context.proto";
+import "monitoring.proto";
+
+service DeviceService {
+  rpc AddDevice       (context.Device    ) returns (context.DeviceId    ) {}
+  rpc ConfigureDevice (context.Device    ) returns (context.DeviceId    ) {}
+  rpc DeleteDevice    (context.DeviceId  ) returns (context.Empty       ) {}
+  rpc GetInitialConfig(context.DeviceId  ) returns (context.DeviceConfig) {}
+  rpc MonitorDeviceKpi(MonitoringSettings) returns (context.Empty       ) {}
+}
+
+message MonitoringSettings {
+  monitoring.KpiId kpi_id = 1;
+  monitoring.KpiDescriptor kpi_descriptor = 2;
+  float sampling_duration_s = 3;
+  float sampling_interval_s = 4;
+}
diff --git a/src/policy/src/main/proto/kpi_sample_types.proto b/src/policy/src/main/proto/kpi_sample_types.proto
deleted file mode 120000
index 98e748bbf4fbadbc04c3657f458d733f1bc7bdb8..0000000000000000000000000000000000000000
--- a/src/policy/src/main/proto/kpi_sample_types.proto
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../proto/kpi_sample_types.proto
\ No newline at end of file
diff --git a/src/policy/src/main/proto/kpi_sample_types.proto b/src/policy/src/main/proto/kpi_sample_types.proto
new file mode 100644
index 0000000000000000000000000000000000000000..1ade4d69bf5a6c23d993cd37ed731eee10d7374e
--- /dev/null
+++ b/src/policy/src/main/proto/kpi_sample_types.proto
@@ -0,0 +1,34 @@
+// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+package kpi_sample_types;
+
+enum KpiSampleType {
+    KPISAMPLETYPE_UNKNOWN                       = 0;
+    KPISAMPLETYPE_PACKETS_TRANSMITTED           = 101;
+    KPISAMPLETYPE_PACKETS_RECEIVED              = 102;
+    KPISAMPLETYPE_PACKETS_DROPPED               = 103;
+    KPISAMPLETYPE_BYTES_TRANSMITTED             = 201;
+    KPISAMPLETYPE_BYTES_RECEIVED                = 202;
+    KPISAMPLETYPE_BYTES_DROPPED                 = 203;
+    KPISAMPLETYPE_ML_CONFIDENCE                 = 401;  //. can be used by both optical and L3 without any issue
+    KPISAMPLETYPE_OPTICAL_SECURITY_STATUS       = 501;  //. can be used by both optical and L3 without any issue
+    KPISAMPLETYPE_L3_UNIQUE_ATTACK_CONNS        = 601;
+    KPISAMPLETYPE_L3_TOTAL_DROPPED_PACKTS       = 602;
+    KPISAMPLETYPE_L3_UNIQUE_ATTACKERS           = 603;
+    KPISAMPLETYPE_L3_UNIQUE_COMPROMISED_CLIENTS = 604;
+    KPISAMPLETYPE_L3_SECURITY_STATUS_CRYPTO     = 605;
+    KPISAMPLETYPE_SERVICE_LATENCY_MS            = 701;
+}
diff --git a/src/policy/src/main/proto/monitoring.proto b/src/policy/src/main/proto/monitoring.proto
deleted file mode 120000
index aceaa7328099fe736163be048ee1ad21a61d79a2..0000000000000000000000000000000000000000
--- a/src/policy/src/main/proto/monitoring.proto
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../proto/monitoring.proto
\ No newline at end of file
diff --git a/src/policy/src/main/proto/monitoring.proto b/src/policy/src/main/proto/monitoring.proto
new file mode 100644
index 0000000000000000000000000000000000000000..3862973e056d6267d8defc68e77cbf3c8a10ebee
--- /dev/null
+++ b/src/policy/src/main/proto/monitoring.proto
@@ -0,0 +1,173 @@
+// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+package monitoring;
+
+import "context.proto";
+import "kpi_sample_types.proto";
+
+service MonitoringService {
+  rpc SetKpi                (KpiDescriptor      ) returns (KpiId               ) {} // Stable not final
+  rpc DeleteKpi             (KpiId              ) returns (context.Empty       ) {} // Stable and final
+  rpc GetKpiDescriptor      (KpiId              ) returns (KpiDescriptor       ) {} // Stable and final
+  rpc GetKpiDescriptorList  (context.Empty      ) returns (KpiDescriptorList   ) {} // Stable and final
+  rpc IncludeKpi            (Kpi                ) returns (context.Empty       ) {} // Stable and final
+  rpc MonitorKpi            (MonitorKpiRequest  ) returns (context.Empty       ) {} // Stable and final
+  rpc QueryKpiData          (KpiQuery           ) returns (RawKpiTable         ) {} // Not implemented
+  rpc SetKpiSubscription    (SubsDescriptor     ) returns (stream SubsResponse ) {} // Stable not final
+  rpc GetSubsDescriptor     (SubscriptionID     ) returns (SubsDescriptor      ) {} // Stable and final
+  rpc GetSubscriptions      (context.Empty      ) returns (SubsList            ) {} // Stable and final
+  rpc DeleteSubscription    (SubscriptionID     ) returns (context.Empty       ) {} // Stable and final
+  rpc SetKpiAlarm           (AlarmDescriptor    ) returns (AlarmID             ) {} // Stable not final
+  rpc GetAlarms             (context.Empty      ) returns (AlarmList           ) {} // Stable and final
+  rpc GetAlarmDescriptor    (AlarmID            ) returns (AlarmDescriptor     ) {} // Stable and final
+  rpc GetAlarmResponseStream(AlarmSubscription  ) returns (stream AlarmResponse) {} // Not Stable not final
+  rpc DeleteAlarm           (AlarmID            ) returns (context.Empty       ) {} // Stable and final
+  rpc GetStreamKpi          (KpiId              ) returns (stream Kpi          ) {} // Stable not final
+  rpc GetInstantKpi         (KpiId              ) returns (Kpi                 ) {} // Stable not final
+}
+
+message KpiDescriptor {
+  KpiId                          kpi_id          = 1;
+  string                         kpi_description = 2;
+  repeated KpiId                 kpi_id_list     = 3;
+  kpi_sample_types.KpiSampleType kpi_sample_type = 4;
+  context.DeviceId               device_id       = 5;
+  context.EndPointId             endpoint_id     = 6;
+  context.ServiceId              service_id      = 7;
+  context.SliceId                slice_id        = 8;
+  context.ConnectionId           connection_id   = 9;
+}
+
+message MonitorKpiRequest {
+  KpiId kpi_id              = 1;
+  float monitoring_window_s = 2;
+  float sampling_rate_s     = 3;
+  // Pending add field to reflect Available Device Protocols
+}
+
+message KpiQuery {
+  repeated KpiId    kpi_ids             = 1;
+  float             monitoring_window_s = 2;
+  uint32            last_n_samples      = 3;  // used when you want something like "get the last N many samples
+  context.Timestamp start_timestamp     = 4;  // used when you want something like "get the samples since X date/time"
+  context.Timestamp end_timestamp       = 5;  // used when you want something like "get the samples until X date/time"
+}
+
+
+message RawKpi { // cell
+  context.Timestamp timestamp = 1;
+  KpiValue          kpi_value = 2;
+}
+
+message RawKpiList { // column
+  KpiId           kpi_id    = 1;
+  repeated RawKpi raw_kpis  = 2;
+}
+
+message RawKpiTable { // table
+  repeated RawKpiList raw_kpi_lists = 1;
+}
+
+message KpiId {
+  context.Uuid kpi_id = 1;
+}
+
+message Kpi {
+  KpiId             kpi_id    = 1;
+  context.Timestamp timestamp = 2;
+  KpiValue          kpi_value = 3;
+}
+
+message KpiValueRange {
+  KpiValue  kpiMinValue     = 1;
+  KpiValue  kpiMaxValue     = 2;
+  bool      inRange         = 3;  // by default True
+  bool      includeMinValue = 4;  // False is outside the interval
+  bool      includeMaxValue = 5;  // False is outside the interval
+}
+
+message KpiValue {
+  oneof value {
+    int32  int32Val  = 1;
+    uint32 uint32Val = 2;
+    int64  int64Val  = 3;
+    uint64 uint64Val = 4;
+    float  floatVal  = 5;
+    string stringVal = 6;
+    bool   boolVal   = 7;
+  }
+}
+
+
+message KpiList {
+  repeated Kpi kpi = 1;
+}
+
+message KpiDescriptorList {
+  repeated KpiDescriptor kpi_descriptor_list = 1;
+}
+
+message SubsDescriptor{
+  SubscriptionID    subs_id             = 1;
+  KpiId             kpi_id              = 2;
+  float             sampling_duration_s = 3;
+  float             sampling_interval_s = 4;
+  context.Timestamp start_timestamp     = 5;  // used when you want something like "get the samples since X date/time"
+  context.Timestamp end_timestamp       = 6;  // used when you want something like "get the samples until X date/time"
+  // Pending add field to reflect Available Device Protocols
+}
+
+message SubscriptionID {
+  context.Uuid subs_id = 1;
+}
+
+message SubsResponse {
+  SubscriptionID   subs_id  = 1;
+  KpiList          kpi_list = 2;
+}
+
+message SubsList {
+  repeated SubsDescriptor subs_descriptor = 1;
+}
+
+message AlarmDescriptor {
+  AlarmID                     alarm_id              = 1;
+  string                      alarm_description     = 2;
+  string                      name                  = 3;
+  KpiId                       kpi_id                = 4;
+  KpiValueRange               kpi_value_range       = 5;
+  context.Timestamp           timestamp             = 6;
+}
+
+message AlarmID{
+  context.Uuid alarm_id = 1;
+}
+
+message AlarmSubscription{
+  AlarmID alarm_id                  = 1;
+  float   subscription_timeout_s    = 2;
+  float   subscription_frequency_ms = 3;
+}
+
+message AlarmResponse {
+  AlarmID           alarm_id  = 1;
+  string            text      = 2;
+  KpiList           kpi_list  = 3;
+}
+
+message AlarmList {
+    repeated AlarmDescriptor alarm_descriptor = 1;
+}
diff --git a/src/policy/src/main/proto/policy.proto b/src/policy/src/main/proto/policy.proto
deleted file mode 120000
index df455f9611632300f34c690b7b3ddcc1f97d10ec..0000000000000000000000000000000000000000
--- a/src/policy/src/main/proto/policy.proto
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../proto/policy.proto
\ No newline at end of file
diff --git a/src/policy/src/main/proto/policy.proto b/src/policy/src/main/proto/policy.proto
new file mode 100644
index 0000000000000000000000000000000000000000..a6f16015035096c6baf13a7b4e707c06e9ab1727
--- /dev/null
+++ b/src/policy/src/main/proto/policy.proto
@@ -0,0 +1,113 @@
+// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+package policy;
+
+import "context.proto";
+import "policy_condition.proto";
+import "policy_action.proto";
+
+service PolicyService {
+  rpc PolicyAddService (PolicyRuleService) returns (PolicyRuleState) {}
+  rpc PolicyAddDevice (PolicyRuleDevice) returns (PolicyRuleState) {}
+  rpc PolicyUpdateService (PolicyRuleService) returns (PolicyRuleState) {}
+  rpc PolicyUpdateDevice (PolicyRuleDevice) returns (PolicyRuleState) {}
+  rpc PolicyDelete (PolicyRuleId) returns (PolicyRuleState) {}
+  rpc GetPolicyService (PolicyRuleId) returns (PolicyRuleService) {}
+  rpc GetPolicyDevice (PolicyRuleId) returns (PolicyRuleDevice) {}
+  rpc GetPolicyByServiceId (context.ServiceId) returns (PolicyRuleServiceList) {}
+}
+
+enum PolicyRuleStateEnum {
+  POLICY_UNDEFINED = 0;     // Undefined rule state
+  POLICY_FAILED = 1;        // Rule failed
+  POLICY_INSERTED = 2;      // Rule is just inserted
+  POLICY_VALIDATED = 3;     // Rule content is correct
+  POLICY_PROVISIONED = 4;   // Rule subscribed to Monitoring
+  POLICY_ACTIVE = 5;        // Rule is currently active (alarm is just thrown by Monitoring)
+  POLICY_ENFORCED = 6;      // Rule action is successfully enforced
+  POLICY_INEFFECTIVE = 7;   // The applied rule action did not work as expected
+  POLICY_EFFECTIVE = 8;     // The applied rule action did work as expected
+  POLICY_UPDATED = 9;       // Operator requires a policy to change
+  POLICY_REMOVED = 10;      // Operator requires to remove a policy
+}
+
+message PolicyRuleId {
+  context.Uuid uuid = 1;
+}
+
+message PolicyRuleState {
+  PolicyRuleStateEnum policyRuleState = 1;
+  string policyRuleStateMessage = 2;
+}
+
+// Basic policy rule attributes
+message PolicyRuleBasic {
+  PolicyRuleId policyRuleId = 1;
+  PolicyRuleState policyRuleState = 2; //policy.proto:58:12: Explicit 'optional' labels are disallowed in the Proto3 syntax. To define 'optional' fields in Proto3, simply remove the 'optional' label, as fields are 'optional' by default.
+  uint32 priority = 3;
+
+  // Event-Condition-Action (ECA) model
+  repeated PolicyRuleCondition conditionList = 4;  // When these policy conditions are met, an event is automatically thrown
+  BooleanOperator booleanOperator = 5;             // Evaluation operator to be used
+  repeated PolicyRuleAction actionList = 6;        // One or more actions should be applied
+}
+
+// Service-oriented policy rule
+message PolicyRuleService {
+  // Basic policy rule attributes
+  PolicyRuleBasic policyRuleBasic = 1;
+
+  // Affected service and (some of) its device(s)
+  context.ServiceId serviceId = 2;
+  repeated context.DeviceId deviceList = 3;  // List of devices this service is traversing (not exhaustive)
+}
+
+// Device-oriented policy rule
+message PolicyRuleDevice {
+  // Basic policy rule attributes
+  PolicyRuleBasic policyRuleBasic = 1;
+
+  // Affected device(s)
+  repeated context.DeviceId deviceList = 2;
+}
+
+// Wrapper policy rule object
+message PolicyRule {
+  oneof policy_rule {
+    PolicyRuleService service = 1;
+    PolicyRuleDevice device = 2;
+  }
+}
+
+// A list of policy rule IDs
+message PolicyRuleIdList {
+  repeated PolicyRuleId policyRuleIdList = 1;
+}
+
+// A list of service-oriented policy rules
+message PolicyRuleServiceList {
+  repeated PolicyRuleService policyRuleServiceList = 1;
+}
+
+// A list of device-oriented policy rules
+message PolicyRuleDeviceList {
+  repeated PolicyRuleDevice policyRuleDeviceList = 1;
+}
+
+// A list of policy rules
+message PolicyRuleList {
+  repeated PolicyRule policyRules = 1;
+}
diff --git a/src/policy/src/main/proto/policy_action.proto b/src/policy/src/main/proto/policy_action.proto
deleted file mode 120000
index 63dcef3d2c6753f9b732dc7491baa5f449e55eff..0000000000000000000000000000000000000000
--- a/src/policy/src/main/proto/policy_action.proto
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../proto/policy_action.proto
\ No newline at end of file
diff --git a/src/policy/src/main/proto/policy_action.proto b/src/policy/src/main/proto/policy_action.proto
new file mode 100644
index 0000000000000000000000000000000000000000..17dd721196c0ed407849aa23099477ea34d39ddd
--- /dev/null
+++ b/src/policy/src/main/proto/policy_action.proto
@@ -0,0 +1,40 @@
+// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+package policy;
+
+// Action
+message PolicyRuleAction {
+  PolicyRuleActionEnum action = 1;
+  repeated PolicyRuleActionConfig action_config = 2;
+}
+
+enum PolicyRuleActionEnum {
+  POLICYRULE_ACTION_NO_ACTION = 0;
+  POLICYRULE_ACTION_SET_DEVICE_STATUS = 1;
+  POLICYRULE_ACTION_ADD_SERVICE_CONFIGRULE = 2;
+  POLICYRULE_ACTION_ADD_SERVICE_CONSTRAINT = 3;
+}
+
+// Action configuration
+message PolicyRuleActionConfig {
+  string action_key = 1;
+  string action_value = 2;
+}
+
+// message PolicyRuleAction {
+//   PolicyRuleActionEnum action = 1;
+//   repeated string parameters = 2;
+// }
\ No newline at end of file
diff --git a/src/policy/src/main/proto/policy_condition.proto b/src/policy/src/main/proto/policy_condition.proto
deleted file mode 120000
index 31f7d9d10539de8c0a1bf06cf6393b86ab223c16..0000000000000000000000000000000000000000
--- a/src/policy/src/main/proto/policy_condition.proto
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../proto/policy_condition.proto
\ No newline at end of file
diff --git a/src/policy/src/main/proto/policy_condition.proto b/src/policy/src/main/proto/policy_condition.proto
new file mode 100644
index 0000000000000000000000000000000000000000..2037af93c375838209e78a07ec95e25d469d1d5a
--- /dev/null
+++ b/src/policy/src/main/proto/policy_condition.proto
@@ -0,0 +1,43 @@
+// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+package policy;
+
+import "monitoring.proto";
+
+// Condition
+message PolicyRuleCondition {
+  monitoring.KpiId kpiId = 1;
+  NumericalOperator numericalOperator = 2;
+  monitoring.KpiValue kpiValue = 3;
+}
+
+// Operator to be used when comparing Kpis with condition values
+enum NumericalOperator {
+  POLICYRULE_CONDITION_NUMERICAL_UNDEFINED = 0;          // Kpi numerical operator undefined
+  POLICYRULE_CONDITION_NUMERICAL_EQUAL = 1;              // Kpi is equal with value
+  POLICYRULE_CONDITION_NUMERICAL_NOT_EQUAL = 2;          // Kpi is not equal with value
+  POLICYRULE_CONDITION_NUMERICAL_LESS_THAN = 3;          // Kpi is less than value
+  POLICYRULE_CONDITION_NUMERICAL_LESS_THAN_EQUAL = 4;    // Kpi is less than or equal with value
+  POLICYRULE_CONDITION_NUMERICAL_GREATER_THAN = 5;       // Kpi is greater than value
+  POLICYRULE_CONDITION_NUMERICAL_GREATER_THAN_EQUAL = 6; // Kpi is less than or equal with value
+}
+
+// Operator to be used when evaluating each condition
+enum BooleanOperator {
+  POLICYRULE_CONDITION_BOOLEAN_UNDEFINED = 0;  // Boolean operator undefined
+  POLICYRULE_CONDITION_BOOLEAN_AND = 1;        // Boolean AND operator
+  POLICYRULE_CONDITION_BOOLEAN_OR = 2;         // Boolean OR operator
+}
\ No newline at end of file
diff --git a/src/policy/src/main/proto/service.proto b/src/policy/src/main/proto/service.proto
deleted file mode 120000
index 5ca543da01298ca25912a534f460d4a7183e3a60..0000000000000000000000000000000000000000
--- a/src/policy/src/main/proto/service.proto
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../proto/service.proto
\ No newline at end of file
diff --git a/src/policy/src/main/proto/service.proto b/src/policy/src/main/proto/service.proto
new file mode 100644
index 0000000000000000000000000000000000000000..21e5699413cc4842962af6ee9c204b383fc61ec0
--- /dev/null
+++ b/src/policy/src/main/proto/service.proto
@@ -0,0 +1,24 @@
+// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+package service;
+
+import "context.proto";
+
+service ServiceService {
+  rpc CreateService(context.Service  ) returns (context.ServiceId) {}
+  rpc UpdateService(context.Service  ) returns (context.ServiceId) {}
+  rpc DeleteService(context.ServiceId) returns (context.Empty    ) {}
+}