diff --git a/conf/namespaces.yaml.example b/conf/namespaces.yaml.example
--- a/conf/namespaces.yaml.example
+++ b/conf/namespaces.yaml.example
@@ -9,4 +9,4 @@
         - git@bitbucket.org:fedoraqa/task-depcheck.git
         - git@bitbucket.org:fedoraqa/task-upgradepath.git
     pkg:
-        - git://pkgs.fedoraproject.org/tasks/
+        - git://pkgs.fedoraproject.org/rpms-checks/
diff --git a/libtaskotron/directives/resultsdb_directive.py b/libtaskotron/directives/resultsdb_directive.py
--- a/libtaskotron/directives/resultsdb_directive.py
+++ b/libtaskotron/directives/resultsdb_directive.py
@@ -30,7 +30,9 @@
   does not contain this extra field.
 raises: |
   * :class:`.TaskotronDirectiveError`: if ``results`` is not in a valid YAML
-    format, or when  ``item`` or ``type`` are missing in the YAML's result data
+    format, or when  ``item`` or ``type`` are missing in the YAML's result data,
+    or when results are not allowed to be posted into a given namespace, or
+    the namespace does not exist.
   * :class:`resultsdb_api.ResultsDBapiException`: for any errors coming from
     the ResultsDB server
 version_added: 0.4
@@ -84,6 +86,7 @@
 from libtaskotron import buildbot_utils
 from libtaskotron.exceptions import TaskotronDirectiveError, TaskotronValueError
 from libtaskotron.logger import log
+from libtaskotron.ext.fedora import rpm_utils
 
 import resultsdb_api
 
@@ -181,6 +184,54 @@
 
         return os.path.relpath(artifact_path, start=artifactsdir)
 
+    def check_namespace(self, checkname, arg_data):
+        conf_ns = config.load_namespaces_config()
+        repos = None
+
+        # check if the namespace exists
+        for ns in conf_ns['namespaces_safe']:
+            if checkname.startswith(ns+'.'):
+                log.debug('Namespace %s found in the safe namespaces.', ns)
+                return
+        else:
+            for ns, rs in conf_ns['namespaces_whitelist'].iteritems():
+                if checkname.startswith(ns+'.'):
+                    log.debug('Namespace %s found in the namespace whitelist.', ns)
+                    repos = rs
+                    break
+            else:
+                raise TaskotronDirectiveError('Namespace %s does not exist.')
+
+        try:
+            taskdir = os.path.dirname(os.path.abspath(arg_data['task']))
+            gitconfig_filename = os.path.join(taskdir, '.git/config')
+
+            gitconfig = configparser.ConfigParser()
+            gitconfig.read(gitconfig_filename)
+            repo_url = gitconfig['remote "origin"']['url']
+        except TypeError, e:
+            log.exception(e)
+            raise TaskotronDirectiveError("Could not find task's git remote 'origin' url"
+                                          "in %s" % gitconfig_filename)
+
+        try:
+            if not [repo for repo in repos if repo.startswith(repo_url.strip())]:
+                raise TaskotronDirectiveError
+
+            log.debug('Repo %s found in the whitelist', repo_url)
+            # dist-git style tasks
+            # here we need to not only check the root namespace but also second level ns,
+            # e.g. a firefox check can post results into pkg.firefox
+            if checkname.startswith('pkg.'):
+                pkg_name = rpm_utils.rpmformat(arg_data['item'], fmt='n')
+                pkg_ns = 'pkg.%s.' % pkg_name
+                if not checkname.startswith(pkg_ns):
+                    raise TaskotronDirectiveError
+        except TaskotronDirectiveError:
+            raise TaskotronDirectiveError("%s is not allowed to post results into %s "
+                                          "namespace. Not posting results." %
+                                          (arg_data['checkname'], arg_data['namespace']))
+
     def process(self, params, arg_data):
         # checking if reporting is enabled is done after importing yaml which
         # serves as validation of input results
@@ -202,39 +253,18 @@
                      "following would get reported:\n%s" % params['results'])
             return check.export_YAML(check_details)
 
-        # find out if the task is allowed to post results into the namespace
-        conf_ns = config.load_namespaces_config()
-        if (conf.profile == config.ProfileName.PRODUCTION and
-                arg_data['namespace'] not in conf_ns['namespaces_safe']):
-
-            try:
-                taskdir = os.path.dirname(os.path.abspath(arg_data['task']))
-                gitconfig_filename = os.path.join(taskdir, '.git/config')
-
-                gitconfig = configparser.ConfigParser()
-                gitconfig.read(gitconfig_filename)
-                repo_url = gitconfig['remote "origin"']['url']
-            except TypeError, e:
-                log.exception(e)
-                raise TaskotronDirectiveError("Could not find task's git remote 'origin' url in %s"
-                                              % gitconfig_filename)
+        checkname = '%s.%s' % (arg_data['namespace'], arg_data['checkname'])
 
