I'm working on an API that I'd like to be accessible internally by other servers as well as devices that I consider both as confidential private clients. Devices are considered private clients because the client_secret is stored in an encrypted area that prevents from unauthorised readout and modification (even though nothing is never bullet proof)

For auth, I'd like to use OAuth2 with the client_credentials grant that seems to be a very good fit for these use cases. However I'm wondering how flexible is the standard regarding sharing the client_secret.

Basically the RFC doesn't say much about sending your client id / client secret, it just offers an example here: https://www.rfc-editor.org/rfc/rfc6749#section-4.4.2 which is very simple by using the following header Authorization Basic: base64(client_id:client_secret)

In my opinion, it could be slightly more secure by computing a hash:

  1. the client requests a random to the server by sending their client_id
  2. the server replies with a random code (valid for like 10 mins, just like an authorization code)
  3. the client computes a hash = sha256(client_id, client_secret, code) and asks for a token
  4. the server computes the same hash, compares the client hash with the computed hash and sends an access token if they match

It would add an extra layer of security in case https is somehow broken or if anyone is able to read the header somehow.

However it doesn't seem very OAuth2 compliant and I don't really like re-inventing a standard. Another option would be to create my own extention grant, I'm just wondering if it's really worth it, like no one seems to have done this.

Also, if I want to share my API with a 3rd party app, not sure it's a good thing to force them into using something non really standard.

2 Answers 2


OAuth2 says that the method of client authentication is up to the authorisation server. It can be anything. Based on RFC 6749,

If the client type is confidential, the client and authorization server establish a client authentication method suitable for the security requirements of the authorization server. The authorization server MAY accept any form of client authentication meeting its security requirements.

Client authentication using client id and client secret is one way. In this case you should follow the best practices for username + password authentication (for example, OWASP Authentication cheetsheet).

One of the important aspects is to not let the attacker figure out a valid username but returning generic error messages (i.e. not returning errors such as "username is invalid"). Your solution's first step would defy this.

  1. the client requests a random to the server by sending their client_id

If the client requests a random value from the server based on their client id, it would confirm to the attacker that the client id is valid.

If the authentication using client id and client secret is not sufficient for you, you should explore other ways of client authentication namely:

  1. Client certificate authentication using TLS (Refer Draft RFC 8705)
  2. Client id + Signed JWT (Refer RFC 7523).

If you're sending a hash of your password then for the server to do this it would need to know the password. Which means storing the password on the server instead of a hash.

Hashing the hash with nonce would make the hash password equivalent so that would result in the same problem. The only way you could prevent this is by using public/private keys

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .