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 withinthe 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 ofindividual 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.
- API to manage registered event streams and subscriptions
- 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
- requireschain.transactions
andchain.receipts
permissions/replies/:UUID
- requireschain.receipts
permission/eventstreams/*
- requireschain.filter
andchain.subscribe
permissions/subscriptions/*
- requireschain.filter
andchain.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
- When matching binary values, the regular expression runs against the hex without an
- First rule to match applies
- If two
tx
specifications match aneth_sendTransaction
call, and the first has"send": false
and the second"send": true
then the request is disallowed - If two
rpc
specifications match antxpool_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
- If two
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 therpc
section, then anyeth_sendTransaction
call be allowed, regardless of the details in thecontracts
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 therpc
section
- 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