diff --git a/cms/envs/aws.py b/cms/envs/aws.py
index a7918cfd2e4375970c82c35f03ac62cc725326ed..f5954abd4117c2bf4cfb29666ce6762c9675f40b 100644
--- a/cms/envs/aws.py
+++ b/cms/envs/aws.py
@@ -518,6 +518,7 @@ OAUTH_OIDC_ISSUER = ENV_TOKENS['OAUTH_OIDC_ISSUER']
 
 #### JWT configuration ####
 JWT_AUTH.update(ENV_TOKENS.get('JWT_AUTH', {}))
+JWT_AUTH.update(AUTH_TOKENS.get('JWT_AUTH', {}))
 
 ######################## CUSTOM COURSES for EDX CONNECTOR ######################
 if FEATURES.get('CUSTOM_COURSES_EDX'):
diff --git a/cms/envs/bok_choy.auth.json b/cms/envs/bok_choy.auth.json
index 3adba2337572d6a8b409775d07b9a2fe5245b79f..402121e7411eaec8ee28e283491f0edfb7aa6863 100644
--- a/cms/envs/bok_choy.auth.json
+++ b/cms/envs/bok_choy.auth.json
@@ -47,6 +47,11 @@
         ],
         "port": 27017
     },
+    "JWT_AUTH": {
+        "JWT_SECRET_KEY": "super-secret-key",
+        "JWT_PUBLIC_SIGNING_JWK_SET": "{\"keys\": [{\"kid\": \"BTZ9HA6K\", \"e\": \"AQAB\", \"kty\": \"RSA\", \"n\": \"o5cn3ljSRi6FaDEKTn0PS-oL9EFyv1pI7dRgffQLD1qf5D6sprmYfWWokSsrWig8u2y0HChSygR6Jn5KXBqQn6FpM0dDJLnWQDRXHLl3Ey1iPYgDSmOIsIGrV9ZyNCQwk03wAgWbfdBTig3QSDYD-sTNOs3pc4UD_PqAvU2nz_1SS2ZiOwOn5F6gulE1L0iE3KEUEvOIagfHNVhz0oxa_VRZILkzV-zr6R_TW1m97h4H8jXl_VJyQGyhMGGypuDrQ9_vaY_RLEulLCyY0INglHWQ7pckxBtI5q55-Vio2wgewe2_qYcGsnBGaDNbySAsvYcWRrqDiFyzrJYivodqTQ\"}]}",
+        "JWT_PRIVATE_SIGNING_JWK": "{\"e\": \"AQAB\", \"d\": \"HIiV7KNjcdhVbpn3KT-I9n3JPf5YbGXsCIedmPqDH1d4QhBofuAqZ9zebQuxkRUpmqtYMv0Zi6ECSUqH387GYQF_XvFUFcjQRPycISd8TH0DAKaDpGr-AYNshnKiEtQpINhcP44I1AYNPCwyoxXA1fGTtmkKChsuWea7o8kytwU5xSejvh5-jiqu2SF4GEl0BEXIAPZsgbzoPIWNxgO4_RzNnWs6nJZeszcaDD0CyezVSuH9QcI6g5QFzAC_YuykSsaaFJhZ05DocBsLczShJ9Omf6PnK9xlm26I84xrEh_7x4fVmNBg3xWTLh8qOnHqGko93A1diLRCrKHOvnpvgQ\", \"n\": \"o5cn3ljSRi6FaDEKTn0PS-oL9EFyv1pI7dRgffQLD1qf5D6sprmYfWWokSsrWig8u2y0HChSygR6Jn5KXBqQn6FpM0dDJLnWQDRXHLl3Ey1iPYgDSmOIsIGrV9ZyNCQwk03wAgWbfdBTig3QSDYD-sTNOs3pc4UD_PqAvU2nz_1SS2ZiOwOn5F6gulE1L0iE3KEUEvOIagfHNVhz0oxa_VRZILkzV-zr6R_TW1m97h4H8jXl_VJyQGyhMGGypuDrQ9_vaY_RLEulLCyY0INglHWQ7pckxBtI5q55-Vio2wgewe2_qYcGsnBGaDNbySAsvYcWRrqDiFyzrJYivodqTQ\", \"q\": \"3T3DEtBUka7hLGdIsDlC96Uadx_q_E4Vb1cxx_4Ss_wGp1Loz3N3ZngGyInsKlmbBgLo1Ykd6T9TRvRNEWEtFSOcm2INIBoVoXk7W5RuPa8Cgq2tjQj9ziGQ08JMejrPlj3Q1wmALJr5VTfvSYBu0WkljhKNCy1KB6fCby0C9WE\", \"p\": \"vUqzWPZnDG4IXyo-k5F0bHV0BNL_pVhQoLW7eyFHnw74IOEfSbdsMspNcPSFIrtgPsn7981qv3lN_staZ6JflKfHayjB_lvltHyZxfl0dvruShZOx1N6ykEo7YrAskC_qxUyrIvqmJ64zPW3jkuOYrFs7Ykj3zFx3Zq1H5568G0\", \"kid\": \"BTZ9HA6K\", \"kty\": \"RSA\"}"
+    },
     "MODULESTORE": {
         "default": {
             "ENGINE": "xmodule.modulestore.mixed.MixedModuleStore",
diff --git a/cms/envs/bok_choy.env.json b/cms/envs/bok_choy.env.json
index 69aa3de58952c95a567588c90f2e63db242e592d..352f3772008e7f0d778ac47ac2e4d30e30b28bee 100644
--- a/cms/envs/bok_choy.env.json
+++ b/cms/envs/bok_choy.env.json
@@ -79,9 +79,6 @@
     },
     "FEEDBACK_SUBMISSION_EMAIL": "",
     "GITHUB_REPO_ROOT": "** OVERRIDDEN **",
-    "JWT_AUTH": {
-        "JWT_SECRET_KEY": "super-secret-key"
-    },
     "GRADES_DOWNLOAD": {
         "BUCKET": "edx-grades",
         "ROOT_PATH": "/tmp/edx-s3/grades",
diff --git a/cms/envs/bok_choy_docker.auth.json b/cms/envs/bok_choy_docker.auth.json
index b70bd46ed13029c840f0ece7fe19b8af8c911de0..00a7283b44a9e8c3f7fb2d1bbb80632afbe66d56 100644
--- a/cms/envs/bok_choy_docker.auth.json
+++ b/cms/envs/bok_choy_docker.auth.json
@@ -47,6 +47,11 @@
         ],
         "port": 27017
     },
