diff --git a/common/python/CMakeLists.txt b/common/python/CMakeLists.txt
index 50ed1de..8fba078 100644
--- a/common/python/CMakeLists.txt
+++ b/common/python/CMakeLists.txt
@@ -38,6 +38,16 @@
 
 rift_python_install_tree(
   FILES
+    rift/mano/sdn/__init__.py
+    rift/mano/sdn/accounts.py
+    rift/mano/sdn/config.py
+    rift/mano/sdn/operdata.py
+  COMPONENT ${PKG_LONG_NAME}
+  PYTHON3_ONLY
+  )
+
+rift_python_install_tree(
+  FILES
     rift/mano/config_agent/operdata.py
     rift/mano/config_agent/__init__.py
     rift/mano/config_agent/config.py
diff --git a/common/python/rift/mano/sdn/__init__.py b/common/python/rift/mano/sdn/__init__.py
new file mode 100644
index 0000000..8f85832
--- /dev/null
+++ b/common/python/rift/mano/sdn/__init__.py
@@ -0,0 +1,30 @@
+
+# 
+#   Copyright 2017 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+from .accounts import (
+    SDNAccount,
+    SDNAccountCalError,
+    )
+
+from .config import (
+    SDNAccountConfigSubscriber,
+    SDNAccountConfigCallbacks
+    )
+
+from .operdata import (
+     SDNAccountDtsOperdataHandler,
+)
diff --git a/common/python/rift/mano/sdn/accounts.py b/common/python/rift/mano/sdn/accounts.py
new file mode 100644
index 0000000..d539ead
--- /dev/null
+++ b/common/python/rift/mano/sdn/accounts.py
@@ -0,0 +1,157 @@
+
+# 
+#   Copyright 2017 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+import sys
+import asyncio
+from gi import require_version
+require_version('RwTypes', '1.0')
+require_version('RwsdnalYang', '1.0')
+require_version('RwSdnYang', '1.0')
+
+from gi.repository import (
+        RwTypes,
+        RwsdnalYang,
+        RwSdnYang,
+        )
+import rw_peas
+
+if sys.version_info < (3, 4, 4):
+    asyncio.ensure_future = asyncio.async
+
+
+class PluginLoadingError(Exception):
+    pass
+
+
+class SDNAccountCalError(Exception):
+    pass
+
+
+class SDNAccount(object):
+    def __init__(self, log, rwlog_hdl, account_msg):
+        self._log = log
+        self._account_msg = account_msg.deep_copy()
+
+        self._sdn_plugin = None
+        self._engine = None
+
+        self._sdn = self.plugin.get_interface("Topology")
+        self._sdn.init(rwlog_hdl)
+
+        self._status = RwsdnalYang.SDNAccount_ConnectionStatus(
+                status="unknown",
+                details="Connection status lookup not started"
+                )
+
+        self._validate_task = None
+
+    @property
+    def plugin(self):
+        if self._sdn_plugin is None:
+            try:
+                self._sdn_plugin = rw_peas.PeasPlugin(
+                        getattr(self._account_msg, self.account_type).plugin_name,
+                        'RwSdn-1.0',
+                        )
+
+            except AttributeError as e:
+                raise PluginLoadingError(str(e))
+
+            self._engine, _, _ = self._sdn_plugin()
+
+        return self._sdn_plugin
+
+    def _wrap_status_fn(self, fn, *args, **kwargs):
+        ret = fn(*args, **kwargs)
+        rw_status = ret[0]
+        if rw_status != RwTypes.RwStatus.SUCCESS:
+            msg = "%s returned %s" % (fn.__name__, str(rw_status))
+            self._log.error(msg)
+            raise SDNAccountCalError(msg)
+
+        # If there was only one other return value besides rw_status, then just
+        # return that element.  Otherwise return the rest of the return values
+        # as a list.
+        return ret[1] if len(ret) == 2 else ret[1:]
+
+    @property
+    def sdn(self):
+        return self._sdn
+
+    @property
+    def name(self):
+        return self._account_msg.name
+
+    @property
+    def account_msg(self):
+        return self._account_msg
+
+    @property
+    def sdnal_account_msg(self):
+        return RwsdnalYang.SDNAccount.from_dict(
+                self.account_msg.as_dict(),
+                ignore_missing_keys=True,
+                )
+
+    def sdn_account_msg(self, account_dict):
+        self._account_msg = RwSdnYang.SDNAccount.from_dict(account_dict)
+
+    @property
+    def account_type(self):
+        return self._account_msg.account_type
+
+    @property
+    def connection_status(self):
+        return self._status
+
+    def update_from_cfg(self, cfg):
+        self._log.debug("Updating parent SDN Account to %s", cfg)
+
+        raise NotImplementedError("Update SDN account not yet supported")
+
+
+    @asyncio.coroutine
+    def validate_sdn_account_credentials(self, loop):
+        self._log.debug("Validating SDN Account credentials %s", self._account_msg)
+        self._status = RwSdnYang.SDNAccount_ConnectionStatus(
+                status="validating",
+                details="SDN account connection validation in progress"
+                )
+        rwstatus, status = yield from loop.run_in_executor(
+                None,
+                self._sdn.validate_sdn_creds,
+                self.sdnal_account_msg,
+                )
+        if rwstatus == RwTypes.RwStatus.SUCCESS:
+            self._status = RwSdnYang.SDNAccount_ConnectionStatus.from_dict(status.as_dict())
+        else:
+            self._status = RwSdnYang.SDNAccount_ConnectionStatus(
+                    status="failure",
+                    details="Error when calling SDNAL validate SDN creds"
+                    )
+
+        self._log.info("Got SDN account validation response: %s", self._status)
+
+    def start_validate_credentials(self, loop):
+        if self._validate_task is not None:
+            self._validate_task.cancel()
+            self._validate_task = None
+
+        self._validate_task = asyncio.ensure_future(
+                self.validate_sdn_account_credentials(loop),
+                loop=loop
+                )
diff --git a/common/python/rift/mano/sdn/config.py b/common/python/rift/mano/sdn/config.py
new file mode 100644
index 0000000..a9de01b
--- /dev/null
+++ b/common/python/rift/mano/sdn/config.py
@@ -0,0 +1,240 @@
+
+#
+#   Copyright 2017 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+import asyncio
+
+import gi
+gi.require_version('RwDts', '1.0')
+import rift.tasklets
+
+from gi.repository import (
+    RwDts as rwdts,
+    ProtobufC,
+    )
+
+from . import accounts
+
+
+class SDNAccountNotFound(Exception):
+    pass
+
+
+class SDNAccountError(Exception):
+    pass
+
+
+def get_add_delete_update_cfgs(dts_member_reg, xact, key_name):
+    # Unforunately, it is currently difficult to figure out what has exactly
+    # changed in this xact without Pbdelta support (RIFT-4916)
+    # As a workaround, we can fetch the pre and post xact elements and
+    # perform a comparison to figure out adds/deletes/updates
+    xact_cfgs = list(dts_member_reg.get_xact_elements(xact))
+    curr_cfgs = list(dts_member_reg.elements)
+
+    xact_key_map = {getattr(cfg, key_name): cfg for cfg in xact_cfgs}
+    curr_key_map = {getattr(cfg, key_name): cfg for cfg in curr_cfgs}
+
+    # Find Adds
+    added_keys = set(xact_key_map) - set(curr_key_map)
+    added_cfgs = [xact_key_map[key] for key in added_keys]
+
+    # Find Deletes
+    deleted_keys = set(curr_key_map) - set(xact_key_map)
+    deleted_cfgs = [curr_key_map[key] for key in deleted_keys]
+
+    # Find Updates
+    updated_keys = set(curr_key_map) & set(xact_key_map)
+    updated_cfgs = [xact_key_map[key] for key in updated_keys if xact_key_map[key] != curr_key_map[key]]
+
+    return added_cfgs, deleted_cfgs, updated_cfgs
+
+
+class SDNAccountConfigCallbacks(object):
+    def __init__(self,
+                 on_add_apply=None, on_add_prepare=None,
+                 on_delete_apply=None, on_delete_prepare=None):
+
+        @asyncio.coroutine
+        def prepare_noop(*args, **kwargs):
+            pass
+
+        def apply_noop(*args, **kwargs):
+            pass
+
+        self.on_add_apply = on_add_apply
+        self.on_add_prepare = on_add_prepare
+        self.on_delete_apply = on_delete_apply
+        self.on_delete_prepare = on_delete_prepare
+
+        for f in ('on_add_apply', 'on_delete_apply'):
+            ref = getattr(self, f)
+            if ref is None:
+                setattr(self, f, apply_noop)
+                continue
+
+            if asyncio.iscoroutinefunction(ref):
+                raise ValueError('%s cannot be a coroutine' % (f,))
+
+        for f in ('on_add_prepare', 'on_delete_prepare'):
+            ref = getattr(self, f)
+            if ref is None:
+                setattr(self, f, prepare_noop)
+                continue
+
+            if not asyncio.iscoroutinefunction(ref):
+                raise ValueError("%s must be a coroutine" % f)
+
+
+class SDNAccountConfigSubscriber(object):
+    XPATH = "C,/rw-sdn:sdn/rw-sdn:account"
+
+    def __init__(self, dts, log, rwlog_hdl, sdn_callbacks, acctstore):
+        self._dts = dts
+        self._log = log
+        self._rwlog_hdl = rwlog_hdl
+        self._reg = None
+
+        self.accounts = acctstore
+
+        self._sdn_callbacks = sdn_callbacks
+
+    def add_account(self, account_msg):
+        self._log.info("adding sdn account: {}".format(account_msg))
+
+        account = accounts.SDNAccount(self._log, self._rwlog_hdl, account_msg)
+        self.accounts[account.name] = account
+
+        self._sdn_callbacks.on_add_apply(account)
+
+    def delete_account(self, account_name):
+        self._log.info("deleting sdn account: {}".format(account_name))
+        del self.accounts[account_name]
+
+        self._sdn_callbacks.on_delete_apply(account_name)
+
+    def update_account(self, account_msg):
+        """ Update an existing sdn account
+
+        In order to simplify update, turn an update into a delete followed by
+        an add.  The drawback to this approach is that we will not support
+        updates of an "in-use" sdn account, but this seems like a
+        reasonable trade-off.
+
+
+        Arguments:
+            account_msg - The sdn account config message
+        """
+        self._log.info("updating sdn account: {}".format(account_msg))
+
+        self.delete_account(account_msg.name)
+        self.add_account(account_msg)
+
+    def register(self):
+        @asyncio.coroutine
+        def apply_config(dts, acg, xact, action, _):
+            self._log.debug("Got sdn account apply config (xact: %s) (action: %s)", xact, action)
+
+            if xact.xact is None:
+                if action == rwdts.AppconfAction.INSTALL:
+                    curr_cfg = self._reg.elements
+                    for cfg in curr_cfg:
+                        self._log.debug("SDN account being re-added after restart.")
+                        if not cfg.has_field('account_type'):
+                            raise SDNAccountError("New SDN account must contain account_type field.")
+                        self.add_account(cfg)
+                else:
+                    # When RIFT first comes up, an INSTALL is called with the current config
+                    # Since confd doesn't actally persist data this never has any data so
+                    # skip this for now.
+                    self._log.debug("No xact handle.  Skipping apply config")
+
+                return
+
+            add_cfgs, delete_cfgs, update_cfgs = get_add_delete_update_cfgs(
+                    dts_member_reg=self._reg,
+                    xact=xact,
+                    key_name="name",
+                    )
+
+            # Handle Deletes
+            for cfg in delete_cfgs:
+                self.delete_account(cfg.name)
+
+            # Handle Adds
+            for cfg in add_cfgs:
+                self.add_account(cfg)
+
+            # Handle Updates
+            for cfg in update_cfgs:
+                self.update_account(cfg)
+
+        @asyncio.coroutine
+        def on_prepare(dts, acg, xact, xact_info, ks_path, msg, scratch):
+            """ Prepare callback from DTS for SDN Account """
+
+            action = xact_info.query_action
+            self._log.debug("SDN account on_prepare config received (action: %s): %s",
+                            xact_info.query_action, msg)
+
+            if action in [rwdts.QueryAction.CREATE, rwdts.QueryAction.UPDATE]:
+                if msg.name in self.accounts:
+                    self._log.debug("SDN account already exists. Invoking update request")
+
+                    # Since updates are handled by a delete followed by an add, invoke the
+                    # delete prepare callbacks to give clients an opportunity to reject.
+                    yield from self._sdn_callbacks.on_delete_prepare(msg.name)
+
+                else:
+                    self._log.debug("SDN account does not already exist. Invoking on_prepare add request")
+                    if not msg.has_field('account_type'):
+                        raise SDNAccountError("New sdn account must contain account_type field.")
+
+                    account = accounts.SDNAccount(self._log, self._rwlog_hdl, msg)
+                    yield from self._sdn_callbacks.on_add_prepare(account)
+
+            elif action == rwdts.QueryAction.DELETE:
+                # Check if the entire SDN account got deleted
+                fref = ProtobufC.FieldReference.alloc()
+                fref.goto_whole_message(msg.to_pbcm())
+                if fref.is_field_deleted():
+                    yield from self._sdn_callbacks.on_delete_prepare(msg.name)
+
+                else:
+                    self._log.error("Deleting individual fields for SDN account not supported")
+                    xact_info.respond_xpath(rwdts.XactRspCode.NACK)
+                    return
+
+            else:
+                self._log.error("Action (%s) NOT SUPPORTED", action)
+                xact_info.respond_xpath(rwdts.XactRspCode.NACK)
+
+            xact_info.respond_xpath(rwdts.XactRspCode.ACK)
+
+        self._log.debug("Registering for SDN Account config using xpath: %s",
+                        SDNAccountConfigSubscriber.XPATH,
+                        )
+
+        acg_handler = rift.tasklets.AppConfGroup.Handler(
+                        on_apply=apply_config,
+                        )
+
+        with self._dts.appconf_group_create(acg_handler) as acg:
+            self._reg = acg.register(
+                    xpath=SDNAccountConfigSubscriber.XPATH,
+                    flags=rwdts.Flag.SUBSCRIBER | rwdts.Flag.DELTA_READY | rwdts.Flag.CACHE,
+                    on_prepare=on_prepare,
+                    )
diff --git a/common/python/rift/mano/sdn/operdata.py b/common/python/rift/mano/sdn/operdata.py
new file mode 100644
index 0000000..b29f100
--- /dev/null
+++ b/common/python/rift/mano/sdn/operdata.py
@@ -0,0 +1,128 @@
+
+#
+#   Copyright 2017 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+import asyncio
+import rift.tasklets
+
+from gi.repository import(
+        RwSdnYang,
+        RwDts as rwdts,
+        )
+
+
+class SDNAccountNotFound(Exception):
+    pass
+
+
+class SDNAccountDtsOperdataHandler(object):
+    def __init__(self, dts, log, loop):
+        self._dts = dts
+        self._log = log
+        self._loop = loop
+
+        self.sdn_accounts = {}
+
+    def add_sdn_account(self, account):
+        self.sdn_accounts[account.name] = account
+        account.start_validate_credentials(self._loop)
+
+    def delete_sdn_account(self, account_name):
+        del self.sdn_accounts[account_name]
+
+    def get_saved_sdn_accounts(self, sdn_account_name):
+        ''' Get SDN Account corresponding to passed name, or all saved accounts if name is None'''
+        saved_sdn_accounts = []
+
+        if sdn_account_name is None or sdn_account_name == "":
+            sdn_accounts = list(self.sdn_accounts.values())
+            saved_sdn_accounts.extend(sdn_accounts)
+        elif sdn_account_name in self.sdn_accounts:
+            account = self.sdn_accounts[sdn_account_name]
+            saved_sdn_accounts.append(account)
+        else:
+            errstr = "SDN account {} does not exist".format(sdn_account_name)
+            raise KeyError(errstr)
+
+        return saved_sdn_accounts
+
+    def _register_show_status(self):
+        def get_xpath(sdn_name=None):
+            return "D,/rw-sdn:sdn/account{}/connection-status".format(
+                    "[name='%s']" % sdn_name if sdn_name is not None else ''
+                    )
+
+        @asyncio.coroutine
+        def on_prepare(xact_info, action, ks_path, msg):
+            self._log.debug("Got show SDN connection status request: %s", ks_path.create_string())
+            path_entry = RwSdnYang.SDNAccount.schema().keyspec_to_entry(ks_path)
+            sdn_account_name = path_entry.key00.name
+
+            try:
+                saved_accounts = self.get_saved_sdn_accounts(sdn_account_name)
+                for account in saved_accounts:
+                    connection_status = account.connection_status
+                    self._log.debug("Responding to SDN connection status request: %s", connection_status)
+                    xact_info.respond_xpath(
+                            rwdts.XactRspCode.MORE,
+                            xpath=get_xpath(account.name),
+                            msg=account.connection_status,
+                            )
+            except KeyError as e:
+                self._log.warning(str(e))
+                xact_info.respond_xpath(rwdts.XactRspCode.NA)
+                return
+
+            xact_info.respond_xpath(rwdts.XactRspCode.ACK)
+
+        yield from self._dts.register(
+                xpath=get_xpath(),
+                handler=rift.tasklets.DTS.RegistrationHandler(
+                    on_prepare=on_prepare),
+                flags=rwdts.Flag.PUBLISHER,
+                )
+
+    def _register_validate_rpc(self):
+        def get_xpath():
+            return "/rw-sdn:update-sdn-status"
+
+        @asyncio.coroutine
+        def on_prepare(xact_info, action, ks_path, msg):
+            if not msg.has_field("sdn_account"):
+                raise SDNAccountNotFound("SDN account name not provided")
+
+            sdn_account_name = msg.sdn_account
+            try:
+                account = self.sdn_accounts[sdn_account_name]
+            except KeyError:
+                raise SDNAccountNotFound("SDN account name %s not found" % sdn_account_name)
+
+            account.start_validate_credentials(self._loop)
+
+            xact_info.respond_xpath(rwdts.XactRspCode.ACK)
+
+        yield from self._dts.register(
+                xpath=get_xpath(),
+                handler=rift.tasklets.DTS.RegistrationHandler(
+                    on_prepare=on_prepare
+                    ),
+                flags=rwdts.Flag.PUBLISHER,
+                )
+
+    @asyncio.coroutine
+    def register(self):
+        yield from self._register_show_status()
+        yield from self._register_validate_rpc()
