Skip to content

IPC Authorization

cryptocode edited this page Sep 9, 2021 · 6 revisions

Permission settings is a work in progress, and their exact definition and defaults will be part of RPC 2.0.

With IPC 2.0, the Nano node offers an authorization system.

The configuration is done in config-access.toml by defining users and optional roles. Permissions are then assigned to these. The node only checks for permissions, never roles. This way, you can freely structure roles and users the way that suits your situation.

There is also a default user with limited default permissions. This is used when no credentials are given. The permissions of the default user can also be changed in the configuration file.

Credentials:

  • IPC clients set the credentials in the message envelope
  • HTTP(S) clients either use a message envelope or the HTTP Header Nano-Api-Key

While permissions enable node operators to pick what functionality to expose to which users, it is still highly recommended that layered security is used. For instance, a wallet backend should expose only required functionality to clients. The backend can then communicate with the node with credentials for additional security.

Call example

curl --header "Nano-Api-Key:mywalletuser" --insecure -d \
   '{ "account": "nano_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3"}' \
   https://www.example.com:7076/api/v2/AccountWeight

This uses https (which the node supports through a build option), and the --insecure is there because the node's certificate in this example is self-signed.

Using an envelope instead of the AccountWeight endpoint:

{ 
   "credentials": "mywalletuser",
   "message_type" : "AccountWeight", 
   "message": 
   {
       "account": "nano_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3" 
   }
} 

POST the above to https://www.example.com:7076/api/v2

Configuration examples

For testing IPC without caring about permissions, this gives access to everything:

[[user]]
allow = "unrestricted"

A more elaborate sample:

[[role]]
id = "process_admin"
allow = "api_service_stop"

[[role]]
id = "walletadmin"
allow = "wallet_read, wallet_write"

# Add some additional permissions to the default user
# This is used when no credentials are given
[[user]]
allow = "wallet_seed_change, epoch_upgrade, wallet_read"

# The default user can also be set to bare (no default permissions). 
# That way, a node can be exposed with a limited set of default permissions.
#bare = true

[[user]]
id = "mywalletuser"
# Inherit all the permissions from these roles
roles = "process_admin, walletadmin"

# Add additional permissions for this specific user
allow = "wallet_seed_change, epoch_upgrade"

# Default and inherited permissions can be denied
deny = "wallet_read"

[[user]]
id = "epoch-user"

# Add specific permission for this user
allow = "epoch_upgrade"

# Do not inherit any default permissions. This is useful
# for making users with an explicit set of minimum permissions.
bare = true

Reload config

The access file can be reloaded without restarting the node or wallet. For the node:

killall -SIGHUP nano_node

(actual syntax depends on OS)

Error response

Example response when the API user lacks sufficient permissions:

{
  "time": 1631189995819,
  "message_type": "Error",
  "message": {
    "code": 3,
    "message": "Access denied"
  }
}