diff --git a/manifests/federation/openidc.pp b/manifests/federation/openidc.pp
index 093f3b58f..0c1d35347 100644
--- a/manifests/federation/openidc.pp
+++ b/manifests/federation/openidc.pp
@@ -65,9 +65,23 @@
 #
 # [*openidc_enable_oauth*]
 #  (Optional) Set to true to enable oauthsupport.
+#  Defaults to false.
 #
 # [*openidc_introspection_endpoint*]
-#  (Required if oauth is enabled) Oauth introspection endpoint url.
+#  (Required if oauth is enabled and configured for introspection)
+#  OAuth introspection endpoint url.
+#  Defaults to undef.
+#
+# [*openidc_verify_jwks_uri*]
+#  (Required if oauth is enabled and configured for JWKS based validation)
+#  The JWKS URL on which the Identity Provider
+#  publishes the keys used to sign its JWT access tokens.
+#  Defaults to undef.
+#
+# [*openidc_verify_method*]
+#  (Optional) The method used to verify OAuth tokens.
+#  Must be one of introspection or jwks
+#  Defaults to introspection
 #
 # [*memcached_servers*]
 #  (Optional) A list of memcache servers. Defaults to undef.
@@ -84,6 +98,7 @@
 # [*remote_id_attribute*]
 #  (Optional) Value to be used to obtain the entity ID of the Identity
 #  Provider from the environment.
+#  Defaults to undef.
 #
 # [*template_order*]
 #  This number indicates the order for the concat::fragment that will apply
@@ -117,6 +132,8 @@ class keystone::federation::openidc (
   $openidc_claim_delimiter        = undef,
   $openidc_enable_oauth           = false,
   $openidc_introspection_endpoint = undef,
+  $openidc_verify_jwks_uri        = undef,
+  $openidc_verify_method          = 'introspection',
   $memcached_servers              = undef,
   $redis_server                   = undef,
   $redis_password                 = undef,
@@ -129,8 +146,21 @@ class keystone::federation::openidc (
   include keystone::deps
   include keystone::params
 
-  if $openidc_enable_oauth and !$openidc_introspection_endpoint {
-    fail('You must set openidc_introspection_endpoint when enabling oauth support')
+  if !($openidc_verify_method in ['introspection', 'jwks']) {
+    fail('Unsupported token verification method.' +
+        '  Must be one of "introspection" or "jwks"')
+  }
+
+  if ($openidc_verify_method == 'introspection') {
+    if $openidc_enable_oauth and !$openidc_introspection_endpoint {
+      fail('You must set openidc_introspection_endpoint when enabling oauth support' +
+          ' and introspection.')
+    }
+  } elsif ($openidc_verify_method == 'jwks') {
+    if $openidc_enable_oauth and !$openidc_verify_jwks_uri {
+      fail('You must set openidc_verify_jwks_uri when enabling oauth support' +
+          ' and local signature verification using a JWKS URL')
+    }
   }
 
   $memcached_servers_real = join(any2array($memcached_servers), ' ')
diff --git a/spec/classes/keystone_federation_openidc_spec.rb b/spec/classes/keystone_federation_openidc_spec.rb
index 5c847f035..10e767575 100644
--- a/spec/classes/keystone_federation_openidc_spec.rb
+++ b/spec/classes/keystone_federation_openidc_spec.rb
@@ -94,7 +94,7 @@ describe 'keystone::federation::openidc' do
       end
     end
 
-    context 'with oauth enabled' do
+    context 'with oauth and introspection enabled' do
       before do
         params.merge!({
           :openidc_enable_oauth => true,
@@ -102,7 +102,7 @@ describe 'keystone::federation::openidc' do
         })
       end
 
-      it 'should contain oauth config' do
+      it 'should contain oauth and introspection config' do
         content = get_param('concat::fragment', 'configure_openidc_keystone', 'content')
         expect(content).to match('OIDCOAuthClientID "openid_client_id"')
         expect(content).to match('OIDCOAuthClientSecret "openid_client_secret"')
@@ -111,6 +111,22 @@ describe 'keystone::federation::openidc' do
       end
     end
 
+    context 'with oauth and jwks enabled' do
+      before do
+        params.merge!({
+          :openidc_enable_oauth => true,
+          :openidc_verify_method => 'jwks',
+          :openidc_verify_jwks_uri => 'http://example.com',
+        })
+      end
+
+      it 'should contain oauth and jwks config' do
+        content = get_param('concat::fragment', 'configure_openidc_keystone', 'content')
+        expect(content).to match('OIDCOAuthVerifyJwksUri "http://example.com"')
+        expect(content).to match('/v3/OS-FEDERATION/identity_providers/myidp/protocols/openid/auth')
+      end
+    end
+
     context 'with remote id attribute' do
       before do
         params.merge!({
diff --git a/templates/openidc.conf.erb b/templates/openidc.conf.erb
index de737b7e8..63a348449 100644
--- a/templates/openidc.conf.erb
+++ b/templates/openidc.conf.erb
@@ -51,9 +51,13 @@
   </LocationMatch>
 
 <%- if scope['::keystone::federation::openidc::openidc_enable_oauth'] -%>
+  <%- if scope['keystone::federation::openidc::openidc_verify_method'] == 'introspection' -%>
   OIDCOAuthClientID "<%= scope['keystone::federation::openidc::openidc_client_id']-%>"
   OIDCOAuthClientSecret "<%= scope['keystone::federation::openidc::openidc_client_secret']-%>"
   OIDCOAuthIntrospectionEndpoint "<%= scope['keystone::federation::openidc::openidc_introspection_endpoint']-%>"
+  <%- elsif scope['keystone::federation::openidc::openidc_verify_method'] == 'jwks' -%>
+  OIDCOAuthVerifyJwksUri "<%= scope['keystone::federation::openidc::openidc_verify_jwks_uri']-%>"
+  <%- end -%>
 
   <Location ~ "/v3/OS-FEDERATION/identity_providers/<%= scope['keystone::federation::openidc::idp_name']-%>/protocols/openid/auth">
       AuthType oauth20