diff --git a/workbench_moderation.api.php b/workbench_moderation.api.php
index 4b2afc6..ba9897a 100644
--- a/workbench_moderation.api.php
+++ b/workbench_moderation.api.php
@@ -28,6 +28,30 @@ function hook_workbench_moderation_access_alter(&$access, $op, $node) {
 }
 
 /**
+ * Allows modules to alter moderation access for a particular state.
+ *
+ * @param &$access
+ *   A boolean access declaration. Passed by reference.
+ * @param $op
+ *   The operation being performed. May be 'view', 'update', 'delete',
+ *   'view revisions' or 'moderate'.
+ * @param $node
+ *   The node being acted upon.
+ * @param $state
+ *  The state change requested.
+ */
+function hook_workbench_moderation_state_access_alter(&$access, $op, $node, $state) {
+  global $user;
+  // If the state change is to published, only let its owner moderate it.
+  if ($state == 'published' || $op != 'moderate') {
+    return;
+  }
+  if ($user->uid != $node->uid) {
+    $access = FALSE;
+  }
+}
+
+/**
  * Allows modules to alter the list of possible next states for a node.
  *
  * @param &$states
diff --git a/workbench_moderation.module b/workbench_moderation.module
index 840b932..14ea29c 100644
--- a/workbench_moderation.module
+++ b/workbench_moderation.module
@@ -551,6 +551,7 @@ function _workbench_moderation_moderate_access($node, $state) {
   // Allow other modules to change our rule set.
   $op = 'moderate';
   drupal_alter('workbench_moderation_access', $access, $op, $node);
+  drupal_alter('workbench_moderation_state_access', $access, $op, $node, $state);
 
   return $access;
 }
