Skip to main content

Security

Managing accounts and private keys requires careful attention to security. This guide covers best practices for keeping your Flow accounts and private keys secure when using the Flow CLI.

Security Overview

⚠️ Critical Warning: Never commit private keys to source control. Always use secure methods to store and manage your private keys.

The Flow CLI provides several secure options for managing private account data:

  1. File-based keys - Store keys in separate files
  2. Environment variables - Use system environment variables
  3. Private configuration files - Separate sensitive config from main config
  4. Multiple config files - Merge secure and public configurations

File-Based Keys

Store private keys in separate files that are excluded from source control.

Setup

  1. Create a key file (e.g., my-account.key):

_10
# Only the hex-encoded private key
_10
334232967f52bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad1111

  1. Add to .gitignore:

_10
# Private key files
_10
*.key
_10
*.pkey
_10
private.json
_10
.env

  1. Configure in flow.json:

_11
{
_11
"accounts": {
_11
"my-testnet-account": {
_11
"address": "3ae53cb6e3f42a79",
_11
"key": {
_11
"type": "file",
_11
"location": "./my-account.key"
_11
}
_11
}
_11
}
_11
}

Benefits

  • ✅ Keys are never stored in configuration files
  • ✅ Easy to manage multiple keys
  • ✅ Clear separation of concerns
  • ✅ Works with all Flow CLI commands

Environment Variables

Use environment variables for sensitive data like private keys and addresses.

Setup

  1. Set environment variables:

_10
export FLOW_PRIVATE_KEY="334232967f52bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad1111"
_10
export FLOW_ACCOUNT_ADDRESS="3ae53cb6e3f42a79"

  1. Reference in flow.json:

_10
{
_10
"accounts": {
_10
"my-testnet-account": {
_10
"address": "$FLOW_ACCOUNT_ADDRESS",
_10
"key": "$FLOW_PRIVATE_KEY"
_10
}
_10
}
_10
}

  1. Use with CLI commands:

_10
FLOW_PRIVATE_KEY="your-key" flow project deploy

Benefits

  • ✅ Keys never stored in files
  • ✅ Easy to manage different environments
  • ✅ Works with CI/CD systems
  • ✅ Can be rotated easily

Private Configuration Files

Create separate configuration files for sensitive data and merge them when needed.

Setup

  1. Main configuration (flow.json):

_10
{
_10
"networks": {
_10
"testnet": "access.devnet.nodes.onflow.org:9000"
_10
},
_10
"contracts": {
_10
"MyContract": "./cadence/contracts/MyContract.cdc"
_10
}
_10
}

  1. Private configuration (private.json):

_10
{
_10
"accounts": {
_10
"my-testnet-account": {
_10
"address": "3ae53cb6e3f42a79",
_10
"key": "334232967f52bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad1111"
_10
}
_10
}
_10
}

  1. Add to .gitignore:

_10
private.json
_10
secrets.json
_10
*.private.json

  1. Use with CLI commands:

_10
flow project deploy -f flow.json -f private.json

Benefits

  • ✅ Clear separation of public and private data
  • ✅ Easy to manage multiple environments
  • ✅ Can be shared safely (without private files)
  • ✅ Works with all CLI commands

Environment Files (.env)

Use .env files for local development with automatic loading by the CLI.

Setup

  1. Create .env file:

_10
# .env
_10
FLOW_PRIVATE_KEY=334232967f52bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad1111
_10
FLOW_ACCOUNT_ADDRESS=3ae53cb6e3f42a79
_10
FLOW_NETWORK=testnet

  1. Reference in flow.json:

_11
{
_11
"accounts": {
_11
"my-testnet-account": {
_11
"address": "$FLOW_ACCOUNT_ADDRESS",
_11
"key": "$FLOW_PRIVATE_KEY"
_11
}
_11
},
_11
"networks": {
_11
"testnet": "access.devnet.nodes.onflow.org:9000"
_11
}
_11
}

  1. Add to .gitignore:

_10
.env
_10
.env.local
_10
.env.*.local

Benefits

  • ✅ Automatic loading by CLI
  • ✅ Easy local development
  • ✅ Can have different files for different environments
  • ✅ Standard practice for many tools

Multiple Configuration Files

Merge multiple configuration files for complex setups.

Priority Order

When using multiple files, they are merged in order:

  1. Left to right - Files specified first have lowest priority
  2. Later files override - Properties in later files take precedence
  3. Non-overlapping properties - Are combined from all files

Example


_10
flow project deploy -f flow.json -f private.json -f local.json

Result: local.json overrides private.json, which overrides flow.json

Use Cases

  • Development: flow.json + dev-private.json
  • Staging: flow.json + staging-private.json
  • Production: flow.json + prod-private.json

Security Best Practices

1. Never Commit Private Keys


_10
# Always add these to .gitignore
_10
*.key
_10
*.pkey
_10
private.json
_10
secrets.json
_10
.env
_10
.env.local
_10
*.private.json

2. Use Different Keys for Different Environments

  • Development: Use testnet keys
  • Staging: Use separate testnet keys
  • Production: Use mainnet keys with highest security

3. Rotate Keys Regularly

  • Generate new keys periodically
  • Update configuration files
  • Test with new keys before switching

4. Limit Key Permissions

  • Use keys with minimal required permissions
  • Consider using different keys for different operations
  • Monitor key usage

5. Secure Key Storage

  • Use hardware security modules (HSMs) for production
  • Consider cloud key management services
  • Encrypt key files when possible

Common Security Mistakes

❌ Don't Do This


_10
// flow.json - NEVER do this
_10
{
_10
"accounts": {
_10
"my-account": {
_10
"address": "3ae53cb6e3f42a79",
_10
"key": "334232967f52bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad1111"
_10
}
_10
}
_10
}

✅ Do This Instead


_12
// flow.json - Safe to commit
_12
{
_12
"accounts": {
_12
"my-account": {
_12
"address": "3ae53cb6e3f42a79",
_12
"key": {
_12
"type": "file",
_12
"location": "./my-account.key"
_12
}
_12
}
_12
}
_12
}

Troubleshooting

Environment Variables Not Loading

Check that your environment variables are set:


_10
echo $FLOW_PRIVATE_KEY

Key File Not Found

Verify the key file path in your configuration:


_10
ls -la ./my-account.key

Multiple Config Files Not Merging

Check the order of your -f flags:


_10
# Correct order (left to right, later overrides earlier)
_10
flow config add account -f flow.json -f private.json