description: Instructions for setting up Clef to seal blocks on a Clique network
---
Clique is a proof-of-authority system where new blocks can be created by authorized ‘signers’ only. The initial set of authorized signers is configured in the genesis block. Signers can be authorized and de-authorized using a voting mechanism, thus allowing the set of signers to change while the blockchain operates. Signing blocks in Clique networks classically uses the "unlock" feature of Geth so that each node is always ready to sign without requiring a user to manually provide authorization.
@ -12,12 +13,10 @@ Clef provides a way to safely circumvent `--unlock` while maintaining a enough a
It is useful to have basic knowledge of private networks and Clef. These topics are covered on our [private networks](/content/docs/developers/geth-developer/private-network) and [Introduction to Clef](/content/docs/tools/Clef/introduction) pages.
{:toc}
- this will be removed by the toc
## Prepping a Clique network
First of all, set up a rudimentary testnet to have something to sign. Create a new keystore (password `testtesttest`)
First of all, set up a rudimentary testnet to have something to sign. Create a new keystore (password `testtesttest`):
```terminal
$ geth account new --datadir ./ddir
@ -186,6 +185,7 @@ And indeed, after approving with `y`, the password is not required - the signed
```terminal
INFO [06-16|11:36:46.714] Successfully sealed new block number=1 sealhash=9589ed..662d03 hash=bd20b9..af8b87 elapsed=4.214s
```
This mode of operation offers quite a poor UX because each block to be sealed requires manual approval. That is fixed in the following section.
## Using rules to approve blocks
@ -334,11 +334,7 @@ DEBUG[06-16|14:20:33.584] Served account_signData reqid=5 durat
## Refinements
If an attacker find the Clef "external" interface (which would only happen if you start it with `http` enabled), they
- cannot make it sign arbitrary transactions,
- cannot sign arbitrary data message,
However, they could still make it sign e.g. 1000 versions of a certain block height, making the chain very unstable.
If an attacker finds the Clef "external" interface (which would only happen if you start it with `--http` enabled), they cannot sign arbitrary data or transactions. However, they could still make it sign e.g. 1000 versions of a certain block height, making the chain very unstable.
It is possible for rule execution to be stateful (i.e. storing data). In this case, one could, for example, store what block heights have been sealed and reject sealing a particular block height twice. In other words, these rules could be used to build a miniature version of an execution layer slashing-db.
@ -381,12 +377,13 @@ JS:> number 46 latest 45
INFO [06-16|22:26:44.313] Op approved
DEBUG[06-16|22:26:45.317] Served account_signData reqid=4 duration=1.010612774s
```
This might be a bit over-the-top, security-wise, and may cause problems if, for some reason, a clique-deadlock needs to be resolved by rolling back and continuing on a side-chain. It is mainly meant as a demonstration that rules can use Javascript and statefulness to construct very intricate signing logic.
This might be a bit over-the-top security-wise, and may cause problems if, for some reason, a clique-deadlock needs to be resolved by rolling back and continuing on a side-chain. It is mainly meant as a demonstration that rules can use Javascript and statefulness to construct very intricate signing logic.
description: Introduction to the external signing tool, Clef
---
{:toc}
- this will be removed by the toc
## What is Clef?
Clef is a tool for **signing transactions and data** in a secure local environment.
t is intended to become a more composable and secure replacement for Geth's built-in
account management. Clef decouples key management from Geth itself, meaning it can be
used as an independent, standalone key management and signing application, or it
can be integrated into Geth. This provides a more flexible modular tool compared to
Geth's account manager. Clef can be used safely in situations where access to Ethereum is
via a remote and/or untrusted node because signing happens locally, either manually or
automatically using custom rulesets. The separation of Clef from the node itself enables it
to run as a daemon on the same machine as the client software, on a secure usb-stick like
[USB armory](https://inversepath.com/usbarmory), or even a separate VM in a
[QubesOS](https://www.qubes-os.org/) type setup.
Clef is a tool for **signing transactions and data** in a secure local environment. It is intended to become a more composable and secure replacement for Geth's built-in account management. Clef decouples key management from Geth itself, meaning it can be used as an independent, standalone key management and signing application, or it can be integrated into Geth. This provides a more flexible modular tool compared to Geth's account manager. Clef can be used safely in situations where access to Ethereum is via a remote and/or untrusted node because signing happens locally, either manually or automatically using custom rulesets. The separation of Clef from the node itself enables it to run as a daemon on the same machine as the client software, on a secure usb-stick like [USB armory](https://inversepath.com/usbarmory), or even a separate VM in a [QubesOS](https://www.qubes-os.org/) type setup.
## Installing and starting Clef
@ -30,9 +17,7 @@ However, Clef is not bound to Geth and can be built on its own using:
`make clef`
Once built, Clef must be initialized. This includes storing some data, some of which is sensitive
(such as passwords, account data, signing rules etc). Initializing Clef takes that data and
encrypts it using a user-defined password.
Once built, Clef must be initialized. This includes storing some data, some of which is sensitive (such as passwords, account data, signing rules etc). Initializing Clef takes that data and encrypts it using a user-defined password.
`clef init`
@ -71,66 +56,31 @@ You should treat 'masterseed.json' with utmost secrecy and make a backup of it!
## Security model
One of the major benefits of Clef is that it is decoupled from the client software,
meaning it can be used by users and dapps to sign data and transactions in a secure,
local environment and send the signed packet to an arbitrary Ethereum entry-point, which
might include, for example, an untrusted remote node. Alternatively, Clef can simply be
used as a standalone, composable signer that can be a backend component for decentralized
applications. This requires a secure architecture that separates cryptographic operations
from user interactions and internal/external communication.
One of the major benefits of Clef is that it is decoupled from the client software, meaning it can be used by users and dapps to sign data and transactions in a secure, local environment and send the signed packet to an arbitrary Ethereum entry-point, which might include, for example, an untrusted remote node. Alternatively, Clef can simply be used as a standalone, composable signer that can be a backend component for decentralized applications. This requires a secure architecture that separates cryptographic operations from user interactions and internal/external communication.
The security model of Clef is as follows:
* A self-contained binary controls all cryptographic operations including encryption,
decryption and storage of keystore files, and signing data and transactions.
* A well defined, deliberately minimal "external" API is used to communicate with the
Clef binary - Clef considers this external traffic to be UNTRUSTED. This means Clef
does not accept any credentials and does not recognize authority of requests received
over this channel. Clef listens on `http.addr:http.port` or `ipcpath` - the same as Geth -
and expects messages to be formatted using the [JSON-RPC 2.0 standard](https://www.jsonrpc.org/specification).
Some of the external API calls require some user interaction (manual approve/deny)- if it is
not received responses can be delayed indefinitely.
* A self-contained binary controls all cryptographic operations including encryption, decryption and storage of keystore files, and signing data and transactions.
* Clef communicates with the process that invoked the binary using stin/stout. The process
invoking the binary is usually the native console-based user interface (UI) but there is
also an API that enables communication with an external UI. This has to be enabled using `--stdio-ui`
at startup. This channel is considered TRUSTED and is used to pass approvals and passwords between
the user and Clef.
* A well defined, deliberately minimal "external" API is used to communicate with the Clef binary - Clef considers this external traffic to be UNTRUSTED. This means Clef does not accept any credentials and does not recognize authority of requests received over this channel. Clef listens on `http.addr:http.port` or `ipcpath` - the same as Geth - and expects messages to be formatted using the [JSON-RPC 2.0 standard](https://www.jsonrpc.org/specification). Some of the external API calls require some user interaction (manual approve/deny)- if it is not received responses can be delayed indefinitely.
* Clef does not store keys - the user is responsible for securely storing and backing up keyfiles.
Clef does store account passwords in its encrypted vault if they are explicitly provided to
Clef by the user to enable automatic account unlocking.
* Clef communicates with the process that invoked the binary using stin/stout. The process invoking the binary is usually the native console-based user interface (UI) but there is also an API that enables communication with an external UI. This has to be enabled using `--stdio-ui` at startup. This channel is considered TRUSTED and is used to pass approvals and passwords between the user and Clef.
The external API never handles any sensitive data directly, but it can be used to request Clef to
sign some data or a transaction. It is the internal API that controls signing and triggers requests for
manual approval (automatic approves actions that conform to attested rulesets) and passwords.
* Clef does not store keys - the user is responsible for securely storing and backing up keyfiles. Clef does store account passwords in its encrypted vault if they are explicitly provided to Clef by the user to enable automatic account unlocking.
The general flow for a basic transaction-signing operation using Clef and an Ethereum node such as
Geth is as follows:
The external API never handles any sensitive data directly, but it can be used to request Clef to sign some data or a transaction. It is the internal API that controls signing and triggers requests for manual approval (automatic approves actions that conform to attested rulesets) and passwords.
The general flow for a basic transaction-signing operation using Clef and an Ethereum node such as Geth is as follows:
In the case illustrated in the schematic above, Geth would be started with `--signer <addr>:<port>` and
would relay requests to `eth.sendTransaction`. Text in `mono` font positioned along arrows shows the objects
passed between each component.
![Clef signing logic](/assets/clef_sign_flow.png)
Most users use Clef by manually approving transactions through the UI as in the schematic above, but it is also
possible to configure Clef to sign transactions without always prompting the user. This requires defining the
precise conditions under which a transaction will be signed. These conditions are known as `Rules` and they are
small Javascript snippets that are *attested* by the user by injecting the snippet's hash into Clef's secure
whitelist. Clef is then started with the rule file, so that requests that satisfy the conditions in the whitelisted
rule files are automatically signed. This is covered in detail on the [Rules page](/docs/_clef/Rules.md).
In the case illustrated in the schematic above, Geth would be started with `--signer <addr>:<port>` and would relay requests to `eth.sendTransaction`. Text in `mono` font positioned along arrows shows the objects passed between each component.
Most users use Clef by manually approving transactions through the UI as in the schematic above, but it is also possible to configure Clef to sign transactions without always prompting the user. This requires defining the precise conditions under which a transaction will be signed. These conditions are known as `Rules` and they are small Javascript snippets that are *attested* by the user by injecting the snippet's hash into Clef's secure whitelist. Clef is then started with the rule file, so that requests that satisfy the conditions in the whitelisted rule files are automatically signed. This is covered in detail on the [Rules page](/content/docs/tools/Clef/rules).
## Basic usage
Clef is started on the command line using the `clef` command. Clef can be configured by providing flags and
commands to `clef` on startup. The full list of command line options is available [below](#command-line-options).
Frequently used options include `--keystore` and `--chainid` which configure the path to an existing keystore
and a network to connect to. These options default to `$HOME/.ethereum/keystore` and `1` (corresponding to
Ethereum Mainnet) respectively. The following code snippet starts Clef, providing a custom path to an existing
keystore and connecting to the Goerli testnet:
Clef is started on the command line using the `clef` command. Clef can be configured by providing flags and commands to `clef` on startup. The full list of command line options is available [below](#command-line-options). Frequently used options include `--keystore` and `--chainid` which configure the path to an existing keystore and a network to connect to. These options default to `$HOME/.ethereum/keystore` and `1` (corresponding to Ethereum Mainnet) respectively. The following code snippet starts Clef, providing a custom path to an existing keystore and connecting to the Goerli testnet:
```sh
clef --keystore /my/keystore --chainid 5
@ -155,12 +105,9 @@ Enter 'ok' to proceed:
>
```
Requests requiring account access or signing now require explicit consent in this terminal.
Activities such as sending transactions via a local Geth node's attached Javascript console or
RPC will now hang indefinitely, awaiting approval in this terminal.
A much more detailed Clef tutorial is available on the [Tutorial page](/docs/clef/tutorial).
Requests requiring account access or signing now require explicit consent in this terminal. Activities such as sending transactions via a local Geth node's attached Javascript console or RPC will now hang indefinitely, awaiting approval in this terminal.
A much more detailed Clef tutorial is available on the [Tutorial page](/content/docs/tools/Clef/tutorial).
## Command line options
@ -200,9 +147,5 @@ GLOBAL OPTIONS:
## Summary
Clef is an external key management and signer tool that comes bundled with Geth but can either be used
as a backend account manager and signer for Geth or as a completely separate standalone application. Being
modular and composable it can be used as a component in decentralized applications or to sign data and
transactions in untrusted environments. Clef is intended to eventually replace Geth's built-in account
management tools.
Clef is an external key management and signer tool that comes bundled with Geth but can either be used as a backend account manager and signer for Geth or as a completely separate standalone application. Being modular and composable it can be used as a component in decentralized applications or to sign data and transactions in untrusted environments. Clef is intended to eventually replace Geth's built-in account management tools.
description: Introduction to automated rulesets in Clef
---
This page provides a fairly low-level explanation for how rules are implemented in
Clef. It is a good idea to read the [Introduction to Clef](/docs/clef/introduction)
and the [Clef tutorial](/docs/clef/tutorial) before diving in to this page.
{:toc}
- this will be removed by the toc
This page provides a fairly low-level explanation for how rules are implemented in Clef. It is a good idea to read the [Introduction to Clef](/content/docs/tools/Clef/introduction) and the [Clef tutorial](/content/docs/tools/Clef/tutorial) before diving in to this page.
## Introduction
Rules in Clef are sets of conditions that determine whether a given action can be
approved automatically without requiring manual intervention from the user. This can be
useful for automatically approving transactions between a user's own accounts, or
approving patterns that are commonly used by applications. Automatic signing also
requires Clef to have access to account passwords which is configured independently
of the ruleset.
Rules in Clef are sets of conditions that determine whether a given action can be approved automatically without requiring manual intervention from the user. This can be useful for automatically approving transactions between a user's own accounts, or approving patterns that are commonly used by applications. Automatic signing also requires Clef to have access to account passwords which is configured independently of the ruleset.
Rules can define arbitrary conditions such as:
* Auto-approve 10 transactions with contract `CasinoDapp`, with value between `0.05 ether` and
`1 ether` per 24h period.
* Auto-approve 10 transactions with contract `CasinoDapp`, with value between `0.05 ether` and `1 ether` per 24h period.
* Auto-approve transactions to contract `Uniswapv2` with `value` up to 1 ether, if
`gas < 44k` and `gasPrice < 40Gwei`.
* Auto-approve transactions to contract `Uniswapv2` with `value` up to 1 ether, if `gas < 44k` and `gasPrice < 40Gwei`.
* Auto-approve signing if the data to be signed contains the string `"approve_me"`.
* Auto-approve any requests to list accounts in keystore if the request arrives over IPC
Because the rules are Javascript files they can be customized to implement any arbitrary logic on
the available request data.
Because the rules are Javascript files they can be customized to implement any arbitrary logic on the available request data.
This page will explain how rules are implemented in Clef and how best to manage credentials
when automatic rulesets are enabled.
This page will explain how rules are implemented in Clef and how best to manage credentials when automatic rulesets are enabled.
## Rule Implementation
The ruleset engine acts as a gatekeeper to the command line interface - it auto-approves
any requests that meet the conditions defined in a set of authenticated rule files. This
prevents the user from having to manually approve or reject every request - instead they
can define common patterns in a rule file and abstract that task away to the ruleset engine.
The general architecture is as follows:
The ruleset engine acts as a gatekeeper to the command line interface - it auto-approves any requests that meet the conditions defined in a set of authenticated rule files. This prevents the user from having to manually approve or reject every request - instead they can define common patterns in a rule file and abstract that task away to the ruleset engine. The general architecture is as follows:
When Clef receives a request, the ruleset engine evaluates a Javascript file for
each method defined in the internal [UI API docs](/docs/clef/apis). For example the code
snippet below is an example ruleset that calls the function `ApproveTx`. The call to `ApproveTx`
is invoking the `ui_approveTx` [JSON_RPC API endpoint](/docs/clef/apis/#ui-api). Every time an RPC
method is invoked the Javascript code is executed in a freshly instantiated virtual machine.
When Clef receives a request, the ruleset engine evaluates a Javascript file for each method defined in the internal [UI API docs](/content/docs/tools/Clef/apis). For example the code snippet below is an example ruleset that calls the function `ApproveTx`. The call to `ApproveTx` is invoking the `ui_approveTx` [JSON_RPC API endpoint](/content/docs/tools/Clef/apis/#ui-api). Every time an RPC method is invoked the Javascript code is executed in a freshly instantiated virtual machine.
```js
function asBig(str) {
@ -102,43 +79,33 @@ handled in different ways:
| Anything else | Pass decision to UI for manual approval |
There are some additional noteworthy implementation details that are important
for defining rules correctly in `ruleset.js`:
There are some additional noteworthy implementation details that are important for defining rules correctly in `ruleset.js`:
* The code in `ruleset.js`**cannot** load external Javascript files.
* The Javascript engine can access `storage` and `console`
* The only preloaded library in the Javascript environment is
`bignumber.js` version `2.0.3`.
* The only preloaded library in the Javascript environment is `bignumber.js` version `2.0.3`.
* Each invocation is made in a fresh virtual machine meaning data cannot be
stored in global variables between invocations.
* Each invocation is made in a fresh virtual machine meaning data cannot be stored in global variables between invocations.
* Since no global variable storage is available, disk backed `storage` must be
used - rules should not rely on ephemeral data.
* Since no global variable storage is available, disk backed `storage` must be used - rules should not rely on ephemeral data.
* Javascript API parameters are always objects. This ensures parameters are
accessed by _key_ to avoid misordering errors.
* Javascript API parameters are always objects. This ensures parameters are accessed by _key_ to avoid misordering errors.
* Otto VM uses ES5. ES6-specific features (such as Typed Arrays) are not supported.
* The regular expression engine (re2/regexp) in Otto VM is not fully compatible
with the [ECMA5 specification](https://tc39.es/ecma262/#sec-intro).
* The regular expression engine (re2/regexp) in Otto VM is not fully compatible with the [ECMA5 specification](https://tc39.es/ecma262/#sec-intro).
is not supported. "Use strict" will parse but it does nothing.
* [Strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode) is not supported. "Use strict" will parse but it does nothing.
## Credential management
The ability to auto-approve transaction requires that the signer has
the necessary credentials, i.e. account passwords, to decrypt keyfiles.
The ability to auto-approve transaction requires that the signer has the necessary credentials, i.e. account passwords, to decrypt keyfiles.
These are stored encrypted as follows:
When the `signer` is started it generates a seed that is locked with a
user specified password. The seed is saved to a location that defaults to
`$HOME/.clef/masterseed.json`. The `seed` itself is a blob of bytes.
When the `signer` is started it generates a seed that is locked with a user specified password. The seed is saved to a location that defaults to `$HOME/.clef/masterseed.json`. The `seed` itself is a blob of bytes.
The `signer` uses the `seed` to:
@ -147,56 +114,28 @@ The `signer` uses the `seed` to:
* `$HOME/.clef/790046d38025/credentials.json`
* Generate the encryption password for the config and credentials files.
`config.json` stores the hashes of any attested rulesets. `credentials.json`
stores encrypted account passwords. The masterseed is required to decrypt
these files. The decrypted account passwords can then be used to decrypt keyfiles.
`config.json` stores the hashes of any attested rulesets. `credentials.json` stores encrypted account passwords. The masterseed is required to decrypt these files. The decrypted account passwords can then be used to decrypt keyfiles.
## Security
### The Javascript VM
The downside of the very flexible rule implementation included in Clef is
that the `signer` binary needs to contain a Javascript engine. This is an
additional attack surface. The only viable attack is for an adversary to
somehow extract cryptographic keys from memory during the Javascript VM execution.
The hash-based rule attestation condition means the actual Javascript code
executed by the Javascript engine is not a viable attack surface -- since if the attacker can control the ruleset, a much simpler
attack would be to surreptitiously insert an attested "always-approve" rule
instead of attempting to exploit the Javascript virtual machine. The Javascript
engine is quite simple to implement and there are currently no known security
vulnerabilities, not have there been any security problems identified for the
The downside of the very flexible rule implementation included in Clef is that the `signer` binary needs to contain a Javascript engine. This is an additional attack surface. The only viable attack is for an adversary to somehow extract cryptographic keys from memory during the Javascript VM execution. The hash-based rule attestation condition means the actual Javascript code executed by the Javascript engine is not a viable attack surface -- since if the attacker can control the ruleset, a much simpler attack would be to surreptitiously insert an attested "always-approve" rule instead of attempting to exploit the Javascript virtual machine. The Javascript engine is quite simple to implement and there are currently no known security vulnerabilities, not have there been any security problems identified for the
similar Javascript VM implemented in Geth.
### Writing rules
Since the user has complete freedom to write custom rules, it is plausible that those rules
could create unintended security vulnerabilities. This can only really be protected by
coding very carefully and trying to test rulesets (e.g. on a private testnet) before
Since the user has complete freedom to write custom rules, it is plausible that those rules could create unintended security vulnerabilities. This can only really be protected by coding very carefully and trying to test rulesets (e.g. on a private testnet) before
implementing them on a public network.
Javascript is very flexible but also easy to write incorrectly. For example, users
might assume that javascript can handle large integers natively rather than explicitly
using `bigInt`. This is an error commonly encountered in the Ethereum context when
users attempt to multiply `gas` by `gasCost`.
It’s unclear whether any other language would be more secure - there is alwas the possibility
of implementing an insecure rule.
### File security
Javascript is very flexible but also easy to write incorrectly. For example, users might assume that javascript can handle large integers natively rather than explicitly using `bigInt`. This is an error commonly encountered in the Ethereum context when users attempt to multiply `gas` by `gasCost`.
It’s unclear whether any other language would be more secure - there is alwas the possibility of implementing an insecure rule.
### Credential security
Clef implements a secure, encrypted vault for storing sensitive data. This vault is
encrypted using a `masterseed` which the user is responsible for storing and backing
up safely and securely. Since this `masterseed` is used to decrypt the secure vault,
and its security is not handled by Clef, it could represent a security vulnerability
if the user does not implement best practise in keeping it safe.
Clef implements a secure, encrypted vault for storing sensitive data. This vault is encrypted using a `masterseed` which the user is responsible for storing and backing up safely and securely. Since this `masterseed` is used to decrypt the secure vault, and its security is not handled by Clef, it could represent a security vulnerability if the user does not implement best practise in keeping it safe.
The same is also true for keys. Keys are not stored by Clef, they are only accessed
using account passwords that Clef does store in its vault. The keys themselves are stored
in an external `keystore` whose security is the responsibility of the user. If the
keys are compromised, the account is not safe irrespective of the security benefits
derived from Clef.
The same is also true for keys. Keys are not stored by Clef, they are only accessed using account passwords that Clef does store in its vault. The keys themselves are stored in an external `keystore` whose security is the responsibility of the user. If the keys are compromised, the account is not safe irrespective of the security benefits derived from Clef.
## Ruleset examples
@ -316,9 +255,4 @@ function OnApprovedTx(resp) {
## Summary
Rules are sets of conditions encoded in Javascript files that enable certain actions to
be auto-approved by Clef. This page outlined the implementation details and security
considerations that will help to build suitrable ruleset files. See the
[Clef Github](https://github.com/ethereum/go-ethereum/tree/master/cmd/clef) for further reading.
Rules are sets of conditions encoded in Javascript files that enable certain actions to be auto-approved by Clef. This page outlined the implementation details and security considerations that will help to build suitrable ruleset files. See the [Clef Github](https://github.com/ethereum/go-ethereum/tree/master/cmd/clef) for further reading.