diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -256,6 +256,7 @@
     'ConpherenceThreadIndexer' => 'applications/conpherence/search/ConpherenceThreadIndexer.php',
     'ConpherenceThreadListView' => 'applications/conpherence/view/ConpherenceThreadListView.php',
     'ConpherenceThreadMailReceiver' => 'applications/conpherence/mail/ConpherenceThreadMailReceiver.php',
+    'ConpherenceThreadMembersPolicyRule' => 'applications/conpherence/policyrule/ConpherenceThreadMembersPolicyRule.php',
     'ConpherenceThreadQuery' => 'applications/conpherence/query/ConpherenceThreadQuery.php',
     'ConpherenceThreadRemarkupRule' => 'applications/conpherence/remarkup/ConpherenceThreadRemarkupRule.php',
     'ConpherenceThreadSearchEngine' => 'applications/conpherence/query/ConpherenceThreadSearchEngine.php',
@@ -3542,6 +3543,7 @@
     'ConpherenceThreadIndexer' => 'PhabricatorSearchDocumentIndexer',
     'ConpherenceThreadListView' => 'AphrontView',
     'ConpherenceThreadMailReceiver' => 'PhabricatorObjectMailReceiver',
+    'ConpherenceThreadMembersPolicyRule' => 'PhabricatorPolicyRule',
     'ConpherenceThreadQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'ConpherenceThreadRemarkupRule' => 'PhabricatorObjectRemarkupRule',
     'ConpherenceThreadSearchEngine' => 'PhabricatorApplicationSearchEngine',
diff --git a/src/applications/conpherence/policyrule/ConpherenceThreadMembersPolicyRule.php b/src/applications/conpherence/policyrule/ConpherenceThreadMembersPolicyRule.php
new file mode 100644
--- /dev/null
+++ b/src/applications/conpherence/policyrule/ConpherenceThreadMembersPolicyRule.php
@@ -0,0 +1,42 @@
+<?php
+
+final class ConpherenceThreadMembersPolicyRule
+  extends PhabricatorPolicyRule {
+
+  public function getObjectPolicyKey() {
+    return 'conpherence.members';
+  }
+
+  public function getObjectPolicyName() {
+    return pht('Thread Members');
+  }
+
+  public function getPolicyExplanation() {
+    return pht('Members of this thread can take this action.');
+  }
+
+  public function getRuleDescription() {
+    return pht('thread members');
+  }
+
+  public function canApplyToObject(PhabricatorPolicyInterface $object) {
+    return ($object instanceof ConpherenceThread);
+  }
+
+  public function applyRule(
+    PhabricatorUser $viewer,
+    $value,
+    PhabricatorPolicyInterface $object) {
+    $viewer_phid = $viewer->getPHID();
+    if (!$viewer_phid) {
+      return false;
+    }
+
+    return (bool)$object->getParticipantIfExists($viewer_phid);
+  }
+
+  public function getValueControlType() {
+    return self::CONTROL_TYPE_NONE;
+  }
+
+}
diff --git a/src/applications/policy/__tests__/PhabricatorPolicyDataTestCase.php b/src/applications/policy/__tests__/PhabricatorPolicyDataTestCase.php
--- a/src/applications/policy/__tests__/PhabricatorPolicyDataTestCase.php
+++ b/src/applications/policy/__tests__/PhabricatorPolicyDataTestCase.php
@@ -150,4 +150,63 @@
     unset($time_b);
   }
 
+  public function testObjectPolicyRuleTaskAuthor() {
+    $author = $this->generateNewTestUser();
+    $viewer = $this->generateNewTestUser();
+
+    $rule = new ManiphestTaskAuthorPolicyRule();
+
+    $task = ManiphestTask::initializeNewTask($author);
+    $task->setViewPolicy($rule->getObjectPolicyFullKey());
+    $task->save();
+
+    $this->assertTrue(
+      PhabricatorPolicyFilter::hasCapability(
+        $author,
+        $task,
+        PhabricatorPolicyCapability::CAN_VIEW));
+
+    $this->assertFalse(
+      PhabricatorPolicyFilter::hasCapability(
+        $viewer,
+        $task,
+        PhabricatorPolicyCapability::CAN_VIEW));
+  }
+
+  public function testObjectPolicyRuleThreadMembers() {
+    $author = $this->generateNewTestUser();
+    $viewer = $this->generateNewTestUser();
+
+    $rule = new ConpherenceThreadMembersPolicyRule();
+
+    $thread = ConpherenceThread::initializeNewRoom($author);
+    $thread->setViewPolicy($rule->getObjectPolicyFullKey());
+    $thread->save();
+
+    $this->assertFalse(
+      PhabricatorPolicyFilter::hasCapability(
+        $author,
+        $thread,
+        PhabricatorPolicyCapability::CAN_VIEW));
+
+    $this->assertFalse(
+      PhabricatorPolicyFilter::hasCapability(
+        $viewer,
+        $thread,
+        PhabricatorPolicyCapability::CAN_VIEW));
+
+    $participant = id(new ConpherenceParticipant())
+      ->setParticipantPHID($viewer->getPHID())
+      ->setConpherencePHID($thread->getPHID());
+
+    $thread->attachParticipants(array($viewer->getPHID() => $participant));
+
+    $this->assertTrue(
+      PhabricatorPolicyFilter::hasCapability(
+        $viewer,
+        $thread,
+        PhabricatorPolicyCapability::CAN_VIEW));
+  }
+
+
 }
diff --git a/src/applications/policy/query/PhabricatorPolicyQuery.php b/src/applications/policy/query/PhabricatorPolicyQuery.php
--- a/src/applications/policy/query/PhabricatorPolicyQuery.php
+++ b/src/applications/policy/query/PhabricatorPolicyQuery.php
@@ -316,7 +316,7 @@
         continue;
       }
 
-      $full_key = self::OBJECT_POLICY_PREFIX.$key;
+      $full_key = $rule->getObjectPolicyFullKey();
       if (isset($results[$full_key])) {
         throw new Exception(
           pht(
diff --git a/src/applications/policy/rule/PhabricatorPolicyRule.php b/src/applications/policy/rule/PhabricatorPolicyRule.php
--- a/src/applications/policy/rule/PhabricatorPolicyRule.php
+++ b/src/applications/policy/rule/PhabricatorPolicyRule.php
@@ -114,6 +114,20 @@
     return null;
   }
 
+  public function getObjectPolicyFullKey() {
+    $key = $this->getObjectPolicyKey();
+
+    if (!$key) {
+      throw new Exception(
+        pht(
+          'This policy rule (of class "%s") does not have an associated '.
+          'object policy key.',
+          get_class($this)));
+    }
+
+    return PhabricatorPolicyQuery::OBJECT_POLICY_PREFIX.$key;
+  }
+
   public function getObjectPolicyName() {
     throw new PhutilMethodNotImplementedException();
   }