diff --git a/controller/controller.go b/controller/controller.go
index b46d77770e7e3a94b4684e826aebebd2e300d60f..a1a24aaf60deb2c47f7b2bf4dc9aa0e37bc66fa4 100644
--- a/controller/controller.go
+++ b/controller/controller.go
@@ -361,6 +361,9 @@ func ensureAdminRoleExists() error {
 			"/gosdn.topology.TopologyService/DeleteLink",
 			"/gosdn.subscriptionmanagement.SubscriptionManagementService/ResetAllSubscriptions",
 			"/gosdn.subscriptionmanagement.SubscriptionManagementService/GetAll",
+			"/gosdn.subscriptionmanagement.SubscriptionManagementService/Get",
+			"/gosdn.subscriptionmanagement.SubscriptionManagementService/Delete",
+			"/gosdn.subscriptionmanagement.SubscriptionManagementService/Add",
 		}))
 		if err != nil {
 			return err
diff --git a/controller/northbound/server/submanagement.go b/controller/northbound/server/submanagement.go
index eb75420e7a482e753895e46d11ae687d7f10adee..8710ef3def57ebc956190fa3b8c6b6361a7dd704 100644
--- a/controller/northbound/server/submanagement.go
+++ b/controller/northbound/server/submanagement.go
@@ -6,6 +6,8 @@ import (
 
 	subpb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/subscriptionmanagement"
 	"code.fbi.h-da.de/danet/gosdn/controller/nucleus"
+	"code.fbi.h-da.de/danet/gosdn/forks/goarista/gnmi"
+	"github.com/google/uuid"
 )
 
 // SubManagementServer represents a SubsriptionManagementServer.
@@ -67,3 +69,99 @@ func (s *SubManagementServer) GetAll(ctx context.Context, request *subpb.GetAllR
 		Subscriptions: subInfosToReturn,
 	}, nil
 }
+
+// Get fetches detailed info for one specific available subscription.
+func (s *SubManagementServer) Get(ctx context.Context, request *subpb.GetRequest) (*subpb.GetResponse, error) {
+	subUUID, err := uuid.Parse(request.GetSubid())
+	if err != nil {
+		return &subpb.GetResponse{
+			Timestamp: time.Now().UnixNano(),
+		}, err
+	}
+
+	info, err := s.networkElementWatchter.GetSubscriptionInformations(subUUID)
+	if err != nil {
+		return &subpb.GetResponse{
+			Timestamp: time.Now().UnixNano(),
+		}, err
+	}
+
+	var pathsToReturn []*subpb.Path
+	for _, path := range info.Opts.Paths {
+		var elems []string
+		for _, elem := range path {
+			elems = append(elems, elem)
+		}
+
+		pathsToReturn = append(pathsToReturn, &subpb.Path{Elem: elems})
+	}
+
+	return &subpb.GetResponse{
+		Timestamp: time.Now().UnixNano(),
+		Subscriptions: &subpb.Subscription{
+			Subid:   info.SubID,
+			Pid:     info.PndID,
+			Mneid:   info.MneID,
+			MneName: info.MneName,
+			Paths:   pathsToReturn,
+			SubscribeOptions: &subpb.SubscribeOptions{
+				GnmiMode:       info.Opts.Mode,
+				GnmiStreamMode: info.Opts.StreamMode,
+				SampleInterval: info.Opts.SampleInterval,
+			},
+		},
+	}, nil
+}
+
+// Delete stops and removes one specific running subscription is a no-op if object connected to ID does not exist.
+func (s *SubManagementServer) Delete(ctx context.Context, request *subpb.DeleteRequest) (*subpb.DeleteResponse, error) {
+	subUUID, err := uuid.Parse(request.GetSubid())
+	if err != nil {
+		return &subpb.DeleteResponse{
+			Timestamp: time.Now().UnixNano(),
+		}, err
+	}
+
+	s.networkElementWatchter.StopAndRemoveNetworkElementSubscription(subUUID)
+
+	return &subpb.DeleteResponse{
+		Timestamp: time.Now().UnixNano(),
+	}, nil
+}
+
+// Add creates a new subscription for the network element matching the provided ID using the provided subscribe options.
+func (s *SubManagementServer) Add(ctx context.Context, request *subpb.AddRequest) (*subpb.AddResponse, error) {
+	mneID, err := uuid.Parse(request.GetMneid())
+	if err != nil {
+		return &subpb.AddResponse{
+			Timestamp: time.Now().UnixNano(),
+		}, err
+	}
+
+	var paths [][]string
+	for _, path := range request.Subscription.Paths {
+		var elems []string
+		for _, elem := range path.Elem {
+			elems = append(elems, elem)
+		}
+		paths = append(paths, elems)
+	}
+
+	err = s.networkElementWatchter.SubscribeToNetworkElementWithID(mneID,
+		&gnmi.SubscribeOptions{
+			Mode:           request.Subscription.SubscribeOptions.GnmiMode,
+			StreamMode:     request.Subscription.SubscribeOptions.GnmiStreamMode,
+			SampleInterval: request.Subscription.SubscribeOptions.SampleInterval,
+			Paths:          paths,
+		},
+	)
+	if err != nil {
+		return &subpb.AddResponse{
+			Timestamp: time.Now().UnixNano(),
+		}, err
+	}
+
+	return &subpb.AddResponse{
+		Timestamp: time.Now().UnixNano(),
+	}, nil
+}
diff --git a/controller/nucleus/networkElementWatcher.go b/controller/nucleus/networkElementWatcher.go
index dd8713aa834ce8156ce423f98a7a9e40e328fb8e..e6d19efd4019d24a953db1745ab46a65e4562769 100644
--- a/controller/nucleus/networkElementWatcher.go
+++ b/controller/nucleus/networkElementWatcher.go
@@ -14,6 +14,7 @@ import (
 	"code.fbi.h-da.de/danet/gosdn/controller/interfaces/networkelement"
 	"code.fbi.h-da.de/danet/gosdn/controller/interfaces/transport"
 	"code.fbi.h-da.de/danet/gosdn/controller/nucleus/types"
+	"code.fbi.h-da.de/danet/gosdn/controller/store"
 	"code.fbi.h-da.de/danet/gosdn/forks/goarista/gnmi"
 	"github.com/google/uuid"
 	gpb "github.com/openconfig/gnmi/proto/gnmi"
@@ -104,6 +105,19 @@ func (n *NetworkElementWatcher) SubscribeToNetworkElement(mne networkelement.Net
 	n.subscribeToNetworkElement(mne, opts)
 }
 
+// SubscribeToNetworkElementWithID subscribes to the network element matching the provided ID according to provided SubscribeOptions.
+// SubscribeOptions can be nil. Use nil for a fixed, pre-defined set of gNMI subscription options (streaming in sample mode each second).
+func (n *NetworkElementWatcher) SubscribeToNetworkElementWithID(mneID uuid.UUID, opts *gnmi.SubscribeOptions) error {
+	mne, err := n.mneService.Get(store.Query{ID: mneID})
+	if err != nil {
+		log.Error(err)
+		return err
+	}
+
+	n.subscribeToNetworkElement(mne, opts)
+	return nil
+}
+
 func (n *NetworkElementWatcher) subscribeToNetworkElement(mne networkelement.NetworkElement, opts *gnmi.SubscribeOptions) {
 	subID := uuid.New()