+    "JWT_AUTH": {
+        "JWT_SECRET_KEY": "super-secret-key",
+        "JWT_PUBLIC_SIGNING_JWK_SET": "{\"keys\": [{\"kid\": \"BTZ9HA6K\", \"e\": \"AQAB\", \"kty\": \"RSA\", \"n\": \"o5cn3ljSRi6FaDEKTn0PS-oL9EFyv1pI7dRgffQLD1qf5D6sprmYfWWokSsrWig8u2y0HChSygR6Jn5KXBqQn6FpM0dDJLnWQDRXHLl3Ey1iPYgDSmOIsIGrV9ZyNCQwk03wAgWbfdBTig3QSDYD-sTNOs3pc4UD_PqAvU2nz_1SS2ZiOwOn5F6gulE1L0iE3KEUEvOIagfHNVhz0oxa_VRZILkzV-zr6R_TW1m97h4H8jXl_VJyQGyhMGGypuDrQ9_vaY_RLEulLCyY0INglHWQ7pckxBtI5q55-Vio2wgewe2_qYcGsnBGaDNbySAsvYcWRrqDiFyzrJYivodqTQ\"}]}",
+        "JWT_PRIVATE_SIGNING_JWK": "{\"e\": \"AQAB\", \"d\": \"HIiV7KNjcdhVbpn3KT-I9n3JPf5YbGXsCIedmPqDH1d4QhBofuAqZ9zebQuxkRUpmqtYMv0Zi6ECSUqH387GYQF_XvFUFcjQRPycISd8TH0DAKaDpGr-AYNshnKiEtQpINhcP44I1AYNPCwyoxXA1fGTtmkKChsuWea7o8kytwU5xSejvh5-jiqu2SF4GEl0BEXIAPZsgbzoPIWNxgO4_RzNnWs6nJZeszcaDD0CyezVSuH9QcI6g5QFzAC_YuykSsaaFJhZ05DocBsLczShJ9Omf6PnK9xlm26I84xrEh_7x4fVmNBg3xWTLh8qOnHqGko93A1diLRCrKHOvnpvgQ\", \"n\": \"o5cn3ljSRi6FaDEKTn0PS-oL9EFyv1pI7dRgffQLD1qf5D6sprmYfWWokSsrWig8u2y0HChSygR6Jn5KXBqQn6FpM0dDJLnWQDRXHLl3Ey1iPYgDSmOIsIGrV9ZyNCQwk03wAgWbfdBTig3QSDYD-sTNOs3pc4UD_PqAvU2nz_1SS2ZiOwOn5F6gulE1L0iE3KEUEvOIagfHNVhz0oxa_VRZILkzV-zr6R_TW1m97h4H8jXl_VJyQGyhMGGypuDrQ9_vaY_RLEulLCyY0INglHWQ7pckxBtI5q55-Vio2wgewe2_qYcGsnBGaDNbySAsvYcWRrqDiFyzrJYivodqTQ\", \"q\": \"3T3DEtBUka7hLGdIsDlC96Uadx_q_E4Vb1cxx_4Ss_wGp1Loz3N3ZngGyInsKlmbBgLo1Ykd6T9TRvRNEWEtFSOcm2INIBoVoXk7W5RuPa8Cgq2tjQj9ziGQ08JMejrPlj3Q1wmALJr5VTfvSYBu0WkljhKNCy1KB6fCby0C9WE\", \"p\": \"vUqzWPZnDG4IXyo-k5F0bHV0BNL_pVhQoLW7eyFHnw74IOEfSbdsMspNcPSFIrtgPsn7981qv3lN_staZ6JflKfHayjB_lvltHyZxfl0dvruShZOx1N6ykEo7YrAskC_qxUyrIvqmJ64zPW3jkuOYrFs7Ykj3zFx3Zq1H5568G0\", \"kid\": \"BTZ9HA6K\", \"kty\": \"RSA\"}"
+    },
     "MODULESTORE": {
         "default": {
             "ENGINE": "xmodule.modulestore.mixed.MixedModuleStore",
diff --git a/cms/envs/bok_choy_docker.env.json b/cms/envs/bok_choy_docker.env.json
index 540b4263d061cce71834877dc108a30627220ee7..373cd2cec121a6023bf2718002cc1382fda0451f 100644
--- a/cms/envs/bok_choy_docker.env.json
+++ b/cms/envs/bok_choy_docker.env.json
@@ -79,9 +79,6 @@
     },
     "FEEDBACK_SUBMISSION_EMAIL": "",
     "GITHUB_REPO_ROOT": "** OVERRIDDEN **",
-    "JWT_AUTH": {
-        "JWT_SECRET_KEY": "super-secret-key"
-    },
     "GRADES_DOWNLOAD": {
         "BUCKET": "edx-grades",
         "ROOT_PATH": "/tmp/edx-s3/grades",
diff --git a/cms/envs/production.py b/cms/envs/production.py
index 65f6f8813a72824f556d07747c1d94954a6b75ec..88c873f107dfea85e8b8b593bfc187ff59b3a5e6 100644
--- a/cms/envs/production.py
+++ b/cms/envs/production.py
@@ -517,6 +517,7 @@ OAUTH_OIDC_ISSUER = ENV_TOKENS['OAUTH_OIDC_ISSUER']
 
 #### JWT configuration ####
 JWT_AUTH.update(ENV_TOKENS.get('JWT_AUTH', {}))
+JWT_AUTH.update(AUTH_TOKENS.get('JWT_AUTH', {}))
 
 ######################## CUSTOM COURSES for EDX CONNECTOR ######################
 if FEATURES.get('CUSTOM_COURSES_EDX'):
diff --git a/cms/envs/test.py b/cms/envs/test.py
index c6689932e216ffddfcb6544ca82f70f45cabc5f8..543cff7d83029b6233577fa3debb06df93d6dbc8 100644
--- a/cms/envs/test.py
+++ b/cms/envs/test.py
@@ -192,6 +192,8 @@ PASSWORD_HASHERS = [
 # No segment key
 CMS_SEGMENT_KEY = None
 
+FEATURES['DISABLE_SET_JWT_COOKIES_FOR_TESTS'] = True
+
 FEATURES['ENABLE_SERVICE_STATUS'] = True
 
 # Toggles embargo on for testing
diff --git a/lms/envs/bok_choy.auth.json b/lms/envs/bok_choy.auth.json
index e8a9e6189484fcbea31f677d33b3defd0427edb4..53c7d7501ba697c5c39669f29ad29efce1901f87 100644
--- a/lms/envs/bok_choy.auth.json
+++ b/lms/envs/bok_choy.auth.json
@@ -74,6 +74,11 @@
             }
         }
     },
