Rulesets

Once an authenticated connection is mapped to a ruleset every JSON/RPC request is evaluated against that ruleset before being passed to the blockchain node.

Matchers and Rules

In the rule specification there are bool (true/false) permissions that enable specific operations.

There are also regular expression regex matchers that determine whether the permissions within a section apply or not.

Where you see []object in the rules table below, you will see a set of matchers inside of that section, and then a set of permissions. The permissions from the first entry that matches a request will be applied.

List of Rules

The following rules can be applied to configure write and read-access to the chain.

Matcher/Rule (Type) JSON/RPC Methods / Description
templated
(bool)
If set then the regex matchers such as tx[].from and tx[].to within
the rule will be dynamically generated from the claims
such as {{.claimName}}3
chain.info
(bool)
net_version
eth_chainId
eth_protocolVersion
eth_gasPrice
Chain information required by a wallet to sign and submit transactions
chain.receipts
(bool)
eth_getTransactionReceipt
Query individual transaction receipts by hash, to confirm mining into a block
chain.blocks
(bool)
eth_blockNumber
eth_getBlockTransactionCountByHash
eth_getBlockTransactionCountByNumber
eth_getBlockByHash
eth_getBlockByNumber
eth_getUncleCountByBlockHash
eth_getUncleCountByBlockNumber
eth_getUncleByBlockHashAndIndex
eth_getUncleByBlockNumberAndIndex
Query block information
chain.transactions
(bool))
eth_getLogs
eth_getCode
eth_getTransactionByHash
eth_getTransactionByBlockHashAndIndex
eth_getTransactionByBlockNumberAndIndex
Query the data and logs (events) of transactions
chain.pending
(bool)
eth_pendingTransactions
Query pending transaction information
chain.filter
(bool)
eth_newFilter
eth_newBlockFilter
eth_newPendingTransactionFilter
eth_uninstallFilter
eth_getFilterChanges
eth_getFilterLogs
Use filters to poll for changes on the chain.
Includes transaction and block data2
chain.subscribe
(bool)
eth_subscribe
Use websocket subscriptions to listen for changes on the chain.
Includes transaction and block data2
accounts.coinbase
(bool)
eth_coinbase
Query the coinbase address used by the connected node
accounts.balance
(bool)
eth_getBalance
Query ether balances for accounts/contracts
accounts.nonce
(bool)
eth_getTransactionCount
Query the transaction count for an address to use for next-nonce calculation
accounts.storage
(bool)
eth_getProof
eth_getStorageAt
Query the storage data for a contract address
accounts.list
(bool)
eth_accounts
List the accounts available for node-based signing on the connected node
accounts.sign
(bool)
eth_sign
Signing of any binary payload by the private key
of accounts managed by the connected node1
tx[]
([]object)
Array of rules that match transaction methods (details follow)
tx[].from
(regex)
Matcher for this rule against the from address of the transaction
tx[].to
(regex)
Matcher for this rule against the to address of the transaction
(empty string matches contract deployment)
tx[].send
(bool)
eth_sendTransaction
Send transactions signed by the private key of accounts managed by the connected node1
tx[].sendRaw
(bool)
eth_sendRawTransaction
Send externally signed transactions
tx[].call
(bool)
eth_call
Query data from contracts by performing read-only execution of methods
tx[].estimate
(bool)
eth_estimateGas
Estimate the gas required to execute the transaction
tx[].deploy
(bool)
eth_sendTransaction
eth_sendRawTransaction with empty to
Send transactions that deploy new contract instances
rpc[]
([]object)
Array of rules to allow execution of JSON/RPC methods.
Use only when detailed rules do not cover the required method.
rpc[].method
(regex)
Matcher for the name of the method
rpc[].allow
(bool)
If the method is allowed (false allows blacklisting of
individual methods otherwise allowed by later rules)
  • [1] Signing could be performed by node based accounts, or managed wallets in the same membership as the node routed dynamically by the REST API Gateway.
  • [2] An on/off permission is provided filters and subscriptions, because the filter/subscription ID namespace for a node is flat. Consider using Kaleido Event Streams for granular access to on-chain events.
  • [3] The templating language is Go templates, and the claims are not escaped before they are inserted into the regular expression.

Example rulesets

