Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for cast wallet accounts in addition to $PRIVATE_KEY envvar and AWS KMS #3382

Open
RichardSlater opened this issue Nov 25, 2024 · 0 comments

Comments

@RichardSlater
Copy link

The majority of the Mud examples use $PRIVATE_KEY defined in .env to populate the private key in the shell environment. There is also the ability to use AWS KMS to store the private keys. There is currently no middle ground for people who wish to maintain a more secure solution yet don't wish to take a dependency on AWS.

Specific Request: add support for Foundry wallets which includes more secure semantics:

  1. an encrypted Keystore per-account stored in ~/.foundry/keystores.
  2. an --account $accountName and --keystore $path parameters to access the keystores.
  3. environment variables (ETH_KEYSTORE= and ETH_KEYSTORE_ACCOUNT=) are also available.
  4. more advanced options such as storing the password in a file with --password-file and ETH_PASSWORD= for unattended operation.
  5. additional hardware security using --ledger and --trezor for those with Hardware Wallets.

Example

Currently to add a key to the Foundry Keystore the following command is run:

cast wallet import --interactive AnvilDefault

This will prompt for a private key and password (secrets are not printed to terminal):

Enter private key: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
Enter password: password
`AnvilDefault` keystore was saved successfully. Address: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266

The password is then passed through a key derivation function (scrypt) and all of the parameters are written to ~/.foundry/keystores/AnvilDefault:

{
    "crypto": {
        "cipher": "aes-128-ctr",
        "cipherparams": {
            "iv": "969866f53be7f2e4e1b62e4be9cd7713"
        },
        "ciphertext": "ecfbaef4c8d26927eb7e6b66081bd88dda260b3eef29933130d1186d40115db1",
        "kdf": "scrypt",
        "kdfparams": {
            "dklen": 32,
            "n": 8192,
            "p": 1,
            "r": 8,
            "salt": "a9d3febc661a35a63c3e8a2b7962ad0499e08737e2f2c84574d05e4ca25c3950"
        },
        "mac": "d5b73f47874f7bab9e1455c422875d209bff3b0675700b259b5997a3030e15f1"
    },
    "id": "832c81e8-100a-45bb-9b1e-fc1900fa1c68",
    "version": 3
}

This file is fully self-contained and includes the cyphertext but not the password so can safely be ported between machines.

This keystore can be used with forge script as follows:

pnpm forge script ./script/Execute.s.sol:Execute --broadcast --rpc-url $RPC_URL --chain-id $CHAIN_ID --sig \"run(address)\" $WORLD_ADDRESS --account AnvilDefault -vvv

At which point the end-user is prompted with a password entry, as mentioned it's possible to specify the keystore path, in addition to specifying a file to read the password from, this enables operation in other cloud build environments including but not limited to Azure, Google Cloud, GitHub Actions, etc. without taking a dependency on AWS.

Desired State

In an ideal world the following commands would leverage Foundry's keystores:

mud deploy --account AnvilDefault
ETH_KEYSTORE_ACCOUNT=AnvilDefault mud deploy
mud deploy --account AnvilDefault --keystore /secrets/keystore
ETH_KEYSTORE=/secrets/keystore mud deploy --account AnvilDefault

Additionally the following would be beneficial:

mud deploy --ledger
mud deploy --trezor

Use Cases

The majority of builders within EVE Frontier are not going to have experience with cloud-native tooling, making AWS KMS a difficult value proposition. Equally some are not crypto-native and do not understand the threat that unencrypted keys represents.

Threats

  1. It's not uncommon to see an EVE Frontier builder check in their .env into GitHub, these keys are routinely picked up by bad actors via automated bots. You can test this by adding a small amount of ETH to a wallet and checking it into GitHub, the ETH will be gone within a day.
  2. Builders often share the contents of their .env during the course of debugging, these files are shared in an open forum (Discord) and we know there are already malicious actors within the Discord who have attempted to phish members of the builder community.
  3. Malware developer are increasingly using command and control infrastructure to deploy crypto stealers that scan disks for unencrypted private keys resulting in Private Key Compromise.
  4. In numerous cases the PRIVATE_KEY variable has been set at the command line, resulting in the key being stored in .bash_history / .history.
  5. Build agents which import a .env will routinely expose the contents of the environment to other processes running on the system, including malware.

By offering a range of options to developers Mud can provide a tiered list of ways to make private keys available to privileged processes:

  1. Private Key in ENV - bad for security, good enough for Anvil devnets.
  2. Private Key in KeyStore - good for solo developers, GitHub Actions and container usage.
  3. Private Key in Ledger/Trezor - good for higher stakes deployments by alliances.
  4. Private Key in AWS - ultimate security at a cost.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: No status
Development

No branches or pull requests

1 participant