+    "JWT_AUTH": {
+        "JWT_SECRET_KEY": "super-secret-key",
+        "JWT_PUBLIC_SIGNING_JWK_SET": "{\"keys\": [{\"kid\": \"BTZ9HA6K\", \"e\": \"AQAB\", \"kty\": \"RSA\", \"n\": \"o5cn3ljSRi6FaDEKTn0PS-oL9EFyv1pI7dRgffQLD1qf5D6sprmYfWWokSsrWig8u2y0HChSygR6Jn5KXBqQn6FpM0dDJLnWQDRXHLl3Ey1iPYgDSmOIsIGrV9ZyNCQwk03wAgWbfdBTig3QSDYD-sTNOs3pc4UD_PqAvU2nz_1SS2ZiOwOn5F6gulE1L0iE3KEUEvOIagfHNVhz0oxa_VRZILkzV-zr6R_TW1m97h4H8jXl_VJyQGyhMGGypuDrQ9_vaY_RLEulLCyY0INglHWQ7pckxBtI5q55-Vio2wgewe2_qYcGsnBGaDNbySAsvYcWRrqDiFyzrJYivodqTQ\"}]}",
+        "JWT_PRIVATE_SIGNING_JWK": "{\"e\": \"AQAB\", \"d\": \"HIiV7KNjcdhVbpn3KT-I9n3JPf5YbGXsCIedmPqDH1d4QhBofuAqZ9zebQuxkRUpmqtYMv0Zi6ECSUqH387GYQF_XvFUFcjQRPycISd8TH0DAKaDpGr-AYNshnKiEtQpINhcP44I1AYNPCwyoxXA1fGTtmkKChsuWea7o8kytwU5xSejvh5-jiqu2SF4GEl0BEXIAPZsgbzoPIWNxgO4_RzNnWs6nJZeszcaDD0CyezVSuH9QcI6g5QFzAC_YuykSsaaFJhZ05DocBsLczShJ9Omf6PnK9xlm26I84xrEh_7x4fVmNBg3xWTLh8qOnHqGko93A1diLRCrKHOvnpvgQ\", \"n\": \"o5cn3ljSRi6FaDEKTn0PS-oL9EFyv1pI7dRgffQLD1qf5D6sprmYfWWokSsrWig8u2y0HChSygR6Jn5KXBqQn6FpM0dDJLnWQDRXHLl3Ey1iPYgDSmOIsIGrV9ZyNCQwk03wAgWbfdBTig3QSDYD-sTNOs3pc4UD_PqAvU2nz_1SS2ZiOwOn5F6gulE1L0iE3KEUEvOIagfHNVhz0oxa_VRZILkzV-zr6R_TW1m97h4H8jXl_VJyQGyhMGGypuDrQ9_vaY_RLEulLCyY0INglHWQ7pckxBtI5q55-Vio2wgewe2_qYcGsnBGaDNbySAsvYcWRrqDiFyzrJYivodqTQ\", \"q\": \"3T3DEtBUka7hLGdIsDlC96Uadx_q_E4Vb1cxx_4Ss_wGp1Loz3N3ZngGyInsKlmbBgLo1Ykd6T9TRvRNEWEtFSOcm2INIBoVoXk7W5RuPa8Cgq2tjQj9ziGQ08JMejrPlj3Q1wmALJr5VTfvSYBu0WkljhKNCy1KB6fCby0C9WE\", \"p\": \"vUqzWPZnDG4IXyo-k5F0bHV0BNL_pVhQoLW7eyFHnw74IOEfSbdsMspNcPSFIrtgPsn7981qv3lN_staZ6JflKfHayjB_lvltHyZxfl0dvruShZOx1N6ykEo7YrAskC_qxUyrIvqmJ64zPW3jkuOYrFs7Ykj3zFx3Zq1H5568G0\", \"kid\": \"BTZ9HA6K\", \"kty\": \"RSA\"}"
+    },
     "MODULESTORE": {
         "default": {
             "ENGINE": "xmodule.modulestore.mixed.MixedModuleStore",
diff --git a/lms/envs/bok_choy.env.json b/lms/envs/bok_choy.env.json
index 7bb9b3756c4d69901095b409b4bc644f4366be82..5b644dcc9c9a29a8373da9b832aecf377d786e81 100644
--- a/lms/envs/bok_choy.env.json
+++ b/lms/envs/bok_choy.env.json
@@ -92,9 +92,6 @@
     },
     "FEEDBACK_SUBMISSION_EMAIL": "",
     "GITHUB_REPO_ROOT": "** OVERRIDDEN **",
-    "JWT_AUTH": {
-        "JWT_SECRET_KEY": "super-secret-key"
-    },
     "LMS_BASE": "localhost:8003",
     "LMS_ROOT_URL": "http://localhost:8003",
     "LOCAL_LOGLEVEL": "INFO",
diff --git a/lms/envs/bok_choy_docker.auth.json b/lms/envs/bok_choy_docker.auth.json
index 9313c402503a2fa18e7817e117deca789bfa7e5c..767c4044962f886c6a0fe5b8f90a1719621fcc97 100644
--- a/lms/envs/bok_choy_docker.auth.json
+++ b/lms/envs/bok_choy_docker.auth.json
@@ -82,6 +82,11 @@
             }
         }
     },
