diff --git a/tools/dnc/dnc.cpp b/tools/dnc/dnc.cpp
index 37c8b229e0ae21e54464e7101145f8b12f927683..88bf61d93ef7821273241edf1d8895e02d7e2b2c 100644
--- a/tools/dnc/dnc.cpp
+++ b/tools/dnc/dnc.cpp
@@ -59,12 +59,14 @@ Dnc::Dnc(const std::filesystem::path& path,
          const std::string& turn_host,
          const std::string& turn_user,
          const std::string& turn_pass,
-         const std::string& turn_realm)
+         const std::string& turn_realm,
+         const bool anonymous)
     : logger(dht::log::getStdLogger())
     , ioContext(std::make_shared<asio::io_context>()),
-    iceFactory(std::make_shared<IceTransportFactory>(logger))
+    iceFactory(std::make_shared<IceTransportFactory>(logger)),
+    certStore(std::make_shared<tls::CertificateStore>(path / "certstore", logger)),
+    trustStore(std::make_shared<tls::TrustStore>(*certStore))
 {
-    auto certStore = std::make_shared<tls::CertificateStore>(path / "certstore", logger);
     ioContextRunner = std::thread([context = ioContext, logger = logger] {
         try {
             auto work = asio::make_work_guard(*context);
@@ -75,6 +77,9 @@ Dnc::Dnc(const std::filesystem::path& path,
         }
     });
 
+    auto ca = identity.second->issuer;
+    trustStore->setCertificateStatus(ca->getId().toString(), tls::TrustStore::PermissionStatus::ALLOWED);
+
     auto config = connectionManagerConfig(path,
                                           identity,
                                           bootstrap,
@@ -90,10 +95,9 @@ Dnc::Dnc(const std::filesystem::path& path,
     connectionManager = std::make_unique<ConnectionManager>(std::move(config));
 
     connectionManager->onDhtConnected(identity.first->getPublicKey());
-    connectionManager->onICERequest([this](const dht::Hash<32>&) { // handle ICE request
-        if (logger)
-            logger->debug("ICE request received");
-        return true;
+    connectionManager->onICERequest([this, identity, anonymous](const DeviceId& deviceId) {
+        auto cert = certStore->getCertificate(deviceId.toString());
+        return trustStore->isAllowed(*cert, anonymous);
     });
 
     std::mutex mtx;
@@ -177,7 +181,7 @@ Dnc::Dnc(const std::filesystem::path& path,
          const std::string& turn_user,
          const std::string& turn_pass,
          const std::string& turn_realm)
-    : Dnc(path, identity, bootstrap,turn_host,turn_user,turn_pass, turn_realm)
+    : Dnc(path, identity, bootstrap,turn_host,turn_user,turn_pass, turn_realm, true)
 {
     std::condition_variable cv;
     auto name = fmt::format("nc://{:s}:{:d}", remote_host, remote_port);
diff --git a/tools/dnc/dnc.h b/tools/dnc/dnc.h
index b9545c151aff6468df3e1f53f3a7e06d833b46b6..77cfe9feeccb92f47863b6507fb7c92869a19025 100644
--- a/tools/dnc/dnc.h
+++ b/tools/dnc/dnc.h
@@ -38,7 +38,8 @@ public:
         const std::string& turn_host,
         const std::string& turn_user,
         const std::string& turn_pass,
-        const std::string& turn_realm);
+        const std::string& turn_realm,
+        const bool anonymous);
     // Build a client
     Dnc(const std::filesystem::path& path,
         dht::crypto::Identity identity,
@@ -46,10 +47,10 @@ public:
         dht::InfoHash peer_id,
         const std::string& remote_host,
         int remote_port,
-        const std::string& turn_host = "",
-        const std::string& turn_user = "",
-        const std::string& turn_pass = "",
-        const std::string& turn_realm = "");
+        const std::string& turn_host,
+        const std::string& turn_user,
+        const std::string& turn_pass,
+        const std::string& turn_realm);
     ~Dnc();
     void run();
 
@@ -60,6 +61,7 @@ private:
     std::shared_ptr<IceTransportFactory> iceFactory;
     std::shared_ptr<asio::io_context> ioContext;
     std::thread ioContextRunner;
+    std::shared_ptr<tls::TrustStore> trustStore;
 
     std::pair<std::string, std::string> parseName(const std::string_view name);
 };
diff --git a/tools/dnc/dnc.yaml b/tools/dnc/dnc.yaml
index 6e092fa3a5a0d869c477c348776476cc78ffafe9..a107615b3493e7e1cf9933db133cda6d5062bcf9 100644
--- a/tools/dnc/dnc.yaml
+++ b/tools/dnc/dnc.yaml
@@ -6,4 +6,5 @@ turn_pass: "ring"
 turn_realm: "ring"
 port: 22
 ip: "127.0.0.1"
-CA: Home/.dhtnet # Change this to the path of the CA directory
+CA: HOME/.dhtnet # Change this to the path of the CA directory
+anonymous: false
\ No newline at end of file
diff --git a/tools/dnc/main.cpp b/tools/dnc/main.cpp
index 0ba8b572ce97b20c08f7d4adbbe81e833715487b..363e05e6d30f4459356b32c67d4e3affe085760b 100644
--- a/tools/dnc/main.cpp
+++ b/tools/dnc/main.cpp
@@ -47,6 +47,7 @@ struct dhtnc_params
     std::string turn_realm {};
     std::string ca {};
     std::string dnc_configuration {};
+    bool anonymous_cnx {false};
 };
 
 static const constexpr struct option long_options[]
@@ -63,6 +64,7 @@ static const constexpr struct option long_options[]
        {"turn_realm", required_argument, nullptr, 'r'},
        {"CA", required_argument, nullptr, 'C'},
        {"dnc_configuration", required_argument, nullptr, 'd'},
+       {"anonymous_cnx", no_argument, nullptr, 'a'},
        {nullptr, 0, nullptr, 0}};
 
 dhtnc_params
@@ -70,7 +72,7 @@ parse_args(int argc, char** argv)
 {
     dhtnc_params params;
     int opt;
-    while ((opt = getopt_long(argc, argv, "hvlw:r:u:t:I:b:p:i:C:d:", long_options, nullptr)) != -1) {
+    while ((opt = getopt_long(argc, argv, "ahvlw:r:u:t:I:b:p:i:C:d:", long_options, nullptr)) != -1) {
         switch (opt) {
         case 'h':
             params.help = true;
@@ -110,6 +112,10 @@ parse_args(int argc, char** argv)
             break;
         case 'd':
             params.dnc_configuration = optarg;
+            break;
+        case 'a':
+            params.anonymous_cnx = true;
+            break;
         default:
             std::cerr << "Invalid option" << std::endl;
             exit(EXIT_FAILURE);
@@ -162,6 +168,9 @@ parse_args(int argc, char** argv)
             if (config["port"] && params.remote_port == 0) {
                 params.remote_port = config["port"].as<int>();
             }
+            if (config["anonymous"] && !params.anonymous_cnx) {
+                params.anonymous_cnx = config["anonymous"].as<bool>();
+            }
         }
     }
     return params;
@@ -202,16 +211,20 @@ main(int argc, char** argv)
                    "  -u, --turn_user       Specify the turn_user option with an argument.\n"
                    "  -w, --turn_pass       Specify the turn_pass option with an argument.\n"
                    "  -r, --turn_realm      Specify the turn_realm option with an argument.\n"
-                   "  -C, --CA              Specify the CA option with an argument.\n");
+                   "  -C, --CA              Specify the CA option with an argument.\n"
+                   "  -d, --dnc_configuration Specify the dnc_configuration option with an argument.\n"
+                   "  -a, --anonymous_cnx   Enable the anonymous mode.\n");
         return EXIT_SUCCESS;
     }
