diff --git a/controller.go b/controller.go
index da943ff1256ceb4701dccf4b98a1bfe87a630b10..f286874790320c61744951965ac6891a329105e4 100644
--- a/controller.go
+++ b/controller.go
@@ -9,6 +9,8 @@ import (
 	"sync"
 	"time"
 
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/southbound"
+
 	"github.com/google/uuid"
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/viper"
@@ -88,7 +90,7 @@ func createSouthboundInterfaces() error {
 }
 
 // createPrincipalNetworkDomain initializes the controller with an initial PND
-func createPrincipalNetworkDomain(s nucleus.SouthboundInterface) error {
+func createPrincipalNetworkDomain(s southbound.SouthboundInterface) error {
 	pnd, err := nucleus.NewPND("base", "gosdn base pnd", uuid.New(), s)
 	if err != nil {
 		return err
diff --git a/initialise_test.go b/initialise_test.go
index 6994a752f978424529d604a7d823ed6be0f9ea9c..984cf81ec228f76245892538aab838209ac981c1 100644
--- a/initialise_test.go
+++ b/initialise_test.go
@@ -5,7 +5,10 @@ import (
 	"os"
 	"testing"
 
-	"code.fbi.h-da.de/cocsn/gosdn/nucleus"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/device"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/networkdomain"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/southbound"
+
 	"code.fbi.h-da.de/cocsn/gosdn/nucleus/util/proto"
 	"github.com/google/uuid"
 	gpb "github.com/openconfig/gnmi/proto/gnmi"
@@ -22,10 +25,10 @@ var defaultSbiID uuid.UUID
 var defaultPndID uuid.UUID
 var cuid uuid.UUID
 
-var sbi nucleus.SouthboundInterface
-var httpTestPND nucleus.PrincipalNetworkDomain
+var sbi southbound.SouthboundInterface
+var httpTestPND networkdomain.NetworkDomain
 var gnmiMessages map[string]pb.Message
-var httpTestDevice nucleus.Device
+var httpTestDevice device.Device
 
 var args string
 var argsNotFound string
diff --git a/interfaces/change/change.go b/interfaces/change/change.go
new file mode 100644
index 0000000000000000000000000000000000000000..9c861b44ad34de54f177e91f2b0eed2a590d6558
--- /dev/null
+++ b/interfaces/change/change.go
@@ -0,0 +1,13 @@
+package change
+
+import "github.com/google/uuid"
+
+// Change is an intended change to an OND. It is unique and immutable.
+// It has a cuid, a timestamp, and holds both the previous and the new
+// state. It keeps track if the state is committed and confirmed. A callback
+// exists to acess the proper transport for the changed OND
+type Change interface {
+	ID() uuid.UUID
+	Commit() error
+	Confirm() error
+}
diff --git a/interfaces/device/device.go b/interfaces/device/device.go
new file mode 100644
index 0000000000000000000000000000000000000000..ca233d357a2fa26688eb2e63f1ee7b6213ccbea0
--- /dev/null
+++ b/interfaces/device/device.go
@@ -0,0 +1,20 @@
+package device
+
+import (
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/southbound"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/transport"
+	"github.com/google/uuid"
+	"github.com/openconfig/ygot/ygot"
+	"google.golang.org/protobuf/proto"
+)
+
+// Device represents an Orchestrated Network Device (OND) which is managed by
+// nucleus
+type Device interface {
+	ID() uuid.UUID
+	Model() ygot.GoStruct
+	Transport() transport.Transport
+	Name() string
+	SBI() southbound.SouthboundInterface
+	ProcessResponse(proto.Message) error
+}
diff --git a/interfaces/networkdomain/pnd.go b/interfaces/networkdomain/pnd.go
new file mode 100644
index 0000000000000000000000000000000000000000..ce032d856f5d3ff64705593d7c2e2cef5c6b7b58
--- /dev/null
+++ b/interfaces/networkdomain/pnd.go
@@ -0,0 +1,37 @@
+package networkdomain
+
+import (
+	ppb "code.fbi.h-da.de/cocsn/api/go/gosdn/pnd"
+	tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/change"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/device"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/southbound"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/store"
+	"github.com/google/uuid"
+)
+
+// NetworkDomain provides an interface for network domain implementations
+// like principal network domain or logical network domain.
+type NetworkDomain interface {
+	Destroy() error
+	AddSbi(s southbound.SouthboundInterface) error
+	RemoveSbi(uuid.UUID) error
+	AddDevice(name string, opts *tpb.TransportOption, sid uuid.UUID) error
+	GetDevice(identifier string) (device.Device, error)
+	RemoveDevice(uuid.UUID) error
+	Devices() []uuid.UUID
+	ChangeOND(uuid uuid.UUID, operation ppb.ApiOperation, path string, value ...string) error
+	Request(uuid.UUID, string) error
+	RequestAll(string) error
+	GetName() string
+	GetDescription() string
+	MarshalDevice(string) (string, error)
+	ContainsDevice(uuid.UUID) bool
+	GetSBIs() store.Store
+	ID() uuid.UUID
+	PendingChanges() []uuid.UUID
+	CommittedChanges() []uuid.UUID
+	GetChange(uuid.UUID, ...int) (change.Change, error)
+	Commit(uuid.UUID) error
+	Confirm(uuid.UUID) error
+}
diff --git a/interfaces/southbound/sbi.go b/interfaces/southbound/sbi.go
new file mode 100644
index 0000000000000000000000000000000000000000..0d4cdb56fd5290a849e33bd107a2ef55e31e3748
--- /dev/null
+++ b/interfaces/southbound/sbi.go
@@ -0,0 +1,25 @@
+package southbound
+
+import (
+	spb "code.fbi.h-da.de/cocsn/api/go/gosdn/southbound"
+
+	"github.com/google/uuid"
+	gpb "github.com/openconfig/gnmi/proto/gnmi"
+	"github.com/openconfig/goyang/pkg/yang"
+	"github.com/openconfig/ygot/ytypes"
+)
+
+// SouthboundInterface provides an
+// interface for SBI implementations
+type SouthboundInterface interface { // nolint
+	// deprecated
+	SbiIdentifier() string
+
+	// SetNode injects SBI specific model
+	// representation to the transport.
+	// Needed for type assertion.
+	SetNode() func(schema *yang.Entry, root interface{}, path *gpb.Path, val interface{}, opts ...ytypes.SetNodeOpt) error
+	Schema() *ytypes.Schema
+	ID() uuid.UUID
+	Type() spb.Type
+}
diff --git a/interfaces/store/store.go b/interfaces/store/store.go
new file mode 100644
index 0000000000000000000000000000000000000000..7d4d4a6a7f51c1cbeb3f60b55587fd9fc205f858
--- /dev/null
+++ b/interfaces/store/store.go
@@ -0,0 +1,17 @@
+package store
+
+import "github.com/google/uuid"
+
+// Storable provides an interface for the controller's storage architecture.
+type Storable interface {
+	ID() uuid.UUID
+}
+
+// Store describes an interface for store implementations.
+type Store interface {
+	Exists(id uuid.UUID) bool
+	Add(item Storable) error
+	Get(id uuid.UUID) (Storable, error)
+	Delete(id uuid.UUID) error
+	UUIDs() []uuid.UUID
+}
diff --git a/interfaces/transport/transport.go b/interfaces/transport/transport.go
new file mode 100644
index 0000000000000000000000000000000000000000..24bc2ab02884dbb6fd8fe446e0cfca2aa0ce3bc4
--- /dev/null
+++ b/interfaces/transport/transport.go
@@ -0,0 +1,17 @@
+package transport
+
+import (
+	"context"
+
+	"github.com/openconfig/ygot/ytypes"
+)
+
+// Transport provides an interface for Transport implementations
+// like RESTCONF or gnmi
+type Transport interface {
+	Get(ctx context.Context, params ...string) (interface{}, error)
+	Set(ctx context.Context, params ...interface{}) error
+	Subscribe(ctx context.Context, params ...string) error
+	Type() string
+	ProcessResponse(resp interface{}, root interface{}, models *ytypes.Schema) error
+}
diff --git a/mocks/Change.go b/mocks/Change.go
new file mode 100644
index 0000000000000000000000000000000000000000..f59f4749d421b8e6dab4388044cd4c9feb3d6b8a
--- /dev/null
+++ b/mocks/Change.go
@@ -0,0 +1,57 @@
+// Code generated by mockery 2.7.5. DO NOT EDIT.
+
+package mocks
+
+import (
+	uuid "github.com/google/uuid"
+	mock "github.com/stretchr/testify/mock"
+)
+
+// Change is an autogenerated mock type for the Change type
+type Change struct {
+	mock.Mock
+}
+
+// Commit provides a mock function with given fields:
+func (_m *Change) Commit() error {
+	ret := _m.Called()
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func() error); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// Confirm provides a mock function with given fields:
+func (_m *Change) Confirm() error {
+	ret := _m.Called()
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func() error); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// ID provides a mock function with given fields:
+func (_m *Change) ID() uuid.UUID {
+	ret := _m.Called()
+
+	var r0 uuid.UUID
+	if rf, ok := ret.Get(0).(func() uuid.UUID); ok {
+		r0 = rf()
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(uuid.UUID)
+		}
+	}
+
+	return r0
+}
diff --git a/mocks/ConfigCallback.go b/mocks/ConfigCallback.go
deleted file mode 100644
index 36173a9d7ae5bafba95cff07a023db983ab80db0..0000000000000000000000000000000000000000
--- a/mocks/ConfigCallback.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Code generated by mockery v2.6.0. DO NOT EDIT.
-
-package mocks
-
-import (
-	ygot "github.com/openconfig/ygot/ygot"
-	mock "github.com/stretchr/testify/mock"
-)
-
-// ConfigCallback is an autogenerated mock type for the ConfigCallback type
-type ConfigCallback struct {
-	mock.Mock
-}
-
-// Execute provides a mock function with given fields: _a0
-func (_m *ConfigCallback) Execute(_a0 ygot.ValidatedGoStruct) error {
-	ret := _m.Called(_a0)
-
-	var r0 error
-	if rf, ok := ret.Get(0).(func(ygot.ValidatedGoStruct) error); ok {
-		r0 = rf(_a0)
-	} else {
-		r0 = ret.Error(0)
-	}
-
-	return r0
-}
diff --git a/mocks/Device.go b/mocks/Device.go
new file mode 100644
index 0000000000000000000000000000000000000000..f3e7d900d1dcda30c253341be4f48517b1b00c41
--- /dev/null
+++ b/mocks/Device.go
@@ -0,0 +1,112 @@
+// Code generated by mockery 2.7.5. DO NOT EDIT.
+
+package mocks
+
+import (
+	southbound "code.fbi.h-da.de/cocsn/gosdn/interfaces/southbound"
+	mock "github.com/stretchr/testify/mock"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+
+	transport "code.fbi.h-da.de/cocsn/gosdn/interfaces/transport"
+
+	uuid "github.com/google/uuid"
+
+	ygot "github.com/openconfig/ygot/ygot"
+)
+
+// Device is an autogenerated mock type for the Device type
+type Device struct {
+	mock.Mock
+}
+
+// ID provides a mock function with given fields:
+func (_m *Device) ID() uuid.UUID {
+	ret := _m.Called()
+
+	var r0 uuid.UUID
+	if rf, ok := ret.Get(0).(func() uuid.UUID); ok {
+		r0 = rf()
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(uuid.UUID)
+		}
+	}
+
+	return r0
+}
+
+// Model provides a mock function with given fields:
+func (_m *Device) Model() ygot.GoStruct {
+	ret := _m.Called()
+
+	var r0 ygot.GoStruct
+	if rf, ok := ret.Get(0).(func() ygot.GoStruct); ok {
+		r0 = rf()
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(ygot.GoStruct)
+		}
+	}
+
+	return r0
+}
+
+// Name provides a mock function with given fields:
+func (_m *Device) Name() string {
+	ret := _m.Called()
+
+	var r0 string
+	if rf, ok := ret.Get(0).(func() string); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Get(0).(string)
+	}
+
+	return r0
+}
+
+// ProcessResponse provides a mock function with given fields: _a0
+func (_m *Device) ProcessResponse(_a0 protoreflect.ProtoMessage) error {
+	ret := _m.Called(_a0)
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(protoreflect.ProtoMessage) error); ok {
+		r0 = rf(_a0)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// SBI provides a mock function with given fields:
+func (_m *Device) SBI() southbound.SouthboundInterface {
+	ret := _m.Called()
+
+	var r0 southbound.SouthboundInterface
+	if rf, ok := ret.Get(0).(func() southbound.SouthboundInterface); ok {
+		r0 = rf()
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(southbound.SouthboundInterface)
+		}
+	}
+
+	return r0
+}
+
+// Transport provides a mock function with given fields:
+func (_m *Device) Transport() transport.Transport {
+	ret := _m.Called()
+
+	var r0 transport.Transport
+	if rf, ok := ret.Get(0).(func() transport.Transport); ok {
+		r0 = rf()
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(transport.Transport)
+		}
+	}
+
+	return r0
+}
diff --git a/mocks/EscapeFunc.go b/mocks/EscapeFunc.go
deleted file mode 100644
index 3ab84b3e650e7bad1fb3e88f2f0f7d02bee2abb1..0000000000000000000000000000000000000000
--- a/mocks/EscapeFunc.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Code generated by mockery v2.6.0. DO NOT EDIT.
-
-package mocks
-
-import mock "github.com/stretchr/testify/mock"
-
-// EscapeFunc is an autogenerated mock type for the EscapeFunc type
-type EscapeFunc struct {
-	mock.Mock
-}
-
-// Execute provides a mock function with given fields: k
-func (_m *EscapeFunc) Execute(k string) string {
-	ret := _m.Called(k)
-
-	var r0 string
-	if rf, ok := ret.Get(0).(func(string) string); ok {
-		r0 = rf(k)
-	} else {
-		r0 = ret.Get(0).(string)
-	}
-
-	return r0
-}
diff --git a/mocks/GNMIClient.go b/mocks/GNMIClient.go
index 255d4a40d68513d1b1125101f8e9cdc12f139dc2..556bb65df2d7dd1a1605a16b984ba39cbe5e08ab 100644
--- a/mocks/GNMIClient.go
+++ b/mocks/GNMIClient.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.6.0. DO NOT EDIT.
+// Code generated by mockery 2.7.5. DO NOT EDIT.
 
 package mocks
 