+    "JWT_AUTH": {
+        "JWT_SECRET_KEY": "super-secret-key",
+        "JWT_PUBLIC_SIGNING_JWK_SET": "{\"keys\": [{\"kid\": \"BTZ9HA6K\", \"e\": \"AQAB\", \"kty\": \"RSA\", \"n\": \"o5cn3ljSRi6FaDEKTn0PS-oL9EFyv1pI7dRgffQLD1qf5D6sprmYfWWokSsrWig8u2y0HChSygR6Jn5KXBqQn6FpM0dDJLnWQDRXHLl3Ey1iPYgDSmOIsIGrV9ZyNCQwk03wAgWbfdBTig3QSDYD-sTNOs3pc4UD_PqAvU2nz_1SS2ZiOwOn5F6gulE1L0iE3KEUEvOIagfHNVhz0oxa_VRZILkzV-zr6R_TW1m97h4H8jXl_VJyQGyhMGGypuDrQ9_vaY_RLEulLCyY0INglHWQ7pckxBtI5q55-Vio2wgewe2_qYcGsnBGaDNbySAsvYcWRrqDiFyzrJYivodqTQ\"}]}",
+        "JWT_PRIVATE_SIGNING_JWK": "{\"e\": \"AQAB\", \"d\": \"HIiV7KNjcdhVbpn3KT-I9n3JPf5YbGXsCIedmPqDH1d4QhBofuAqZ9zebQuxkRUpmqtYMv0Zi6ECSUqH387GYQF_XvFUFcjQRPycISd8TH0DAKaDpGr-AYNshnKiEtQpINhcP44I1AYNPCwyoxXA1fGTtmkKChsuWea7o8kytwU5xSejvh5-jiqu2SF4GEl0BEXIAPZsgbzoPIWNxgO4_RzNnWs6nJZeszcaDD0CyezVSuH9QcI6g5QFzAC_YuykSsaaFJhZ05DocBsLczShJ9Omf6PnK9xlm26I84xrEh_7x4fVmNBg3xWTLh8qOnHqGko93A1diLRCrKHOvnpvgQ\", \"n\": \"o5cn3ljSRi6FaDEKTn0PS-oL9EFyv1pI7dRgffQLD1qf5D6sprmYfWWokSsrWig8u2y0HChSygR6Jn5KXBqQn6FpM0dDJLnWQDRXHLl3Ey1iPYgDSmOIsIGrV9ZyNCQwk03wAgWbfdBTig3QSDYD-sTNOs3pc4UD_PqAvU2nz_1SS2ZiOwOn5F6gulE1L0iE3KEUEvOIagfHNVhz0oxa_VRZILkzV-zr6R_TW1m97h4H8jXl_VJyQGyhMGGypuDrQ9_vaY_RLEulLCyY0INglHWQ7pckxBtI5q55-Vio2wgewe2_qYcGsnBGaDNbySAsvYcWRrqDiFyzrJYivodqTQ\", \"q\": \"3T3DEtBUka7hLGdIsDlC96Uadx_q_E4Vb1cxx_4Ss_wGp1Loz3N3ZngGyInsKlmbBgLo1Ykd6T9TRvRNEWEtFSOcm2INIBoVoXk7W5RuPa8Cgq2tjQj9ziGQ08JMejrPlj3Q1wmALJr5VTfvSYBu0WkljhKNCy1KB6fCby0C9WE\", \"p\": \"vUqzWPZnDG4IXyo-k5F0bHV0BNL_pVhQoLW7eyFHnw74IOEfSbdsMspNcPSFIrtgPsn7981qv3lN_staZ6JflKfHayjB_lvltHyZxfl0dvruShZOx1N6ykEo7YrAskC_qxUyrIvqmJ64zPW3jkuOYrFs7Ykj3zFx3Zq1H5568G0\", \"kid\": \"BTZ9HA6K\", \"kty\": \"RSA\"}"
+    },
     "MODULESTORE": {
         "default": {
             "ENGINE": "xmodule.modulestore.mixed.MixedModuleStore",
diff --git a/lms/envs/bok_choy_docker.env.json b/lms/envs/bok_choy_docker.env.json
index 713ce3d22f575687de739082599cbadf7ca338f5..b2a799da2f7f476264fc34d9c0bda61e16cf540a 100644
--- a/lms/envs/bok_choy_docker.env.json
+++ b/lms/envs/bok_choy_docker.env.json
@@ -92,9 +92,6 @@
     },
     "FEEDBACK_SUBMISSION_EMAIL": "",
     "GITHUB_REPO_ROOT": "** OVERRIDDEN **",
-    "JWT_AUTH": {
-        "JWT_SECRET_KEY": "super-secret-key"
-    },
     "LMS_BASE": "http://edx.devstack.lms:18003",
     "LMS_ROOT_URL": "http://edx.devstack.lms:18003",
     "LOCAL_LOGLEVEL": "INFO",
diff --git a/lms/envs/test.py b/lms/envs/test.py
index 08cfdd4e7e6aea65a5295225c9b195966288e1bc..f8c2f2a83c63748b4b6ad1110dc45be54f72d16d 100644
--- a/lms/envs/test.py
+++ b/lms/envs/test.py
@@ -50,6 +50,8 @@ os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS'] = 'localhost:8000-9000'
 
 THIS_UUID = uuid4().hex[:5]
 
+FEATURES['DISABLE_SET_JWT_COOKIES_FOR_TESTS'] = True
+
 # can't test start dates with this True, but on the other hand,
 # can test everything else :)
 FEATURES['DISABLE_START_DATES'] = True
@@ -596,7 +598,6 @@ JWT_AUTH.update({
         'ayjB_lvltHyZxfl0dvruShZOx1N6ykEo7YrAskC_qxUyrIvqmJ64zPW3jkuOYrFs7Ykj3zFx3Zq1H5568G0", "kid": "BTZ9HA6K", "kty"'
         ': "RSA"}'
     ),
-    'JWT_LOGIN_CLIENT_ID': 'test-login-service-client-id',
 })
 
 ####################### Plugin Settings ##########################
