diff --git a/src/security/v2/trust-anchor-group.cpp b/src/security/v2/trust-anchor-group.cpp
index 24f5b9e..6d702ab 100644
--- a/src/security/v2/trust-anchor-group.cpp
+++ b/src/security/v2/trust-anchor-group.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2013-2017 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
@@ -96,6 +96,8 @@
     BOOST_THROW_EXCEPTION(std::runtime_error("Refresh period for the dynamic group must be positive"));
   }
 
+  NDN_LOG_TRACE("Create dynamic trust anchor group " << id << " for file/dir " << path
+                << " with refresh time " << refreshPeriod);
   refresh();
 }
 
diff --git a/src/security/v2/validation-policy-config.cpp b/src/security/v2/validation-policy-config.cpp
new file mode 100644
index 0000000..ba87a23
--- /dev/null
+++ b/src/security/v2/validation-policy-config.cpp
@@ -0,0 +1,314 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "validation-policy-config.hpp"
+#include "validator.hpp"
+#include "../../util/io.hpp"
+
+#include <boost/algorithm/string.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/property_tree/info_parser.hpp>
+
+namespace ndn {
+namespace security {
+namespace v2 {
+namespace validator_config {
+
+ValidationPolicyConfig::ValidationPolicyConfig()
+  : m_shouldBypass(false)
+  , m_isConfigured(false)
+{
+}
+
+void
+ValidationPolicyConfig::load(const std::string& filename)
+{
+  std::ifstream inputFile;
+  inputFile.open(filename.c_str());
+  if (!inputFile.good() || !inputFile.is_open()) {
+    std::string msg = "Failed to read configuration file: ";
+    msg += filename;
+    BOOST_THROW_EXCEPTION(Error(msg));
+  }
+  load(inputFile, filename);
+  inputFile.close();
+}
+
+void
+ValidationPolicyConfig::load(const std::string& input, const std::string& filename)
+{
+  std::istringstream inputStream(input);
+  load(inputStream, filename);
+}
+
+void
+ValidationPolicyConfig::load(std::istream& input, const std::string& filename)
+{
+  ConfigSection tree;
+  try {
+    boost::property_tree::read_info(input, tree);
+  }
+  catch (const boost::property_tree::info_parser_error& error) {
+    std::stringstream msg;
+    msg << "Failed to parse configuration file";
+    msg << " " << filename;
+    msg << " " << error.message() << " line " << error.line();
+    BOOST_THROW_EXCEPTION(Error(msg.str()));
+  }
+
+  load(tree, filename);
+}
+
+void
+ValidationPolicyConfig::load(const ConfigSection& configSection,
+                             const std::string& filename)
+{
+  if (m_isConfigured) {
+    BOOST_THROW_EXCEPTION(std::logic_error("ValidationPolicyConfig can be configured only once"));
+  }
+  m_isConfigured = true;
+
+  BOOST_ASSERT(!filename.empty());
+
+  if (configSection.begin() == configSection.end()) {
+    std::string msg = "Error processing configuration file";
+    msg += ": ";
+    msg += filename;
+    msg += " no data";
+    BOOST_THROW_EXCEPTION(Error(msg));
+  }
+
+  for (const auto& subSection : configSection) {
+    const std::string& sectionName = subSection.first;
+    const ConfigSection& section = subSection.second;
+
+    if (boost::iequals(sectionName, "rule")) {
+      auto rule = Rule::create(section, filename);
+      if (rule->getPktType() == tlv::Data) {
+        m_dataRules.push_back(std::move(rule));
+      }
+      else if (rule->getPktType() == tlv::Interest) {
+        m_interestRules.push_back(std::move(rule));
+      }
+    }
+    else if (boost::iequals(sectionName, "trust-anchor")) {
+      processConfigTrustAnchor(section, filename);
+    }
+    else {
+      std::string msg = "Error processing configuration file";
+      msg += " ";
+      msg += filename;
+      msg += " unrecognized section: " + sectionName;
+      BOOST_THROW_EXCEPTION(Error(msg));
+    }
+  }
+}
+
+void
+ValidationPolicyConfig::processConfigTrustAnchor(const ConfigSection& configSection, const std::string& filename)
+{
+  using namespace boost::filesystem;
+
+  ConfigSection::const_iterator propertyIt = configSection.begin();
+
+  // Get trust-anchor.type
+  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type")) {
+    BOOST_THROW_EXCEPTION(Error("Expecting <trust-anchor.type>"));
+  }
+
+  std::string type = propertyIt->second.data();
+  propertyIt++;
+
+  if (boost::iequals(type, "file")) {
+    // Get trust-anchor.file
+    if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "file-name")) {
+      BOOST_THROW_EXCEPTION(Error("Expecting <trust-anchor.file-name>"));
+    }
+
+    std::string file = propertyIt->second.data();
+    propertyIt++;
+
+    time::nanoseconds refresh = getRefreshPeriod(propertyIt, configSection.end());
+    if (propertyIt != configSection.end()) {
+      BOOST_THROW_EXCEPTION(Error("Expect the end of trust-anchor!"));
+    }
+
+    m_validator->loadAnchor(filename, absolute(file, path(filename).parent_path()).string(),
+                            refresh, false);
+    return;
+  }
+  else if (boost::iequals(type, "base64")) {
+    // Get trust-anchor.base64-string
+    if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "base64-string"))
+      BOOST_THROW_EXCEPTION(Error("Expecting <trust-anchor.base64-string>"));
+
+    std::stringstream ss(propertyIt->second.data());
+    propertyIt++;
+
+    // Check other stuff
+    if (propertyIt != configSection.end())
+      BOOST_THROW_EXCEPTION(Error("Expecting the end of trust-anchor"));
+
+    auto idCert = io::load<Certificate>(ss);
+    if (idCert != nullptr) {
+      m_validator->loadAnchor("", std::move(*idCert));
+    }
+    else {
+      BOOST_THROW_EXCEPTION(Error("Cannot decode certificate from base64-string"));
+    }
+
+    return;
+  }
+  else if (boost::iequals(type, "dir")) {
+    if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "dir"))
+      BOOST_THROW_EXCEPTION(Error("Expect <trust-anchor.dir>"));
+
+    std::string dirString(propertyIt->second.data());
+    propertyIt++;
+
+    time::nanoseconds refresh = getRefreshPeriod(propertyIt, configSection.end());
+    if (propertyIt != configSection.end()) {
+      BOOST_THROW_EXCEPTION(Error("Expecting the end of trust-anchor"));
+    }
+
+    path dirPath = absolute(dirString, path(filename).parent_path());
+    m_validator->loadAnchor(dirString, dirPath.string(), refresh, true);
+    return;
+  }
+  else if (boost::iequals(type, "any")) {
+    m_shouldBypass = true;
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Unsupported trust-anchor.type: " + type));
+  }
+}
+
+time::nanoseconds
+ValidationPolicyConfig::getRefreshPeriod(ConfigSection::const_iterator& it,
+                                         const ConfigSection::const_iterator& end)
+{
+  time::nanoseconds refresh = time::nanoseconds::max();
+  if (it == end) {
+    return refresh;
+  }
+
+  if (!boost::iequals(it->first, "refresh")) {
+    BOOST_THROW_EXCEPTION(Error("Expecting <trust-anchor.refresh>"));
+  }
+
+  std::string inputString = it->second.data();
+  ++it;
+
+  char unit = inputString[inputString.size() - 1];
+  std::string refreshString = inputString.substr(0, inputString.size() - 1);
+
+  uint32_t refreshPeriod = 0;
+
+  try {
+    refreshPeriod = boost::lexical_cast<uint32_t>(refreshString);
+  }
+  catch (const boost::bad_lexical_cast&) {
+    BOOST_THROW_EXCEPTION(Error("Bad number: " + refreshString));
+  }
+
+  if (refreshPeriod == 0) {
+    return getDefaultRefreshPeriod();
+  }
+
+  switch (unit) {
+    case 'h':
+      return time::duration_cast<time::nanoseconds>(time::hours(refreshPeriod));
+    case 'm':
+      return time::duration_cast<time::nanoseconds>(time::minutes(refreshPeriod));
+    case 's':
+      return time::duration_cast<time::nanoseconds>(time::seconds(refreshPeriod));
+    default:
+      BOOST_THROW_EXCEPTION(Error(std::string("Wrong time unit: ") + unit));
+  }
+}
+
+time::nanoseconds
+ValidationPolicyConfig::getDefaultRefreshPeriod()
+{
+  return time::duration_cast<time::nanoseconds>(time::seconds(3600));
+}
+
+void
+ValidationPolicyConfig::checkPolicy(const Data& data, const shared_ptr<ValidationState>& state,
+                                    const ValidationContinuation& continueValidation)
+{
+  BOOST_ASSERT_MSG(!hasInnerPolicy(), "ValidationPolicyConfig must be a terminal inner policy");
+
+  if (m_shouldBypass) {
+    return continueValidation(nullptr, state);
+  }
+
+  Name klName = getKeyLocatorName(data, *state);
+  if (!state->getOutcome()) { // already failed
+    return;
+  }
+
+  for (const auto& rule : m_dataRules) {
+    if (rule->match(tlv::Data, data.getName())) {
+      if (rule->check(tlv::Data, data.getName(), klName, state)) {
+        return continueValidation(make_shared<CertificateRequest>(Interest(klName)), state);
+      }
+      // rule->check calls state->fail(...) if the check fails
+      return;
+    }
+  }
+
+  return state->fail({ValidationError::POLICY_ERROR, "No rule matched for data `" + data.getName().toUri() + "`"});
+}
+
+void
+ValidationPolicyConfig::checkPolicy(const Interest& interest, const shared_ptr<ValidationState>& state,
+                                    const ValidationContinuation& continueValidation)
+{
+  BOOST_ASSERT_MSG(!hasInnerPolicy(), "ValidationPolicyConfig must be a terminal inner policy");
+
+  if (m_shouldBypass) {
+    return continueValidation(nullptr, state);
+  }
+
+  Name klName = getKeyLocatorName(interest, *state);
+  if (!state->getOutcome()) { // already failed
+    return;
+  }
+
+  for (const auto& rule : m_interestRules) {
+    if (rule->match(tlv::Interest, interest.getName())) {
+      if (rule->check(tlv::Interest, interest.getName(), klName, state)) {
+        return continueValidation(make_shared<CertificateRequest>(Interest(klName)), state);
+      }
+      // rule->check calls state->fail(...) if the check fails
+      return;
+    }
+  }
+
+  return state->fail({ValidationError::POLICY_ERROR, "No rule matched for interest `" + interest.getName().toUri() + "`"});
+}
+
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
diff --git a/src/security/v2/validation-policy-config.hpp b/src/security/v2/validation-policy-config.hpp
new file mode 100644
index 0000000..7690cc1
--- /dev/null
+++ b/src/security/v2/validation-policy-config.hpp
@@ -0,0 +1,99 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#ifndef NDN_SECURITY_V2_VALIDATION_POLICY_CONFIG_HPP
+#define NDN_SECURITY_V2_VALIDATION_POLICY_CONFIG_HPP
+
+#include "validation-policy.hpp"
+#include "validator-config/rule.hpp"
+#include "validator-config/common.hpp"
+
+namespace ndn {
+namespace security {
+namespace v2 {
+namespace validator_config {
+
+/**
+ * @brief The validator which can be set up via a configuration file.
+ *
+ * @note For command Interest validation, this policy must be combined with
+ *       @p ValidationPolicyCommandInterest, in order to guard against replay attacks.
+ * @note This policy does not support inner policies (a sole policy or a terminal inner policy)
+ * @sa https://named-data.net/doc/ndn-cxx/current/tutorials/security-validator-config.html
+ */
+class ValidationPolicyConfig : public ValidationPolicy
+{
+public:
+  ValidationPolicyConfig();
+
+  void
+  load(const std::string& filename);
+
+  void
+  load(const std::string& input, const std::string& filename);
+
+  void
+  load(std::istream& input, const std::string& filename);
+
+  void
+  load(const ConfigSection& configSection, const std::string& filename);
+
+protected:
+  void
+  checkPolicy(const Data& data, const shared_ptr<ValidationState>& state,
+              const ValidationContinuation& continueValidation) override;
+
+  void
+  checkPolicy(const Interest& interest, const shared_ptr<ValidationState>& state,
+              const ValidationContinuation& continueValidation) override;
+
+private:
+  void
+  processConfigTrustAnchor(const ConfigSection& section, const std::string& filename);
+
+  time::nanoseconds
+  getRefreshPeriod(ConfigSection::const_iterator& it, const ConfigSection::const_iterator& end);
+
+  time::nanoseconds
+  getDefaultRefreshPeriod();
+
+NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  /** @brief whether to always bypass validation
+   *
+   *  This is set to true when 'any' is specified as a trust anchor.
+   *  It causes all packets to bypass validation.
+   */
+  bool m_shouldBypass;
+  bool m_isConfigured;
+
+  std::vector<unique_ptr<Rule>> m_dataRules;
+  std::vector<unique_ptr<Rule>> m_interestRules;
+};
+
+} // namespace validator_config
+
+using validator_config::ValidationPolicyConfig;
+
+} // namespace v2
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_V2_VALIDATION_POLICY_CONFIG_HPP
diff --git a/src/security/v2/validation-policy.hpp b/src/security/v2/validation-policy.hpp
index 351ffed..d7a261b 100644
--- a/src/security/v2/validation-policy.hpp
+++ b/src/security/v2/validation-policy.hpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2013-2017 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
@@ -65,6 +65,20 @@
   void
   setInnerPolicy(unique_ptr<ValidationPolicy> innerPolicy);
 
+  /**
+   * @brief Check if inner policy is set
+   */
+  bool
+  hasInnerPolicy() const
+  {
+    return m_innerPolicy != nullptr;
+  }
+
+  /**
+   * @brief Return the inner policy
+   *
+   * If the inner policy was not set, behavior is undefined.
+   */
   ValidationPolicy&
   getInnerPolicy();
 
diff --git a/src/security/v2/validator-config/checker.cpp b/src/security/v2/validator-config/checker.cpp
new file mode 100644
index 0000000..47415af
--- /dev/null
+++ b/src/security/v2/validator-config/checker.cpp
@@ -0,0 +1,334 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "checker.hpp"
+#include "security/v2/validation-state.hpp"
+#include "security/verification-helpers.hpp"
+#include "security/pib/key.hpp"
+#include "util/logger.hpp"
+
+#include <boost/algorithm/string.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+namespace security {
+namespace v2 {
+namespace validator_config {
+
+bool
+Checker::check(uint32_t pktType, const Name& pktName, const Name& klName, const shared_ptr<ValidationState>& state)
+{
+  BOOST_ASSERT(pktType == tlv::Interest || pktType == tlv::Data);
+
+  if (pktType == tlv::Interest) {
+    if (pktName.size() < signed_interest::MIN_SIZE)
+      return false;
+
+    return checkNames(pktName.getPrefix(-signed_interest::MIN_SIZE), klName, state);
+  }
+  else {
+    return checkNames(pktName, klName, state);
+  }
+}
+
+NameRelationChecker::NameRelationChecker(const Name& name, const NameRelation& relation)
+  : m_name(name)
+  , m_relation(relation)
+{
+}
+
+bool
+NameRelationChecker::checkNames(const Name& pktName, const Name& klName, const shared_ptr<ValidationState>& state)
+{
+  // pktName not used in this check
+  Name identity = extractIdentityFromKeyName(klName);
+  bool result = checkNameRelation(m_relation, m_name, identity);
+  if (!result) {
+    std::ostringstream os;
+    os << "KeyLocator check failed: name relation " << m_name << " " << m_relation
+       << " for packet " << pktName << " is invalid"
+       << " (KeyLocator=" << klName << ", identity=" << identity << ")";
+    state->fail({ValidationError::POLICY_ERROR, os.str()});
+  }
+  return result;
+}
+
+RegexChecker::RegexChecker(const Regex& regex)
+  : m_regex(regex)
+{
+}
+
+bool
+RegexChecker::checkNames(const Name& pktName, const Name& klName, const shared_ptr<ValidationState>& state)
+{
+  // pktName not used in this check
+  Name identity = extractIdentityFromKeyName(klName);
+  bool result = m_regex.match(identity);
+  if (!result) {
+    std::ostringstream os;
+    os << "KeyLocator check failed: regex " << m_regex << " for packet " << pktName << " is invalid"
+       << " (KeyLocator=" << klName << ", identity=" << identity << ")";
+    state->fail({ValidationError::POLICY_ERROR, os.str()});
+  }
+
+  return result;
+}
+
+HyperRelationChecker::HyperRelationChecker(const std::string& pktNameExpr, const std::string pktNameExpand,
+                                           const std::string& klNameExpr, const std::string klNameExpand,
+                                           const NameRelation& hyperRelation)
+  : m_hyperPRegex(pktNameExpr, pktNameExpand)
+  , m_hyperKRegex(klNameExpr, klNameExpand)
+  , m_hyperRelation(hyperRelation)
+{
+}
+
+bool
+HyperRelationChecker::checkNames(const Name& pktName, const Name& klName, const shared_ptr<ValidationState>& state)
+{
+  if (!m_hyperPRegex.match(pktName) || !m_hyperKRegex.match(klName)) {
+    std::ostringstream os;
+    os << "Packet " << pktName << " (" << "KeyLocator=" << klName << ") does not match "
+       << "the hyper relation rule pkt=" << m_hyperPRegex << ", key=" << m_hyperKRegex;
+    state->fail({ValidationError::POLICY_ERROR, os.str()});
+    return false;
+  }
+
+  bool result = checkNameRelation(m_hyperRelation, m_hyperKRegex.expand(), m_hyperPRegex.expand());
+  if (!result) {
+    std::ostringstream os;
+    os << "KeyLocator check failed: hyper relation " << m_hyperRelation
+       << " pkt=" << m_hyperPRegex << ", key=" << m_hyperKRegex
+       << " of packet " << pktName << " (KeyLocator=" << klName << ") is invalid";
+    state->fail({ValidationError::POLICY_ERROR, os.str()});
+  }
+  return result;
+}
+
+unique_ptr<Checker>
+Checker::create(const ConfigSection& configSection, const std::string& configFilename)
+{
+  auto propertyIt = configSection.begin();
+
+  // Get checker.type
+  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type")) {
+    BOOST_THROW_EXCEPTION(Error("Expect <checker.type>"));
+  }
+
+  std::string type = propertyIt->second.data();
+
+  if (boost::iequals(type, "customized")) {
+    return createCustomizedChecker(configSection, configFilename);
+  }
+  else if (boost::iequals(type, "hierarchical")) {
+    return createHierarchicalChecker(configSection, configFilename);
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Unsupported checker type: " + type));
+  }
+}
+
+unique_ptr<Checker>
+Checker::createCustomizedChecker(const ConfigSection& configSection,
+                                        const std::string& configFilename)
+{
+  auto propertyIt = configSection.begin();
+  propertyIt++;
+
+  // TODO implement restrictions based on signature type (outside this checker)
+
+  if (propertyIt != configSection.end() && boost::iequals(propertyIt->first, "sig-type")) {
+    // ignore sig-type
+    propertyIt++;
+  }
+
+  // Get checker.key-locator
+  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "key-locator")) {
+    BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator>"));
+  }
+
+  auto checker = createKeyLocatorChecker(propertyIt->second, configFilename);
+  propertyIt++;
+
+  if (propertyIt != configSection.end()) {
+    BOOST_THROW_EXCEPTION(Error("Expect the end of checker"));
+  }
+
+  return checker;
+}
+
+unique_ptr<Checker>
+Checker::createHierarchicalChecker(const ConfigSection& configSection,
+                                          const std::string& configFilename)
+{
+  auto propertyIt = configSection.begin();
+  propertyIt++;
+
+  // TODO implement restrictions based on signature type (outside this checker)
+
+  if (propertyIt != configSection.end() && boost::iequals(propertyIt->first, "sig-type")) {
+    // ignore sig-type
+    propertyIt++;
+  }
+
+  if (propertyIt != configSection.end()) {
+    BOOST_THROW_EXCEPTION(Error("Expect the end of checker"));
+  }
+
+  return make_unique<HyperRelationChecker>("^(<>*)$",        "\\1",
+                                           "^(<>*)<KEY><>$", "\\1",
+                                           NameRelation::IS_PREFIX_OF);
+}
+
+///
+
+unique_ptr<Checker>
+Checker::createKeyLocatorChecker(const ConfigSection& configSection, const std::string& configFilename)
+{
+  auto propertyIt = configSection.begin();
+
+  // Get checker.key-locator.type
+  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type"))
+    BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator.type>"));
+
+  std::string type = propertyIt->second.data();
+
+  if (boost::iequals(type, "name"))
+    return createKeyLocatorNameChecker(configSection, configFilename);
+  else
+    BOOST_THROW_EXCEPTION(Error("Unsupported checker.key-locator.type: " + type));
+}
+
+unique_ptr<Checker>
+Checker::createKeyLocatorNameChecker(const ConfigSection& configSection, const std::string& configFilename)
+{
+  auto propertyIt = configSection.begin();
+  propertyIt++;
+
+  if (propertyIt == configSection.end())
+    BOOST_THROW_EXCEPTION(Error("Expect more checker.key-locator properties"));
+
+  if (boost::iequals(propertyIt->first, "name")) {
+    Name name;
+    try {
+      name = Name(propertyIt->second.data());
+    }
+    catch (const Name::Error& e) {
+      BOOST_THROW_EXCEPTION(Error("Invalid checker.key-locator.name: " + propertyIt->second.data()));
+    }
+    propertyIt++;
+
+    if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "relation")) {
+      BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator.relation>"));
+    }
+
+    std::string relationString = propertyIt->second.data();
+    propertyIt++;
+
+    NameRelation relation = getNameRelationFromString(relationString);
+
+    if (propertyIt != configSection.end()) {
+      BOOST_THROW_EXCEPTION(Error("Expect the end of checker.key-locator"));
+    }
+    return make_unique<NameRelationChecker>(name, relation);
+  }
+  else if (boost::iequals(propertyIt->first, "regex")) {
+    std::string regexString = propertyIt->second.data();
+    propertyIt++;
+
+    if (propertyIt != configSection.end()) {
+      BOOST_THROW_EXCEPTION(Error("Expect the end of checker.key-locator"));
+    }
+
+    try {
+      return make_unique<RegexChecker>(regexString);
+    }
+    catch (const Regex::Error& e) {
+      BOOST_THROW_EXCEPTION(Error("Invalid checker.key-locator.regex: " + regexString));
+    }
+  }
+  else if (boost::iequals(propertyIt->first, "hyper-relation")) {
+    const ConfigSection& hSection = propertyIt->second;
+
+    ConfigSection::const_iterator hPropertyIt = hSection.begin();
+
+    // Get k-regex
+    if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "k-regex")) {
+      BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator.hyper-relation.k-regex>"));
+    }
+
+    std::string kRegex = hPropertyIt->second.data();
+    hPropertyIt++;
+
+    // Get k-expand
+    if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "k-expand")) {
+      BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator.hyper-relation.k-expand>"));
+    }
+
+    std::string kExpand = hPropertyIt->second.data();
+    hPropertyIt++;
+
+    // Get h-relation
+    if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "h-relation")) {
+      BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator.hyper-relation.h-relation>"));
+    }
+
+    std::string hRelation = hPropertyIt->second.data();
+    hPropertyIt++;
+
+    // Get p-regex
+    if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "p-regex")) {
+      BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator.hyper-relation.p-regex>"));
+    }
+
+    std::string pRegex = hPropertyIt->second.data();
+    hPropertyIt++;
+
+    // Get p-expand
+    if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "p-expand")) {
+      BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator.hyper-relation.p-expand>"));
+    }
+
+    std::string pExpand = hPropertyIt->second.data();
+    hPropertyIt++;
+
+    if (hPropertyIt != hSection.end()) {
+      BOOST_THROW_EXCEPTION(Error("Expect the end of checker.key-locator.hyper-relation"));
+    }
+
+    NameRelation relation = getNameRelationFromString(hRelation);
+    try {
+      return make_unique<HyperRelationChecker>(pRegex, pExpand, kRegex, kExpand, relation);
+    }
+    catch (const Regex::Error& e) {
+      BOOST_THROW_EXCEPTION(Error("Invalid regex for key-locator.hyper-relation"));
+    }
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Unsupported checker.key-locator"));
+  }
+}
+
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
diff --git a/src/security/v2/validator-config/checker.hpp b/src/security/v2/validator-config/checker.hpp
new file mode 100644
index 0000000..390dc08
--- /dev/null
+++ b/src/security/v2/validator-config/checker.hpp
@@ -0,0 +1,136 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#ifndef NDN_SECURITY_V2_VALIDATOR_CONFIG_CHECKER_HPP
+#define NDN_SECURITY_V2_VALIDATOR_CONFIG_CHECKER_HPP
+
+#include "common.hpp"
+#include "name-relation.hpp"
+#include "../../../name.hpp"
+#include "../../../util/regex.hpp"
+
+namespace ndn {
+namespace security {
+namespace v2 {
+
+class ValidationState;
+
+namespace validator_config {
+
+class Checker : noncopyable
+{
+public:
+  virtual
+  ~Checker() = default;
+
+  /**
+   * @brief Check if packet name ane KeyLocator satisfy the checker's conditions
+   *
+   * @param pktType tlv::Interest or tlv::Data
+   * @param pktName packet's name
+   * @param klName  KeyLocator's name
+   * @param state Validation state
+   *
+   * @retval false data is immediately invalid. Will call state::fail() with proper code and message.
+   * @retval true  further signature verification is needed.
+   */
+  bool
+  check(uint32_t pktType, const Name& pktName, const Name& klName, const shared_ptr<ValidationState>& state);
+
+  /**
+   * @brief create a checker from configuration section
+   *
+   * @param configSection The section containing the definition of checker.
+   * @param configFilename The configuration file name.
+   * @return a checker created from configuration
+   */
+  static unique_ptr<Checker>
+  create(const ConfigSection& configSection, const std::string& configFilename);
+
+private:
+  static unique_ptr<Checker>
+  createCustomizedChecker(const ConfigSection& configSection, const std::string& configFilename);
+
+  static unique_ptr<Checker>
+  createHierarchicalChecker(const ConfigSection& configSection, const std::string& configFilename);
+
+  static unique_ptr<Checker>
+  createKeyLocatorChecker(const ConfigSection& configSection, const std::string& configFilename);
+
+  static unique_ptr<Checker>
+  createKeyLocatorNameChecker(const ConfigSection& configSection, const std::string& configFilename);
+
+protected:
+  virtual bool
+  checkNames(const Name& pktName, const Name& klName, const shared_ptr<ValidationState>& state) = 0;
+};
+
+class NameRelationChecker : public Checker
+{
+public:
+  NameRelationChecker(const Name& name, const NameRelation& relation);
+
+protected:
+  bool
+  checkNames(const Name& pktName, const Name& klName, const shared_ptr<ValidationState>& state) override;
+
+private:
+  Name m_name;
+  NameRelation m_relation;
+};
+
+class RegexChecker : public Checker
+{
+public:
+  explicit
+  RegexChecker(const Regex& regex);
+
+protected:
+  bool
+  checkNames(const Name& pktName, const Name& klName, const shared_ptr<ValidationState>& state) override;
+
+private:
+  Regex m_regex;
+};
+
+class HyperRelationChecker : public Checker
+{
+public:
+  HyperRelationChecker(const std::string& pktNameExpr, const std::string pktNameExpand,
+                       const std::string& klNameExpr, const std::string klNameExpand,
+                       const NameRelation& hyperRelation);
+
+protected:
+  bool
+  checkNames(const Name& pktName, const Name& klName, const shared_ptr<ValidationState>& state) override;
+
+private:
+  Regex m_hyperPRegex;
+  Regex m_hyperKRegex;
+  NameRelation m_hyperRelation;
+};
+
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_V2_VALIDATOR_CONFIG_CHECKER_HPP
diff --git a/src/security/v2/validator-config/common.hpp b/src/security/v2/validator-config/common.hpp
new file mode 100644
index 0000000..1663e5a
--- /dev/null
+++ b/src/security/v2/validator-config/common.hpp
@@ -0,0 +1,48 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
+ */
+
+#ifndef NDN_SECURITY_V2_VALIDATOR_CONFIG_COMMON_HPP
+#define NDN_SECURITY_V2_VALIDATOR_CONFIG_COMMON_HPP
+
+#include "../../../common.hpp"
+#include <boost/property_tree/ptree.hpp>
+
+namespace ndn {
+namespace security {
+namespace v2 {
+namespace validator_config {
+
+typedef boost::property_tree::ptree ConfigSection;
+
+class Error : public std::runtime_error
+{
+public:
+  using std::runtime_error::runtime_error;
+};
+
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_V2_VALIDATOR_CONFIG_COMMON_HPP
diff --git a/src/security/v2/validator-config/filter.cpp b/src/security/v2/validator-config/filter.cpp
new file mode 100644
index 0000000..baeba1d
--- /dev/null
+++ b/src/security/v2/validator-config/filter.cpp
@@ -0,0 +1,149 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "filter.hpp"
+
+#include "data.hpp"
+#include "interest.hpp"
+#include "util/regex.hpp"
+#include "security/security-common.hpp"
+
+#include <boost/algorithm/string.hpp>
+
+namespace ndn {
+namespace security {
+namespace v2 {
+namespace validator_config {
+
+bool
+Filter::match(uint32_t pktType, const Name& pktName)
+{
+  BOOST_ASSERT(pktType == tlv::Interest || pktType == tlv::Data);
+
+  if (pktType == tlv::Interest) {
+    if (pktName.size() < signed_interest::MIN_SIZE)
+      return false;
+
+    return matchName(pktName.getPrefix(-signed_interest::MIN_SIZE));
+  }
+  else {
+    return matchName(pktName);
+  }
+}
+
+RelationNameFilter::RelationNameFilter(const Name& name, NameRelation relation)
+  : m_name(name)
+  , m_relation(relation)
+{
+}
+
+bool
+RelationNameFilter::matchName(const Name& name)
+{
+  return checkNameRelation(m_relation, m_name, name);
+}
+
+RegexNameFilter::RegexNameFilter(const Regex& regex)
+  : m_regex(regex)
+{
+}
+
+bool
+RegexNameFilter::matchName(const Name& name)
+{
+  return m_regex.match(name);
+}
+
+unique_ptr<Filter>
+Filter::create(const ConfigSection& configSection, const std::string& configFilename)
+{
+  auto propertyIt = configSection.begin();
+
+  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type")) {
+    BOOST_THROW_EXCEPTION(Error("Expect <filter.type>"));
+  }
+
+  std::string type = propertyIt->second.data();
+
+  if (boost::iequals(type, "name"))
+    return createNameFilter(configSection, configFilename);
+  else
+    BOOST_THROW_EXCEPTION(Error("Unsupported filter.type: " + type));
+}
+
+unique_ptr<Filter>
+Filter::createNameFilter(const ConfigSection& configSection, const std::string& configFilename)
+{
+  auto propertyIt = configSection.begin();
+  propertyIt++;
+
+  if (propertyIt == configSection.end()) {
+    BOOST_THROW_EXCEPTION(Error("Expect more properties for filter(name)"));
+  }
+
+  if (boost::iequals(propertyIt->first, "name")) {
+    // Get filter.name
+    Name name;
+    try {
+      name = Name(propertyIt->second.data());
+    }
+    catch (const Name::Error& e) {
+      BOOST_THROW_EXCEPTION(Error("Wrong filter.name: " + propertyIt->second.data()));
+    }
+
+    propertyIt++;
+
+    // Get filter.relation
+    if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "relation")) {
+      BOOST_THROW_EXCEPTION(Error("Expect <filter.relation>"));
+    }
+
+    NameRelation relation = getNameRelationFromString(propertyIt->second.data());
+    propertyIt++;
+
+    if (propertyIt != configSection.end())
+      BOOST_THROW_EXCEPTION(Error("Expect the end of filter"));
+
+    return make_unique<RelationNameFilter>(name, relation);
+  }
+  else if (boost::iequals(propertyIt->first, "regex")) {
+    std::string regexString = propertyIt->second.data();
+    propertyIt++;
+
+    if (propertyIt != configSection.end())
+      BOOST_THROW_EXCEPTION(Error("Expect the end of filter"));
+
+    try {
+      return make_unique<RegexNameFilter>(regexString);
+    }
+    catch (const Regex::Error& e) {
+      BOOST_THROW_EXCEPTION(Error("Wrong filter.regex: " + regexString));
+    }
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Wrong filter(name) properties"));
+  }
+}
+
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
diff --git a/src/security/v2/validator-config/filter.hpp b/src/security/v2/validator-config/filter.hpp
new file mode 100644
index 0000000..cbd5275
--- /dev/null
+++ b/src/security/v2/validator-config/filter.hpp
@@ -0,0 +1,142 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#ifndef NDN_SECURITY_V2_VALIDATOR_CONFIG_FILTER_HPP
+#define NDN_SECURITY_V2_VALIDATOR_CONFIG_FILTER_HPP
+
+#include "common.hpp"
+#include "name-relation.hpp"
+#include "../../../interest.hpp"
+#include "../../../data.hpp"
+#include "../../../util/regex.hpp"
+
+namespace ndn {
+namespace security {
+namespace v2 {
+namespace validator_config {
+
+/**
+ * @brief Filter is one of the classes used by ValidatorConfig.
+ *
+ * The ValidatorConfig class consists of a set of rules.
+ * The Filter class is a part of a rule and is used to match packet.
+ * Matched packets will be checked against the checkers defined in the rule.
+ */
+class Filter : noncopyable
+{
+public:
+  virtual
+  ~Filter() = default;
+
+  bool
+  match(uint32_t pktType, const Name& pktName);
+
+public:
+  /**
+   * @brief Create a filter from the configuration section
+   *
+   * @param configSection The section containing the definition of filter.
+   * @param configFilename The configuration file name.
+   * @return a filter created from configuration
+   */
+  static unique_ptr<Filter>
+  create(const ConfigSection& configSection, const std::string& configFilename);
+
+private:
+  static unique_ptr<Filter>
+  createNameFilter(const ConfigSection& configSection, const std::string& configFilename);
+
+private:
+  virtual bool
+  matchName(const Name& pktName) = 0;
+};
+
+/**
+ * @brief Check that name is in relation to the packet name
+ *
+ * The following configuration
+ * @code
+ * filter
+ * {
+ *   type name
+ *   name /example
+ *   relation is-prefix-of
+ * }
+ * @endcode
+ *
+ * creates
+ * @code
+ * RelationNameFilter("/example", RelationNameFilter::RELATION_IS_PREFIX_OF);
+ * @endcode
+ */
+class RelationNameFilter : public Filter
+{
+public:
+  RelationNameFilter(const Name& name, NameRelation relation);
+
+private:
+  bool
+  matchName(const Name& pktName) override;
+
+private:
+  Name m_name;
+  NameRelation m_relation;
+};
+
+/**
+ * @brief Filter to check that packet name matches the specified regular expression
+ *
+ * The following configuration
+ * @code
+ * filter
+ * {
+ *   type name
+ *   regex ^[^<KEY>]*<KEY><>*<ksk-.*>$
+ * }
+ * @endcode
+ *
+ * creates
+ * @code
+ * RegexNameFilter("^[^<KEY>]*<KEY><>*<ksk-.*>$");
+ * @endcode
+ *
+ * @sa Regex
+ */
+class RegexNameFilter : public Filter
+{
+public:
+  explicit
+  RegexNameFilter(const Regex& regex);
+
+private:
+  bool
+  matchName(const Name& pktName) override;
+
+private:
+  Regex m_regex;
+};
+
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_V2_VALIDATOR_CONFIG_FILTER_HPP
diff --git a/src/security/v2/validator-config/name-relation.cpp b/src/security/v2/validator-config/name-relation.cpp
new file mode 100644
index 0000000..ad65e9a
--- /dev/null
+++ b/src/security/v2/validator-config/name-relation.cpp
@@ -0,0 +1,79 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "name-relation.hpp"
+
+#include <boost/algorithm/string.hpp>
+
+namespace ndn {
+namespace security {
+namespace v2 {
+namespace validator_config {
+
+std::ostream&
+operator<<(std::ostream& os, NameRelation relation)
+{
+  switch (relation)  {
+    case NameRelation::EQUAL:
+      return os << "equal";
+    case NameRelation::IS_PREFIX_OF:
+      return os << "is-prefix-of";
+    case NameRelation::IS_STRICT_PREFIX_OF:
+      return os << "is-strict-prefix-of";
+  }
+  return os;
+}
+
+bool
+checkNameRelation(NameRelation relation, const Name& name1, const Name& name2)
+{
+  switch (relation)  {
+    case NameRelation::EQUAL:
+      return name1 == name2;
+    case NameRelation::IS_PREFIX_OF:
+      return name1.isPrefixOf(name2);
+    case NameRelation::IS_STRICT_PREFIX_OF:
+      return name1.isPrefixOf(name2) && name1.size() < name2.size();
+  }
+  return false;
+}
+
+NameRelation
+getNameRelationFromString(const std::string& relationString)
+{
+  if (boost::iequals(relationString, "equal")) {
+    return NameRelation::EQUAL;
+  }
+  else if (boost::iequals(relationString, "is-prefix-of")) {
+    return NameRelation::IS_PREFIX_OF;
+  }
+  else if (boost::iequals(relationString, "is-strict-prefix-of")) {
+    return NameRelation::IS_STRICT_PREFIX_OF;
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Unsupported relation: " + relationString));
+  }
+}
+
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
diff --git a/src/security/v2/validator-config/name-relation.hpp b/src/security/v2/validator-config/name-relation.hpp
new file mode 100644
index 0000000..5aa0dcf
--- /dev/null
+++ b/src/security/v2/validator-config/name-relation.hpp
@@ -0,0 +1,60 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#ifndef NDN_SECURITY_V2_VALIDATOR_CONFIG_NAME_RELATION_HPP
+#define NDN_SECURITY_V2_VALIDATOR_CONFIG_NAME_RELATION_HPP
+
+#include "common.hpp"
+#include "../../../name.hpp"
+
+namespace ndn {
+namespace security {
+namespace v2 {
+namespace validator_config {
+
+enum class NameRelation {
+  EQUAL,
+  IS_PREFIX_OF,
+  IS_STRICT_PREFIX_OF
+};
+
+std::ostream&
+operator<<(std::ostream& os, NameRelation relation);
+
+/**
+ * @brief check whether @p name1 and @p name2 satisfies @p relation
+ */
+bool
+checkNameRelation(NameRelation relation, const Name& name1, const Name& name2);
+
+/**
+ * @brief convert @p relationString to NameRelation
+ * @throw Error if @p relationString cannot be converted
+ */
+NameRelation
+getNameRelationFromString(const std::string& relationString);
+
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_V2_VALIDATOR_CONFIG_NAME_RELATION_HPP
diff --git a/src/security/v2/validator-config/rule.cpp b/src/security/v2/validator-config/rule.cpp
new file mode 100644
index 0000000..93b8df4
--- /dev/null
+++ b/src/security/v2/validator-config/rule.cpp
@@ -0,0 +1,169 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "rule.hpp"
+#include "util/logger.hpp"
+
+#include <boost/algorithm/string/predicate.hpp>
+
+NDN_LOG_INIT(ndn.security.validator_config.Rule);
+
+namespace ndn {
+namespace security {
+namespace v2 {
+namespace validator_config {
+
+Rule::Rule(const std::string& id, uint32_t pktType)
+  : m_id(id)
+  , m_pktType(pktType)
+{
+}
+
+void
+Rule::addFilter(unique_ptr<Filter> filter)
+{
+  m_filters.push_back(std::move(filter));
+}
+
+void
+Rule::addChecker(unique_ptr<Checker> checker)
+{
+  m_checkers.push_back(std::move(checker));
+}
+
+bool
+Rule::match(uint32_t pktType, const Name& pktName) const
+{
+  NDN_LOG_TRACE("Trying to match " << pktName);
+  if (pktType != m_pktType) {
+    BOOST_THROW_EXCEPTION(Error("Invalid packet type supplied (" +
+                                to_string(pktType) + " != " + to_string(m_pktType) + ")"));
+  }
+
+  if (m_filters.empty()) {
+    return true;
+  }
+
+  bool retval = false;
+  for (const auto& filter : m_filters) {
+    retval |= filter->match(pktType, pktName);
+    if (retval) {
+      break;
+    }
+  }
+  return retval;
+}
+
+bool
+Rule::check(uint32_t pktType, const Name& pktName, const Name& klName, const shared_ptr<ValidationState>& state) const
+{
+  NDN_LOG_TRACE("Trying to check " << pktName << " with keyLocator " << klName);
+
+  if (pktType != m_pktType) {
+    BOOST_THROW_EXCEPTION(Error("Invalid packet type supplied (" +
+                                to_string(pktType) + " != " + to_string(m_pktType) + ")"));
+  }
+
+  bool hasPendingResult = false;
+  for (const auto& checker : m_checkers) {
+    bool result = checker->check(pktType, pktName, klName, state);
+    if (!result) {
+      return result;
+    }
+    hasPendingResult = true;
+  }
+
+  return hasPendingResult;
+}
+
+unique_ptr<Rule>
+Rule::create(const ConfigSection& configSection, const std::string& configFilename)
+{
+  auto propertyIt = configSection.begin();
+
+  // Get rule.id
+  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "id")) {
+    BOOST_THROW_EXCEPTION(Error("Expecting <rule.id>"));
+  }
+
+  std::string ruleId = propertyIt->second.data();
+  propertyIt++;
+
+  // Get rule.for
+  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "for")) {
+    BOOST_THROW_EXCEPTION(Error("Expecting <rule.for> in rule: " + ruleId));
+  }
+
+  std::string usage = propertyIt->second.data();
+  propertyIt++;
+
+  bool isForData = false;
+  if (boost::iequals(usage, "data")) {
+    isForData = true;
+  }
+  else if (boost::iequals(usage, "interest")) {
+    isForData = false;
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Unrecognized <rule.for>: " + usage + " in rule: " + ruleId));
+  }
+
+  auto rule = make_unique<Rule>(ruleId, isForData ? tlv::Data : tlv::Interest);
+
+  // Get rule.filter(s)
+  for (; propertyIt != configSection.end(); propertyIt++) {
+    if (!boost::iequals(propertyIt->first, "filter")) {
+      if (boost::iequals(propertyIt->first, "checker")) {
+        break;
+      }
+      BOOST_THROW_EXCEPTION(Error("Expecting <rule.filter> in rule: " + ruleId));
+    }
+
+    rule->addFilter(Filter::create(propertyIt->second, configFilename));
+  }
+
+  // Get rule.checker(s)
+  bool hasCheckers = false;
+  for (; propertyIt != configSection.end(); propertyIt++) {
+    if (!boost::iequals(propertyIt->first, "checker")) {
+      BOOST_THROW_EXCEPTION(Error("Expecting <rule.checker> in rule: " + ruleId));
+    }
+
+    rule->addChecker(Checker::create(propertyIt->second, configFilename));
+    hasCheckers = true;
+  }
+
+  // Check other stuff
+  if (propertyIt != configSection.end()) {
+    BOOST_THROW_EXCEPTION(Error("Expecting the end of rule: " + ruleId));
+  }
+
+  if (!hasCheckers) {
+    BOOST_THROW_EXCEPTION(Error("No <rule.checker> is specified in rule: " + ruleId));
+  }
+
+  return rule;
+}
+
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
diff --git a/src/security/v2/validator-config/rule.hpp b/src/security/v2/validator-config/rule.hpp
new file mode 100644
index 0000000..66d6d6a
--- /dev/null
+++ b/src/security/v2/validator-config/rule.hpp
@@ -0,0 +1,113 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#ifndef NDN_SECURITY_V2_VALIDATOR_CONFIG_RULE_HPP
+#define NDN_SECURITY_V2_VALIDATOR_CONFIG_RULE_HPP
+
+#include "filter.hpp"
+#include "checker.hpp"
+
+namespace ndn {
+namespace security {
+namespace v2 {
+
+class ValidationState;
+
+namespace validator_config {
+
+class Rule : noncopyable
+{
+public:
+  Rule(const std::string& id, uint32_t pktType);
+
+  const std::string&
+  getId() const
+  {
+    return m_id;
+  }
+
+  uint32_t
+  getPktType() const
+  {
+    return m_pktType;
+  }
+
+  void
+  addFilter(unique_ptr<Filter> filter);
+
+  void
+  addChecker(unique_ptr<Checker> checker);
+
+  /**
+   * @brief check if the packet name matches rule's filter
+   *
+   * If no filters were added, the rule matches everything.
+   *
+   * @param pktType tlv::Interest or tlv::Data
+   * @param pktName packet name, for signed Interests the last two components are not removed
+   * @retval true  If at least one filter matches @p pktName
+   * @retval false If none of the filters match @p pktName
+   *
+   * @throw Error the supplied pktType doesn't match one for which the rule is designed
+   */
+  bool
+  match(uint32_t pktType, const Name& pktName) const;
+
+  /**
+   * @brief check if packet satisfies rule's condition
+   *
+   * @param pktType tlv::Interest or tlv::Data
+   * @param pktName packet name, for signed Interests the last two components are not removed
+   * @param klName KeyLocator name
+   * @param state Validation state
+   *
+   * @retval false packet violates at least one checker. Will call state::fail() with proper code and message.
+   * @retval true  packet satisfies all checkers, further validation is needed
+   *
+   * @throw Error the supplied pktType doesn't match one for which the rule is designed
+   */
+  bool
+  check(uint32_t pktType, const Name& pktName, const Name& klName, const shared_ptr<ValidationState>& state) const;
+
+public:
+  /**
+   * @brief create a rule from configuration section
+   *
+   * @param configSection The section containing the definition of checker.
+   * @param configFilename The configuration file name.
+   * @return a rule created from configuration
+   */
+  static unique_ptr<Rule>
+  create(const ConfigSection& configSection, const std::string& configFilename);
+
+NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  std::string m_id;
+  uint32_t m_pktType;
+  std::vector<unique_ptr<Filter>> m_filters;
+  std::vector<unique_ptr<Checker>> m_checkers;
+};
+
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_V2_VALIDATOR_CONFIG_RULE_HPP