diff --git a/mocks/GNMIServer.go b/mocks/GNMIServer.go
index 0628c5b31fe2c971810f5a2c9f7be3a8326ee40c..47dfbd15510c27896f0cb201999992816dfdeb59 100644
--- a/mocks/GNMIServer.go
+++ b/mocks/GNMIServer.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.6.0. DO NOT EDIT.
+// Code generated by mockery 2.7.5. DO NOT EDIT.
 
 package mocks
 
diff --git a/mocks/GNMI_SubscribeClient.go b/mocks/GNMI_SubscribeClient.go
index 456be898e5d92171a26add0d03e863f08f302d24..0d58afc80bc054a8c8f94dd8b27e5864e86239a4 100644
--- a/mocks/GNMI_SubscribeClient.go
+++ b/mocks/GNMI_SubscribeClient.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.6.0. DO NOT EDIT.
+// Code generated by mockery 2.7.5. DO NOT EDIT.
 
 package mocks
 
diff --git a/mocks/GNMI_SubscribeServer.go b/mocks/GNMI_SubscribeServer.go
index e19a9379ffc57345b30141b757dbd5d57327a82a..f663f552a3acb72cf00e011c0d557450bcca45a3 100644
--- a/mocks/GNMI_SubscribeServer.go
+++ b/mocks/GNMI_SubscribeServer.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.6.0. DO NOT EDIT.
+// Code generated by mockery 2.7.5. DO NOT EDIT.
 
 package mocks
 
diff --git a/mocks/JSONUnmarshaler.go b/mocks/JSONUnmarshaler.go
deleted file mode 100644
index 15dd0529058297459efe0de40d6264846bb03586..0000000000000000000000000000000000000000
--- a/mocks/JSONUnmarshaler.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// Code generated by mockery v2.6.0. DO NOT EDIT.
-
-package mocks
-
-import (
-	ygot "github.com/openconfig/ygot/ygot"
-	mock "github.com/stretchr/testify/mock"
-
-	ytypes "github.com/openconfig/ygot/ytypes"
-)
-
-// JSONUnmarshaler is an autogenerated mock type for the JSONUnmarshaler type
-type JSONUnmarshaler struct {
-	mock.Mock
-}
-
-// Execute provides a mock function with given fields: _a0, _a1, _a2
-func (_m *JSONUnmarshaler) Execute(_a0 []byte, _a1 ygot.GoStruct, _a2 ...ytypes.UnmarshalOpt) error {
-	_va := make([]interface{}, len(_a2))
-	for _i := range _a2 {
-		_va[_i] = _a2[_i]
-	}
-	var _ca []interface{}
-	_ca = append(_ca, _a0, _a1)
-	_ca = append(_ca, _va...)
-	ret := _m.Called(_ca...)
-
-	var r0 error
-	if rf, ok := ret.Get(0).(func([]byte, ygot.GoStruct, ...ytypes.UnmarshalOpt) error); ok {
-		r0 = rf(_a0, _a1, _a2...)
-	} else {
-		r0 = ret.Error(0)
-	}
-
-	return r0
-}
diff --git a/mocks/PrincipalNetworkDomain.go b/mocks/NetworkDomain.go
similarity index 71%
rename from mocks/PrincipalNetworkDomain.go
rename to mocks/NetworkDomain.go
index ed11f411beeff2f5f7e44d7e49550f2d2d937476..c43edae6837df98034f87947c4457ec1c7de7465 100644
--- a/mocks/PrincipalNetworkDomain.go
+++ b/mocks/NetworkDomain.go
@@ -3,22 +3,29 @@
 package mocks
 
 import (
+	change "code.fbi.h-da.de/cocsn/gosdn/interfaces/change"
+	device "code.fbi.h-da.de/cocsn/gosdn/interfaces/device"
+
 	mock "github.com/stretchr/testify/mock"
 
 	pnd "code.fbi.h-da.de/cocsn/api/go/gosdn/pnd"
 
+	southbound "code.fbi.h-da.de/cocsn/gosdn/interfaces/southbound"
+
+	store "code.fbi.h-da.de/cocsn/gosdn/interfaces/store"
+
 	transport "code.fbi.h-da.de/cocsn/api/go/gosdn/transport"
 
 	uuid "github.com/google/uuid"
 )
 