diff --git a/openedx/core/djangoapps/user_api/accounts/tests/test_api.py b/openedx/core/djangoapps/user_api/accounts/tests/test_api.py
index cf1001312363870f3c83a4c3188c73092a38e0d5..48e54f483d11385b9027fced7f7d510c7ad29cb7 100644
--- a/openedx/core/djangoapps/user_api/accounts/tests/test_api.py
+++ b/openedx/core/djangoapps/user_api/accounts/tests/test_api.py
@@ -57,7 +57,6 @@ from openedx.core.djangoapps.user_api.errors import (
     UserNotAuthorized,
     UserNotFound
 )
-from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_flag
 from openedx.core.djangolib.testing.utils import skip_unless_lms
 from openedx.core.lib.tests import attr
 from student.models import PendingEmailChange
diff --git a/openedx/core/djangoapps/user_authn/cookies.py b/openedx/core/djangoapps/user_authn/cookies.py
index 242edf0aeb9a70540503339eac8f3a5e90f1d78a..38d9e012a4dab84793d7ffdefef554690dd4d962 100644
--- a/openedx/core/djangoapps/user_authn/cookies.py
+++ b/openedx/core/djangoapps/user_authn/cookies.py
@@ -22,7 +22,6 @@ from openedx.core.djangoapps.oauth_dispatch.api import create_dot_access_token,
 from openedx.core.djangoapps.oauth_dispatch.jwt import create_jwt_from_token
 from openedx.core.djangoapps.user_api.accounts.utils import retrieve_last_sitewide_block_completed
 from openedx.core.djangoapps.user_authn.exceptions import AuthFailedError
