Skip to content

RPC 2.0

Zach Hyatt edited this page Sep 13, 2021 · 5 revisions

Brief history

IPC 2.0 was added here: https://github.com/nanocurrency/nano-node/pull/2487 and established the framework for building a new RPC 2.0 on top. Plans for needed RPC changes were gathered.

Current state notes

From cryptocode: https://gist.github.com/cryptocode/b1ab2ef321df5e7ecf6b29cef0d387e8

RPC 2.0 changes identified

Authentication

From cryptocode:

Regarding exposing RPCs in a more fine-grained way, I think we should ditch enable_control and introduce a simple IPC-level permission system. One approach is to have an api-key or JWT tag in every message, along with role and permission settings in the node. The node code would check for permissions, and then you assign roles and users/api-keys in the config, with reasonable defaults. A good start is to treat every RPC message as a permission, but you can of course envision to go beyond that, like wallet access to specific accounts.

Default could be access to "safe" apis (like now), and adjusting this would be a configuration matter for the node owner. For the HTTP gateway, we could do a mapping from an x-api-key header entry.

The config format would allow for things like making a list of a few RPCs you'd like to expose to a user or role.

If we think this idea is worth exploring, then I would like to experiment with this during the IPC rework.

Update: Below some config examples that materialized in chats with Guilherme.

Made-up syntax, but similar to what I've used in similar role/permission systems like Apache Shiro

Example where the default user gets everything (same as flipping enable_control):

[[user]]
roles = "full-control"

Example where a specific user gets wallet control, as well as a specific callback:

[[user]]
id = "apikey-958249029092834029834"
roles = "wallet-control"
resources = "callback:notification_Confirmation"

Example where a role is defined, and a user gets the role and additional resource

[[role]]
name = "my-awesome-wallet-client"
desc = "Access to what my awesome nano wallet needs"
resources = "api:accounts_History, api:blocks_Process, ..."

[[user]]
id = "apikey-my-frontend-server"
roles = "my-awesome-wallet-client"
resources = "callback:notification_Confirmation"

In the node, we'd use something like this to check permissions (notice no role checks, only permission checks, to avoid maintenance nightmares):

if (nano::ipc::auth::has_access (msg, nano::permission::wallet_seed_export))
{ ... }