{
  "rulesets": {
    // Example that allows all JSON/RPC operations and REST API Gateway APIs
    "admin-ruleset": {
      "chain": {
        "receipts": true,
        "transactions": true,
        "filter": true,
        "subscribe": true
      },
      "rpc": [{
        "method": ".*",
        "allow": true
      }]
    },
    // Example that allows existing contracts to be invoked with external wallet signing keys,
    // but disallows deployment of new contract instanaces
    "extsign-and-read-chain": {
      "tx": [
        {
          "from": ".*", // any external signing address
          "to": ".*", // any deployed contract
          "call": true, // query data from the chain
          "estimate": true, // perform gas estimation
          "send": false,
          "sendRaw": true, // externally sign
          "deploy": false // cannot deploy new contracts (prevents empty 'to' address)
        }
      ],
      "chain": {
        "info": true, // needed for chain ID
        "receipts": true, // needed to query receipts
        "pending": false,
        "blocks": false,
        "transactions": false,
        "filter": false,
        "subscribe": false
      },
      "accounts": {
        "coinbase": true,
        "balance": true,
        "nonce": true, // needed to calculate the next nonce
        "storage": false,
        "list": false,
        "sign": false
      },
      "rpc": []
    },
    // Use one key to send to one contract
    "sign-and-send-single-address": {
      "tx": [
        {
          "from": "3881c71d6a6B94a6741257bf0aE17770DBAAdBD8", // signing key
          "to": "c114A22618156F6B42CEbFaEA823a94455cA3F19", // contract address
          "call": true, // query data from the chain
          "estimate": true, // perform gas estimation
          "send": true, // sign using managed keys
          "sendRaw": false,
          "deploy": false
        }
      ],
      "chain": {
        "info": true,
        "receipts": true,
        "pending": false,
        "blocks": false,
        "transactions": false,
        "filter": false,
        "subscribe": false
      },
      "accounts": {
        "coinbase": true,
        "balance": true,
        "nonce": false,
        "storage": false,
        "list": false,
        "sign": false // this allows arbitrary signing of data, and is not required for sending transactions to be remotedly signed
      },
      "rpc": []
    }
  }
}

Special rules for the REST API Gateway

There are two areas of function in the REST API Gateway that do not directly map to a set of JSON/RPC commands issued against a blockchain node.

  1. API to manage registered event streams and subscriptions
  2. API to query the receipt store

We are working on a more sophisticated permissioning system for these stateful resources.

Currently are permissioned as follows:

  • /replies - requires chain.transactions and chain.receipts permissions
  • /replies/:UUID - requires chain.receipts permission
  • /eventstreams/* - requires chain.filter and chain.subscribe permissions
  • /subscriptions/* - requires chain.filter and chain.subscribe permissions

Detailed ruleset semantics

  • Rules are boolean flags, applied to a matching JSON/RPC request
    • Matching is performed against the JSON/RPC method name
    • For transaction send/call/estimate payloads, the RLP request is decoded and matching is performed against the parameters of the request as well
  • Regular expressions are used for flexible matching, according to the following rules
    • When matching binary values, the regular expression runs against the hex without an 0x prefix
    • The whole string must match (an implicit ^ prefix and $ suffix exist on the regex)
    • Multi-line mode is disabled - so the whole string must match across lines
    • The match is case insensitive
    • See https://github.com/google/re2/wiki/Syntax for the precise regex syntax supported
  • First rule to match applies
    • If two tx specifications match an eth_sendTransaction call, and the first has "send": false and the second "send": true then the request is disallowed
    • If two rpc specifications match an txpool_summary call, and the first has has "allow": false and the second has "allow": true then the request id disallowed
    • If no rule matches, then the request is disallowed
  • rpc rules are applied first, so override any detailed rule (tx/chain/accounts etc.)
    • Allows additional RPC namespaces and methods to be authorized that are not included in the default rules. Does not currently allow restriction on the parameters - so any params are allowed when a method is allowed in the rpc section.
    • If eth_.* is included in the rpc section, then any eth_sendTransaction call be allowed, regardless of the details in the contracts section
    • This global override approach allows future extensibility of the detailed rules, because new categories and boolean flags can be introduced (with a false default) without revoking overlapping permissions in the rpc section