diff --git a/README.md b/README.md
index 318b3c02117165fd1ac6e24730a209771baf2759..1bb1c2ecf502d0e296ec48237fe70b793b4e2b99 100644
--- a/README.md
+++ b/README.md
@@ -110,6 +110,10 @@ Parameters under `mqtt` section are used for creating paho's `mqtt.Client` and i
 
 See `mqtt_bridge.mqtt_client` for detail.
 
+### mqtt private path
+
+If `mqtt/private_path` parameter is set, leading `~/` in MQTT topic path will be replaced by this value. For example, if `mqtt/pivate_path` is set as "device/001", MQTT path "~/value" will be converted to "device/001/value".
+
 ### selializer and deselializer
 
 `mqtt_bridge` uses `json` as a selializer in default. But you can also configure other selializers. For example, if you want to use messagepack for selialization, add following configuration.
diff --git a/config/demo_params.yaml b/config/demo_params.yaml
index e6fa3de44cf5442213dad2f49b85e9f12c22dfa3..6ac90efdfb394134814e38912dd717ba6193263a 100644
--- a/config/demo_params.yaml
+++ b/config/demo_params.yaml
@@ -5,6 +5,7 @@ mqtt:
     host: localhost
     port: 1883
     keepalive: 60
+  private_path: device/001
 selializer: msgpack:dumps
 deselializer: msgpack:loads
 bridge:
@@ -26,3 +27,12 @@ bridge:
     msg_type: std_msgs.msg:String
     topic_from: echo
     topic_to: /back
+  # private path
+  - factory: mqtt_bridge.bridge:RosToMqttBridge
+    msg_type: std_msgs.msg:String
+    topic_from: /private/echo
+    topic_to: ~/echo
+  - factory: mqtt_bridge.bridge:MqttToRosBridge
+    msg_type: std_msgs.msg:String
+    topic_from: ~/echo
+    topic_to: /private/back
diff --git a/src/mqtt_bridge/app.py b/src/mqtt_bridge/app.py
index ad627a2508a7ee5e1fe8bd76ea1ff10e92a5223f..7f5a1dfa52929a73baae0880701dcad56e233ebc 100644
--- a/src/mqtt_bridge/app.py
+++ b/src/mqtt_bridge/app.py
@@ -6,18 +6,21 @@ import paho.mqtt.client as mqtt
 import rospy
 
 from .bridge import create_bridge
+from .mqtt_client import create_private_path_extractor
 from .util import lookup_object
 
 
-def create_config(mqtt_client, selializer, deselializer):
+def create_config(mqtt_client, selializer, deselializer, mqtt_private_path):
     if isinstance(selializer, basestring):
         selializer = lookup_object(selializer)
     if isinstance(deselializer, basestring):
         deselializer = lookup_object(deselializer)
+    private_path_extractor = create_private_path_extractor(mqtt_private_path)
     def config(binder):
         binder.bind('selializer', selializer)
         binder.bind('deselializer', deselializer)
         binder.bind(mqtt.Client, mqtt_client)
+        binder.bind('mqtt_private_path_extractor', private_path_extractor)
     return config
 
 
@@ -29,6 +32,7 @@ def mqtt_bridge_node():
     params = rospy.get_param("~", {})
     mqtt_params = params.pop("mqtt", {})
     conn_params = mqtt_params.pop("connection")
+    mqtt_private_path = mqtt_params.pop("private_path", "")
     bridge_params = params.get("bridge", [])
 
     # create mqtt client
@@ -42,7 +46,8 @@ def mqtt_bridge_node():
     deselializer = params.get('deselializer', 'json:loads')
 
     # dependency injection
-    config = create_config(mqtt_client, selializer, deselializer)
+    config = create_config(
+        mqtt_client, selializer, deselializer, mqtt_private_path)
     inject.configure(config)
 
     # configure and connect to MQTT broker
diff --git a/src/mqtt_bridge/bridge.py b/src/mqtt_bridge/bridge.py
index e87f2548cc43badadee1b597e50dc2ea0040c5cd..2aa22d9a3fba8f696b18e19c78ed055fea1f08b8 100644
--- a/src/mqtt_bridge/bridge.py
+++ b/src/mqtt_bridge/bridge.py
@@ -46,6 +46,7 @@ class Bridge(object):
     _mqtt_client = inject.attr(mqtt.Client)
     _selialize = inject.attr('selializer')
     _deselialize = inject.attr('deselializer')
+    _extract_private_path = inject.attr('mqtt_private_path_extractor')
 
 
 class RosToMqttBridge(Bridge):
@@ -59,7 +60,7 @@ class RosToMqttBridge(Bridge):
 
     def __init__(self, topic_from, topic_to, msg_type, frequency=None):
         self._topic_from = topic_from
-        self._topic_to = topic_to
+        self._topic_to = self._extract_private_path(topic_to)
         self._last_published = rospy.get_time()
         self._interval = 0 if frequency is None else 1.0 / frequency
         rospy.Subscriber(topic_from, msg_type, self._callback_ros)
@@ -88,7 +89,7 @@ class MqttToRosBridge(Bridge):
 
     def __init__(self, topic_from, topic_to, msg_type, frequency=None,
                  queue_size=10):
-        self._topic_from = topic_from
+        self._topic_from = self._extract_private_path(topic_from)
         self._topic_to = topic_to
         self._msg_type = msg_type
         self._queue_size = queue_size
diff --git a/src/mqtt_bridge/mqtt_client.py b/src/mqtt_bridge/mqtt_client.py
index 3093c0e820580d7827fdb9087cd225c4853c28cf..bf4498a095a82b000db5b7d7e948bef6388a63b8 100644
--- a/src/mqtt_bridge/mqtt_client.py
+++ b/src/mqtt_bridge/mqtt_client.py
@@ -53,4 +53,12 @@ def default_mqtt_client_factory(params):
     return client
 
 
-__all__ = ["default_mqtt_client_factory"]
+def create_private_path_extractor(mqtt_private_path):
+    def extractor(topic_path):
+        if topic_path.startswith('~/'):
+            return '{}/{}'.format(mqtt_private_path, topic_path[2:])
+        return topic_path
+    return extractor
+
+
+__all__ = ['default_mqtt_client_factory', 'create_private_path_extractor']