API permission/scope?

Hello,

I am studying the Nakama API documentation, and I am searching how I can restrict Permissions to access the API.
For example, I want to block by default access to all Users to the API Leaderboard POST, but not to the GET. So that User can read the leaderboard without any restriction, but only specific set of Admin User will have the permission to write the score.

I can not find way to achieve that, can someone redirect me to where it would be documented please?

Hello @Jonathan,

You’d achieve this by registering a before-hook with some custom code on the public-facing API.

A POST request maps to WriteLeaderboardRecords, so you’d add a before-hook like so:

if err := initializer.RegisterBeforeWriteLeaderboardRecord(func(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, in *api.WriteLeaderboardRecordRequest) (*api.WriteLeaderboardRecordRequest, error) {
  userId, ok := ctx.Value(runtime.RUNTIME_CTX_USER_ID).(string)
  if !ok {
    // User ID not found in the context (happens if the request is a server-to-server call).
    return nil, errors.New("user_id not found")
  }
  
  // Custom logic to validate whether user is admin or not.
  if !isAdmin {
    return nil, errors.New("unauthorized")
  }

  // Allow request through - write will be accepted.
  return in, nil
}); err != nil {
 // Handle register error
}

An alternative route would be to create these leaderboards via the server runtime with the param authoritative set to true (this disallows any writes that don’t come from the server runtime) and register a custom RPC that checks whether the incoming request is from an admin (the logic would be similar to the above) and if yes, then you’d call the server runtime LeaderboardRecordWrite to update the score.

Hope this helps.

Thank you ! I see the idea, that can work indeed!
Followup question, can I add custom information in the session token?
I am thinking to add a role information into the token, that can be checked in the before-hook.

That would allow me to have multiple role per User. It would allow me to have User access role with higher permission in specific condition.
For example from his device, the User can access to a role giving him access to read his own Profile and Leaderboards.
From a GameServer, the User can access a role giving him access to Read/Write his Profile/Leaderboard.
Etc …

Yes you can, you’re looking for session-variables.

You just need to be mindful that if these variables need updating, you’d have to force a SessionRefresh to update the values in the token.

Alternatively you could store the roles in a Storage Object that can only be updated by the server.

Best.

2 Likes

@Jonathan Just to add to what @sesposito shared with you. You can find information on how to guard the API for various types of game design within our documentation here:

https://heroiclabs.com/docs/nakama/guides/server-framework/guarding-apis/

1 Like