+
     if (params.version) {
         fmt::print("dnc v1.0\n");
         return EXIT_SUCCESS;
     }
+    auto identity = dhtnet::loadIdentity(params.path, params.ca);
+
 
     fmt::print("dnc 1.0\n");
-    auto identity = dhtnet::loadIdentity(params.path, params.ca);
     fmt::print("Loaded identity: {} from {}\n", identity.second->getId(), params.path);
 
     std::unique_ptr<dhtnet::Dnc> dhtnc;
@@ -223,7 +236,8 @@ main(int argc, char** argv)
                                               params.turn_host,
                                               params.turn_user,
                                               params.turn_pass,
-                                              params.turn_realm);
+                                              params.turn_realm,
+                                              params.anonymous_cnx);
     } else {
         dhtnc = std::make_unique<dhtnet::Dnc>(params.path,
                                               identity,
diff --git a/tools/dsh/dsh.cpp b/tools/dsh/dsh.cpp
index ca4e99d2f38ee754114b73ac1d4a3234ae72ed82..4e7507d7e555b02deca73d7fe9a16be6761be73a 100644
--- a/tools/dsh/dsh.cpp
+++ b/tools/dsh/dsh.cpp
@@ -91,13 +91,14 @@ dhtnet::Dsh::Dsh(const std::filesystem::path& path,
                  const std::string& turn_host,
                  const std::string& turn_user,
                  const std::string& turn_pass,
-                 const std::string& turn_realm)
+                 const std::string& turn_realm,
+                 bool anonymous)
     :logger(dht::log::getStdLogger())
     , ioContext(std::make_shared<asio::io_context>()),
-    iceFactory(std::make_shared<IceTransportFactory>(logger))
+    iceFactory(std::make_shared<IceTransportFactory>(logger)),
+    certStore(std::make_shared<tls::CertificateStore>(path / "certstore", logger)),
+    trustStore(std::make_shared<tls::TrustStore>(*certStore))
 {
-    auto certStore = std::make_shared<tls::CertificateStore>(path / "certstore", logger);
-
     ioContext = std::make_shared<asio::io_context>();
     ioContextRunner = std::thread([context = ioContext, logger = logger] {
         try {
@@ -108,6 +109,8 @@ dhtnet::Dsh::Dsh(const std::filesystem::path& path,
                 logger->error("Error in ioContextRunner: {}", ex.what());
         }
     });
+    auto ca = identity.second->issuer;
+    trustStore->setCertificateStatus(ca->getId().toString(), tls::TrustStore::PermissionStatus::ALLOWED);
     // Build a server
     auto config = connectionManagerConfig(path,
                                           identity,
@@ -120,10 +123,8 @@ dhtnet::Dsh::Dsh(const std::filesystem::path& path,
     connectionManager = std::make_unique<ConnectionManager>(std::move(config));
 
     connectionManager->onDhtConnected(identity.first->getPublicKey());
-    connectionManager->onICERequest([this](const dht::Hash<32>&) { // handle ICE request
-        if (logger)
-            logger->debug("ICE request received");
-        return true;
+    connectionManager->onICERequest([this,identity,anonymous](const DeviceId& deviceId ) { // handle ICE request
+        return trustStore->isAllowed(*certStore->getCertificate(deviceId.toString()), anonymous);
     });
 
     std::mutex mtx;
@@ -228,7 +229,7 @@ dhtnet::Dsh::Dsh(const std::filesystem::path& path,
                  const std::string& turn_user,
                  const std::string& turn_pass,
                  const std::string& turn_realm)
-    : Dsh(path, identity, bootstrap, turn_host, turn_user, turn_pass, turn_realm)
+    : Dsh(path, identity, bootstrap, turn_host, turn_user, turn_pass, turn_realm, false)
 {
     // Build a client
     std::condition_variable cv;
diff --git a/tools/dsh/dsh.h b/tools/dsh/dsh.h
index 3bdc93476e65135d065c79539e31e2aa4970edff..dd6a4ea616c9e43e019619ad4986f5d293dedab1 100644
--- a/tools/dsh/dsh.h
+++ b/tools/dsh/dsh.h
@@ -33,7 +33,8 @@ public:
         const std::string& turn_host,
         const std::string& turn_user,
         const std::string& turn_pass,
-        const std::string& turn_realm);
+        const std::string& turn_realm,
+        const bool anonymous);
     // Build a client
     Dsh(const std::filesystem::path& path,
         dht::crypto::Identity identity,
@@ -54,6 +55,8 @@ private:
     std::shared_ptr<dhtnet::IceTransportFactory> iceFactory {nullptr};
     std::shared_ptr<asio::io_context> ioContext;
     std::thread ioContextRunner;
+    std::shared_ptr<tls::TrustStore> trustStore;
+
 };
 
 } // namespace dhtnet
diff --git a/tools/dsh/dsh.yaml b/tools/dsh/dsh.yaml
index 54e13abb7252b4ae0745ddcbbebaf612bc70828d..a023aa3afde6270837bcf3f66976f210be92402e 100644
--- a/tools/dsh/dsh.yaml
+++ b/tools/dsh/dsh.yaml
@@ -6,3 +6,4 @@ turn_pass: "ring"
 turn_realm: "ring"
 binary: "bash"
 CA: HOME/.dhtnet # Change this to the path of the CA directory
+anonymous: false
diff --git a/tools/dsh/main.cpp b/tools/dsh/main.cpp
index 7c5e006a6dbf8cdd2dc01caab4006a65d93f93c9..19ff4e5950e20ef59cb8cddbd69e29b7a863a898 100644
--- a/tools/dsh/main.cpp
+++ b/tools/dsh/main.cpp
@@ -46,6 +46,7 @@ struct dhtsh_params
     std::string turn_pass {};
     std::string turn_realm {};
     std::string dsh_configuration {};
+    bool anonymous_cnx {false};
 };
 
 static const constexpr struct option long_options[]
@@ -61,6 +62,7 @@ static const constexpr struct option long_options[]
        {"turn_pass", required_argument, nullptr, 'w'},
        {"turn_realm", required_argument, nullptr, 'r'},
        {"dsh_configuration", required_argument, nullptr, 'd'},
+       {"anonymous", no_argument, nullptr, 'a'},
        {nullptr, 0, nullptr, 0}};
 
 dhtsh_params
@@ -105,6 +107,10 @@ parse_args(int argc, char** argv)
             break;
         case 'd':
             params.dsh_configuration = optarg;
+            break;
+        case 'a':
+            params.anonymous_cnx = true;
+            break;
         default:
             std::cerr << "Invalid option" << std::endl;
             exit(EXIT_FAILURE);
@@ -154,6 +160,10 @@ parse_args(int argc, char** argv)
             if (config["binary"] && params.binary.empty()) {
                 params.binary = config["binary"].as<std::string>();
             }
+            if (config["anonymous"] && !params.anonymous_cnx) {
+                params.anonymous_cnx = config["anonymous"].as<bool>();
+            }
+
         }
     }
     return params;
@@ -211,14 +221,15 @@ main(int argc, char** argv)
 
     std::unique_ptr<dhtnet::Dsh> dhtsh;
     if (params.listen) {
-        // create dnc instance
+        // create dsh instance
         dhtsh = std::make_unique<dhtnet::Dsh>(params.path,
                                               identity,
                                               params.bootstrap,
                                               params.turn_host,
                                               params.turn_user,
                                               params.turn_pass,
-                                              params.turn_realm);
+                                              params.turn_realm,
+                                              params.anonymous_cnx);
     } else {
         dhtsh = std::make_unique<dhtnet::Dsh>(params.path,
                                               identity,
diff --git a/tools/dvpn/dvpn.cpp b/tools/dvpn/dvpn.cpp
index f0fc8209fd384bfb628223ce190ea59ff8a810b8..b7a0d03e9771839f6e5e10b43bfc61cdefb7b707 100644
--- a/tools/dvpn/dvpn.cpp
+++ b/tools/dvpn/dvpn.cpp
@@ -166,9 +166,10 @@ dhtnet::Dvpn::Dvpn(const std::filesystem::path& path,
                    const std::string& configuration_file)
     : logger(dht::log::getStdLogger())
     , ioContext(std::make_shared<asio::io_context>()),
-    iceFactory(std::make_shared<IceTransportFactory>(logger))
+    iceFactory(std::make_shared<IceTransportFactory>(logger)),
+    certStore(std::make_shared<tls::CertificateStore>(path / "certstore", logger)),
+    trustStore(std::make_shared<tls::TrustStore>(*certStore))
 {
-    auto certStore = std::make_shared<tls::CertificateStore>(path / "certstore", logger);
     ioContextRunner = std::thread([context = ioContext, logger = logger] {
         try {
             auto work = asio::make_work_guard(*context);
@@ -178,6 +179,8 @@ dhtnet::Dvpn::Dvpn(const std::filesystem::path& path,
                 logger->error("Error in ioContextRunner: {}", ex.what());
         }
     });
+    auto ca = identity.second->issuer;
+    trustStore->setCertificateStatus(ca->getId().toString(), tls::TrustStore::PermissionStatus::ALLOWED);
 
     auto config = connectionManagerConfig(path,
                                           identity,
@@ -194,11 +197,7 @@ dhtnet::Dvpn::Dvpn(const std::filesystem::path& path,
     connectionManager = std::make_unique<ConnectionManager>(std::move(config));
 
     connectionManager->onDhtConnected(identity.first->getPublicKey());
-    connectionManager->onICERequest([this](const dht::Hash<32>&) { // handle ICE request
-        if (logger)
-            logger->debug("ICE request received");
-        return true;
-    });
+
 }
 
 dhtnet::DvpnServer::DvpnServer(const std::filesystem::path& path,
@@ -208,7 +207,8 @@ dhtnet::DvpnServer::DvpnServer(const std::filesystem::path& path,
                                const std::string& turn_user,
                                const std::string& turn_pass,
                                const std::string& turn_realm,
-                               const std::string& configuration_file)
+                               const std::string& configuration_file,
+                               bool anonymous)
     : Dvpn(path, identity, bootstrap, turn_host, turn_user, turn_pass, turn_realm, configuration_file)
 {
     std::mutex mtx;
@@ -222,6 +222,9 @@ dhtnet::DvpnServer::DvpnServer(const std::filesystem::path& path,
             return true;
         });
 
+    connectionManager->onICERequest([this, identity, anonymous](const DeviceId& deviceId) {
+       return trustStore->isAllowed(*certStore->getCertificate(deviceId.toString()), anonymous);
+    });
     connectionManager->onConnectionReady([=](const DeviceId&,
                                              const std::string& channel,
                                              std::shared_ptr<ChannelSocket> socket) {
diff --git a/tools/dvpn/dvpn.h b/tools/dvpn/dvpn.h
index 42382aa57fb221e008a3dc0e7a953ed5cf2fd42c..6331907b86b34a2dd195cff9703f4316129f8e69 100644
--- a/tools/dvpn/dvpn.h
+++ b/tools/dvpn/dvpn.h
@@ -66,7 +66,7 @@ public:
     std::shared_ptr<asio::io_context> ioContext;
     std::thread ioContextRunner;
     enum class CommunicationState { METADATA, DATA };
-
+    std::shared_ptr<tls::TrustStore> trustStore;
 };
 
 class DvpnServer : public Dvpn
@@ -80,7 +80,8 @@ public:
                const std::string& turn_user,
                const std::string& turn_pass,
                const std::string& turn_realm,
-               const std::string& configuration_file);
+               const std::string& configuration_file,
+               bool anonymous);
 };
 
 class DvpnClient : public Dvpn
@@ -103,7 +104,6 @@ private:
     int tun_fd;
     char tun_device[IFNAMSIZ] = {0}; // IFNAMSIZ is typically the maximum size for interface names
     std::shared_ptr<asio::posix::stream_descriptor> tun_stream;
-
 };
 
 } // namespace dhtnet
\ No newline at end of file
diff --git a/tools/dvpn/dvpn.yaml b/tools/dvpn/dvpn.yaml
index 20929ecd27f4c3e31f7da5efea58c03c40a6e6b9..7e14842752658645dbefe7b8e10551026bf1fc49 100644
--- a/tools/dvpn/dvpn.yaml
+++ b/tools/dvpn/dvpn.yaml
@@ -4,6 +4,6 @@ turn_host: "turn.jami.net"
 turn_user: "ring"
 turn_pass: "ring"
 turn_realm: "ring"
-configuration_file: "./test_config.yaml"
+configuration_file: "HOME/dhtnet/tools/dvpn/dvpn.yaml" # Change this to the path of the dvpn.yaml file
 CA: HOME/.dhtnet # Change this to the path of the CA directory
-
+anonymous: false
\ No newline at end of file
diff --git a/tools/dvpn/main.cpp b/tools/dvpn/main.cpp
index 97dd0de06d757114be672282f29ac9aaf6bada05..5b1945900da02e2d833854663ac3b9e77ce313f2 100644
--- a/tools/dvpn/main.cpp
+++ b/tools/dvpn/main.cpp
@@ -46,6 +46,7 @@ struct dhtvpn_params
     std::string configuration_file {};
     std::string ca {};
     std::string dvpn_configuration_file {};
+    bool anonymous_cnx {false};
 };
 
 static const constexpr struct option long_options[]
