diff --git a/includes/rules.core.inc b/includes/rules.core.inc
index 03ef537..0c9b905 100644
--- a/includes/rules.core.inc
+++ b/includes/rules.core.inc
@@ -111,7 +111,7 @@ class RulesEntityController extends EntityAPIControllerExportable {
     // Create an empty configuration, re-set basic keys and import.
     $config = rules_plugin_factory($export['PLUGIN']);
     $config->name = $name;
-    foreach (array('label', 'active', 'weight', 'tags') as $key) {
+    foreach (array('label', 'active', 'weight', 'tags', 'access_exposed') as $key) {
       if (isset($export[strtoupper($key)])) {
         $config->$key = $export[strtoupper($key)];
       }
@@ -1257,6 +1257,9 @@ abstract class RulesPlugin extends RulesExtendable {
     if ($modules = $this->dependencies()) {
       $export_cfg[$this->name]['REQUIRES'] = $modules;
     }
+    if (!empty($this->access_exposed)) {
+      $export_cfg[$this->name]['ACCESS_EXPOSED'] = $this->access_exposed;
+    };
     $export_cfg[$this->name] += $export;
     return $php ? entity_var_export($export_cfg, $prefix) : entity_var_json_export($export_cfg, $prefix);
   }
diff --git a/modules/rules_core.rules.inc b/modules/rules_core.rules.inc
index 6f00996..c08bc4e 100644
--- a/modules/rules_core.rules.inc
+++ b/modules/rules_core.rules.inc
@@ -299,11 +299,17 @@ function rules_element_invoke_component_features_export(&$export, &$pipe, $modul
  * Access callback for the invoke component condition/action.
  */
 function rules_element_invoke_component_access_callback($type, $name) {
-  // Only allow access to the action/condition if the user has access to the
-  // component.
+  global $user;
   // Cut of the leading 'component_' from the action name.
   $component = rules_config_load(substr($name, 10));
-  return $component && $component->access();
+
+  // If the access is not exposed for this component, don't check and allow it.
+  if (!isset($component->access_exposed) || !$component->access_exposed) {
+    return TRUE;
+  }
+
+  // Limit access by role, if any roles were selected for the component.
+  return user_access('bypass rules access', $user) || user_access("access {$component->name}", $user);
 }
 
 /**
diff --git a/rules.install b/rules.install
index 832a557..af6d1dd 100644
--- a/rules.install
+++ b/rules.install
@@ -87,6 +87,13 @@ function rules_schema() {
         'length' => 255,
         'not null' => FALSE,
       ),
+      'access_exposed' => array(
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+        'size' => 'tiny',
+        'description' => 'Flag to control access by permissions to rules components.',
+      ),
       'data' => array(
         'type' => 'blob',
         'size' => 'big',
@@ -413,3 +420,17 @@ function rules_update_7207() {
 function rules_update_7208() {
   // The update system is going to flush all caches anyway, so nothing to do.
 }
+
+/**
+ * Create roles control flag to manage access to specific components.
+ */
+function rules_update_7209() {
+  // Create a access exposed flag column.
+  db_add_field('rules_config', 'access_exposed', array(
+    'type' => 'int',
+    'not null' => TRUE,
+    'default' => 0,
+    'size' => 'tiny',
+    'description' => 'Flag to control access by permissions to rules components.',
+  ));
+}
diff --git a/rules.module b/rules.module
index b99ce96..0866b21 100644
--- a/rules.module
+++ b/rules.module
@@ -975,7 +975,7 @@ function rules_theme() {
  * Implements hook_permission().
  */
 function rules_permission() {
-  return array(
+  $perms = array(
     'administer rules' => array(
       'title' => t('Administer rule configurations'),
       'description' => t('Administer rule configurations including events, conditions and actions for which the user has sufficient access permissions.'),
@@ -989,6 +989,31 @@ function rules_permission() {
       'title' => t('Access the Rules debug log'),
     ),
   );
+
+  // Fetch all components to generate the access keys.
+  $conditions['plugin'] = array_keys(rules_filter_array(rules_fetch_data('plugin_info'), 'component', TRUE));
+  $conditions['access_exposed'] = 1;
+  $components = entity_load('rules_config', FALSE, $conditions);
+  $perms += rules_permissions_by_component($components);
+
+  return $perms;
+}
+
+/**
+ * Helper function to get all the permissions for the components that have
+ * access exposed.
+ */
+function rules_permissions_by_component(array $components = array()) {
+  $perms = array();
+  foreach ($components as $component) {
+    $perms += array(
+      "access $component->name" => array(
+        'title' => t('Access to %component rules component', array('%component' => $component->label)),
+        'description' => t('Allows users to access %component rules component. <a href="@component-edit-url">Edit this component</a>', array('%component' => $component->label, '@component-edit-url' => url(RulesPluginUI::path($component->name)))),
+      ),
+    );
+  }
+  return $perms;
 }
 
 /**
diff --git a/tests/rules.test b/tests/rules.test
index e932479..0b7cb11 100644
--- a/tests/rules.test
+++ b/tests/rules.test
@@ -337,6 +337,43 @@ class RulesTestCase extends DrupalWebTestCase {
   }
 
   /**
+   * Test rule component access.
+   */
+  function testRuleComponentAccess() {
+    // Create a normal user.
+    $normal_user = $this->drupalCreateUser();
+    // Create a role for granting access to the rule component.
+    $this->normal_role = $this->drupalCreateRole(array(), 'access_rule_components');
+    $normal_user->roles[$this->normal_role] = 'access_rule_components';
+    user_save($normal_user, array('roles' => $normal_user->roles));
+    // Create an 'action set' rule component with permission access to that
+    // role.
+    $action_set = rules_action_set(array('node' => array('type' => 'node')));
+    $action_set->access_exposed = TRUE;
+    $action_set->save('rules_test_roles');
+
+
+    // Login as normal user, force the user object to be the current one as
+    // there's a global $user call in the permission check.
+    $this->drupalLogin($normal_user);
+    global $user;
+    $user = user_load($normal_user->uid);
+
+    $this->assertFalse(rules_action('component_rules_test_roles')->access(), 'Authenticated user without the correct role can\'t access to the rule component.');
+
+    // Assign the role that will have permissions for the rule component.
+    user_role_change_permissions($this->normal_role, array('access rules_test_roles' => 'access rules_test_roles'));
+
+    $this->assertTrue(rules_action('component_rules_test_roles')->access(), 'Authenticated user with the correct role can access to the rule component.');
+
+    // Logout and access as anonymous.
+    $this->drupalLogout();
+    $user = user_load(0);
+
+    $this->assertFalse(rules_action('component_rules_test_roles')->access(), 'Anonymous user can\'t access to the rule component.');
+  }
+
+  /**
    * Test passing arguments by reference to an action.
    */
   function testPassingByReference() {
diff --git a/ui/rules.ui.css b/ui/rules.ui.css
index f85212c..41f0b2f 100755
--- a/ui/rules.ui.css
+++ b/ui/rules.ui.css
@@ -183,6 +183,12 @@ ul.rules-autocomplete .ui-corner-all {
   -moz-border-radius: 0px;
 }
 
+/**
+ * Do not display the hide/show descriptions link above the permissions matrix.
+ */
+#edit-settings-access-permissions .compact-link {
+  display: none;
+}
 
 /* IE 6 hack for max-height. */
 * html ul.rule-autocomplete{
diff --git a/ui/ui.core.inc b/ui/ui.core.inc
index bc69ac4..d56401f 100644
--- a/ui/ui.core.inc
+++ b/ui/ui.core.inc
@@ -478,11 +478,74 @@ class RulesPluginUI extends FacesExtender implements RulesPluginUIInterface {
         '#limit_validation_errors' => array(array('vars')),
         '#submit' => array('rules_form_submit_rebuild'),
       );
+      if (!empty($this->element->id)) {
+        // Display a setting to manage access.
+        $form['settings']['access'] = array(
+          '#weight' => 99,
+        );
+        $form['settings']['access']['access_exposed'] = array(
+          '#type' => 'checkbox',
+          '#title' => t('Enable access permissions for this component.'),
+          '#default_value' => isset($this->element->access_exposed) ? $this->element->access_exposed : array(),
+        );
+        $form['settings']['access']['permissions'] = array(
+          '#type' => 'container',
+          '#states' => array(
+            'visible' => array(
+              ':input[name="settings[access][access_exposed]"]' => array('checked' => TRUE),
+            ),
+          ),
+        );
+        $form['settings']['access']['permissions']['matrix'] = $this->settingsFormPermissionMatrix();
+      }
     }
 
     // TODO: Attach field form thus description.
   }
 
+  /**
+   * Provie a matrix permission for the component based in the existing roles.
+   *
+   * @return form element with the matrix of permissions for this component.
+   */
+  protected function settingsFormPermissionMatrix() {
+    $form['#theme'] = 'user_admin_permissions';
+    $status = array();
+    $options = array();
+
+    $role_names = user_roles();
+    $role_permissions = user_role_permissions($role_names);
+    $component_permission = rules_permissions_by_component(array($this->element));
+    $component_permission_name = key($component_permission);
+
+    $form['permission'][$component_permission_name] = array(
+      '#type' => 'item',
+      '#markup' => $component_permission[$component_permission_name]['title'],
+    );
+    $options[$component_permission_name] = '';
+    foreach ($role_names as $rid => $name) {
+      if (isset($role_permissions[$rid][$component_permission_name])) {
+        $status[$rid][] = $component_permission_name;
+      }
+    }
+
+    // Build the checkboxes for each role.
+    foreach ($role_names as $rid => $name) {
+      $form['checkboxes'][$rid] = array(
+        '#type' => 'checkboxes',
+        '#options' => $options,
+        '#default_value' => isset($status[$rid]) ? $status[$rid] : array(),
+        '#attributes' => array('class' => array('rid-' . $rid)),
+      );
+      $form['role_names'][$rid] = array('#markup' => check_plain($name), '#tree' => TRUE);
+    }
+
+    // Attach the default permissions page JavaScript.
+    $form['#attached']['js'][] = drupal_get_path('module', 'user') . '/user.permissions.js';
+
+    return $form;
+  }
+
   public function settingsFormExtractValues($form, &$form_state) {
     $form_values = RulesPluginUI::getFormStateValues($form['settings'], $form_state);
     $this->element->label = $form_values['label'];
@@ -522,6 +585,9 @@ class RulesPluginUI extends FacesExtender implements RulesPluginUIInterface {
       }
       unset($input['vars']);
     }
+
+    // Store the access exposed setting.
+    $this->element->access_exposed = isset($form_values['access']['access_exposed']) ? $form_values['access']['access_exposed'] : 0;
   }
 
   public function settingsFormValidate($form, &$form_state) {
@@ -532,7 +598,12 @@ class RulesPluginUI extends FacesExtender implements RulesPluginUIInterface {
   }
 
   public function settingsFormSubmit($form, &$form_state) {
-
+    if (isset($form_state['values']['settings']['access'])) {
+      // Save the permission matrix.
+      foreach ($form_state['values']['settings']['access']['permissions']['matrix']['checkboxes'] as $rid => $value) {
+        user_role_change_permissions($rid, $value);
+      }
+    }
   }
 
   /**
