Skip to content
robertu edited this page Sep 3, 2020 · 5 revisions

What's Scope?

Scope is a mechanism in OAuth 2.0 to limit an application's access to a user's account. An application can request one or more scopes, this information is then presented to the user in the consent screen, and the access token issued to the application will be limited to the scopes granted.

The OAuth spec allows the authorization server or user to modify the scopes granted to the application compared to what is requested, although there are not many examples of services doing this in practice.

OAuth does not define any particular values for scopes, since it is highly dependent on the service's internal architecture and needs.

https://oauth.net/2/scope/

Scopes to Matters API

Unlike GitHub or Slack, we designed intuitive scopes like a GraphQL native:

  • Operation: similar to GraphQL, there are two types of operation: query and mutation.
  • Hierarchical: similar to GrahphQL schema, query scopes can define in a hierarchy.

Query

The following fields aren't public, so you should request what you need in the scopes.

Name Description
User.settings
User.recommendation
User.drafts
User.activity
User.blockList
User.info.email
User.status.role
User.status.unreadNoticeCount
User.liker.total

Currently, we only support query that starts from the viewer root. The pattern of Query scope is query:viewer:${fieldName} (nested fields split with :):

# to access the viewer's email
query:viewer:info:email

# to access the viewer's status, including unreadNoticeCount and role
query:viewer:status

Mutation

The following mutations aren't public, so you should request what you need in the scopes.

Article & Tag

Name Related priviate fields Group
publishArticle User.drafts level2
editArticle level3
toggleSubscribeArticle User.subscriptions level1
appreciateArticle User.activity level3
putTag level1
addArticlesTags level1
updateArticlesTags level1
deleteArticlesTags level1

Comment

Name Related priviate fields Group
putComment level2
deleteComment level2
togglePinComment level1
voteComment level1
unvoteComment level1
updateCommentsState level2

Draft

Name Related priviate fields Group
putDraft User.drafts level3
deleteDraft User.drafts level2

Payment

Name Related priviate fields Group
addCredit User.wallet level3
payTo User.wallet level3
payout User.wallet level3
connectStripeAccount User.wallet level3

User

Name Related priviate fields Group
changeEmail User.info.email level3
verifyEmail level1
generateLikerId User.likerId level3
updateUserInfo level1
updateNotificationSetting User.settings level1
toggleFollowTag level1
toggleFollowUser level1
toggleBlockUser User.blockList level1
toggleSubscribePush level1
clearReadHistory User.activity level3
clearSearchHistory User.activity level3
migration level1

System

Name Related priviate fields Group
singleFileUpload level3
singleFileDelete level3

To simplify the length of the scope, we split them into three groups based on revertibility and the correlation with private fields:

  • level1: no relation with private fields or easy to revert
  • level2: not so easy to revert
  • level3: hard to revert
# to access all mutations in `level1`
mutation:level1

# to access specific mutation
mutation:level1:voteComment
mutation:level2:updateCommentsState

# to access mutations in `level3`, you should request for each mutation 
mutation:level3:payTo # valid
mutation:level3 # invalid

Scope Permission

In order to help you understand how scope permission works, we list some samples in below:

Scope Can Access Can't Access
query:viewer query:viewer
query:viewer:info
query:viewer:info:email
N/A
query:viewer:info query:viewer:info
query:viewer:info:email
query:viewer
mutation:level1 mutation:level1:verifyEmail
mutation:level1:toggleFollowTag
N/A
mutation:level1:verifyEmail mutation:level1:verifyEmail mutation:level1:toggleFollowTag
mutation:level3 N/A N/A
mutation:level3:payTo mutation:level3:payTo mutation:level3:changeEmail