-from openedx.core.djangoapps.user_authn.waffle import JWT_COOKIES_FLAG
 from student.models import CourseEnrollment
 
 
@@ -152,15 +151,14 @@ def refresh_jwt_cookies(request, response):
     Resets the JWT related cookies in the response, while expecting a refresh
     cookie in the request.
     """
-    if JWT_COOKIES_FLAG.is_enabled():
-        try:
-            refresh_token = request.COOKIES[jwt_cookies.jwt_refresh_cookie_name()]
-        except KeyError:
-            raise AuthFailedError(u"JWT Refresh Cookie not found in request.")
+    try:
+        refresh_token = request.COOKIES[jwt_cookies.jwt_refresh_cookie_name()]
+    except KeyError:
+        raise AuthFailedError(u"JWT Refresh Cookie not found in request.")
 
-        # TODO don't extend the cookie expiration - reuse value from existing cookie
-        cookie_settings = standard_cookie_settings(request)
-        _create_and_set_jwt_cookies(response, request, cookie_settings, refresh_token=refresh_token)
+    # TODO don't extend the cookie expiration - reuse value from existing cookie
+    cookie_settings = standard_cookie_settings(request)
+    _create_and_set_jwt_cookies(response, request, cookie_settings, refresh_token=refresh_token)
     return response
 
 
@@ -248,7 +246,12 @@ def _get_user_info_cookie_data(request, user):
 
 def _create_and_set_jwt_cookies(response, request, cookie_settings, user=None, refresh_token=None):
     """ Sets a cookie containing a JWT on the response. """
-    if not JWT_COOKIES_FLAG.is_enabled():
+
+    # Skip setting JWT cookies for most unit tests, since it raises errors when
+    # a login oauth client cannot be found in the database in ``_get_login_oauth_client``.
+    # This solution is not ideal, but see https://github.com/edx/edx-platform/pull/19180#issue-226706355
+    # for a discussion of alternative solutions that did not work or were halted.
+    if settings.FEATURES.get('DISABLE_SET_JWT_COOKIES_FOR_TESTS', False):
         return
 
     # For security reasons, the JWT that is embedded inside the cookie expires
diff --git a/openedx/core/djangoapps/user_authn/tests/test_cookies.py b/openedx/core/djangoapps/user_authn/tests/test_cookies.py
index daefd24fc6778bdf8fd1c411bf2104e12ce52ee5..ce903d370860d78219bb2fd720c643367b959858 100644
--- a/openedx/core/djangoapps/user_authn/tests/test_cookies.py
+++ b/openedx/core/djangoapps/user_authn/tests/test_cookies.py
@@ -1,7 +1,7 @@
 # pylint: disable=missing-docstring
 from __future__ import unicode_literals
 
-from mock import MagicMock
+from mock import MagicMock, patch
 import six
 from django.conf import settings
 from django.http import HttpResponse
@@ -108,14 +108,14 @@ class CookieTests(TestCase):
         self._assert_consistent_expires(response)
         self._assert_recreate_jwt_from_cookies(response, can_recreate=False)
 
+    @patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": False})
     def test_set_logged_in_jwt_cookies(self):
         setup_login_oauth_client()
         self._set_use_jwt_cookie_header(self.request)
-        with cookies_api.JWT_COOKIES_FLAG.override(True):
-            response = cookies_api.set_logged_in_cookies(self.request, HttpResponse(), self.user)
-            self._assert_cookies_present(response, cookies_api.ALL_LOGGED_IN_COOKIE_NAMES)
-            self._assert_consistent_expires(response)
-            self._assert_recreate_jwt_from_cookies(response, can_recreate=True)
+        response = cookies_api.set_logged_in_cookies(self.request, HttpResponse(), self.user)
+        self._assert_cookies_present(response, cookies_api.ALL_LOGGED_IN_COOKIE_NAMES)
+        self._assert_consistent_expires(response)
+        self._assert_recreate_jwt_from_cookies(response, can_recreate=True)
 
     def test_delete_and_is_logged_in_cookie_set(self):
         response = cookies_api.set_logged_in_cookies(self.request, HttpResponse(), self.user)
@@ -126,19 +126,19 @@ class CookieTests(TestCase):
         self._copy_cookies_to_request(response, self.request)
         self.assertFalse(cookies_api.is_logged_in_cookie_set(self.request))
 
+    @patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": False})
     def test_refresh_jwt_cookies(self):
         def _get_refresh_token_value(response):
             return response.cookies[cookies_api.jwt_cookies.jwt_refresh_cookie_name()].value
 
         setup_login_oauth_client()
         self._set_use_jwt_cookie_header(self.request)
-        with cookies_api.JWT_COOKIES_FLAG.override(True):
-            response = cookies_api.set_logged_in_cookies(self.request, HttpResponse(), self.user)
-            self._copy_cookies_to_request(response, self.request)
-
-            new_response = cookies_api.refresh_jwt_cookies(self.request, HttpResponse())
-            self._assert_recreate_jwt_from_cookies(new_response, can_recreate=True)
-            self.assertNotEqual(
-                _get_refresh_token_value(response),
-                _get_refresh_token_value(new_response),
-            )
+        response = cookies_api.set_logged_in_cookies(self.request, HttpResponse(), self.user)
+        self._copy_cookies_to_request(response, self.request)
+
+        new_response = cookies_api.refresh_jwt_cookies(self.request, HttpResponse())
+        self._assert_recreate_jwt_from_cookies(new_response, can_recreate=True)
+        self.assertNotEqual(
+            _get_refresh_token_value(response),
+            _get_refresh_token_value(new_response),
+        )
diff --git a/openedx/core/djangoapps/user_authn/views/tests/test_login.py b/openedx/core/djangoapps/user_authn/views/tests/test_login.py
index bfb6db00691a86d7a4cc1f7b21f82d43f5b53046..0e69f90f2a26891667fe5eb3f995556e891b4dcb 100644
--- a/openedx/core/djangoapps/user_authn/views/tests/test_login.py
+++ b/openedx/core/djangoapps/user_authn/views/tests/test_login.py
@@ -26,7 +26,6 @@ from openedx.core.djangoapps.password_policy.compliance import (
 from openedx.core.djangoapps.user_api.config.waffle import PREVENT_AUTH_USER_WRITES, waffle
 from openedx.core.djangoapps.user_authn.cookies import jwt_cookies
 from openedx.core.djangoapps.user_authn.tests.utils import setup_login_oauth_client
-from openedx.core.djangoapps.user_authn.waffle import JWT_COOKIES_FLAG
 from openedx.core.djangolib.testing.utils import CacheIsolationTestCase
 from student.tests.factories import RegistrationFactory, UserFactory, UserProfileFactory
 from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
@@ -292,18 +291,18 @@ class LoginTest(CacheIsolationTestCase):
         response, _audit_log = self._login_response('test@edx.org', 'wrong_password')
         self._assert_response(response, success=False, value='Too many failed login attempts')
 
+    @patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": False})
     def test_login_refresh(self):
         def _assert_jwt_cookie_present(response):
             self.assertEqual(response.status_code, 200)
             self.assertIn(jwt_cookies.jwt_refresh_cookie_name(), self.client.cookies)
 
         setup_login_oauth_client()
-        with JWT_COOKIES_FLAG.override(True):
-            response, _ = self._login_response('test@edx.org', 'test_password')
-            _assert_jwt_cookie_present(response)
+        response, _ = self._login_response('test@edx.org', 'test_password')
+        _assert_jwt_cookie_present(response)
 
-            response = self.client.post(reverse('login_refresh'))
-            _assert_jwt_cookie_present(response)
+        response = self.client.post(reverse('login_refresh'))
+        _assert_jwt_cookie_present(response)
 
     @patch.dict("django.conf.settings.FEATURES", {'PREVENT_CONCURRENT_LOGINS': True})
     def test_single_session(self):
diff --git a/openedx/core/djangoapps/user_authn/views/tests/test_register.py b/openedx/core/djangoapps/user_authn/views/tests/test_register.py
index 749b76e8ec24d79d123ac7604ee8219e9f4e31a7..98a0d3bfcf9bccc5bac1b1581bc0cdae7993b74c 100644
--- a/openedx/core/djangoapps/user_authn/views/tests/test_register.py
+++ b/openedx/core/djangoapps/user_authn/views/tests/test_register.py
@@ -25,7 +25,6 @@ from openedx.core.djangoapps.user_authn.views.register import (
     _skip_activation_email,
 )
 from openedx.core.djangoapps.external_auth.models import ExternalAuthMap
-from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_flag
 from openedx.core.djangoapps.lang_pref import LANGUAGE_KEY
 from openedx.core.djangoapps.site_configuration.tests.mixins import SiteMixin
 from openedx.core.djangoapps.user_api.accounts import (
diff --git a/openedx/core/djangoapps/user_authn/waffle.py b/openedx/core/djangoapps/user_authn/waffle.py
deleted file mode 100644
index 79fae6db8170f0e4386184b9d2520b5488ab0695..0000000000000000000000000000000000000000
--- a/openedx/core/djangoapps/user_authn/waffle.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
-Feature toggles for user_authn.
-"""
-from openedx.core.djangoapps.waffle_utils import WaffleFlagNamespace, WaffleFlag
-
-# Namespace
-_WAFFLE_NAMESPACE = u'user_authn'
-_WAFFLE_FLAG_NAMESPACE = WaffleFlagNamespace(_WAFFLE_NAMESPACE)
-
-# Flags
-
-# TODO (ARCH-247)
-# Intended as a temporary toggle for roll-out of jwt cookies feature.
-# Satisfies Use Case #3 "Ops - Monitored Rollout" from
-# https://open-edx-proposals.readthedocs.io/en/latest/oep-0017-bp-feature-toggles.html
-JWT_COOKIES_FLAG = WaffleFlag(_WAFFLE_FLAG_NAMESPACE, u'jwt_cookies')