Extending admin console with custom pages?

The Nakama Console is great. I was wondering is there any way to extend it with custom pages for my specific game?

For example, like creating a custom page for giving players rewards, or some other sort of specific game management page. I know I can use API Explorer and RPCs, but I was hoping to create dedicated pages/dashboards.

Regarding admin-only RPCs, what’s the best approach to keep them safe and only allow them to be invoked from the Nakama admin console – while still allowing to pass in userId (e.g. giving item to player)?

If the Nakama Console can not easily be extended directly, is there any other recommended approach where I can serve my custom game dashboard webpage in a different port and still interact with Nakama backend as an admin?

Hello @KamilDev,

Currently there’s no way to extend the functionality directly within the console, we recommend exposing server-to-server RPCs and use something like retool to build custom dashboards.

The way of preventing an admin-only RPC from being called from the client is to add some logic that checks whether the context itself contains the userId - if yes then the function is being called in the context of a player session (see the second code snippet here).

If these functions require an arbitrary user_id then just pass them as part of the custom RPC payload.

Hope this helps.

I’d like to better understand the security of admin or server-to-server RPCs. I’m using Unity client and TypeScript server runtime.

I believe the client must know the HTTP key to connect, as shown in docs:

var client = new Nakama.Client("http", "127.0.0.1", 7350, "defaultkey");

Looking at server-to-server RPC docs example:

const serverRpc : nkruntime.RpcFunction = function (ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, payload: string) : string | void {
  if (ctx.userId != "") {
    logger.error("rpc was called by a user");
    return null;
  }
  
  // Valid server to server RPC call, continue executing the RPC...
  return "<JsonResponse>";
}

Can’t a malicious actor easily invoke admin or server-to-server RPCs using:

curl "http://127.0.0.1:7350/v2/rpc/http_handler_path?http_key=defaulthttpkey" \
    -d '"{\"some\": \"data\"}"' \
    -H 'Content-Type: application/json' \
    -H 'Accept: application/json'

As they can obtain the HTTP key from the Unity client code? I’m assuming the HTTP key is treated as public information, given that it is required to be passed into the client as the docs show.

Isn’t what the docs show only prevent user-clients from calling the RPCs, but they can easily open a terminal and use curl to invoke those server RPC actions?

The runtime.http_key is meant to be used for Server-To-Server ONLY and is not meant to be shared with the client.

Ah, that makes sense. So only socket.server_key is the key that’s shared with the client?

Though doesn’t Nakama support HTTP user clients and not exclusively socket user clients? That’s where my confusion came from.

Looking at the docs:

The socket interface is the primary entry point for real-time activity such as chat and real-time multiplayer. The socket interface runs on WebSockets and rUDP, with a choice of binary (protocol buffers) or text (JSON) payloads.

The request interface, which runs on gRPC and HTTP, is the primary entry point for non-real-time activity, such as user account management.

I was confused and thought socket.server_key is only for socket clients, and not for HTTP clients as well.

Is it just a weird naming thing?

Yes, we admit the chosen name for this config wasn’t the best, but the idea is that it sort of protects the socket connection regardless of protocol (ultimately both rt or http connections run over sockets).

The socket.server_key doesn’t really provide additional security, it’s more to ensure that the clients are connecting to the correct instance.

1 Like