diff --git a/go.mod b/go.mod
index 8628f46fafb45b308fa95a0247ffe2eda56ed629..88c297be87bdc3b80e5d33beae02f9d51c3b0609 100644
--- a/go.mod
+++ b/go.mod
@@ -1,18 +1,22 @@
 module code.fbi.h-da.de/danet/proto-kms
 
-go 1.20
+go 1.21
 
 require (
-	github.com/google/uuid v1.3.0
+	github.com/google/uuid v1.3.1
 	github.com/sirupsen/logrus v1.9.3
-	google.golang.org/grpc v1.56.2
+	google.golang.org/grpc v1.58.2
 	google.golang.org/protobuf v1.31.0
 )
 
 require (
+	code.fbi.h-da.de/danet/ekms v0.0.0-20231031082917-60e1f07a8617 // indirect
+	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
 	github.com/golang/protobuf v1.5.3 // indirect
-	golang.org/x/net v0.9.0 // indirect
-	golang.org/x/sys v0.7.0 // indirect
-	golang.org/x/text v0.9.0 // indirect
-	google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
+	github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
+	github.com/stretchr/testify v1.8.4 // indirect
+	golang.org/x/net v0.15.0 // indirect
+	golang.org/x/sys v0.13.0 // indirect
+	golang.org/x/text v0.13.0 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect
 )
diff --git a/go.sum b/go.sum
index d03b5e77e82b5bd48952a6ba0acdbdf4d461bc2c..ae1df24502653a73e8917bc1b557cdad887315ca 100644
--- a/go.sum
+++ b/go.sum
@@ -1,36 +1,49 @@
+code.fbi.h-da.de/danet/ekms v0.0.0-20231027141805-c77e2d25accb h1:6PbnWyn8QwhZWPVN5L3cSO148gGxk7X5GGYkL5awMl8=
+code.fbi.h-da.de/danet/ekms v0.0.0-20231027141805-c77e2d25accb/go.mod h1:qVaZ1wGJ+XrE+S3eW1CEB0gAarzClnxYEog06BLnD4k=
+code.fbi.h-da.de/danet/ekms v0.0.0-20231030172039-48ca51ab722d h1:wfjIMNVdMf0fr1xMgNwImlE9UsWgDBRj/bQY9QtzlW8=
+code.fbi.h-da.de/danet/ekms v0.0.0-20231030172039-48ca51ab722d/go.mod h1:qVaZ1wGJ+XrE+S3eW1CEB0gAarzClnxYEog06BLnD4k=
+code.fbi.h-da.de/danet/ekms v0.0.0-20231030180651-55420c3dc33f h1:JXRwaYLIcQ1uuH1PVRJ8jcXvLjXKmup2RLlDpnUYqvo=
+code.fbi.h-da.de/danet/ekms v0.0.0-20231030180651-55420c3dc33f/go.mod h1:qVaZ1wGJ+XrE+S3eW1CEB0gAarzClnxYEog06BLnD4k=
+code.fbi.h-da.de/danet/ekms v0.0.0-20231031082917-60e1f07a8617 h1:tceO3twY87RXD5Jet7YZdC0SXo5NuWHr0IZ/IvCO/0s=
+code.fbi.h-da.de/danet/ekms v0.0.0-20231031082917-60e1f07a8617/go.mod h1:qVaZ1wGJ+XrE+S3eW1CEB0gAarzClnxYEog06BLnD4k=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
 github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
 github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
-github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
-github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
+github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
 github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
-golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
+github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
+golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
 golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
-golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
-golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
+golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A=
-google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
-google.golang.org/grpc v1.56.2 h1:fVRFRnXvU+x6C4IlHZewvJOVHoOv1TUuQyoRsYnB4bI=
-google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 h1:N3bU/SQDCDyD6R528GJ/PwW9KjYcJA3dgyH+MovAkIM=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA=
+google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I=
+google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
 google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/kms/kmsintercom.go b/kms/kmsintercom.go
index 78cd85502e2d52c17534f794e26bad77a36ad27e..7076f2782ac1a43349906703d5dde62ced521824 100644
--- a/kms/kmsintercom.go
+++ b/kms/kmsintercom.go
@@ -4,12 +4,14 @@ import (
 	"context"
 	"encoding/base64"
 	"flag"
+	"io/ioutil"
 	"net"
 	"time"
 
 	"github.com/google/uuid"
 	log "github.com/sirupsen/logrus"
 
+	etsi14 "code.fbi.h-da.de/danet/ekms/api/go/rest/etsi/client"
 	pb "code.fbi.h-da.de/danet/proto-kms/api/gen/proto/go/kmsintercom"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/codes"
@@ -38,6 +40,52 @@ func (s *kmsTalkerServer) InterComCapabilities(ctx context.Context, in *pb.Inter
 	}, nil
 }
 
