Draft guidance for developers on how to manage OAuth secrets and app confidentiality, including guidance for mobile and desktop apps.
When creating a client, the OAuth extension supports a checkbox for "Client is confidential: A confidential client is an application that is capable of keeping a client password confidential to the world. Non-confidential clients are less secure". For the API Portal, our current working copy for this checkbox is: "I can keep my app credentials secure" with a link out to a documentation page.
From the backend perspective, this is a purely self-reported field. There's no way for the extension to know whether the credentials are actually secure or not. If a user doesn't check the box, two things happen:
- When using the authorization code flow, the client must use a PKCE code challenge and the client credentials are not evaluated when exchanging an authorization code for an access token.
- The client cannot use the client credentials flow.
- From Reedy: It might be best having something more wordy; making it explicit that we expect some action in case of suspected compromise/breach/poor handling etc. And making it explicit (on the page) what difference checking it or not makes.
- From Dejan: Actually, this was something that stood out to me as weird when implementing OAuth2.0. If you cannot keep your secret secure (client not confidential) Oauth says: "Ok, then i just wont check the secret", and grant you full functionality. PKCE CC is required, that is true, but that does not do much in the matter of security
Drafts for Create App flow:
"I agree to follow [[security best practices]] for key management. If I have reason to believe that the key may have been compromised, I also agree to revoke that key and replace it"
Guidance for mobile and desktop apps
From OAuth for Developers, "The application secret must be kept secret. Submitting it to source control or putting it into user-accessible code (such as mobile app or desktop application; even if it is obfuscated) undermines the security model and will result in admins forcefully disabling the application. Exceptions are made for example applications demoing OAuth usage, if they are explicitly labeled as such and request limited rights."
See also: T255370
Comparison of app types and OAuth flows
|app type||authorization code flow||client credentials flow||owner-only authorization flow|
|public||allowed with PKCE||not allowed||not allowed|
confidential: "Clients capable of maintaining the confidentiality of their credentials (e.g., client implemented on a secure server with restricted access to the client credentials), or capable of secure client authentication using other means."(ref) Example: web server app
public + authorization code flow: As recommended by RFC 8252, the OAuth extension requires public clients to use a PKCE as part of the auth process. In addition, the RFC recommends that public apps open the authorization request in the system browser and use a redirect URI that returns the authorization response back to the app. We can easily include these best practices in the API Portal docs.
public + client credentials flow: If the client is marked as public during creation, the OAuth extension prohibits the client from using the client credentials flow. However, I can see a possible need for this use case. For example: a mobile-app developer might want to incorporate content from Wikimedia into their app, but they don't want their users to have to go through the Wikimedia authorization process just to see that content. The only option I see for these use cases (short of advising them to call the API without OAuth) is to ask them to re-architect their apps so that the app communicates with a server that they control, making it a confidential client. How much friction does it cause to make this recommendation? What percentage of API Portal developers fall into this use case?
public + owner-only authorization flow: This would be a bot running on a public client, which seems like an odd choice. Is there any chance someone would want to do this?