-            try:
-                ns_whitelist = conf_ns['namespaces_whitelist'][arg_data['namespace']]
-                if not [ns for ns in ns_whitelist if ns.startswith(repo_url.strip())]:
-                    raise TaskotronDirectiveError
-            except (KeyError, TaskotronDirectiveError):
-                raise TaskotronDirectiveError("%s is not allowed to post results into %s "
-                                              "namespace. Not posting results." %
-                                              (arg_data['checkname'], arg_data['namespace']))
+        # find out if the task is allowed to post results into the namespace
+        if config.get_config().profile == config.ProfileName.PRODUCTION:
+            self.check_namespace(checkname, arg_data)
 
         # for now, we're creating the resultsdb job at reporting time
         # the job needs to be 'RUNNING' in order to append any results
         job_url, log_url = buildbot_utils.get_urls(arg_data['jobid'],
                                                    self.masterurl,
                                                    self.task_stepname)
 
-        checkname = '%s.%s' % (arg_data['namespace'], arg_data['checkname'])
         job_data = self.create_resultsdb_job(checkname, uuid=arg_data['uuid'])
 
         log.info('Posting %s results to ResultsDB...' % len(check_details))
diff --git a/testing/test_resultsdb_directive.py b/testing/test_resultsdb_directive.py
--- a/testing/test_resultsdb_directive.py
+++ b/testing/test_resultsdb_directive.py
@@ -54,7 +54,8 @@
                 'jobid': 'all/123',
                 'uuid': 'c25237a4-b6b3-11e4-b98a-3c970e018701',
                 'artifactsdir': '/some/directory/',
-                'task': '/taskdir'
+                'task': '/taskdir',
+                'item': 'firefox-45.0.2-1.fc23'
                 }
 
         self.ref_resultdata = {u'id': 1234}
@@ -331,3 +332,48 @@
 
         self.test_rdb.process(self.ref_input, self.ref_arg_data)
         # did not raise, pass
+
+    def test_safe_namespace_multilevel(self, monkeypatch):
+        ref_ns = {'namespaces_safe': ['qa']}
+        monkeypatch.setattr(config, 'load_namespaces_config', lambda: ref_ns)
+        self.ref_arg_data['namespace'] = 'qa.firefox'
+        self.conf.profile = config_defaults.ProfileName.PRODUCTION
+
+        self.test_rdb.process(self.ref_input, self.ref_arg_data)
+        # did not raise, pass
+
+    def test_allowed_namespace_pkg(self, monkeypatch):
+        ref_ns = {'namespaces_safe': [], 'namespaces_whitelist': {'pkg': ['giturl']}}
+        monkeypatch.setattr(config, 'load_namespaces_config', lambda: ref_ns)
+        self.ref_arg_data['namespace'] = 'pkg.firefox'
+        self.conf.profile = config_defaults.ProfileName.PRODUCTION
+
+        self.test_rdb.process(self.ref_input, self.ref_arg_data)
+        # did not raise, pass
+
+    def test_not_allowed_namespace_pkg(self, monkeypatch):
+        ref_ns = {'namespaces_safe': [], 'namespaces_whitelist': {'pkg': ['giturl']}}
+        monkeypatch.setattr(config, 'load_namespaces_config', lambda: ref_ns)
+        self.ref_arg_data['namespace'] = 'pkg.not_firefox'
+        self.conf.profile = config_defaults.ProfileName.PRODUCTION
+
+        with pytest.raises(TaskotronDirectiveError):
+            self.test_rdb.process(self.ref_input, self.ref_arg_data)
+
+    def test_not_allowed_namespace_prefix(self, monkeypatch):
+        ref_ns = {'namespaces_safe': [], 'namespaces_whitelist': {'qa': ['giturl']}}
+        monkeypatch.setattr(config, 'load_namespaces_config', lambda: ref_ns)
+        self.ref_arg_data['namespace'] = 'qa1'
+        self.conf.profile = config_defaults.ProfileName.PRODUCTION
+
+        with pytest.raises(TaskotronDirectiveError):
+            self.test_rdb.process(self.ref_input, self.ref_arg_data)
+
+    def test_namespace_not_exist(self, monkeypatch):
+        ref_ns = {'namespaces_safe': ['scratch'], 'namespaces_whitelist': {'qa': ['giturl']}}
+        monkeypatch.setattr(config, 'load_namespaces_config', lambda: ref_ns)
+        self.ref_arg_data['namespace'] = 'qa1'
+        self.conf.profile = config_defaults.ProfileName.PRODUCTION
+
+        with pytest.raises(TaskotronDirectiveError):
+            self.test_rdb.process(self.ref_input, self.ref_arg_data)

