Disable ROPC for all OAuth applications on SaaS

What does this MR do and why?

Adds the ability to disable ROPC for all OAuth applications, based on a feature flag.

Previously we already added an OAuth application-level level control that effectively let us disable ROPC for all new OAuth applications. This FF has been enabled in production for a while, and the behaviour has been verified.

This MR takes the next step with even stricter enforcement: when the disable_ropc_for_all_applications flag is enabled, ROPC is disabled for all OAuth applications, regardless of the application-level setting.

References

Issue: #457352 (closed) FF rollout issue: #566300 (closed)

Previous step MR: !192410 (merged) Previous step FF rollout issue: #545459 (closed)

Screenshots or screen recordings

How to set up and validate locally

  1. Simulate SaaS
  2. We need to create an OAuth application with ROPC enabled, so make sure the disable_ropc_for_new_appliations flag and the new flag are disabled:
# $ gdk rails c 

Feature.disable(:disable_ropc_for_new_applications)
Feature.disable(:disable_ropc_for_all_applications)
  1. Create a new OAuth application via UI: *Admin area > Applications
  2. Test the OAuth password grant flow. Observe you receive an access token, i.e., the flow works OK.
echo "grant_type=password&username=<your_username>&password=<your_password>" > auth.txt
curl --data "@auth.txt" --user <oauth_application_id>:<oauth_application_secret> --request POST "https://<your_gdk_url>/oauth/token"
{"access_token":"<a_token>","token_type":"Bearer","expires_in":7200,"refresh_token":"<a_refresh_token>","scope":"api","created_at":1756406772}
  1. Enable the application-level flag. We want to verify that our OAuth application -- which existed before this flag was turned on -- will still receive a token using ROPC:
Feature.enable(:disable_ropc_for_new_applications)
  1. Test the OAuth password grant flow again. Observe you still received a token.
echo "grant_type=password&username=<your_username>&password=<your_password>" > auth.txt
curl --data "@auth.txt" --user <oauth_application_id>:<oauth_application_secret> --request POST "https://<your_gdk_url>/oauth/token"
{"access_token":"<a_token>","token_type":"Bearer","expires_in":7200,"refresh_token":"<a_refresh_token>","scope":"api","created_at":1756406772}
  1. Enable the global flag. We want to verify that our OAuth application will now not receive a token via ROPC.
Feature.enable(:disable_ropc_for_all_applications)
  1. Test the password grant flow again. Observe you now receive HTTP 401 with an error message, and don't receive a token. This confirms that ROPC is disabled for existing OAuth apps.
echo "grant_type=password&username=<your_username>&password=<your_password>" > auth.txt
curl --data "@auth.txt" --user <oauth_application_id>:<oauth_application_secret> --request POST "https://<your_gdk_url>/oauth/token"
{"error":"unauthorized_client","error_description":"The client is not authorized to perform this request using this method."}

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Related to #457352 (closed)

Merge request reports

Loading