+func (s *kmsTalkerServer) KeyIdNotification(ctx context.Context, in *pb.KeyIdNotificationRequest) (*pb.KeyIdNotificationResponse, error) {
+	// check if a peer exists
+	peer, ok := s.eKMS.KmsPeers[in.GetInterComAddr()]
+	if !ok {
+		//TODO: proper error message
+		return nil, status.Error(codes.Internal, "peer does not exist")
+	}
+
+	eqm, ok := peer.servingQuantumModul.(*ETSI014HTTPQuantumModule)
+	if !ok {
+		return nil, status.Error(codes.Internal, "expected etsi014 quantum module")
+	}
+
+	etsi14KeyIds := make([]etsi14.KeyIDsRequestKeyIDsInner, len(in.KeyIds))
+	for i, keyid := range in.KeyIds {
+		etsi14KeyIds[i] = etsi14.KeyIDsRequestKeyIDsInner{
+			KeyID: keyid,
+		}
+	}
+
+	keyContainer, resp, err := eqm.client.GetKeyWithIdPost(eqm.masterSAEID, etsi14KeyIds)
+	if err != nil {
+		return nil, err
+	}
+
+	defer resp.Body.Close()
+
+	// TODO: add proper status code handling
+	if resp.StatusCode != 200 {
+		body, err := ioutil.ReadAll(resp.Body)
+		if err != nil {
+			return nil, err
+		}
+		return nil, status.Error(codes.Aborted, string(body))
+	}
+
+	// TODO: could be run in go routine
+	if err := addETSIKeysToKeystore(eqm.keyStore, keyContainer.GetKeys()); err != nil {
+		return nil, status.Error(codes.Internal, "expected etsi014 quantum module")
+	}
+
+	return &pb.KeyIdNotificationResponse{
+		Timestamp: time.Now().Unix(),
+	}, nil
+}
+
 // TODO: should be removed as soon as the emulated quantum module has been
 // changed; is specific for emulated quantum module
 func (s *kmsTalkerServer) SyncQkdBulk(ctx context.Context, in *pb.SyncQkdBulkRequest) (*pb.SyncQkdBulkResponse, error) {
diff --git a/kms/module.go b/kms/module.go
index 736cc6858345ed51f63a614e2b2d9a99d4b8cdac..dd0a5a23790cbf19563678676703943b8316f6ca 100644
--- a/kms/module.go
+++ b/kms/module.go
@@ -6,9 +6,12 @@ import (
 	"fmt"
 	"io"
 	"net"
+	"net/url"
 	"sync"
 	"time"
 
+	etsi14 "code.fbi.h-da.de/danet/ekms/api/go/rest/etsi/client"
+	restclient "code.fbi.h-da.de/danet/ekms/restclient"
 	pbIC "code.fbi.h-da.de/danet/proto-kms/api/gen/proto/go/kmsintercom"
 	"code.fbi.h-da.de/danet/proto-kms/quantumlayer"
 	"github.com/google/uuid"
@@ -174,7 +177,114 @@ func (eqe *EmulatedQuantumModule) KeyChopper(bulkKey *quantumlayer.QuantumLayerB
 }
 
 type ETSI014HTTPQuantumModule struct {
-	id       uuid.UUID
-	keyStore *kmsKeyStore
-	peer     *kmsPeer
+	id          uuid.UUID
+	keyStore    *kmsKeyStore
+	peer        *kmsPeer
+	client      *restclient.ClientImpl
+	slaveSAEID  string
+	masterSAEID string
+}
+
+func NewETSI014HTTPQuantumModule(addr, slaveSAEID, masterSAEID string) (*ETSI014HTTPQuantumModule, error) {
+	parsedUrl, err := url.Parse("http://" + addr)
+	if err != nil {
+		return nil, err
+	}
+
+	restClientConf := &etsi14.Configuration{
+		Debug: true,
+		Servers: etsi14.ServerConfigurations{
+			{
+				URL:         parsedUrl.String(),
+				Description: "QKD Module with ETSI14 implemented as API.",
+			},
+		},
+		Scheme: parsedUrl.Scheme,
+		// HTTPClient: &http.Client{
+		// 	Transport: &http.Transport{
+		// 		TLSClientConfig: &tls.Config{},
+		// 	},
+		// },
+	}
+
+	// TODO: we might want to add mastersaeid here aswell
+	client, err := restclient.NewClientImpl(slaveSAEID, restClientConf)
+	if err != nil {
+		return nil, err
+	}
+
+	return &ETSI014HTTPQuantumModule{
+		id:          uuid.New(),
+		keyStore:    NewKmsKeyStore(256),
+		peer:        nil,
+		client:      client,
+		slaveSAEID:  slaveSAEID,
+		masterSAEID: masterSAEID,
+	}, nil
+}
+
+func (eqe *ETSI014HTTPQuantumModule) ID() uuid.UUID {
+	return eqe.id
+}
+
+func (eqe *ETSI014HTTPQuantumModule) Initialize() error {
+	// start polling
+	go func() {
+		ticker := time.NewTicker(2 * time.Second)
+		defer ticker.Stop()
+
+		// TODO: add context/channel to stop
+		for {
+			select {
+			case <-ticker.C:
+				container, _, err := eqe.client.GetKey()
+				if err != nil {
+					log.Error(err)
+					break
+				}
+
+				keyIds := make([]string, len(container.GetKeys()))
+				for i, keyItem := range container.GetKeys() {
+					keyIds[i] = keyItem.GetKeyID()
+				}
+
+				_, err = eqe.peer.peerClient.KeyIdNotification(context.Background(),
+					&pbIC.KeyIdNotificationRequest{
+						Timestamp:    time.Now().Unix(),
+						InterComAddr: eqe.peer.interComAddr,
+						KeyIds:       keyIds,
+					})
+				if err != nil {
+					log.Error(err)
+					break
+				}
+
+				if err := addETSIKeysToKeystore(eqe.keyStore, container.GetKeys()); err != nil {
+					log.Error(err)
+					break
+				}
+			}
+		}
+	}()
+	return nil
+}
+
+func (eqe *ETSI014HTTPQuantumModule) Address() net.Addr {
+	return nil
+}
+
+func (eqe *ETSI014HTTPQuantumModule) KeyStore() *kmsKeyStore {
+	return eqe.keyStore
+}
+
+func (eqe *ETSI014HTTPQuantumModule) Peer() *kmsPeer {
+	return eqe.peer
+}
+
+func (eqe *ETSI014HTTPQuantumModule) SetPeer(peer *kmsPeer) {
+	eqe.peer = peer
+}
+
+func (eqe *ETSI014HTTPQuantumModule) Sync() error {
+	return nil
 }
diff --git a/kms/util.go b/kms/util.go
index 696ab67a597dca78b97158191ad130884e484376..c17bf87f27edd757c57e11ad9cebabe6d0f02a44 100644
--- a/kms/util.go
+++ b/kms/util.go
@@ -2,8 +2,12 @@ package kms
 
 import (
 	"bytes"
+	"encoding/base64"
 	"fmt"
 	"net/http"
+	"strconv"
+
+	etsi14 "code.fbi.h-da.de/danet/ekms/api/go/rest/etsi/client"
 )
 
 func randomItemFromMap[T comparable, M any](m map[T]M) (M, error) {
@@ -37,6 +41,29 @@ func keysOfMap[T comparable, M any](m map[T]M) []T {
 	return keys
 }
 
+func addETSIKeysToKeystore(keyStore *kmsKeyStore, keyContainer []etsi14.KeyContainerKeysInner) error {
+	for _, keyItem := range keyContainer {
+		// decode base64 encoded key string
+		key, err := base64.StdEncoding.DecodeString(keyItem.GetKey())
+		if err != nil {
+			return err
+		}
+
+		// key id to uint
+		keyId := keyItem.GetKeyID()
+		keyIdUint, err := strconv.ParseUint(keyId, 10, 64)
+		if err != nil {
+			return err
+		}
+
+		// add to keystore
+		keyStore.keyStoreMutex.Lock()
+		keyStore.addKey(keyIdUint, key)
+		keyStore.keyStoreMutex.Unlock()
+	}
+	return nil
+}
+
 // NOTE: For demo purpose only
 func sendKmsInfoMessage(url string, json []byte) error {
 	request, err := http.NewRequest("POST", url, bytes.NewBuffer(json))
diff --git a/main_test.go b/main_test.go
index da2e697a1fbe6d889f2f3af8a08641b58f29f731..1ce88b4aa61f521bc8d2af59029be237121ef4de 100644
--- a/main_test.go
+++ b/main_test.go
@@ -88,9 +88,6 @@ func emulatedKMS(myName, myUDPAddr, myInterComAddr, peerUDPAddr, peerInterComAdd
 
 	// Start the SDN/management and key retrieval interface
 	go kms.StartETSI(myUDPAddr, emuKMS)
-
-	// // TODO/XXX catch errors!
-	// emuKMS.GlobalKeyHandler(7 * time.Second)
 }
 
 func middleKMS(myName, myUDPAddr, myInterComAddr, leftUDPAddr, leftInterComAddr, rightUDPAddr, rightInterComAddr string) {