diff --git a/simple_oauth.module b/simple_oauth.module
index ebf714589b48ce942fca6608bd167f82e926fe47..61349e1512ef26f3ca8e74f57f5cec6ebbc7d318 100644
--- a/simple_oauth.module
+++ b/simple_oauth.module
@@ -95,7 +95,7 @@ function simple_oauth_entity_base_field_info(EntityTypeInterface $entity_type) {
 
     $fields['scopes'] = BaseFieldDefinition::create('oauth2_scope_reference')
       ->setLabel(new TranslatableMarkup('Scopes'))
-      ->setDescription(new TranslatableMarkup('Here you can select scopes that would be the default scopes when authorizing.'))
+      ->setDescription(new TranslatableMarkup('Selecting scopes here will be set as default when authorizing (so no need to specify the scope parameter on the token request), also the selection of scopes will limit the allowed scopes on the consumer/client.'))
       ->setDisplayOptions('view', [
         'label' => 'inline',
         'type' => 'oauth2_scope_reference_label',
diff --git a/src/Controller/Oauth2Token.php b/src/Controller/Oauth2Token.php
index c0f31e20dcf5adc57be4724c5433f43554fbdfef..a3d8e6e4625d3defd71db833aa64b2032f0afaac 100644
--- a/src/Controller/Oauth2Token.php
+++ b/src/Controller/Oauth2Token.php
@@ -113,6 +113,8 @@ class Oauth2Token extends ControllerBase {
     $server_request = $this->httpMessageFactory->createRequest($request);
     $server_response = new Response();
     $client_id = $request->get('client_id');
+    $grant_type = $request->get('grant_type');
+    $scopes = $request->get('scope');
 
     $lock_key = $this->createLockKey($request);
 
@@ -135,6 +137,16 @@ class Oauth2Token extends ControllerBase {
       }
       $client_drupal_entity = $client_entity->getDrupalEntity();
 
+      // Omitting scopes is not allowed when dealing with client_credentials
+      // and no default scopes are set.
+      if (
+        $grant_type === 'client_credentials' &&
+        empty($scopes) &&
+        $client_drupal_entity->get('scopes')->isEmpty()
+      ) {
+        throw OAuthServerException::invalidRequest('scope');
+      }
+
       // Respond to the incoming request and fill in the response.
       $server = $this->authorizationServerFactory->get($client_drupal_entity);
       $response = $server->respondToAccessTokenRequest($server_request, $server_response);
diff --git a/src/Repositories/ScopeRepository.php b/src/Repositories/ScopeRepository.php
index 4cf5d4e16566985ab2eee58cfbd57dbdd7e4cbd4..3824b4c6321eb6be27973e4be25763cb9eac37bd 100644
--- a/src/Repositories/ScopeRepository.php
+++ b/src/Repositories/ScopeRepository.php
@@ -66,11 +66,24 @@ class ScopeRepository implements ScopeRepositoryInterface {
     }
 
     $default_scopes = [];
+    $allowed_scopes = [];
     $client_drupal_entity = $clientEntity->getDrupalEntity();
     if (!$client_drupal_entity->get('scopes')->isEmpty()) {
-      $default_scopes = array_map(function (Oauth2ScopeInterface $scope) {
-        return $this->scopeFactory($scope);
-      }, $client_drupal_entity->get('scopes')->getScopes());
+      foreach ($client_drupal_entity->get('scopes')->getScopes() as $scope) {
+        $default_scope = $this->scopeFactory($scope);
+        $default_scopes[] = $default_scope;
+        $allowed_scopes[] = $default_scope->getIdentifier();
+      }
+
+      // Limit the scopes if default scopes are set on the consumer for the
+      // client credentials grant type.
+      if ($grantType === 'client_credentials') {
+        foreach ($scopes as $scope) {
+          if (!in_array($scope->getIdentifier(), $allowed_scopes)) {
+            throw OAuthServerException::invalidScope($scope->getIdentifier());
+          }
+        }
+      }
     }
 
     $finalized_scopes = !empty($scopes) ? $scopes : $default_scopes;
diff --git a/tests/src/Kernel/ClientCredentialsTest.php b/tests/src/Kernel/ClientCredentialsTest.php
index 965bbb18069bb591a1d250bcc31ce131df26c70a..e57ac3631ee686045e2917d536222137472e1880 100644
--- a/tests/src/Kernel/ClientCredentialsTest.php
+++ b/tests/src/Kernel/ClientCredentialsTest.php
@@ -4,6 +4,9 @@ namespace Drupal\Tests\simple_oauth\Kernel;
 
 use Drupal\Component\Serialization\Json;
 use Drupal\TestTools\Random;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\simple_oauth\Entity\Oauth2Scope;
+use Drupal\simple_oauth\Oauth2ScopeInterface;
 use Symfony\Component\HttpFoundation\Request;
 
 /**
@@ -68,21 +71,26 @@ class ClientCredentialsTest extends AuthorizedRequestBase {
    */
   public static function missingClientCredentialsProvider(): array {
     return [
-      'grant_type' => [
+      [
         'grant_type',
         'unsupported_grant_type',
         400,
       ],
-      'client_id' => [
+      [
         'client_id',
         'invalid_request',
         400,
       ],
-      'client_secret' => [
+      [
         'client_secret',
         'invalid_client',
         401,
       ],
+      [
+        'scope',
+        'invalid_request',
+        400,
+      ],
     ];
   }
 
@@ -99,6 +107,8 @@ class ClientCredentialsTest extends AuthorizedRequestBase {
       'scope' => $this->scope,
     ];
     unset($parameters[$key]);
+    $this->client->set('scopes', []);
+    $this->client->save();
     $request = Request::create($this->url->toString(), 'POST', $parameters);
     $response = $this->httpKernel->handle($request);
     $parsed_response = Json::decode((string) $response->getContent());
@@ -197,7 +207,6 @@ class ClientCredentialsTest extends AuthorizedRequestBase {
    * @dataProvider publicClientCredentialsGrantProvider
    */
   public function testPublicClientCredentialsGrant(bool $confidential, string|null $client_secret, string $error, int $code): void {
-
     // Configure the client for the test.
     $this->client
       ->set('confidential', $confidential)
@@ -218,4 +227,47 @@ class ClientCredentialsTest extends AuthorizedRequestBase {
     $this->assertSame($error, $parsed_response['error'], sprintf('Correct error code %s', $error));
   }
 
+  /**
+   * Test the not allowed scopes set on the client.
+   */
+  public function testNotAllowedScopes(): void {
+    $not_allowed_scope = Oauth2Scope::create([
+      'name' => 'test:scope3',
+      'description' => 'Test scope 3 description',
+      'grant_types' => [
+        'client_credentials' => [
+          'status' => TRUE,
+          'description' => 'Test scope 3 description client_credentials',
+        ],
+      ],
+      'umbrella' => FALSE,
+      'granularity_id' => Oauth2ScopeInterface::GRANULARITY_ROLE,
+      'granularity_configuration' => [
+        'role' => AccountInterface::AUTHENTICATED_ROLE,
+      ],
+    ]);
+    $not_allowed_scope->save();
+
+    $parameters = [
+      'grant_type' => 'client_credentials',
+      'client_id' => $this->client->getClientId(),
+      'client_secret' => $this->clientSecret,
+      'scope' => $not_allowed_scope->getName(),
+    ];
+    $request = Request::create($this->url->toString(), 'POST', $parameters);
+    $response = $this->httpKernel->handle($request);
+    $parsed_response = Json::decode((string) $response->getContent());
+
+    $this->assertEquals(400, $response->getStatusCode());
+    $this->assertEquals('The requested scope is invalid, unknown, or malformed', $parsed_response['error_description']);
+
+    $parameters['scope'] = "{$this->scope} {$not_allowed_scope->getName()}";
+    $request = Request::create($this->url->toString(), 'POST', $parameters);
+    $response = $this->httpKernel->handle($request);
+    $parsed_response = Json::decode((string) $response->getContent());
+
+    $this->assertEquals(400, $response->getStatusCode());
+    $this->assertEquals('The requested scope is invalid, unknown, or malformed', $parsed_response['error_description']);
+  }
+
 }