-// PrincipalNetworkDomain is an autogenerated mock type for the PrincipalNetworkDomain type
-type PrincipalNetworkDomain struct {
+// NetworkDomain is an autogenerated mock type for the NetworkDomain type
+type NetworkDomain struct {
 	mock.Mock
 }
 
 // AddDevice provides a mock function with given fields: name, opts, sid
-func (_m *PrincipalNetworkDomain) AddDevice(name string, opts *transport.TransportOption, sid uuid.UUID) error {
+func (_m *NetworkDomain) AddDevice(name string, opts *transport.TransportOption, sid uuid.UUID) error {
 	ret := _m.Called(name, opts, sid)
 
 	var r0 error
@@ -31,13 +38,13 @@ func (_m *PrincipalNetworkDomain) AddDevice(name string, opts *transport.Transpo
 	return r0
 }
 
-// AddSbi provides a mock function with given fields: _a0
-func (_m *PrincipalNetworkDomain) AddSbi(_a0 interface{}) error {
-	ret := _m.Called(_a0)
+// AddSbi provides a mock function with given fields: s
+func (_m *NetworkDomain) AddSbi(s southbound.SouthboundInterface) error {
+	ret := _m.Called(s)
 
 	var r0 error
-	if rf, ok := ret.Get(0).(func(interface{}) error); ok {
-		r0 = rf(_a0)
+	if rf, ok := ret.Get(0).(func(southbound.SouthboundInterface) error); ok {
+		r0 = rf(s)
 	} else {
 		r0 = ret.Error(0)
 	}
@@ -46,7 +53,7 @@ func (_m *PrincipalNetworkDomain) AddSbi(_a0 interface{}) error {
 }
 
 // ChangeOND provides a mock function with given fields: _a0, operation, path, value
-func (_m *PrincipalNetworkDomain) ChangeOND(_a0 uuid.UUID, operation pnd.ApiOperation, path string, value ...string) error {
+func (_m *NetworkDomain) ChangeOND(_a0 uuid.UUID, operation pnd.ApiOperation, path string, value ...string) error {
 	_va := make([]interface{}, len(value))
 	for _i := range value {
 		_va[_i] = value[_i]
@@ -67,7 +74,7 @@ func (_m *PrincipalNetworkDomain) ChangeOND(_a0 uuid.UUID, operation pnd.ApiOper
 }
 
 // Commit provides a mock function with given fields: _a0
-func (_m *PrincipalNetworkDomain) Commit(_a0 uuid.UUID) error {
+func (_m *NetworkDomain) Commit(_a0 uuid.UUID) error {
 	ret := _m.Called(_a0)
 
 	var r0 error
@@ -81,7 +88,7 @@ func (_m *PrincipalNetworkDomain) Commit(_a0 uuid.UUID) error {
 }
 
 // CommittedChanges provides a mock function with given fields:
-func (_m *PrincipalNetworkDomain) CommittedChanges() []uuid.UUID {
+func (_m *NetworkDomain) CommittedChanges() []uuid.UUID {
 	ret := _m.Called()
 
 	var r0 []uuid.UUID
@@ -97,7 +104,7 @@ func (_m *PrincipalNetworkDomain) CommittedChanges() []uuid.UUID {
 }
 
 // Confirm provides a mock function with given fields: _a0
-func (_m *PrincipalNetworkDomain) Confirm(_a0 uuid.UUID) error {
+func (_m *NetworkDomain) Confirm(_a0 uuid.UUID) error {
 	ret := _m.Called(_a0)
 
 	var r0 error
@@ -111,7 +118,7 @@ func (_m *PrincipalNetworkDomain) Confirm(_a0 uuid.UUID) error {
 }
 
 // ContainsDevice provides a mock function with given fields: _a0
-func (_m *PrincipalNetworkDomain) ContainsDevice(_a0 uuid.UUID) bool {
+func (_m *NetworkDomain) ContainsDevice(_a0 uuid.UUID) bool {
 	ret := _m.Called(_a0)
 
 	var r0 bool
@@ -125,7 +132,7 @@ func (_m *PrincipalNetworkDomain) ContainsDevice(_a0 uuid.UUID) bool {
 }
 
 // Destroy provides a mock function with given fields:
-func (_m *PrincipalNetworkDomain) Destroy() error {
+func (_m *NetworkDomain) Destroy() error {
 	ret := _m.Called()
 
 	var r0 error
@@ -139,7 +146,7 @@ func (_m *PrincipalNetworkDomain) Destroy() error {
 }
 
 // Devices provides a mock function with given fields:
-func (_m *PrincipalNetworkDomain) Devices() []uuid.UUID {
+func (_m *NetworkDomain) Devices() []uuid.UUID {
 	ret := _m.Called()
 
 	var r0 []uuid.UUID
@@ -155,7 +162,7 @@ func (_m *PrincipalNetworkDomain) Devices() []uuid.UUID {
 }
 
 // GetChange provides a mock function with given fields: _a0, _a1
-func (_m *PrincipalNetworkDomain) GetChange(_a0 uuid.UUID, _a1 ...int) (interface{}, error) {
+func (_m *NetworkDomain) GetChange(_a0 uuid.UUID, _a1 ...int) (change.Change, error) {
 	_va := make([]interface{}, len(_a1))
 	for _i := range _a1 {
 		_va[_i] = _a1[_i]
@@ -165,12 +172,12 @@ func (_m *PrincipalNetworkDomain) GetChange(_a0 uuid.UUID, _a1 ...int) (interfac
 	_ca = append(_ca, _va...)
 	ret := _m.Called(_ca...)
 
-	var r0 interface{}
-	if rf, ok := ret.Get(0).(func(uuid.UUID, ...int) interface{}); ok {
+	var r0 change.Change
+	if rf, ok := ret.Get(0).(func(uuid.UUID, ...int) change.Change); ok {
 		r0 = rf(_a0, _a1...)
 	} else {
 		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(interface{})
+			r0 = ret.Get(0).(change.Change)
 		}
 	}
 
@@ -185,7 +192,7 @@ func (_m *PrincipalNetworkDomain) GetChange(_a0 uuid.UUID, _a1 ...int) (interfac
 }
 
 // GetDescription provides a mock function with given fields:
-func (_m *PrincipalNetworkDomain) GetDescription() string {
+func (_m *NetworkDomain) GetDescription() string {
 	ret := _m.Called()
 
 	var r0 string
@@ -199,15 +206,15 @@ func (_m *PrincipalNetworkDomain) GetDescription() string {
 }
 
 // GetDevice provides a mock function with given fields: identifier
-func (_m *PrincipalNetworkDomain) GetDevice(identifier string) (interface{}, error) {
+func (_m *NetworkDomain) GetDevice(identifier string) (device.Device, error) {
 	ret := _m.Called(identifier)
 
-	var r0 interface{}
-	if rf, ok := ret.Get(0).(func(string) interface{}); ok {
+	var r0 device.Device
+	if rf, ok := ret.Get(0).(func(string) device.Device); ok {
 		r0 = rf(identifier)
 	} else {
 		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(interface{})
+			r0 = ret.Get(0).(device.Device)
 		}
 	}
 
@@ -222,7 +229,7 @@ func (_m *PrincipalNetworkDomain) GetDevice(identifier string) (interface{}, err
 }
 
 // GetName provides a mock function with given fields:
-func (_m *PrincipalNetworkDomain) GetName() string {
+func (_m *NetworkDomain) GetName() string {
 	ret := _m.Called()
 
 	var r0 string
@@ -236,15 +243,15 @@ func (_m *PrincipalNetworkDomain) GetName() string {
 }
 
 // GetSBIs provides a mock function with given fields:
-func (_m *PrincipalNetworkDomain) GetSBIs() interface{} {
+func (_m *NetworkDomain) GetSBIs() store.Store {
 	ret := _m.Called()
 
-	var r0 interface{}
-	if rf, ok := ret.Get(0).(func() interface{}); ok {
+	var r0 store.Store
+	if rf, ok := ret.Get(0).(func() store.Store); ok {
 		r0 = rf()
 	} else {
 		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(interface{})
+			r0 = ret.Get(0).(store.Store)
 		}
 	}
 
@@ -252,7 +259,7 @@ func (_m *PrincipalNetworkDomain) GetSBIs() interface{} {
 }
 
 // ID provides a mock function with given fields:
-func (_m *PrincipalNetworkDomain) ID() uuid.UUID {
+func (_m *NetworkDomain) ID() uuid.UUID {
 	ret := _m.Called()
 
 	var r0 uuid.UUID
@@ -268,7 +275,7 @@ func (_m *PrincipalNetworkDomain) ID() uuid.UUID {
 }
 
 // MarshalDevice provides a mock function with given fields: _a0
-func (_m *PrincipalNetworkDomain) MarshalDevice(_a0 string) (string, error) {
+func (_m *NetworkDomain) MarshalDevice(_a0 string) (string, error) {
 	ret := _m.Called(_a0)
 
 	var r0 string
@@ -289,7 +296,7 @@ func (_m *PrincipalNetworkDomain) MarshalDevice(_a0 string) (string, error) {
 }
 
 // PendingChanges provides a mock function with given fields:
-func (_m *PrincipalNetworkDomain) PendingChanges() []uuid.UUID {
+func (_m *NetworkDomain) PendingChanges() []uuid.UUID {
 	ret := _m.Called()
 
 	var r0 []uuid.UUID
@@ -305,7 +312,7 @@ func (_m *PrincipalNetworkDomain) PendingChanges() []uuid.UUID {
 }
 
 // RemoveDevice provides a mock function with given fields: _a0
-func (_m *PrincipalNetworkDomain) RemoveDevice(_a0 uuid.UUID) error {
+func (_m *NetworkDomain) RemoveDevice(_a0 uuid.UUID) error {
 	ret := _m.Called(_a0)
 
 	var r0 error
@@ -319,7 +326,7 @@ func (_m *PrincipalNetworkDomain) RemoveDevice(_a0 uuid.UUID) error {
 }
 
 // RemoveSbi provides a mock function with given fields: _a0
-func (_m *PrincipalNetworkDomain) RemoveSbi(_a0 uuid.UUID) error {
+func (_m *NetworkDomain) RemoveSbi(_a0 uuid.UUID) error {
 	ret := _m.Called(_a0)
 
 	var r0 error
@@ -333,7 +340,7 @@ func (_m *PrincipalNetworkDomain) RemoveSbi(_a0 uuid.UUID) error {
 }
 
 // Request provides a mock function with given fields: _a0, _a1
-func (_m *PrincipalNetworkDomain) Request(_a0 uuid.UUID, _a1 string) error {
+func (_m *NetworkDomain) Request(_a0 uuid.UUID, _a1 string) error {
 	ret := _m.Called(_a0, _a1)
 
 	var r0 error
@@ -347,7 +354,7 @@ func (_m *PrincipalNetworkDomain) Request(_a0 uuid.UUID, _a1 string) error {
 }
 
 // RequestAll provides a mock function with given fields: _a0
-func (_m *PrincipalNetworkDomain) RequestAll(_a0 string) error {
+func (_m *NetworkDomain) RequestAll(_a0 string) error {
 	ret := _m.Called(_a0)
 
 	var r0 error
diff --git a/mocks/PublishFunc.go b/mocks/PublishFunc.go
deleted file mode 100644
index 9bafd22090b46cd8a0b9d9aedcb5d502b340911b..0000000000000000000000000000000000000000
--- a/mocks/PublishFunc.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Code generated by mockery v2.6.0. DO NOT EDIT.
-
-package mocks
-
-import (
-	mock "github.com/stretchr/testify/mock"
-	protoiface "google.golang.org/protobuf/runtime/protoiface"
-)
-
-// PublishFunc is an autogenerated mock type for the PublishFunc type
-type PublishFunc struct {
-	mock.Mock
-}
-
-// Execute provides a mock function with given fields: addr, message
-func (_m *PublishFunc) Execute(addr string, message protoiface.MessageV1) {
-	_m.Called(addr, message)
-}
diff --git a/mocks/SBIGreeter.go b/mocks/SBIGreeter.go
deleted file mode 100644
index 7b7c999166b64bdf711da1b7ddb8e5801e9330fc..0000000000000000000000000000000000000000
--- a/mocks/SBIGreeter.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Code generated by mockery v2.6.0. DO NOT EDIT.
-
-package mocks
-
-import mock "github.com/stretchr/testify/mock"
-
-// SBIGreeter is an autogenerated mock type for the SBIGreeter type
-type SBIGreeter struct {
-	mock.Mock
-}
-
-// SBIHello provides a mock function with given fields:
-func (_m *SBIGreeter) SBIHello() {
-	_m.Called()
-}
diff --git a/mocks/SouthboundInterface.go b/mocks/SouthboundInterface.go
index 560db283ced93dfae4790ac5d934e132feb5d92f..c7936b27df0f42f4c6331711b357635badb1a05b 100644
--- a/mocks/SouthboundInterface.go
+++ b/mocks/SouthboundInterface.go
@@ -3,10 +3,10 @@
 package mocks
 
 import (
+	gosdnsouthbound "code.fbi.h-da.de/cocsn/api/go/gosdn/southbound"
 	gnmi "github.com/openconfig/gnmi/proto/gnmi"
-	mock "github.com/stretchr/testify/mock"
 
-	southbound "code.fbi.h-da.de/cocsn/api/go/gosdn/southbound"
+	mock "github.com/stretchr/testify/mock"
 
 	uuid "github.com/google/uuid"
 
@@ -83,14 +83,14 @@ func (_m *SouthboundInterface) SetNode() func(*yang.Entry, interface{}, *gnmi.Pa
 }
 
 // Type provides a mock function with given fields:
-func (_m *SouthboundInterface) Type() southbound.Type {
+func (_m *SouthboundInterface) Type() gosdnsouthbound.Type {
 	ret := _m.Called()
 
-	var r0 southbound.Type
-	if rf, ok := ret.Get(0).(func() southbound.Type); ok {
+	var r0 gosdnsouthbound.Type
+	if rf, ok := ret.Get(0).(func() gosdnsouthbound.Type); ok {
 		r0 = rf()
 	} else {
-		r0 = ret.Get(0).(southbound.Type)
+		r0 = ret.Get(0).(gosdnsouthbound.Type)
 	}
 
 	return r0
diff --git a/mocks/Store.go b/mocks/Store.go
new file mode 100644
index 0000000000000000000000000000000000000000..d964f824e8d29aa7d851e7553bcaaf0804167a13
--- /dev/null
+++ b/mocks/Store.go
@@ -0,0 +1,95 @@
+// Code generated by mockery 2.7.5. DO NOT EDIT.
+
+package mocks
+
+import (
+	store "code.fbi.h-da.de/cocsn/gosdn/interfaces/store"
+	uuid "github.com/google/uuid"
+	mock "github.com/stretchr/testify/mock"
+)
+
+// Store is an autogenerated mock type for the Store type
+type Store struct {
+	mock.Mock
+}
+
+// Add provides a mock function with given fields: item
+func (_m *Store) Add(item store.Storable) error {
+	ret := _m.Called(item)
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(store.Storable) error); ok {
+		r0 = rf(item)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// Delete provides a mock function with given fields: id
+func (_m *Store) Delete(id uuid.UUID) error {
+	ret := _m.Called(id)
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(uuid.UUID) error); ok {
+		r0 = rf(id)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// Exists provides a mock function with given fields: id
+func (_m *Store) Exists(id uuid.UUID) bool {
+	ret := _m.Called(id)
+
+	var r0 bool
+	if rf, ok := ret.Get(0).(func(uuid.UUID) bool); ok {
+		r0 = rf(id)
+	} else {
+		r0 = ret.Get(0).(bool)
+	}
+
+	return r0
+}
+
+// Get provides a mock function with given fields: id
+func (_m *Store) Get(id uuid.UUID) (store.Storable, error) {
+	ret := _m.Called(id)
+
+	var r0 store.Storable
+	if rf, ok := ret.Get(0).(func(uuid.UUID) store.Storable); ok {
+		r0 = rf(id)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(store.Storable)
+		}
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(uuid.UUID) error); ok {
+		r1 = rf(id)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// UUIDs provides a mock function with given fields:
+func (_m *Store) UUIDs() []uuid.UUID {
+	ret := _m.Called()
+
+	var r0 []uuid.UUID
+	if rf, ok := ret.Get(0).(func() []uuid.UUID); ok {
+		r0 = rf()
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).([]uuid.UUID)
+		}
+	}
+
+	return r0
+}
diff --git a/mocks/TransportOptions.go b/mocks/TransportOptions.go
deleted file mode 100644
index b969fdb60e490658017a191dfb2bae818408b83a..0000000000000000000000000000000000000000
--- a/mocks/TransportOptions.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// Code generated by mockery 2.7.4. DO NOT EDIT.
-
-package mocks
-
-import mock "github.com/stretchr/testify/mock"
-
-// TransportOptions is an autogenerated mock type for the TransportOptions type
-type TransportOptions struct {
-	mock.Mock
-}
-
-// GetAddress provides a mock function with given fields:
-func (_m *TransportOptions) GetAddress() string {
-	ret := _m.Called()
-
-	var r0 string
-	if rf, ok := ret.Get(0).(func() string); ok {
-		r0 = rf()
-	} else {
-		r0 = ret.Get(0).(string)
-	}
-
-	return r0
-}
-
-// GetPassword provides a mock function with given fields:
-func (_m *TransportOptions) GetPassword() string {
-	ret := _m.Called()
-
-	var r0 string
-	if rf, ok := ret.Get(0).(func() string); ok {
-		r0 = rf()
-	} else {
-		r0 = ret.Get(0).(string)
-	}
-
-	return r0
-}
-
-// GetUsername provides a mock function with given fields:
-func (_m *TransportOptions) GetUsername() string {
-	ret := _m.Called()
-
-	var r0 string
-	if rf, ok := ret.Get(0).(func() string); ok {
-		r0 = rf()
-	} else {
-		r0 = ret.Get(0).(string)
-	}
-
-	return r0
-}
-
-// IsTransportOption provides a mock function with given fields:
-func (_m *TransportOptions) IsTransportOption() {
-	_m.Called()
-}
diff --git a/mocks/UnsafeGNMIServer.go b/mocks/UnsafeGNMIServer.go
new file mode 100644
index 0000000000000000000000000000000000000000..377e2d1cdda4eff9764adc784825237c7f2f4356
--- /dev/null
+++ b/mocks/UnsafeGNMIServer.go
@@ -0,0 +1,15 @@
+// Code generated by mockery 2.7.5. DO NOT EDIT.
+
+package mocks
+
+import mock "github.com/stretchr/testify/mock"
+
+// UnsafeGNMIServer is an autogenerated mock type for the UnsafeGNMIServer type
+type UnsafeGNMIServer struct {
+	mock.Mock
+}
+
+// mustEmbedUnimplementedGNMIServer provides a mock function with given fields:
+func (_m *UnsafeGNMIServer) mustEmbedUnimplementedGNMIServer() {
+	_m.Called()
+}
diff --git a/mocks/isSubscribeRequest_Request.go b/mocks/isSubscribeRequest_Request.go
index 73f763981ed7bd4586787e88694c844885b2b843..b1b09e55db8d7b31bbd4b02d383bb45e786b1de6 100644
--- a/mocks/isSubscribeRequest_Request.go
+++ b/mocks/isSubscribeRequest_Request.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.6.0. DO NOT EDIT.
+// Code generated by mockery 2.7.5. DO NOT EDIT.
 
 package mocks
 
diff --git a/mocks/isSubscribeResponse_Response.go b/mocks/isSubscribeResponse_Response.go
index ba10966e2703113f5fc03233883022efb7843b4b..0f38e4ee6d5ccc28a7e13943de6434d6647e811f 100644
--- a/mocks/isSubscribeResponse_Response.go
+++ b/mocks/isSubscribeResponse_Response.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.6.0. DO NOT EDIT.
+// Code generated by mockery 2.7.5. DO NOT EDIT.
 
 package mocks
 
diff --git a/mocks/isTypedValue_Value.go b/mocks/isTypedValue_Value.go
index a49fc787f9dbe7f24023258d180371a5bcd42c7b..bc9ac6962403f9d2251accafaf295ad63ca36303 100644
--- a/mocks/isTypedValue_Value.go
+++ b/mocks/isTypedValue_Value.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.6.0. DO NOT EDIT.
+// Code generated by mockery 2.7.5. DO NOT EDIT.
 
 package mocks
 
diff --git a/northbound/server/core.go b/northbound/server/core.go
index a655ef4d21889974240ecf6607fbcfbc3b59721c..0bc9415fae5eace64856a30683ed71bf01c872df 100644
--- a/northbound/server/core.go
+++ b/northbound/server/core.go
@@ -32,7 +32,7 @@ func (s core) Get(ctx context.Context, request *pb.GetRequest) (*pb.GetResponse,
 
 	pnds := make([]*ppb.PrincipalNetworkDomain, len(pndList))
 	for i, id := range pndList {
-		pnd, err := pndc.Get(id)
+		pnd, err := pndc.GetPND(id)
 		if err != nil {
 			return nil, err
 		}
diff --git a/northbound/server/nbi.go b/northbound/server/nbi.go
index 2e17223c969be515b278f07e6c02775b4e761dc7..931dc4795f1c073ea6693f838726cf40e51675aa 100644
--- a/northbound/server/nbi.go
+++ b/northbound/server/nbi.go
@@ -9,7 +9,7 @@ var pndc *nucleus.PndStore
 // NorthboundInterface is the representation of the
 // gRPC services used provided.
 type NorthboundInterface struct {
-	Pnd  *pnd
+	Pnd  *pndServer
 	Core *core
 }
 
@@ -17,7 +17,7 @@ type NorthboundInterface struct {
 func NewNBI(pnds *nucleus.PndStore) *NorthboundInterface {
 	pndc = pnds
 	return &NorthboundInterface{
-		Pnd:  &pnd{},
+		Pnd:  &pndServer{},
 		Core: &core{},
 	}
 }
diff --git a/northbound/server/pnd.go b/northbound/server/pnd.go
index 00a334b8808a6877ab4129bfdb865934edde9f4f..9b46337668225aa4508aada51c44c388ca955d28 100644
--- a/northbound/server/pnd.go
+++ b/northbound/server/pnd.go
@@ -5,19 +5,22 @@ import (
 	"reflect"
 	"time"
 
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/device"
+
 	ppb "code.fbi.h-da.de/cocsn/api/go/gosdn/pnd"
 	spb "code.fbi.h-da.de/cocsn/api/go/gosdn/southbound"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/networkdomain"
 	"code.fbi.h-da.de/cocsn/gosdn/nucleus"
 	"code.fbi.h-da.de/cocsn/gosdn/nucleus/errors"
 	"github.com/google/uuid"
 	"github.com/openconfig/ygot/ygot"
 )
 
-type pnd struct {
+type pndServer struct {
 	ppb.UnimplementedPndServer
 }
 
-func (p pnd) Get(ctx context.Context, request *ppb.GetRequest) (*ppb.GetResponse, error) {
+func (p pndServer) Get(ctx context.Context, request *ppb.GetRequest) (*ppb.GetResponse, error) {
 	pid, err := uuid.Parse(request.Pid)
 	if err != nil {
 		return nil, err
@@ -37,7 +40,7 @@ func (p pnd) Get(ctx context.Context, request *ppb.GetRequest) (*ppb.GetResponse
 }
 
 func handleGetPnd(pid uuid.UUID) (*ppb.GetResponse, error) {
-	pnd, err := pndc.Get(pid)
+	pnd, err := pndc.GetPND(pid)
 	if err != nil {
 		return nil, err
 	}
@@ -68,7 +71,7 @@ func handleGetPnd(pid uuid.UUID) (*ppb.GetResponse, error) {
 }
 
 func handleGetSbi(pid uuid.UUID, req *ppb.GetRequest_Sbi) (*ppb.GetResponse, error) {
-	pnd, err := pndc.Get(pid)
+	pnd, err := pndc.GetPND(pid)
 	if err != nil {
 		return nil, err
 	}
@@ -95,7 +98,7 @@ func stringToUUID(sid []string) ([]uuid.UUID, error) {
 }
 
 func handleGetOnd(pid uuid.UUID, req *ppb.GetRequest_Ond) (*ppb.GetResponse, error) {
-	pnd, err := pndc.Get(pid)
+	pnd, err := pndc.GetPND(pid)
 	if err != nil {
 		return nil, err
 	}
@@ -110,7 +113,7 @@ func handleGetOnd(pid uuid.UUID, req *ppb.GetRequest_Ond) (*ppb.GetResponse, err
 }
 
 func handleGetChange(pid uuid.UUID, req *ppb.GetRequest_Change) (*ppb.GetResponse, error) {
-	pnd, err := pndc.Get(pid)
+	pnd, err := pndc.GetPND(pid)
 	if err != nil {
 		return nil, err
 	}
@@ -124,7 +127,7 @@ func handleGetChange(pid uuid.UUID, req *ppb.GetRequest_Change) (*ppb.GetRespons
 	}, nil
 }
 
-func fillSbis(pnd nucleus.PrincipalNetworkDomain, all bool, sid ...string) ([]*spb.SouthboundInterface, error) {
+func fillSbis(pnd networkdomain.NetworkDomain, all bool, sid ...string) ([]*spb.SouthboundInterface, error) {
 	var sbiList []uuid.UUID
 
 	sbiStore := pnd.GetSBIs().(*nucleus.SbiStore)
@@ -146,7 +149,7 @@ func fillSbis(pnd nucleus.PrincipalNetworkDomain, all bool, sid ...string) ([]*s
 	}
 	sbis := make([]*spb.SouthboundInterface, len(sbiList))
 	for i, id := range sbiList {
-		sbi, err := sbiStore.Get(id)
+		sbi, err := sbiStore.GetSBI(id)
 		if err != nil {
 			return nil, err
 		}
@@ -158,7 +161,7 @@ func fillSbis(pnd nucleus.PrincipalNetworkDomain, all bool, sid ...string) ([]*s
 	return sbis, nil
 }
 
-func fillOnds(pnd nucleus.PrincipalNetworkDomain, all bool, did ...string) ([]*ppb.OrchestratedNetworkingDevice, error) {
+func fillOnds(pnd networkdomain.NetworkDomain, all bool, did ...string) ([]*ppb.OrchestratedNetworkingDevice, error) {
 	var ondList []uuid.UUID
 
 	switch all {
@@ -185,7 +188,7 @@ func fillOnds(pnd nucleus.PrincipalNetworkDomain, all bool, did ...string) ([]*p
 			return nil, err
 		}
 		cfg := ygot.GNMINotificationsConfig{}
-		dev, err := ygot.TogNMINotifications(d.(nucleus.Device).Model(), time.Now().UnixNano(), cfg)
+		dev, err := ygot.TogNMINotifications(d.(device.Device).Model(), time.Now().UnixNano(), cfg)
 		if err != nil {
 			return nil, err
 		}
@@ -198,7 +201,7 @@ func fillOnds(pnd nucleus.PrincipalNetworkDomain, all bool, did ...string) ([]*p
 	return onds, nil
 }
 
-func fillChanges(pnd nucleus.PrincipalNetworkDomain, all bool, cuid ...string) ([]*ppb.Change, error) {
+func fillChanges(pnd networkdomain.NetworkDomain, all bool, cuid ...string) ([]*ppb.Change, error) {
 	var changeList []uuid.UUID
 
 	switch all {
@@ -242,13 +245,13 @@ func fillChanges(pnd nucleus.PrincipalNetworkDomain, all bool, cuid ...string) (
 	return changes, nil
 }
 
-func (p pnd) Set(ctx context.Context, request *ppb.SetRequest) (*ppb.SetResponse, error) {
+func (p pndServer) Set(ctx context.Context, request *ppb.SetRequest) (*ppb.SetResponse, error) {
 	pid, err := uuid.Parse(request.Pid)
 	if err != nil {
 		return nil, err
 	}
 
-	pnd, err := pndc.Get(pid)
+	pnd, err := pndc.GetPND(pid)
 	if err != nil {
 		return nil, err
 	}
@@ -276,7 +279,7 @@ func (p pnd) Set(ctx context.Context, request *ppb.SetRequest) (*ppb.SetResponse
 	}, nil
 }
 
-func handleSetOnd(pnd nucleus.PrincipalNetworkDomain, req []*ppb.SetOnd) (*ppb.SetResponse, error) {
+func handleSetOnd(pnd networkdomain.NetworkDomain, req []*ppb.SetOnd) (*ppb.SetResponse, error) {
 	for _, r := range req {
 		sid, err := uuid.Parse(r.Sbi.Id)
 		if err != nil {
@@ -292,14 +295,14 @@ func handleSetOnd(pnd nucleus.PrincipalNetworkDomain, req []*ppb.SetOnd) (*ppb.S
 	}, nil
 }
 
-func handleSetSbi(pnd nucleus.PrincipalNetworkDomain, req []*ppb.SetSbi) (*ppb.SetResponse, error) {
+func handleSetSbi(pnd networkdomain.NetworkDomain, req []*ppb.SetSbi) (*ppb.SetResponse, error) {
 	return &ppb.SetResponse{
 		Timestamp: time.Now().UnixNano(),
 		Status:    ppb.SetResponse_ERROR,
 	}, nil
 }
 
-func handleSetChange(pnd nucleus.PrincipalNetworkDomain, req []*ppb.SetChange) (*ppb.SetResponse, error) {
+func handleSetChange(pnd networkdomain.NetworkDomain, req []*ppb.SetChange) (*ppb.SetResponse, error) {
 	for _, r := range req {
 		cuid, err := uuid.Parse(r.Cuid)
 		if err != nil {
@@ -327,7 +330,7 @@ func handleSetChange(pnd nucleus.PrincipalNetworkDomain, req []*ppb.SetChange) (
 	}, nil
 }
 
-func handleChangeRequest(pnd nucleus.PrincipalNetworkDomain, req []*ppb.ChangeRequest) (*ppb.SetResponse, error) {
+func handleChangeRequest(pnd networkdomain.NetworkDomain, req []*ppb.ChangeRequest) (*ppb.SetResponse, error) {
 	for _, r := range req {
 		did, err := uuid.Parse(r.Id)
 		if err != nil {
diff --git a/northbound/server/pnd_test.go b/northbound/server/pnd_test.go
index e5fea39f2c9b22d3f6469e23e10ace2ef152e8b4..0d25e79ca28e1b778b452ad2781e7a0c8169f6a1 100644
--- a/northbound/server/pnd_test.go
+++ b/northbound/server/pnd_test.go
@@ -9,6 +9,7 @@ import (
 	ppb "code.fbi.h-da.de/cocsn/api/go/gosdn/pnd"
 	spb "code.fbi.h-da.de/cocsn/api/go/gosdn/southbound"
 	"code.fbi.h-da.de/cocsn/api/go/gosdn/transport"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/device"
 	"code.fbi.h-da.de/cocsn/gosdn/mocks"
 	"code.fbi.h-da.de/cocsn/gosdn/nucleus"
 	"code.fbi.h-da.de/cocsn/yang-models/generated/openconfig"
@@ -28,8 +29,8 @@ var pndUUID uuid.UUID
 var pendingChangeUUID uuid.UUID
 var committedChangeUUID uuid.UUID
 var deviceUUID uuid.UUID
-var mockPnd *mocks.PrincipalNetworkDomain
-var mockDevice nucleus.Device
+var mockPnd *mocks.NetworkDomain
+var mockDevice device.Device
 var sbiStore *nucleus.SbiStore
 
 func TestMain(m *testing.M) {
@@ -74,7 +75,7 @@ func TestMain(m *testing.M) {
 		log.Fatal(err)
 	}
 
-	mockPnd = &mocks.PrincipalNetworkDomain{}
+	mockPnd = &mocks.NetworkDomain{}
 	mockPnd.On("ID").Return(pndUUID)
 	mockPnd.On("GetName").Return("test")
 	mockPnd.On("GetDescription").Return("test")
@@ -130,7 +131,7 @@ func Test_pnd_Get(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			p := pnd{
+			p := pndServer{
 				UnimplementedPndServer: ppb.UnimplementedPndServer{},
 			}
 			resp, err := p.Get(tt.args.ctx, tt.args.request)
@@ -241,7 +242,7 @@ func Test_pnd_Set(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			p := pnd{
+			p := pndServer{
 				UnimplementedPndServer: ppb.UnimplementedPndServer{},
 			}
 			resp, err := p.Set(tt.args.ctx, tt.args.request)
diff --git a/nucleus/device.go b/nucleus/device.go
index fc74f50e3f845c66f61287a892b064229a202a3c..716deb687c90fe26d5d68bf6e0e607236dbaef3a 100644
--- a/nucleus/device.go
+++ b/nucleus/device.go
@@ -2,23 +2,33 @@ package nucleus
 
 import (
 	tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/device"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/southbound"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/transport"
 	"github.com/docker/docker/pkg/namesgenerator"
 	"github.com/google/uuid"
 	"github.com/openconfig/ygot/ygot"
 	"google.golang.org/protobuf/proto"
 )
 
-// Device represents an Orchestrated Network Device (OND) which is managed by
-// nucleus
-type Device interface {
-	ID() uuid.UUID
-	Model() ygot.GoStruct
-	Transport() Transport
-	Name() string
-	SBI() SouthboundInterface
-	ProcessResponse(proto.Message) error
+// NewDevice creates a Device
+func NewDevice(name string, opt *tpb.TransportOption, sbi southbound.SouthboundInterface) (device.Device, error) {
+	t, err := NewTransport(opt, sbi)
+	if err != nil {
+		return nil, err
+	}
 
-	isDevice()
+	if name == "" {
+		name = namesgenerator.GetRandomName(0)
+	}
+
+	return &CommonDevice{
+		UUID:      uuid.New(),
+		GoStruct:  sbi.Schema().Root,
+		sbi:       sbi,
+		transport: t,
+		name:      name,
+	}, nil
 }
 
 // CommonDevice represents an OND
@@ -30,35 +40,15 @@ type CommonDevice struct {
 	ygot.GoStruct
 
 	// SBI is the device's southbound interface implementation
-	sbi SouthboundInterface
+	sbi southbound.SouthboundInterface
 
 	// Transport is the device's Transport implementation
-	transport Transport
+	transport transport.Transport
 
 	// Name is the device's human readable name
 	name string
 }
 
-// NewDevice creates a Device
-func NewDevice(name string, opt *tpb.TransportOption, sbi SouthboundInterface) (Device, error) {
-	transport, err := NewTransport(opt, sbi)
-	if err != nil {
-		return nil, err
-	}
-
-	if name == "" {
-		name = namesgenerator.GetRandomName(0)
-	}
-
-	return &CommonDevice{
-		UUID:      uuid.New(),
-		GoStruct:  sbi.Schema().Root,
-		sbi:       sbi,
-		transport: transport,
-		name:      name,
-	}, nil
-}
-
 // ID returns the UUID of the Device
 func (d *CommonDevice) ID() uuid.UUID {
 	return d.UUID
@@ -70,7 +60,7 @@ func (d *CommonDevice) Model() ygot.GoStruct {
 }
 
 // Transport returns the Transport of the device
-func (d *CommonDevice) Transport() Transport {
+func (d *CommonDevice) Transport() transport.Transport {
 	return d.transport
 }
 
@@ -80,12 +70,12 @@ func (d *CommonDevice) Name() string {
 }
 
 // SBI returns the sbi of the Device
-func (d *CommonDevice) SBI() SouthboundInterface {
+func (d *CommonDevice) SBI() southbound.SouthboundInterface {
 	return d.sbi
 }
 
 // SetTransport sets the Device's Transport
-func (d *CommonDevice) SetTransport(t Transport) {
+func (d *CommonDevice) SetTransport(t transport.Transport) {
 	d.transport = t
 }
 
@@ -95,7 +85,7 @@ func (d *CommonDevice) SetName(n string) {
 }
 
 // SetSBI sets the Device's SBI
-func (d *CommonDevice) SetSBI(sbi SouthboundInterface) {
+func (d *CommonDevice) SetSBI(sbi southbound.SouthboundInterface) {
 	d.sbi = sbi
 }
 
@@ -104,8 +94,6 @@ func (d *CommonDevice) ProcessResponse(resp proto.Message) error {
 	return d.transport.ProcessResponse(resp, d.GoStruct, d.sbi.Schema())
 }
 
-func (d *CommonDevice) isDevice() {}
-
 type csbiDevice struct {
 	CommonDevice
 }
@@ -119,20 +107,18 @@ func (d *csbiDevice) Model() ygot.GoStruct {
 	return d.GoStruct
 }
 
-func (d *csbiDevice) Transport() Transport {
-	return d.Transport()
+func (d *csbiDevice) Transport() transport.Transport {
+	return d.transport
 }
 
 func (d *csbiDevice) Name() string {
-	return d.Name()
+	return d.name
 }
 
-func (d *csbiDevice) SBI() SouthboundInterface {
-	return d.SBI()
+func (d *csbiDevice) SBI() southbound.SouthboundInterface {
+	return d.sbi
 }
 
 func (d *csbiDevice) ProcessResponse(resp proto.Message) error {
 	return d.transport.ProcessResponse(resp, d.GoStruct, d.sbi.Schema())
 }
-
-func (d *csbiDevice) isDevice() {}
diff --git a/nucleus/device_test.go b/nucleus/device_test.go
index 1efa756817f6db9fc5a7e2e5bd54a9353e2ec48a..9290231c1235bf8b05f0aac7ca5cd1145e87ebaa 100644
--- a/nucleus/device_test.go
+++ b/nucleus/device_test.go
@@ -4,6 +4,9 @@ import (
 	"reflect"
 	"testing"
 
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/southbound"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/transport"
+
 	tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport"
 
 	"code.fbi.h-da.de/cocsn/yang-models/generated/openconfig"
@@ -14,8 +17,8 @@ import (
 func TestDevice_Id(t *testing.T) {
 	type fields struct {
 		GoStruct  ygot.GoStruct
-		SBI       SouthboundInterface
-		Transport Transport
+		SBI       southbound.SouthboundInterface
+		Transport transport.Transport
 		UUID      uuid.UUID
 		Name      string
 	}
@@ -51,7 +54,7 @@ func TestDevice_Id(t *testing.T) {
 func TestNewDevice(t *testing.T) {
 	sbi := &OpenConfig{}
 	type args struct {
-		sbi  SouthboundInterface
+		sbi  southbound.SouthboundInterface
 		opts *tpb.TransportOption
 		name string
 	}
diff --git a/nucleus/gnmi_transport.go b/nucleus/gnmi_transport.go
index 6e8318e382e80df2885feefb22a5b35d11a20784..1185107479694aae1b22f77ee9e2d9ea26035169 100644
--- a/nucleus/gnmi_transport.go
+++ b/nucleus/gnmi_transport.go
@@ -4,6 +4,8 @@ import (
 	"context"
 	"reflect"
 
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/southbound"
+
 	"google.golang.org/grpc"
 
 	ppb "code.fbi.h-da.de/cocsn/api/go/gosdn/pnd"
@@ -41,7 +43,7 @@ type Gnmi struct {
 
 // NewGnmiTransport takes a struct of GnmiTransportOptions and returns a Gnmi
 // transport based on the values of it.
-func NewGnmiTransport(opts *tpb.TransportOption, sbi SouthboundInterface) (*Gnmi, error) {
+func NewGnmiTransport(opts *tpb.TransportOption, sbi southbound.SouthboundInterface) (*Gnmi, error) {
 	gnmiConfig := &gnmi.Config{
 		Addr:        opts.Address,
 		Password:    opts.Password,
diff --git a/nucleus/gnmi_transport_test.go b/nucleus/gnmi_transport_test.go
index d4d89bd10b886ca4481c02dc75256dca1ab01a35..597cecd8ff954aa2b623df9f339115014ce08266 100644
--- a/nucleus/gnmi_transport_test.go
+++ b/nucleus/gnmi_transport_test.go
@@ -6,6 +6,8 @@ import (
 	"reflect"
 	"testing"
 
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/southbound"
+
 	spb "code.fbi.h-da.de/cocsn/api/go/gosdn/southbound"
 	tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport"
 
@@ -212,7 +214,7 @@ func TestGnmi_Get(t *testing.T) {
 
 func TestGnmi_ProcessResponse(t *testing.T) {
 	type fields struct {
-		Sbi SouthboundInterface
+		Sbi southbound.SouthboundInterface
 	}
 	type args struct {
 		path string
diff --git a/nucleus/initialise_test.go b/nucleus/initialise_test.go
index e3b589fe4cf4c846996484edcabd6ecf2147bd38..ffa4fa64a19b9fd44929c0287ef846127618f067 100644
--- a/nucleus/initialise_test.go
+++ b/nucleus/initialise_test.go
@@ -5,6 +5,8 @@ import (
 	"os"
 	"testing"
 
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/device"
+
 	tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport"
 
 	"code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi"
@@ -115,7 +117,7 @@ func readTestUUIDs() {
 	}
 }
 
-func mockDevice() Device {
+func mockDevice() device.Device {
 	sbi := &OpenConfig{}
 	return &CommonDevice{
 		UUID:      mdid,
@@ -129,11 +131,11 @@ func newPnd() pndImplementation {
 	return pndImplementation{
 		name:             "default",
 		description:      "default test pnd",
-		sbic:             SbiStore{store{}},
+		sbic:             SbiStore{genericStore{}},
 		devices:          NewDeviceStore(),
-		pendingChanges:   ChangeStore{store{}},
-		committedChanges: ChangeStore{store{}},
-		confirmedChanges: ChangeStore{store{}},
+		pendingChanges:   ChangeStore{genericStore{}},
+		committedChanges: ChangeStore{genericStore{}},
+		confirmedChanges: ChangeStore{genericStore{}},
 		id:               defaultPndID,
 		errChans:         make(map[uuid.UUID]chan error),
 	}
diff --git a/nucleus/principalNetworkDomain.go b/nucleus/principalNetworkDomain.go
index 7192878c39b172d92200c88b2d1290eebd1eb2c1..2a25b7bdd1b259353d66ad1001e72b3363494281 100644
--- a/nucleus/principalNetworkDomain.go
+++ b/nucleus/principalNetworkDomain.go
@@ -7,53 +7,32 @@ import (
 
 	ppb "code.fbi.h-da.de/cocsn/api/go/gosdn/pnd"
 	tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport"
+	"google.golang.org/protobuf/proto"
 
 	"code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/change"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/device"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/networkdomain"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/southbound"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/store"
 	"code.fbi.h-da.de/cocsn/gosdn/nucleus/errors"
 
 	"github.com/google/uuid"
 	"github.com/openconfig/ygot/ygot"
 	"github.com/openconfig/ygot/ytypes"
 	log "github.com/sirupsen/logrus"
-	"google.golang.org/protobuf/proto"
 )
 
-// PrincipalNetworkDomain provides an
-// interface for PND implementations
-type PrincipalNetworkDomain interface {
-	Destroy() error
-	AddSbi(interface{}) error
-	RemoveSbi(uuid.UUID) error
-	AddDevice(name string, opts *tpb.TransportOption, sid uuid.UUID) error
-	GetDevice(identifier string) (interface{}, error)
-	RemoveDevice(uuid.UUID) error
-	Devices() []uuid.UUID
-	ChangeOND(uuid uuid.UUID, operation ppb.ApiOperation, path string, value ...string) error
-	Request(uuid.UUID, string) error
-	RequestAll(string) error
-	GetName() string
-	GetDescription() string
-	MarshalDevice(string) (string, error)
-	ContainsDevice(uuid.UUID) bool
-	GetSBIs() interface{}
-	ID() uuid.UUID
-	PendingChanges() []uuid.UUID
-	CommittedChanges() []uuid.UUID
-	GetChange(uuid.UUID, ...int) (interface{}, error)
-	Commit(uuid.UUID) error
-	Confirm(uuid.UUID) error
-}
-
 // NewPND creates a Principle Network Domain
-func NewPND(name, description string, id uuid.UUID, sbi SouthboundInterface) (PrincipalNetworkDomain, error) {
+func NewPND(name, description string, id uuid.UUID, sbi southbound.SouthboundInterface) (networkdomain.NetworkDomain, error) {
 	pnd := &pndImplementation{
 		name:             name,
 		description:      description,
-		sbic:             SbiStore{store{}},
+		sbic:             SbiStore{genericStore{}},
 		devices:          NewDeviceStore(),
-		pendingChanges:   ChangeStore{store{}},
-		committedChanges: ChangeStore{store{}},
-		confirmedChanges: ChangeStore{store{}},
+		pendingChanges:   ChangeStore{genericStore{}},
+		committedChanges: ChangeStore{genericStore{}},
+		confirmedChanges: ChangeStore{genericStore{}},
 		id:               id,
 		errChans:         make(map[uuid.UUID]chan error),
 	}
@@ -83,7 +62,7 @@ func (pnd *pndImplementation) CommittedChanges() []uuid.UUID {
 	return pnd.committedChanges.UUIDs()
 }
 
-func (pnd *pndImplementation) GetChange(cuid uuid.UUID, i ...int) (interface{}, error) {
+func (pnd *pndImplementation) GetChange(cuid uuid.UUID, i ...int) (change.Change, error) {
 	var index int
 	if len(i) == 1 {
 		index = i[0]
@@ -98,7 +77,7 @@ func (pnd *pndImplementation) GetChange(cuid uuid.UUID, i ...int) (interface{},
 		&pnd.committedChanges,
 		&pnd.confirmedChanges,
 	}
-	ch, err := stores[index].Get(cuid)
+	ch, err := stores[index].GetChange(cuid)
 	index++
 	if err != nil {
 		switch err.(type) {
@@ -124,11 +103,11 @@ func (pnd *pndImplementation) GetChange(cuid uuid.UUID, i ...int) (interface{},
 }
 
 func (pnd *pndImplementation) Commit(u uuid.UUID) error {
-	change, err := pnd.pendingChanges.Get(u)
+	ch, err := pnd.pendingChanges.GetChange(u)
 	if err != nil {
 		return err
 	}
-	if err := change.Commit(); err != nil {
+	if err := ch.Commit(); err != nil {
 		return err
 	}
 	go func() {
@@ -136,27 +115,27 @@ func (pnd *pndImplementation) Commit(u uuid.UUID) error {
 			select {
 			case err := <-pnd.errChans[u]:
 				if err != nil {
-					handleRollbackError(change.ID(), err)
+					handleRollbackError(ch.ID(), err)
 				}
-			case <-change.done:
+			case <-ch.done:
 			}
 		}
 	}()
-	if err := pnd.committedChanges.Add(change); err != nil {
+	if err := pnd.committedChanges.Add(ch); err != nil {
 		return err
 	}
 	return pnd.pendingChanges.Delete(u)
 }
 
 func (pnd *pndImplementation) Confirm(u uuid.UUID) error {
-	change, err := pnd.committedChanges.Get(u)
+	ch, err := pnd.committedChanges.GetChange(u)
 	if err != nil {
 		return err
 	}
-	if err := change.Confirm(); err != nil {
+	if err := ch.Confirm(); err != nil {
 		return err
 	}
-	if err := pnd.confirmedChanges.Add(change); err != nil {
+	if err := pnd.confirmedChanges.Add(ch); err != nil {
 		return err
 	}
 	return pnd.committedChanges.Delete(u)
@@ -186,7 +165,7 @@ func (pnd *pndImplementation) GetDescription() string {
 }
 
 // GetSBIs returns the registered SBIs
-func (pnd *pndImplementation) GetSBIs() interface{} {
+func (pnd *pndImplementation) GetSBIs() store.Store {
 	return &pnd.sbic
 }
 
@@ -196,14 +175,7 @@ func (pnd *pndImplementation) Destroy() error {
 }
 
 // AddSbi adds a SBI to the PND which will be supported
-func (pnd *pndImplementation) AddSbi(sbi interface{}) error {
-	s, ok := sbi.(SouthboundInterface)
-	if !ok {
-		return &errors.ErrInvalidTypeAssertion{
-			Value: sbi,
-			Type:  "Device",
-		}
-	}
+func (pnd *pndImplementation) AddSbi(s southbound.SouthboundInterface) error {
 	return pnd.addSbi(s)
 }
 
@@ -217,7 +189,7 @@ func (pnd *pndImplementation) RemoveSbi(id uuid.UUID) error {
 
 //AddDevice adds a new device to the PND
 func (pnd *pndImplementation) AddDevice(name string, opt *tpb.TransportOption, sid uuid.UUID) error {
-	sbi, err := pnd.sbic.Get(sid)
+	sbi, err := pnd.sbic.GetSBI(sid)
 	if err != nil {
 		return err
 	}
@@ -229,8 +201,8 @@ func (pnd *pndImplementation) AddDevice(name string, opt *tpb.TransportOption, s
 	return pnd.addDevice(d)
 }
 
-func (pnd *pndImplementation) GetDevice(identifier string) (interface{}, error) {
-	d, err := pnd.devices.Get(FromString(identifier))
+func (pnd *pndImplementation) GetDevice(identifier string) (device.Device, error) {
+	d, err := pnd.devices.GetDevice(FromString(identifier))
 	if err != nil {
 		return nil, err
 	}
@@ -256,7 +228,7 @@ func destroy() error {
 	return nil
 }
 
-func (pnd *pndImplementation) addSbi(sbi SouthboundInterface) error {
+func (pnd *pndImplementation) addSbi(sbi southbound.SouthboundInterface) error {
 	return pnd.sbic.Add(sbi)
 }
 
@@ -264,7 +236,7 @@ func (pnd *pndImplementation) removeSbi(id uuid.UUID) error {
 	return pnd.sbic.Delete(id)
 }
 
-func (pnd *pndImplementation) addDevice(device Device) error {
+func (pnd *pndImplementation) addDevice(device device.Device) error {
 	err := pnd.devices.Add(device, device.Name())
 	if err != nil {
 		return err
@@ -278,7 +250,7 @@ func (pnd *pndImplementation) removeDevice(id uuid.UUID) error {
 }
 
 func (pnd *pndImplementation) MarshalDevice(identifier string) (string, error) {
-	foundDevice, err := pnd.devices.Get(FromString(identifier))
+	foundDevice, err := pnd.devices.GetDevice(FromString(identifier))
 	if err != nil {
 		return "", err
 	}
@@ -298,7 +270,7 @@ func (pnd *pndImplementation) MarshalDevice(identifier string) (string, error) {
 
 // Request sends a get request to a specific device
 func (pnd *pndImplementation) Request(uuid uuid.UUID, path string) error {
-	d, err := pnd.devices.Get(FromString(uuid.String()))
+	d, err := pnd.devices.GetDevice(FromString(uuid.String()))
 	if err != nil {
 		return err
 	}
@@ -330,7 +302,7 @@ func (pnd *pndImplementation) RequestAll(path string) error {
 
 // ChangeOND creates a change from the provided Operation, path and value. The Change is Pending and
 func (pnd *pndImplementation) ChangeOND(uuid uuid.UUID, operation ppb.ApiOperation, path string, value ...string) error {
-	d, err := pnd.devices.Get(uuid)
+	d, err := pnd.devices.GetDevice(uuid)
 	if err != nil {
 		return err
 	}
@@ -372,10 +344,10 @@ func (pnd *pndImplementation) ChangeOND(uuid uuid.UUID, operation ppb.ApiOperati
 	}
 
 	errChan := make(chan error)
-	change := NewChange(uuid, d.Model(), cpy, callback, errChan)
-	pnd.errChans[change.ID()] = errChan
+	ch := NewChange(uuid, d.Model(), cpy, callback, errChan)
+	pnd.errChans[ch.ID()] = errChan
 
-	return pnd.pendingChanges.Add(change)
+	return pnd.pendingChanges.Add(ch)
 }
 
 func handleRollbackError(id uuid.UUID, err error) {
diff --git a/nucleus/principalNetworkDomain_test.go b/nucleus/principalNetworkDomain_test.go
index 5e6e5ec43e6c9463447aed72f703df0a398d7d5e..7e7a4e252997f1e14964f8b66c12873d0cf4dd01 100644
--- a/nucleus/principalNetworkDomain_test.go
+++ b/nucleus/principalNetworkDomain_test.go
@@ -9,6 +9,9 @@ import (
 	spb "code.fbi.h-da.de/cocsn/api/go/gosdn/southbound"
 	tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport"
 
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/device"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/networkdomain"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/southbound"
 	"code.fbi.h-da.de/cocsn/gosdn/mocks"
 	"code.fbi.h-da.de/cocsn/yang-models/generated/openconfig"
 	"github.com/google/uuid"
@@ -18,20 +21,20 @@ import (
 )
 
 func TestNewPND(t *testing.T) {
-	pnd := newPnd()
-	if err := pnd.addSbi(&OpenConfig{id: defaultSbiID}); err != nil {
+	p := newPnd()
+	if err := p.addSbi(&OpenConfig{id: defaultSbiID}); err != nil {
 		t.Error(err)
 	}
 	type args struct {
 		name        string
 		description string
-		sbi         SouthboundInterface
+		sbi         southbound.SouthboundInterface
 		pid         uuid.UUID
 	}
 	tests := []struct {
 		name    string
 		args    args
-		want    PrincipalNetworkDomain
+		want    networkdomain.NetworkDomain
 		wantErr bool
 	}{
 		{
@@ -42,7 +45,7 @@ func TestNewPND(t *testing.T) {
 				sbi:         &OpenConfig{id: defaultSbiID},
 				pid:         defaultPndID,
 			},
-			want:    &pnd,
+			want:    &p,
 			wantErr: false,
 		},
 	}
@@ -123,7 +126,7 @@ func Test_pndImplementation_AddDevice(t *testing.T) {
 				t.Error(err)
 			}
 			if tt.name == "already exists" {
-				pnd.devices.store[did] = tt.args.device.(Device)
+				pnd.devices.genericStore[did] = tt.args.device.(device.Device)
 			}
 			err := pnd.AddDevice(tt.args.name, tt.args.opts, defaultSbiID)
 			if (err != nil) != tt.wantErr {
@@ -131,7 +134,7 @@ func Test_pndImplementation_AddDevice(t *testing.T) {
 			}
 			if tt.name != "fails wrong type" {
 				if err == nil {
-					d, err := pnd.devices.Get(FromString(tt.args.name))
+					d, err := pnd.devices.GetDevice(FromString(tt.args.name))
 					if err != nil {
 						t.Errorf("AddDevice() error = %v", err)
 						return
@@ -150,7 +153,7 @@ func Test_pndImplementation_AddDevice(t *testing.T) {
 
 func Test_pndImplementation_AddSbi(t *testing.T) {
 	type args struct {
-		sbi interface{}
+		sbi southbound.SouthboundInterface
 	}
 	tests := []struct {
 		name    string
@@ -175,21 +178,12 @@ func Test_pndImplementation_AddSbi(t *testing.T) {
 			},
 			wantErr: true,
 		},
-		{
-			name: "fails wrong type",
-			args: args{
-				sbi: &pndImplementation{
-					id: defaultSbiID,
-				},
-			},
-			wantErr: true,
-		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			pnd := newPnd()
 			if tt.name == "already exists" {
-				pnd.sbic.store[defaultSbiID] = tt.args.sbi.(*OpenConfig)
+				pnd.sbic.genericStore[defaultSbiID] = tt.args.sbi
 			}
 			err := pnd.AddSbi(tt.args.sbi)
 			if (err != nil) != tt.wantErr {
@@ -197,7 +191,7 @@ func Test_pndImplementation_AddSbi(t *testing.T) {
 			}
 			if tt.name != "fails wrong type" {
 				if err == nil {
-					_, ok := pnd.sbic.store[defaultSbiID]
+					_, ok := pnd.sbic.genericStore[defaultSbiID]
 					if !ok {
 						t.Errorf("AddSbi() SBI %v not in device store %v",
 							tt.args.sbi, pnd.GetSBIs())
@@ -214,7 +208,7 @@ func Test_pndImplementation_AddSbi(t *testing.T) {
 func Test_pndImplementation_ContainsDevice(t *testing.T) {
 	type args struct {
 		uuid   uuid.UUID
-		device Device
+		device device.Device
 	}
 	tests := []struct {
 		name string
@@ -426,7 +420,7 @@ func Test_pndImplementation_RemoveSbi(t *testing.T) {
 			pnd := &pndImplementation{
 				name:        "test-remove-sbi",
 				description: "test-remove-sbi",
-				sbic:        SbiStore{store{}},
+				sbic:        SbiStore{genericStore{}},
 				devices:     NewDeviceStore(),
 				id:          defaultPndID,
 			}
@@ -657,8 +651,8 @@ func Test_pndImplementation_ChangeOND(t *testing.T) {
 				return
 			}
 			if !tt.wantErr {
-				if len(pnd.pendingChanges.store) != 1 {
-					t.Errorf("ChangeOND() unexpected change count. got %v, want 1", len(pnd.pendingChanges.store))
+				if len(pnd.pendingChanges.genericStore) != 1 {
+					t.Errorf("ChangeOND() unexpected change count. got %v, want 1", len(pnd.pendingChanges.genericStore))
 				}
 			}
 		})
@@ -707,8 +701,8 @@ func Test_pndImplementation_GetDevice(t *testing.T) {
 				return
 			}
 			if foundDevice != nil {
-				if !reflect.DeepEqual(foundDevice.(Device).Model(), tt.want) {
-					t.Errorf("GetDevice() got = %v, want %v", foundDevice.(Device).Model(), tt.want)
+				if !reflect.DeepEqual(foundDevice.(device.Device).Model(), tt.want) {
+					t.Errorf("GetDevice() got = %v, want %v", foundDevice.(device.Device).Model(), tt.want)
 				}
 			}
 
@@ -758,8 +752,8 @@ func Test_pndImplementation_GetDeviceByName(t *testing.T) {
 				return
 			}
 			if foundDevice != nil {
-				if !reflect.DeepEqual(foundDevice.(Device).Model(), tt.want) {
-					t.Errorf("GetDeviceByName() got = %v, want %v", foundDevice.(Device).Model(), tt.want)
+				if !reflect.DeepEqual(foundDevice.(device.Device).Model(), tt.want) {
+					t.Errorf("GetDeviceByName() got = %v, want %v", foundDevice.(device.Device).Model(), tt.want)
 				}
 			}
 
diff --git a/nucleus/southbound.go b/nucleus/southbound.go
index 11d63ddb6e537c78d6e0d9ecb29652efd53df77f..0f2eda136b167053125b66d67890f6657b39699c 100644
--- a/nucleus/southbound.go
+++ b/nucleus/southbound.go
@@ -4,6 +4,7 @@ import (
 	"reflect"
 
 	spb "code.fbi.h-da.de/cocsn/api/go/gosdn/southbound"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/southbound"
 	"code.fbi.h-da.de/cocsn/gosdn/nucleus/errors"
 
 	"code.fbi.h-da.de/cocsn/yang-models/generated/openconfig"
@@ -16,23 +17,8 @@ import (
 	log "github.com/sirupsen/logrus"
 )
 
-// SouthboundInterface provides an
-// interface for SBI implementations
-type SouthboundInterface interface {
-	// deprecated
-	SbiIdentifier() string
-
-	// SetNode injects SBI specific model
-	// representation to the transport.
-	// Needed for type assertion.
-	SetNode() func(schema *yang.Entry, root interface{}, path *gpb.Path, val interface{}, opts ...ytypes.SetNodeOpt) error
-	Schema() *ytypes.Schema
-	ID() uuid.UUID
-	Type() spb.Type
-}
-
 // NewSBI creates a SouthboundInterface of a given type.
-func NewSBI(southbound spb.Type) SouthboundInterface {
+func NewSBI(southbound spb.Type) southbound.SouthboundInterface {
 	switch southbound {
 	case spb.Type_OPENCONFIG:
 		return &OpenConfig{id: uuid.New()}
diff --git a/nucleus/southbound_test.go b/nucleus/southbound_test.go
index 0bdaa18ec4c481c532f0eebd2de810c373acd89b..65f9d4b2faa87d3d0c319e8185036042a0eccab4 100644
--- a/nucleus/southbound_test.go
+++ b/nucleus/southbound_test.go
@@ -4,6 +4,8 @@ import (
 	"reflect"
 	"testing"
 
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/transport"
+
 	"code.fbi.h-da.de/cocsn/gosdn/nucleus/util/path"
 	"code.fbi.h-da.de/cocsn/gosdn/nucleus/util/proto"
 	"code.fbi.h-da.de/cocsn/yang-models/generated/openconfig"
@@ -14,7 +16,7 @@ import (
 
 func TestOpenConfig_Id(t *testing.T) {
 	type fields struct {
-		transport Transport
+		transport transport.Transport
 		schema    *ytypes.Schema
 		id        uuid.UUID
 	}
diff --git a/nucleus/store.go b/nucleus/store.go
index 911ae31129a32358660e52afb9a14d4125983d84..94a741bc69e395b833e0267fecd3452774a49b6b 100644
--- a/nucleus/store.go
+++ b/nucleus/store.go
@@ -5,6 +5,10 @@ import (
 	"reflect"
 	"sync"
 
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/device"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/networkdomain"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/southbound"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/store"
 	"code.fbi.h-da.de/cocsn/gosdn/nucleus/errors"
 
 	"github.com/google/uuid"
@@ -13,49 +17,35 @@ import (
 
 var storeLock sync.RWMutex
 
-// Storable provides an interface for the controller's storage architecture.
-type Storable interface {
-	ID() uuid.UUID
-}
-
-// Store describes an interface for store implementations.
-type Store interface {
-	Exists(id uuid.UUID) bool
-	Add(item Storable) error
-	Get(id uuid.UUID) (Storable, error)
-	Delete(id uuid.UUID) error
-	UUIDs() []uuid.UUID
-}
-
 // NewStore returns a generic Store
-func NewStore() Store {
-	return store{}
+func NewStore() store.Store {
+	return genericStore{}
 }
 
 // NewPndStore returns a PndStore
 func NewPndStore() *PndStore {
-	return &PndStore{store{}}
+	return &PndStore{genericStore{}}
 }
 
 // NewSbiStore returns a SbiStore
 func NewSbiStore() *SbiStore {
-	return &SbiStore{store{}}
+	return &SbiStore{genericStore{}}
 }
 
 // NewDeviceStore returns a DeviceStore
 func NewDeviceStore() *DeviceStore {
-	return &DeviceStore{store: store{}, deviceNameToUUIDLookup: make(map[string]uuid.UUID)}
+	return &DeviceStore{genericStore: genericStore{}, deviceNameToUUIDLookup: make(map[string]uuid.UUID)}
 }
 
 // NewChangeStore returns a ChangeStore
 func NewChangeStore() *ChangeStore {
-	return &ChangeStore{store{}}
+	return &ChangeStore{genericStore{}}
 }
 
-type store map[uuid.UUID]Storable
+type genericStore map[uuid.UUID]store.Storable
 
 // Exists takes a Storable's UUID and checks its existence in the store.
-func (s store) Exists(id uuid.UUID) bool {
+func (s genericStore) Exists(id uuid.UUID) bool {
 	storeLock.RLock()
 	defer storeLock.RUnlock()
 	_, ok := s[id]
@@ -63,7 +53,7 @@ func (s store) Exists(id uuid.UUID) bool {
 }
 
 // Add adds a Storable to the Store
-func (s store) Add(item Storable) error {
+func (s genericStore) Add(item store.Storable) error {
 	if s.Exists(item.ID()) {
 		return &errors.ErrAlreadyExists{Item: item}
 	}
@@ -79,7 +69,7 @@ func (s store) Add(item Storable) error {
 
 // Get takes a Storable's UUID and returns the Storable. If the requested
 // Storable does not exist an error is returned.
-func (s store) Get(id uuid.UUID) (Storable, error) {
+func (s genericStore) Get(id uuid.UUID) (store.Storable, error) {
 	if !s.Exists(id) {
 		return nil, &errors.ErrNotFound{ID: id}
 	}
@@ -93,7 +83,7 @@ func (s store) Get(id uuid.UUID) (Storable, error) {
 
 // Delete takes a Storable's UUID and deletes it. If the specified UUID does not
 // exist in the Store an error is returned.
-func (s store) Delete(id uuid.UUID) error {
+func (s genericStore) Delete(id uuid.UUID) error {
 	if !s.Exists(id) {
 		return &errors.ErrNotFound{ID: id}
 	}
@@ -107,7 +97,7 @@ func (s store) Delete(id uuid.UUID) error {
 }
 
 // UUIDs returns all UUIDs in the store.
-func (s store) UUIDs() []uuid.UUID {
+func (s genericStore) UUIDs() []uuid.UUID {
 	storeLock.RLock()
 	defer storeLock.RUnlock()
 	keys := make([]uuid.UUID, len(s))
@@ -121,17 +111,17 @@ func (s store) UUIDs() []uuid.UUID {
 
 // SbiStore is used to store SouthboundInterfaces
 type SbiStore struct {
-	store
+	genericStore
 }
 
-// Get takes a SouthboundInterface's UUID and returns the SouthboundInterface. If the requested
+// GetSBI takes a SouthboundInterface's UUID and returns the SouthboundInterface. If the requested
 // SouthboundInterface does not exist an error is returned.
-func (s SbiStore) Get(id uuid.UUID) (SouthboundInterface, error) {
-	item, err := s.store.Get(id)
+func (s SbiStore) GetSBI(id uuid.UUID) (southbound.SouthboundInterface, error) {
+	item, err := s.genericStore.Get(id)
 	if err != nil {
 		return nil, err
 	}
-	sbi, ok := item.(SouthboundInterface)
+	sbi, ok := item.(southbound.SouthboundInterface)
 	if !ok {
 		return nil, &errors.ErrInvalidTypeAssertion{
 			Value: sbi,
@@ -146,17 +136,17 @@ func (s SbiStore) Get(id uuid.UUID) (SouthboundInterface, error) {
 
 // PndStore is used to store PrincipalNetworkDomains
 type PndStore struct {
-	store
+	genericStore
 }
 
-// Get takes a PrincipalNetworkDomain's UUID and returns the PrincipalNetworkDomain. If the requested
+// GetPND takes a PrincipalNetworkDomain's UUID and returns the PrincipalNetworkDomain. If the requested
 // PrincipalNetworkDomain does not exist an error is returned.
-func (s PndStore) Get(id uuid.UUID) (PrincipalNetworkDomain, error) {
-	item, err := s.store.Get(id)
+func (s PndStore) GetPND(id uuid.UUID) (networkdomain.NetworkDomain, error) {
+	item, err := s.genericStore.Get(id)
 	if err != nil {
 		return nil, err
 	}
-	pnd, ok := item.(PrincipalNetworkDomain)
+	pnd, ok := item.(networkdomain.NetworkDomain)
 	if !ok {
 		return nil, &errors.ErrInvalidTypeAssertion{
 			Value: pnd,
@@ -172,12 +162,12 @@ func (s PndStore) Get(id uuid.UUID) (PrincipalNetworkDomain, error) {
 // DeviceStore is used to store Devices
 type DeviceStore struct {
 	deviceNameToUUIDLookup map[string]uuid.UUID
-	store
+	genericStore
 }
 
-// Get takes a Device's UUID and returns the Device. If the requested
+// GetDevice takes a Device's UUID and returns the Device. If the requested
 // Device does not exist an error is returned.
-func (s DeviceStore) Get(id uuid.UUID, parseErrors ...error) (Device, error) {
+func (s DeviceStore) GetDevice(id uuid.UUID, parseErrors ...error) (device.Device, error) {
 	var foundID uuid.UUID
 
 	foundID = id
@@ -197,23 +187,23 @@ func (s DeviceStore) Get(id uuid.UUID, parseErrors ...error) (Device, error) {
 		}
 	}
 
-	item, err := s.store.Get(foundID)
+	item, err := s.genericStore.Get(foundID)
 	if err != nil {
 		return nil, err
 	}
-	device, ok := item.(Device)
+	d, ok := item.(device.Device)
 	if !ok {
 		return nil, &errors.ErrInvalidTypeAssertion{
-			Value: device,
-			Type:  reflect.TypeOf((Device)(nil)),
+			Value: d,
+			Type:  reflect.TypeOf((device.Device)(nil)),
 		}
 	}
 	log.WithFields(log.Fields{
 		"uuid": id,
-		"name": device.Name,
+		"name": d.Name,
 	}).Debug("device was accessed")
 
-	return device, nil
+	return d, nil
 }
 
 // FromString is a helper to check if a provided string as a valid UUID or a name.
@@ -234,7 +224,7 @@ func FromString(id string) (uuid.UUID, error) {
 
 // Add adds a device to the device store.
 // It also adds the name of the device to the lookup table.
-func (s DeviceStore) Add(item Storable, name string) error {
+func (s DeviceStore) Add(item store.Storable, name string) error {
 	if s.Exists(item.ID()) {
 		return &errors.ErrAlreadyExists{Item: item}
 	}
@@ -242,7 +232,7 @@ func (s DeviceStore) Add(item Storable, name string) error {
 	s.deviceNameToUUIDLookup[name] = item.ID()
 
 	storeLock.Lock()
-	s.store[item.ID()] = item
+	s.genericStore[item.ID()] = item
 	storeLock.Unlock()
 
 	log.WithFields(log.Fields{
@@ -260,7 +250,7 @@ func (s DeviceStore) Delete(id uuid.UUID) error {
 	}
 
 	storeLock.Lock()
-	delete(s.store, id)
+	delete(s.genericStore, id)
 	storeLock.Unlock()
 
 	for key, value := range s.deviceNameToUUIDLookup {
@@ -278,13 +268,13 @@ func (s DeviceStore) Delete(id uuid.UUID) error {
 
 // ChangeStore is used to store Changes
 type ChangeStore struct {
-	store
+	genericStore
 }
 
-// Get takes a Change's UUID and returns the Change. If the requested
+// GetChange takes a Change's UUID and returns the Change. If the requested
 // Change does not exist an error is returned.
-func (s ChangeStore) Get(id uuid.UUID) (*Change, error) {
-	item, err := s.store.Get(id)
+func (s ChangeStore) GetChange(id uuid.UUID) (*Change, error) {
+	item, err := s.genericStore.Get(id)
 	if err != nil {
 		return nil, err
 	}
diff --git a/nucleus/store_test.go b/nucleus/store_test.go
index 69bbd6282f2e9bf7946d851e9c9bef2ba98b3949..abba8efcc2153e642bca10c222ea629aa3834eb3 100644
--- a/nucleus/store_test.go
+++ b/nucleus/store_test.go
@@ -5,30 +5,35 @@ import (
 	"sort"
 	"testing"
 
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/device"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/networkdomain"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/southbound"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/store"
+
 	"code.fbi.h-da.de/cocsn/gosdn/mocks"
 	"github.com/google/uuid"
 )
 
-func Test_store_add(t *testing.T) {
+func Test_Store_add(t *testing.T) {
 	type args struct {
-		item Storable
+		item store.Storable
 	}
 	tests := []struct {
 		name    string
-		s       store
+		s       genericStore
 		args    args
 		wantErr bool
 	}{
 		{
 			name: "default",
-			s:    store{},
+			s:    genericStore{},
 			args: args{
 				item: &mocks.Storable{},
 			},
 		},
 		{
 			name: "already exists",
-			s: store{
+			s: genericStore{
 				iid: &mocks.Storable{},
 			},
 			args: args{
@@ -52,19 +57,19 @@ func Test_store_add(t *testing.T) {
 	}
 }
 
-func Test_store_delete(t *testing.T) {
+func Test_Store_delete(t *testing.T) {
 	type args struct {
 		id uuid.UUID
 	}
 	tests := []struct {
 		name    string
-		s       store
+		s       genericStore
 		args    args
 		wantErr bool
 	}{
 		{
 			name: "default",
-			s: store{
+			s: genericStore{
 				iid: &mocks.Storable{},
 			},
 			args:    args{id: iid},
@@ -72,13 +77,13 @@ func Test_store_delete(t *testing.T) {
 		},
 		{
 			name:    "not found empty",
-			s:       store{},
+			s:       genericStore{},
 			args:    args{id: iid},
 			wantErr: true,
 		},
 		{
 			name: "not found",
-			s: store{
+			s: genericStore{
 				iid: &mocks.Storable{},
 			},
 			args:    args{id: altIid},
@@ -93,26 +98,26 @@ func Test_store_delete(t *testing.T) {
 			if tt.name == "default" {
 				item, ok := tt.s[iid]
 				if ok {
-					t.Errorf("delete() item %v still in store %v", item, tt.s)
+					t.Errorf("delete() item %v still in genericStore %v", item, tt.s)
 				}
 			}
 		})
 	}
 }
 
-func Test_store_exists(t *testing.T) {
+func Test_Store_exists(t *testing.T) {
 	type args struct {
 		id uuid.UUID
 	}
 	tests := []struct {
 		name string
-		s    store
+		s    genericStore
 		args args
 		want bool
 	}{
 		{
 			name: "default",
-			s: store{
+			s: genericStore{
 				iid: &mocks.Storable{},
 			},
 			args: args{id: iid},
@@ -120,13 +125,13 @@ func Test_store_exists(t *testing.T) {
 		},
 		{
 			name: "not found empty",
-			s:    store{},
+			s:    genericStore{},
 			args: args{id: iid},
 			want: false,
 		},
 		{
 			name: "not found",
-			s: store{
+			s: genericStore{
 				iid: &mocks.Storable{},
 			},
 			args: args{id: altIid},
@@ -142,20 +147,20 @@ func Test_store_exists(t *testing.T) {
 	}
 }
 
-func Test_store_get(t *testing.T) {
+func Test_Store_get(t *testing.T) {
 	type args struct {
 		id uuid.UUID
 	}
 	tests := []struct {
 		name    string
-		s       store
+		s       genericStore
 		args    args
-		want    Storable
+		want    store.Storable
 		wantErr bool
 	}{
 		{
 			name: "exists",
-			s: store{
+			s: genericStore{
 				iid: &mocks.Storable{},
 			},
 			args:    args{id: iid},
@@ -164,7 +169,7 @@ func Test_store_get(t *testing.T) {
 		},
 		{
 			name: "not found",
-			s: store{
+			s: genericStore{
 				iid: &mocks.Storable{},
 			},
 			args:    args{id: altIid},
@@ -173,7 +178,7 @@ func Test_store_get(t *testing.T) {
 		},
 		{
 			name:    "not found empty",
-			s:       store{},
+			s:       genericStore{},
 			args:    args{id: iid},
 			want:    nil,
 			wantErr: true,
@@ -193,15 +198,15 @@ func Test_store_get(t *testing.T) {
 	}
 }
 
-func Test_store_UUIDs(t *testing.T) {
+func Test_Store_UUIDs(t *testing.T) {
 	tests := []struct {
 		name string
-		s    store
+		s    genericStore
 		want []uuid.UUID
 	}{
 		{
 			name: "default",
-			s: store{
+			s: genericStore{
 				iid:    &mocks.Storable{},
 				altIid: &mocks.Storable{},
 			},
@@ -226,7 +231,7 @@ func Test_store_UUIDs(t *testing.T) {
 
 func Test_sbiStore_get(t *testing.T) {
 	type fields struct {
-		store store
+		genericStore genericStore
 	}
 	type args struct {
 		id uuid.UUID
@@ -235,13 +240,13 @@ func Test_sbiStore_get(t *testing.T) {
 		name    string
 		fields  fields
 		args    args
-		want    SouthboundInterface
+		want    southbound.SouthboundInterface
 		wantErr bool
 	}{
 		{
 			name: "exists",
 			fields: fields{
-				store: store{
+				genericStore: genericStore{
 					defaultSbiID: &OpenConfig{id: defaultSbiID},
 				},
 			},
@@ -252,7 +257,7 @@ func Test_sbiStore_get(t *testing.T) {
 		{
 			name: "fails",
 			fields: fields{
-				store: store{
+				genericStore: genericStore{
 					defaultSbiID: &OpenConfig{id: defaultSbiID},
 				},
 			},
@@ -262,7 +267,7 @@ func Test_sbiStore_get(t *testing.T) {
 		{
 			name: "fails empty",
 			fields: fields{
-				store: store{},
+				genericStore: genericStore{},
 			},
 			args:    args{id: defaultSbiID},
 			wantErr: true,
@@ -270,7 +275,7 @@ func Test_sbiStore_get(t *testing.T) {
 		{
 			name: "fails wrong type",
 			fields: fields{
-				store: store{
+				genericStore: genericStore{
 					did: &CommonDevice{
 						UUID: did,
 					},
@@ -283,7 +288,7 @@ func Test_sbiStore_get(t *testing.T) {
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			s := SbiStore{
-				store: tt.fields.store,
+				genericStore: tt.fields.genericStore,
 			}
 			got, err := s.Get(tt.args.id)
 			if (err != nil) != tt.wantErr {
@@ -299,7 +304,7 @@ func Test_sbiStore_get(t *testing.T) {
 
 func Test_pndStore_get(t *testing.T) {
 	type fields struct {
-		store store
+		genericStore genericStore
 	}
 	type args struct {
 		id uuid.UUID
@@ -308,13 +313,13 @@ func Test_pndStore_get(t *testing.T) {
 		name    string
 		fields  fields
 		args    args
-		want    PrincipalNetworkDomain
+		want    networkdomain.NetworkDomain
 		wantErr bool
 	}{
 		{
 			name: "exists",
 			fields: fields{
-				store: store{
+				genericStore: genericStore{
 					defaultPndID: &pndImplementation{id: defaultPndID},
 				},
 			},
@@ -325,7 +330,7 @@ func Test_pndStore_get(t *testing.T) {
 		{
 			name: "fails",
 			fields: fields{
-				store: store{
+				genericStore: genericStore{
 					defaultPndID: &pndImplementation{id: defaultPndID},
 				},
 			},
@@ -335,7 +340,7 @@ func Test_pndStore_get(t *testing.T) {
 		{
 			name: "fails empty",
 			fields: fields{
-				store: store{},
+				genericStore: genericStore{},
 			},
 			args:    args{id: defaultPndID},
 			wantErr: true,
@@ -343,7 +348,7 @@ func Test_pndStore_get(t *testing.T) {
 		{
 			name: "fails wrong type",
 			fields: fields{
-				store: store{
+				genericStore: genericStore{
 					did: &CommonDevice{
 						UUID: did,
 					},
@@ -356,7 +361,7 @@ func Test_pndStore_get(t *testing.T) {
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			s := PndStore{
-				store: tt.fields.store,
+				genericStore: tt.fields.genericStore,
 			}
 			got, err := s.Get(tt.args.id)
 			if (err != nil) != tt.wantErr {
@@ -372,7 +377,7 @@ func Test_pndStore_get(t *testing.T) {
 
 func Test_deviceStore_get(t *testing.T) {
 	type fields struct {
-		store store
+		genericStore genericStore
 	}
 	type args struct {
 		id uuid.UUID
@@ -381,13 +386,13 @@ func Test_deviceStore_get(t *testing.T) {
 		name    string
 		fields  fields
 		args    args
-		want    Device
+		want    device.Device
 		wantErr bool
 	}{
 		{
 			name: "exists",
 			fields: fields{
-				store: store{
+				genericStore: genericStore{
 					defaultPndID: &CommonDevice{UUID: did}}},
 			args: args{id: defaultPndID},
 			want: &CommonDevice{
@@ -398,7 +403,7 @@ func Test_deviceStore_get(t *testing.T) {
 		{
 			name: "fails",
 			fields: fields{
-				store: store{
+				genericStore: genericStore{
 					defaultPndID: &CommonDevice{UUID: did}}},
 			args:    args{id: iid},
 			wantErr: true,
@@ -406,7 +411,7 @@ func Test_deviceStore_get(t *testing.T) {
 		{
 			name: "fails empty",
 			fields: fields{
-				store: store{},
+				genericStore: genericStore{},
 			},
 			args:    args{id: defaultPndID},
 			wantErr: true,
@@ -414,7 +419,7 @@ func Test_deviceStore_get(t *testing.T) {
 		{
 			name: "fails wrong type",
 			fields: fields{
-				store: store{
+				genericStore: genericStore{
 					defaultPndID: &pndImplementation{id: defaultPndID}}},
 			args:    args{id: defaultPndID},
 			wantErr: true,
@@ -423,11 +428,11 @@ func Test_deviceStore_get(t *testing.T) {
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			s := DeviceStore{
-				store:                  tt.fields.store,
+				genericStore:           tt.fields.genericStore,
 				deviceNameToUUIDLookup: make(map[string]uuid.UUID),
 			}
 
-			got, err := s.Get(FromString(tt.args.id.String()))
+			got, err := s.GetDevice(FromString(tt.args.id.String()))
 			if (err != nil) != tt.wantErr {
 				t.Errorf("get() error = %v, wantErr %v", err, tt.wantErr)
 				return
diff --git a/nucleus/transport.go b/nucleus/transport.go
index dded3c4b299dcf9e9046b52e9c18c5f52dfe737e..3d8523e954d448a9fa461b42bacf56bf8b83e668 100644
--- a/nucleus/transport.go
+++ b/nucleus/transport.go
@@ -1,27 +1,15 @@
 package nucleus
 
 import (
-	"context"
-
 	tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/southbound"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/transport"
 	"code.fbi.h-da.de/cocsn/gosdn/nucleus/errors"
-
-	"github.com/openconfig/ygot/ytypes"
 )
 
-// Transport provides an interface for Transport implementations
-// like RESTCONF or gnmi
-type Transport interface {
-	Get(ctx context.Context, params ...string) (interface{}, error)
-	Set(ctx context.Context, params ...interface{}) error
-	Subscribe(ctx context.Context, params ...string) error
-	Type() string
-	ProcessResponse(resp interface{}, root interface{}, models *ytypes.Schema) error
-}
-
 // NewTransport receives TransportOptions and returns an appropriate Transport
 // implementation
-func NewTransport(opts *tpb.TransportOption, sbi SouthboundInterface) (Transport, error) {
+func NewTransport(opts *tpb.TransportOption, sbi southbound.SouthboundInterface) (transport.Transport, error) {
 	if opts == nil {
 		return nil, &errors.ErrInvalidParameters{
 			Func:  NewTransport,
diff --git a/nucleus/transport_test.go b/nucleus/transport_test.go
index 0fa4ffa903a1f894325aaf5211341e19a2df754a..787c12a36021b1efe304a388b49092dd8515910d 100644
--- a/nucleus/transport_test.go
+++ b/nucleus/transport_test.go
@@ -1 +1,37 @@
 package nucleus
+
+import (
+	"reflect"
+	"testing"
+
+	tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/southbound"
+	"code.fbi.h-da.de/cocsn/gosdn/interfaces/transport"
+)
+
+func TestNewTransport(t *testing.T) {
+	type args struct {
+		opts *tpb.TransportOption
+		sbi  southbound.SouthboundInterface
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    transport.Transport
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := NewTransport(tt.args.opts, tt.args.sbi)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("NewTransport() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("NewTransport() got = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}