diff --git a/apps/segmentrouting/BUCK b/apps/segmentrouting/BUCK
index 5942871..39243fe 100644
--- a/apps/segmentrouting/BUCK
+++ b/apps/segmentrouting/BUCK
@@ -5,6 +5,7 @@
     '//lib:org.apache.karaf.shell.console',
     '//lib:javax.ws.rs-api',
     '//cli:onos-cli',
+    '//core/common:onos-core-common',
     '//core/store/serializers:onos-core-serializers',
     '//incubator/api:onos-incubator-api',
     '//utils/rest:onlab-rest',
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/PortAuthTracker.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/PortAuthTracker.java
new file mode 100644
index 0000000..627ca7d
--- /dev/null
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/PortAuthTracker.java
@@ -0,0 +1,337 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.
+ */
+
+package org.onosproject.segmentrouting;
+
+
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.segmentrouting.config.BlockedPortsConfig;
+import org.onosproject.utils.Comparators;
+import org.slf4j.Logger;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.onosproject.net.DeviceId.deviceId;
+import static org.onosproject.net.PortNumber.portNumber;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Keeps track of ports that have been configured for blocking,
+ * and their current authentication state.
+ */
+public class PortAuthTracker {
+
+    private static final Logger log = getLogger(PortAuthTracker.class);
+
+    private Map<DeviceId, Map<PortNumber, BlockState>> blockedPorts = new HashMap<>();
+    private Map<DeviceId, Map<PortNumber, BlockState>> oldMap;
+
+    @Override
+    public String toString() {
+        return "PortAuthTracker{entries = " + blockedPorts.size() + "}";
+    }
+
+    /**
+     * Changes the state of the given device id / port number pair to the
+     * specified state.
+     *
+     * @param d        device identifier
+     * @param p        port number
+     * @param newState the updated state
+     * @return true, if the state changed from what was previously mapped
+     */
+    private boolean changeStateTo(DeviceId d, PortNumber p, BlockState newState) {
+        Map<PortNumber, BlockState> portMap =
+                blockedPorts.computeIfAbsent(d, k -> new HashMap<>());
+        BlockState oldState =
+                portMap.computeIfAbsent(p, k -> BlockState.UNCHECKED);
+        portMap.put(p, newState);
+        return (oldState != newState);
+    }
+
+    /**
+     * Radius has authorized the supplicant at this connect point. If
+     * we are tracking this port, clear the blocking flow and mark the
+     * port as authorized.
+     *
+     * @param connectPoint supplicant connect point
+     */
+    void radiusAuthorize(ConnectPoint connectPoint) {
+        DeviceId d = connectPoint.deviceId();
+        PortNumber p = connectPoint.port();
+        if (configured(d, p)) {
+            clearBlockingFlow(d, p);
+            markAsAuthenticated(d, p);
+        }
+    }
+
+    /**
+     * Supplicant at specified connect point has logged off Radius. If
+     * we are tracking this port, install a blocking flow and mark the
+     * port as blocked.
+     *
+     * @param connectPoint supplicant connect point
+     */
+    void radiusLogoff(ConnectPoint connectPoint) {
+        DeviceId d = connectPoint.deviceId();
+        PortNumber p = connectPoint.port();
+        if (configured(d, p)) {
+            installBlockingFlow(d, p);
+            markAsBlocked(d, p);
+        }
+    }
+
+    /**
+     * Marks the specified device/port as blocked.
+     *
+     * @param d device id
+     * @param p port number
+     * @return true if the state changed (was not already blocked)
+     */
+    private boolean markAsBlocked(DeviceId d, PortNumber p) {
+        return changeStateTo(d, p, BlockState.BLOCKED);
+    }
+
+    /**
+     * Marks the specified device/port as authenticated.
+     *
+     * @param d device id
+     * @param p port number
+     * @return true if the state changed (was not already authenticated)
+     */
+    private boolean markAsAuthenticated(DeviceId d, PortNumber p) {
+        return changeStateTo(d, p, BlockState.AUTHENTICATED);
+    }
+
+    /**
+     * Returns true if the given device/port are configured for blocking.
+     *
+     * @param d device id
+     * @param p port number
+     * @return true if this device/port configured for blocking
+     */
+    private boolean configured(DeviceId d, PortNumber p) {
+        Map<PortNumber, BlockState> portMap = blockedPorts.get(d);
+        return portMap != null && portMap.get(p) != null;
+    }
+
+    private BlockState whatState(DeviceId d, PortNumber p,
+                                 Map<DeviceId, Map<PortNumber, BlockState>> m) {
+        Map<PortNumber, BlockState> portMap = m.get(d);
+        if (portMap == null) {
+            return BlockState.UNCHECKED;
+        }
+        BlockState state = portMap.get(p);
+        if (state == null) {
+            return BlockState.UNCHECKED;
+        }
+        return state;
+    }
+
+    /**
+     * Returns the current state of the given device/port.
+     *
+     * @param d device id
+     * @param p port number
+     * @return current block-state
+     */
+    BlockState currentState(DeviceId d, PortNumber p) {
+        return whatState(d, p, blockedPorts);
+    }
+
+    /**
+     * Returns the current state of the given connect point.
+     *
+     * @param cp connect point
+     * @return current block-state
+     */
+
+    BlockState currentState(ConnectPoint cp) {
+        return whatState(cp.deviceId(), cp.port(), blockedPorts);
+    }
+
+    /**
+     * Returns the number of entries being tracked.
+     *
+     * @return the number of tracked entries
+     */
+    int entryCount() {
+        int count = 0;
+        for (Map<PortNumber, BlockState> m : blockedPorts.values()) {
+            count += m.size();
+        }
+        return count;
+    }
+
+    /**
+     * Returns the previously recorded state of the given device/port.
+     *
+     * @param d device id
+     * @param p port number
+     * @return previous block-state
+     */
+    private BlockState oldState(DeviceId d, PortNumber p) {
+        return whatState(d, p, oldMap);
+    }
+
+    private void configurePort(DeviceId d, PortNumber p) {
+        boolean alreadyAuthenticated =
+                oldState(d, p) == BlockState.AUTHENTICATED;
+
+        if (alreadyAuthenticated) {
+            clearBlockingFlow(d, p);
+            markAsAuthenticated(d, p);
+        } else {
+            installBlockingFlow(d, p);
+            markAsBlocked(d, p);
+        }
+        log.info("Configuring port {}/{} as {}", d, p,
+                 alreadyAuthenticated ? "AUTHENTICATED" : "BLOCKED");
+    }
+
+    private boolean notInMap(DeviceId deviceId, PortNumber portNumber) {
+        Map<PortNumber, BlockState> m = blockedPorts.get(deviceId);
+        return m == null || m.get(portNumber) == null;
+    }
+
+    private void logPortsNoLongerBlocked() {
+        for (Map.Entry<DeviceId, Map<PortNumber, BlockState>> entry :
+                oldMap.entrySet()) {
+            DeviceId d = entry.getKey();
+            Map<PortNumber, BlockState> portMap = entry.getValue();
+
+            for (PortNumber p : portMap.keySet()) {
+                if (notInMap(d, p)) {
+                    clearBlockingFlow(d, p);
+                    log.info("De-configuring port {}/{} (UNCHECKED)", d, p);
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Reconfigures the port tracker using the supplied configuration.
+     *
+     * @param cfg the new configuration
+     */
+    void configurePortBlocking(BlockedPortsConfig cfg) {
+        // remember the old map; prepare a new map
+        oldMap = blockedPorts;
+        blockedPorts = new HashMap<>();
+
+        // for each configured device, add configured ports to map
+        for (String devId : cfg.deviceIds()) {
+            cfg.portIterator(devId)
+                    .forEachRemaining(p -> configurePort(deviceId(devId),
+                                                         portNumber(p)));
+        }
+
+        // have we de-configured any ports?
+        logPortsNoLongerBlocked();
+
+        // allow old map to be garbage collected
+        oldMap = null;
+    }
+
+    private List<PortAuthState> reportPortsAuthState() {
+        List<PortAuthState> result = new ArrayList<>();
+
+        for (Map.Entry<DeviceId, Map<PortNumber, BlockState>> entry :
+                blockedPorts.entrySet()) {
+            DeviceId d = entry.getKey();
+            Map<PortNumber, BlockState> portMap = entry.getValue();
+
+            for (PortNumber p : portMap.keySet()) {
+                result.add(new PortAuthState(d, p, portMap.get(p)));
+            }
+        }
+        Collections.sort(result);
+        return result;
+    }
+
+    /**
+     * Installs a "blocking" flow for device/port specified.
+     *
+     * @param d device id
+     * @param p port number
+     */
+    void installBlockingFlow(DeviceId d, PortNumber p) {
+        log.debug("Installing Blocking Flow at {}/{}", d, p);
+        // TODO: invoke SegmentRoutingService.block(...) appropriately
+        log.info("TODO >> Installing Blocking Flow at {}/{}", d, p);
+    }
+
+    /**
+     * Removes the "blocking" flow from device/port specified.
+     *
+     * @param d device id
+     * @param p port number
+     */
+    void clearBlockingFlow(DeviceId d, PortNumber p) {
+        log.debug("Clearing Blocking Flow from {}/{}", d, p);
+        // TODO: invoke SegmentRoutingService.block(...) appropriately
+        log.info("TODO >> Clearing Blocking Flow from {}/{}", d, p);
+    }
+
+
+    /**
+     * Designates the state of a given port. One of:
+     * <ul>
+     * <li> UNCHECKED: not configured for blocking </li>
+     * <li> BLOCKED: configured for blocking, and not yet authenticated </li>
+     * <li> AUTHENTICATED: configured for blocking, but authenticated </li>
+     * </ul>
+     */
+    public enum BlockState {
+        UNCHECKED,
+        BLOCKED,
+        AUTHENTICATED
+    }
+
+    /**
+     * A simple DTO binding of device identifier, port number, and block state.
+     */
+    public static final class PortAuthState implements Comparable<PortAuthState> {
+        private final DeviceId d;
+        private final PortNumber p;
+        private final BlockState s;
+
+        private PortAuthState(DeviceId d, PortNumber p, BlockState s) {
+            this.d = d;
+            this.p = p;
+            this.s = s;
+        }
+
+        @Override
+        public String toString() {
+            return String.valueOf(d) + "/" + p + " -- " + s;
+        }
+
+        @Override
+        public int compareTo(PortAuthState o) {
+            // NOTE: only compare against "deviceid/port"
+            int result = Comparators.ELEMENT_ID_COMPARATOR.compare(d, o.d);
+            return (result != 0) ? result : Long.signum(p.toLong() - o.p.toLong());
+        }
+    }
+}
diff --git a/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/AugmentedPortAuthTracker.java b/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/AugmentedPortAuthTracker.java
new file mode 100644
index 0000000..cc214e3
--- /dev/null
+++ b/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/AugmentedPortAuthTracker.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.
+ */
+
+package org.onosproject.segmentrouting;
+
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An augmented implementation of {@link PortAuthTracker}, so that we can
+ * instrument its behavior for unit test assertions.
+ */
+class AugmentedPortAuthTracker extends PortAuthTracker {
+
+    // instrument blocking flow activity, so we can see when we get hits
+    final List<ConnectPoint> installed = new ArrayList<>();
+    final List<ConnectPoint> cleared = new ArrayList<>();
+
+
+    void resetMetrics() {
+        installed.clear();
+        cleared.clear();
+    }
+
+    @Override
+    void installBlockingFlow(DeviceId d, PortNumber p) {
+        super.installBlockingFlow(d, p);
+        installed.add(new ConnectPoint(d, p));
+    }
+
+    @Override
+    void clearBlockingFlow(DeviceId d, PortNumber p) {
+        super.clearBlockingFlow(d, p);
+        cleared.add(new ConnectPoint(d, p));
+    }
+}
diff --git a/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/PortAuthTrackerTest.java b/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/PortAuthTrackerTest.java
new file mode 100644
index 0000000..6ab4bad
--- /dev/null
+++ b/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/PortAuthTrackerTest.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.
+ */
+
+package org.onosproject.segmentrouting;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.segmentrouting.PortAuthTracker.BlockState;
+import org.onosproject.segmentrouting.config.BlockedPortsConfig;
+import org.onosproject.segmentrouting.config.BlockedPortsConfigTest;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.net.ConnectPoint.deviceConnectPoint;
+import static org.onosproject.net.DeviceId.deviceId;
+import static org.onosproject.net.PortNumber.portNumber;
+import static org.onosproject.segmentrouting.PortAuthTracker.BlockState.AUTHENTICATED;
+import static org.onosproject.segmentrouting.PortAuthTracker.BlockState.BLOCKED;
+import static org.onosproject.segmentrouting.PortAuthTracker.BlockState.UNCHECKED;
+
+/**
+ * Unit Tests for {@link PortAuthTracker}.
+ */
+public class PortAuthTrackerTest {
+    private static final ApplicationId APP_ID = new DefaultApplicationId(1, "foo");
+    private static final String KEY = "blocked";
+    private static final ObjectMapper MAPPER = new ObjectMapper();
+    private static final String PATH_CFG = "/blocked-ports.json";
+    private static final String PATH_CFG_ALT = "/blocked-ports-alt.json";
+
+    private static final String DEV1 = "of:0000000000000001";
+    private static final String DEV3 = "of:0000000000000003";
+    private static final String DEV4 = "of:0000000000000004";
+
+    private BlockedPortsConfig cfg;
+    private AugmentedPortAuthTracker tracker;
+
+    private void print(String s) {
+        System.out.println(s);
+    }
+
+    private void print(Object o) {
+        print(o.toString());
+    }
+
+    private void print(String fmt, Object... params) {
+        print(String.format(fmt, params));
+    }
+
+    private void title(String s) {
+        print("=== %s ===", s);
+    }
+
+    private BlockedPortsConfig makeConfig(String path) throws IOException {
+        InputStream blockedPortsJson = BlockedPortsConfigTest.class
+                .getResourceAsStream(path);
+        JsonNode node = MAPPER.readTree(blockedPortsJson);
+        BlockedPortsConfig cfg = new BlockedPortsConfig();
+        cfg.init(APP_ID, KEY, node, MAPPER, null);
+        return cfg;
+    }
+
+    ConnectPoint cp(String devId, int port) {
+        return ConnectPoint.deviceConnectPoint(devId + "/" + port);
+    }
+
+    @Before
+    public void setUp() throws IOException {
+        cfg = makeConfig(PATH_CFG);
+        tracker = new AugmentedPortAuthTracker();
+    }
+
+    private void verifyPortState(String devId, int first, BlockState... states) {
+        DeviceId dev = deviceId(devId);
+        int last = first + states.length;
+        int pn = first;
+        int i = 0;
+        while (pn < last) {
+            PortNumber pnum = portNumber(pn);
+            BlockState actual = tracker.currentState(dev, pnum);
+            print("%s/%s [%s]  --> %s", devId, pn, states[i], actual);
+            assertEquals("oops: " + devId + "/" + pn + "~" + actual,
+                         states[i], actual);
+            pn++;
+            i++;
+        }
+    }
+
+    @Test
+    public void basic() {
+        title("basic");
+        print(tracker);
+        print(cfg);
+
+        assertEquals("wrong entry count", 0, tracker.entryCount());
+
+        // let's assume that the net config just got loaded..
+        tracker.configurePortBlocking(cfg);
+        assertEquals("wrong entry count", 13, tracker.entryCount());
+
+        verifyPortState(DEV1, 1, BLOCKED, BLOCKED, BLOCKED, BLOCKED, UNCHECKED);
+        verifyPortState(DEV1, 6, UNCHECKED, BLOCKED, BLOCKED, BLOCKED, UNCHECKED);
+
+        verifyPortState(DEV3, 1, UNCHECKED, UNCHECKED, UNCHECKED);
+        verifyPortState(DEV3, 6, UNCHECKED, BLOCKED, BLOCKED, BLOCKED, UNCHECKED);
+
+        verifyPortState(DEV4, 1, BLOCKED, UNCHECKED, UNCHECKED, UNCHECKED, BLOCKED);
+    }
+
+    @Test
+    public void logonLogoff() {
+        title("logonLogoff");
+
+        tracker.configurePortBlocking(cfg);
+        assertEquals("wrong entry count", 13, tracker.entryCount());
+        verifyPortState(DEV1, 1, BLOCKED, BLOCKED, BLOCKED);
+
+        ConnectPoint cp = deviceConnectPoint(DEV1 + "/2");
+        tracker.radiusAuthorize(cp);
+        print("");
+        verifyPortState(DEV1, 1, BLOCKED, AUTHENTICATED, BLOCKED);
+
+        tracker.radiusLogoff(cp);
+        print("");
+        verifyPortState(DEV1, 1, BLOCKED, BLOCKED, BLOCKED);
+    }
+
+    @Test
+    public void installedFlows() {
+        title("installed flows");
+
+        assertEquals(0, tracker.installed.size());
+        tracker.configurePortBlocking(cfg);
+        assertEquals(13, tracker.installed.size());
+
+        assertTrue(tracker.installed.contains(cp(DEV1, 1)));
+        assertTrue(tracker.installed.contains(cp(DEV3, 7)));
+        assertTrue(tracker.installed.contains(cp(DEV4, 5)));
+    }
+
+    @Test
+    public void flowsLogonLogoff() {
+        title("flows logon logoff");
+
+        tracker.configurePortBlocking(cfg);
+
+        // let's pick a connect point from the configuration
+        ConnectPoint cp = cp(DEV4, 5);
+
+        assertTrue(tracker.installed.contains(cp));
+        assertEquals(0, tracker.cleared.size());
+
+        tracker.resetMetrics();
+        tracker.radiusAuthorize(cp);
+        // verify we requested the blocking flow to be cleared
+        assertTrue(tracker.cleared.contains(cp));
+
+        tracker.resetMetrics();
+        assertEquals(0, tracker.installed.size());
+        tracker.radiusLogoff(cp);
+        // verify we requested the blocking flow to be reinstated
+        assertTrue(tracker.installed.contains(cp));
+    }
+
+    @Test
+    public void uncheckedPortIgnored() {
+        title("unchecked port ignored");
+
+        tracker.configurePortBlocking(cfg);
+        tracker.resetMetrics();
+
+        // let's pick a connect point NOT in the configuration
+        ConnectPoint cp = cp(DEV4, 2);
+        assertEquals(BlockState.UNCHECKED, tracker.currentState(cp));
+
+        assertEquals(0, tracker.installed.size());
+        assertEquals(0, tracker.cleared.size());
+        tracker.radiusAuthorize(cp);
+        assertEquals(0, tracker.installed.size());
+        assertEquals(0, tracker.cleared.size());
+        tracker.radiusLogoff(cp);
+        assertEquals(0, tracker.installed.size());
+        assertEquals(0, tracker.cleared.size());
+    }
+
+    @Test
+    public void reconfiguration() throws IOException {
+        title("reconfiguration");
+
+        /* see 'blocked-ports.json' and 'blocked-ports-alt.json'
+
+          cfg:  "1": ["1-4", "7-9"],
+                "3": ["7-9"],
+                "4": ["1", "5", "9"]
+
+          alt:  "1": ["1-9"],
+                "3": ["7"],
+                "4": ["1"]
+         */
+        tracker.configurePortBlocking(cfg);
+        // dev1: ports 5 and 6 are NOT configured in the original CFG
+        assertFalse(tracker.installed.contains(cp(DEV1, 5)));
+        assertFalse(tracker.installed.contains(cp(DEV1, 6)));
+
+        tracker.resetMetrics();
+        assertEquals(0, tracker.installed.size());
+        assertEquals(0, tracker.cleared.size());
+
+        BlockedPortsConfig alt = makeConfig(PATH_CFG_ALT);
+        tracker.configurePortBlocking(alt);
+
+        // dev1: ports 5 and 6 ARE configured in the alternate CFG
+        assertTrue(tracker.installed.contains(cp(DEV1, 5)));
+        assertTrue(tracker.installed.contains(cp(DEV1, 6)));
+
+        // also, check for the ports that were decommissioned
+        assertTrue(tracker.cleared.contains(cp(DEV3, 8)));
+        assertTrue(tracker.cleared.contains(cp(DEV3, 9)));
+        assertTrue(tracker.cleared.contains(cp(DEV4, 5)));
+        assertTrue(tracker.cleared.contains(cp(DEV4, 9)));
+    }
+}
diff --git a/apps/segmentrouting/src/test/resources/blocked-ports-alt.json b/apps/segmentrouting/src/test/resources/blocked-ports-alt.json
new file mode 100644
index 0000000..3d8749e
--- /dev/null
+++ b/apps/segmentrouting/src/test/resources/blocked-ports-alt.json
@@ -0,0 +1,5 @@
+{
+  "of:0000000000000001": ["1-9"],
+  "of:0000000000000003": ["7"],
+  "of:0000000000000004": ["1"]
+}
