diff --git a/password_policy_consecutive/config/schema/password_policy_consecutive.schema.yml b/password_policy_consecutive/config/schema/password_policy_consecutive.schema.yml
new file mode 100644
index 0000000..85ad068
--- /dev/null
+++ b/password_policy_consecutive/config/schema/password_policy_consecutive.schema.yml
@@ -0,0 +1,6 @@
+password_policy.constraint.plugin.consecutive:
+  type: password_policy.constraint.plugin
+  mapping:
+    max_consecutive_characters:
+      type: integer
+      label: 'Maximum consecutive character count'
diff --git a/password_policy_consecutive/password_policy_consecutive.info.yml b/password_policy_consecutive/password_policy_consecutive.info.yml
new file mode 100644
index 0000000..47f3ba0
--- /dev/null
+++ b/password_policy_consecutive/password_policy_consecutive.info.yml
@@ -0,0 +1,7 @@
+name: Password Consecutive Characters Policy
+description: Sets up a consecutive characters constraint for passwords.
+package: Security
+type: module
+core: 8.x
+dependencies:
+  - password_policy
diff --git a/password_policy_consecutive/src/Plugin/PasswordConstraint/ConsecutiveCharacters.php b/password_policy_consecutive/src/Plugin/PasswordConstraint/ConsecutiveCharacters.php
new file mode 100644
index 0000000..640164f
--- /dev/null
+++ b/password_policy_consecutive/src/Plugin/PasswordConstraint/ConsecutiveCharacters.php
@@ -0,0 +1,85 @@
+<?php
+
+namespace Drupal\password_policy_consecutive\Plugin\PasswordConstraint;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\password_policy\PasswordConstraintBase;
+use Drupal\password_policy\PasswordPolicyValidation;
+
+/**
+ * Enforces a maximum number of consecutive identical characters.
+ *
+ * @PasswordConstraint(
+ *   id = "consecutive",
+ *   title = @Translation("Consecutive characters"),
+ *   description = @Translation("Verifying that a password has a maximum number of consecutive identical characters."),
+ *   error_message = @Translation("Your password has too many consecutive characters.")
+ * )
+ */
+class ConsecutiveCharacters extends PasswordConstraintBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validate($password, $user_context) {
+    $validation = new PasswordPolicyValidation();
+    $max = $this->getConfiguration()['max_consecutive_characters'];
+    if ($max < 2) {
+      $validation->setErrorMessage($this->t('Invalid plugin configuration.'));
+    }
+    $pattern = '/(.)\1{' . ($max - 1) . '}/';
+    if (preg_match($pattern, $password)) {
+      $validation->setErrorMessage($this->t('Password must have fewer than @max consecutive identical characters.', ['@max' => $max]));
+    }
+    return $validation;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultConfiguration() {
+    return [
+      'max_consecutive_characters' => 2,
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getSummary() {
+    return $this->t('Maximum consecutive identical characters: @max', ['@max' => $this->getConfiguration()['max_consecutive_characters']]);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    $range = range(2, 5);
+    $form['max_consecutive_characters'] = [
+      '#type' => 'select',
+      '#options' => array_combine(array_values($range), $range),
+      '#title' => $this->t('Maximum consecutive identical characters'),
+      '#description' => $this->t('Select the maximum number of consecutive identical characters allowed in the password.'),
+      '#default_value' => $this->getConfiguration()['max_consecutive_characters'],
+    ];
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
+    $types = $form_state->getValue('max_consecutive_characters');
+    if (!is_numeric($types) || $types < 2) {
+      $form_state->setErrorByName('max_consecutive_characters', $this->t('The number of character types must be higher than 1 otherwise all passwords will fail.'));
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
+    $this->configuration['max_consecutive_characters'] = $form_state->getValue('max_consecutive_characters');
+  }
+
+}
diff --git a/password_policy_consecutive/tests/src/Functional/PasswordConsecutiveCharactersOperationsTest.php b/password_policy_consecutive/tests/src/Functional/PasswordConsecutiveCharactersOperationsTest.php
new file mode 100644
index 0000000..92492bd
--- /dev/null
+++ b/password_policy_consecutive/tests/src/Functional/PasswordConsecutiveCharactersOperationsTest.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace Drupal\Tests\password_policy_consecutive\Functional;
+
+use Drupal\Tests\BrowserTestBase;
+
+/**
+ * Tests password character types operations.
+ *
+ * @group password_policy_consecutive
+ */
+class PasswordConsecutiveCharactersOperationsTest extends BrowserTestBase {
+
+  /**
+   * Modules to enable at the start of the test.
+   *
+   * @var array
+   */
+  public static $modules = [
+    'password_policy_consecutive',
+    'password_policy',
+  ];
+
+  /**
+   * Administrative user.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $adminUser;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->drupalLogin($this->drupalCreateUser(['administer site configuration']));
+  }
+
+  /**
+   * Test the management of the "password_policy_consecutive" constraint.
+   */
+  public function testPasswordConsecutiveConstraintManagement() {
+    $web_assert = $this->assertSession();
+
+    // Create a policy and add a "consecutive" constraint.
+    $this->drupalPostForm('admin/config/security/password-policy/add', ['label' => 'Test policy', 'id' => 'test_policy'], 'Next');
+    $this->drupalGet('admin/config/system/password_policy/constraint/add/test_policy/consecutive');
+    $web_assert->pageTextContains('Maximum consecutive identical characters');
+
+    $this->drupalGet('admin/config/system/password_policy/constraint/add/test_policy/consecutive');
+    $this->drupalPostForm(NULL, ['max_consecutive_characters' => 2], 'Save');
+    $web_assert->pageTextContains('Maximum consecutive identical characters: 2');
+  }
+
+}
diff --git a/password_policy_consecutive/tests/src/Unit/ConsecutiveCharactersTest.php b/password_policy_consecutive/tests/src/Unit/ConsecutiveCharactersTest.php
new file mode 100644
index 0000000..1e27dc8
--- /dev/null
+++ b/password_policy_consecutive/tests/src/Unit/ConsecutiveCharactersTest.php
@@ -0,0 +1,80 @@
+<?php
+
+namespace Drupal\Tests\password_policy_consecutive\Unit;
+
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * Tests the consecutive constraint.
+ *
+ * @group password_policy_consecutive
+ */
+class ConsecutiveCharactersTest extends UnitTestCase {
+
+  /**
+   * Tests the four character types and minimum character count per type.
+   *
+   * @dataProvider passwordsDataProvider
+   */
+  public function testConsecutiveCharacters($count, $password, $result) {
+    $characters = $this->getMockBuilder('Drupal\password_policy_consecutive\Plugin\PasswordConstraint\ConsecutiveCharacters')
+      ->disableOriginalConstructor()
+      ->setMethods(['getConfiguration', 't'])
+      ->getMock();
+    $characters
+      ->method('getConfiguration')
+      ->willReturn(['max_consecutive_characters' => $count]);
+    $this->assertEquals($characters->validate($password, NULL)->isValid(), $result);
+  }
+
+  /**
+   * Provides data for the testConsecutiveCharacters method.
+   */
+  public function passwordsDataProvider() {
+    return [
+      // Passing conditions.
+      [
+        2,
+        'PasSword',
+        TRUE,
+      ],
+      [
+        3,
+        'Password',
+        TRUE,
+      ],
+      [
+        4,
+        'PasSword',
+        TRUE,
+      ],
+      [
+        5,
+        'PasSsSworD',
+        TRUE,
+      ],
+      // Failing conditions.
+      [
+        2,
+        'Password',
+        FALSE,
+      ],
+      [
+        3,
+        'Passsword',
+        FALSE,
+      ],
+      [
+        4,
+        'paSSWOOOORD',
+        FALSE,
+      ],
+      [
+        5,
+        'Password1233333',
+        FALSE,
+      ],
+    ];
+  }
+
+}