@@ -61,6 +62,7 @@ static const constexpr struct option long_options[]
        {"vpn_configuration_file", required_argument, nullptr, 'c'},
        {"CA", required_argument, nullptr, 'C'},
        {"dvpn_configuration_file", required_argument, nullptr, 'd'},
+       {"anonymous", no_argument, nullptr, 'a'},
        {nullptr, 0, nullptr, 0}};
 
 dhtvpn_params
@@ -106,6 +108,9 @@ parse_args(int argc, char** argv)
         case 'd':
             params.dvpn_configuration_file = optarg;
             break;
+        case 'a':
+            params.anonymous_cnx = true;
+            break;
         default:
             std::cerr << "Invalid option" << std::endl;
             exit(EXIT_FAILURE);
@@ -143,6 +148,9 @@ parse_args(int argc, char** argv)
             if (config["configuration_file"] && params.configuration_file.empty()) {
                 params.configuration_file = config["configuration_file"].as<std::string>();
             }
+            if (config["anonymous"] && !params.anonymous_cnx) {
+                params.anonymous_cnx = config["anonymous"].as<bool>();
+            }
         }
     }
 
@@ -196,6 +204,7 @@ main(int argc, char** argv)
             "  -c, --vpn_configuration_file Specify the vpn_configuration_file path option with an argument.\n"
             "  -C, --CA              Specify the CA path option with an argument.\n"
             "  -d, --dvpn_configuration_file Specify the dvpn_configuration_file path option with an argument.\n"
+            "  -a, --anonymous       Specify the anonymous option with an argument.\n"
             "\n");
         return EXIT_SUCCESS;
     }
@@ -219,7 +228,8 @@ main(int argc, char** argv)
                                                     params.turn_user,
                                                     params.turn_pass,
                                                     params.turn_realm,
-                                                    params.configuration_file);
+                                                    params.configuration_file,
+                                                    params.anonymous_cnx);
     } else {
         dvpn = std::make_unique<dhtnet::DvpnClient>(params.peer_id,
                                                     params.path,