braintree / graphql-api

Schemas, changelogs and feature requests for Braintree's GraphQL API
https://graphql.braintreepayments.com/
61 stars 46 forks source link

Alternative authorization method #5

Closed lukehedger closed 4 years ago

lukehedger commented 5 years ago

Braintree GraphQL API calls are currently authorized by including a base64 encoded combination of a merchant's public and private keys in an Authorization HTTP header, as shown in this example from the docs:

curl \
 -H 'Content-Type: application/json' \
 -H 'Authorization: Basic PUBLICKEY:PRIVATEKEY_BASE64ENCODED' \
 -H 'Braintree-Version: 2019-01-01' \
 -X POST https://payments.sandbox.braintree-api.com/graphql \
 -d '{"query": "query { ping }", "variables": {} }'

Requiring the private key in the Authorization header means that API requests cannot be sent direct from a web client securely, as the merchant's private key is exposed. Instead, API requests would have to be brokered by a server-side service, which seems to negate some of the benefits that GraphQL provides.

Are there plans to offer alternative methods for authorizing GraphQL API requests, such as JSON Web Tokens?

lkorth commented 5 years ago

@lukehedger thanks for opening the issue. This is primarily a documentation issue. The GraphQL API already supports a few different kinds of authorization, tokenization keys, client tokens and oauth access tokens to name a few.

We'll add some information to our documentation around how use these other forms of authorization. In most cases Bearer AUTHORIZATION is going to work for you.

Do note that we don't recommend completely consuming the API from an untrusted client such as a browser or mobile application, especially when it concerns transactions and money movement. We currently restrict some forms of lesser authorization (tokenization keys and client tokens) to only a few operations in the API.

lukehedger commented 5 years ago

Thanks @lkorth - that's a bit clearer for me now. So the GraphQL API is predominantly designed to be consumed on the server, in the same way the SDKs are?

The current ping curl example in the docs also suggests 'Authorization: Basic PUBLICKEY:PRIVATEKEY_BASE64ENCODED as the auth header. Is this correct, or should it be 'Authorization: Bearer PUBLICKEY:PRIVATEKEY_BASE64ENCODED?

Another point here is it's not immediately obvious that you have to encode the public and private key combination and not just the private key. It might be helpful to add a note to clarify what's is required in the auth header.

lkorth commented 5 years ago

Yes, the vast majority of queries and mutations in the API are restricted to server side authorization via public and private keys or oauth access tokens, however in the future we may open up more queries to other forms of authorization as they make sense.

Yes, Basic should be used for public and private key authorization and Bearer for oauth access tokens. There is an earlier section on that page which contains more information about the authorization headers.

Yes, that code snippet could be worded better, if you take a look at the section above it, it describes the format of the public and private keys. We'll update the snippet with PUBLICKEY:PRIVATEKEY_BASE64ENCODED to remove the confusion.

kghandhi commented 4 years ago

@lukehedger we've added documentation for the other forms of authentication we support here if you want to take a look. Thanks again for pointing this out!