Skip to content

Commit

Permalink
Secrets manager introduced to commands (#1251)
Browse files Browse the repository at this point in the history
secret manager introduced to commands stake/unstake/withdraw/info
  • Loading branch information
Nemanja0x authored Feb 27, 2023
1 parent 6c66439 commit d815a3f
Show file tree
Hide file tree
Showing 12 changed files with 160 additions and 86 deletions.
74 changes: 17 additions & 57 deletions command/polybftsecrets/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package polybftsecrets

import (
"encoding/hex"
"errors"
"fmt"
"strings"

Expand All @@ -15,30 +14,16 @@ import (
)

const (
dataPathFlag = "data-dir"
configFlag = "config"
accountFlag = "account"
privateKeyFlag = "private"
networkFlag = "network"
numFlag = "num"
outputFlag = "output"
chainIDFlag = "chain-id"
accountFlag = "account"
privateKeyFlag = "private"
insecureLocalStoreFlag = "insecure"
networkFlag = "network"
numFlag = "num"
outputFlag = "output"
chainIDFlag = "chain-id"

// maxInitNum is the maximum value for "num" flag
maxInitNum = 30

insecureLocalStore = "insecure"
)

var (
errInvalidNum = fmt.Errorf("num flag value should be between 1 and %d", maxInitNum)
errInvalidConfig = errors.New("invalid secrets configuration")
errInvalidParams = errors.New("no config file or data directory passed in")
errUnsupportedType = errors.New("unsupported secrets manager")
errSecureLocalStoreNotImplemented = errors.New(
"use a secrets backend, or supply an --insecure flag " +
"to store the private keys locally on the filesystem, " +
"avoid doing so in production")
)

type initParams struct {
Expand All @@ -61,11 +46,11 @@ type initParams struct {

func (ip *initParams) validateFlags() error {
if ip.numberOfSecrets < 1 || ip.numberOfSecrets > maxInitNum {
return errInvalidNum
return ErrInvalidNum
}

if ip.dataPath == "" && ip.configPath == "" {
return errInvalidParams
return ErrInvalidParams
}

return nil
Expand All @@ -74,17 +59,16 @@ func (ip *initParams) validateFlags() error {
func (ip *initParams) setFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(
&ip.dataPath,
dataPathFlag,
DataPathFlag,
"",
"the directory for the Polygon Edge data if the local FS is used",
DataPathFlagDesc,
)

cmd.Flags().StringVar(
&ip.configPath,
configFlag,
ConfigFlag,
"",
"the path to the SecretsManager config file, "+
"if omitted, the local FS secrets manager is used",
ConfigFlagDesc,
)

cmd.Flags().IntVar(
Expand All @@ -96,10 +80,10 @@ func (ip *initParams) setFlags(cmd *cobra.Command) {

// Don't accept data-dir and config flags because they are related to different secrets managers.
// data-dir is about the local FS as secrets storage, config is about remote secrets manager.
cmd.MarkFlagsMutuallyExclusive(dataPathFlag, configFlag)
cmd.MarkFlagsMutuallyExclusive(DataPathFlag, ConfigFlag)

// num flag should be used with data-dir flag only so it should not be used with config flag.
cmd.MarkFlagsMutuallyExclusive(numFlag, configFlag)
cmd.MarkFlagsMutuallyExclusive(numFlag, ConfigFlag)

cmd.Flags().BoolVar(
&ip.generatesAccount,
Expand All @@ -124,7 +108,7 @@ func (ip *initParams) setFlags(cmd *cobra.Command) {

cmd.Flags().BoolVar(
&ip.insecureLocalStore,
insecureLocalStore,
insecureLocalStoreFlag,
false,
"the flag indicating should the secrets stored on the local storage be encrypted",
)
Expand Down Expand Up @@ -158,7 +142,7 @@ func (ip *initParams) Execute() (Results, error) {
configDir = fmt.Sprintf("%s%d", ip.configPath, i+1)
}

secretManager, err := getSecretsManager(dataDir, configDir, ip.insecureLocalStore)
secretManager, err := GetSecretsManager(dataDir, configDir, ip.insecureLocalStore)
if err != nil {
return results, err
}
Expand Down Expand Up @@ -281,27 +265,3 @@ func (ip *initParams) getResult(

return res, nil
}

func getSecretsManager(dataPath, configPath string, insecureLocalStore bool) (secrets.SecretsManager, error) {
if configPath != "" {
secretsConfig, readErr := secrets.ReadConfig(configPath)
if readErr != nil {
return nil, errInvalidConfig
}

if !secrets.SupportedServiceManager(secretsConfig.Type) {
return nil, errUnsupportedType
}

return helper.InitCloudSecretsManager(secretsConfig)
}

//Storing secrets on a local file system should only be allowed with --insecure flag,
//to raise awareness that it should be only used in development/testing environments.
//Production setups should use one of the supported secrets managers
if !insecureLocalStore {
return nil, errSecureLocalStoreNotImplemented
}

return helper.SetupLocalSecretsManager(dataPath)
}
56 changes: 56 additions & 0 deletions command/polybftsecrets/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package polybftsecrets

import (
"errors"
"fmt"

"github.com/0xPolygon/polygon-edge/secrets"
"github.com/0xPolygon/polygon-edge/secrets/helper"
)

// common flags for all polybft commands
const (
DataPathFlag = "data-dir"
ConfigFlag = "config"

DataPathFlagDesc = "the directory for the Polygon Edge data if the local FS is used"
ConfigFlagDesc = "the path to the SecretsManager config file, if omitted, the local FS secrets manager is used"
)

// common errors for all polybft commands
var (
ErrInvalidNum = fmt.Errorf("num flag value should be between 1 and %d", maxInitNum)
ErrInvalidConfig = errors.New("invalid secrets configuration")
ErrInvalidParams = errors.New("no config file or data directory passed in")
ErrUnsupportedType = errors.New("unsupported secrets manager")
ErrSecureLocalStoreNotImplemented = errors.New(
"use a secrets backend, or supply an --insecure flag " +
"to store the private keys locally on the filesystem, " +
"avoid doing so in production")
)

// GetSecretsManager function resolves secrets manager instance based on provided data or config paths.
// insecureLocalStore defines if utilization of local secrets manager is allowed.
func GetSecretsManager(dataPath, configPath string, insecureLocalStore bool) (secrets.SecretsManager, error) {
if configPath != "" {
secretsConfig, readErr := secrets.ReadConfig(configPath)
if readErr != nil {
return nil, errors.New(ErrInvalidConfig.Error() + ": " + readErr.Error())
}

if !secrets.SupportedServiceManager(secretsConfig.Type) {
return nil, ErrUnsupportedType
}

return helper.InitCloudSecretsManager(secretsConfig)
}

// Storing secrets on a local file system should only be allowed with --insecure flag,
// to raise awareness that it should be only used in development/testing environments.
// Production setups should use one of the supported secrets managers
if !insecureLocalStore {
return nil, ErrSecureLocalStoreNotImplemented
}

return helper.SetupLocalSecretsManager(dataPath)
}
28 changes: 22 additions & 6 deletions command/sidechain/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,20 @@ import (
"math/big"
"os"

"github.com/0xPolygon/polygon-edge/command/polybftsecrets"
"github.com/0xPolygon/polygon-edge/consensus/polybft"
"github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi"
"github.com/0xPolygon/polygon-edge/consensus/polybft/wallet"
"github.com/0xPolygon/polygon-edge/contracts"
"github.com/0xPolygon/polygon-edge/helper/hex"
secretsHelper "github.com/0xPolygon/polygon-edge/secrets/helper"
"github.com/0xPolygon/polygon-edge/txrelayer"
"github.com/0xPolygon/polygon-edge/types"
"github.com/umbracle/ethgo"
)

const (
AccountDirFlag = "account"
SelfFlag = "self"
AmountFlag = "amount"
SelfFlag = "self"
AmountFlag = "amount"

DefaultGasPrice = 1879048192 // 0x70000000
)
Expand All @@ -33,15 +32,32 @@ func CheckIfDirectoryExist(dir string) error {
return nil
}

func GetAccountFromDir(dir string) (*wallet.Account, error) {
secretsManager, err := secretsHelper.SetupLocalSecretsManager(dir)
func ValidateSecretFlags(dataDir, config string) error {
if config == "" {
if dataDir == "" {
return polybftsecrets.ErrInvalidParams
} else {
return CheckIfDirectoryExist(dataDir)
}
}

return nil
}

func GetAccount(dataDir, config string) (*wallet.Account, error) {
// resolve secrets manager instance and allow usage of insecure local secrets manager
secretsManager, err := polybftsecrets.GetSecretsManager(dataDir, config, true)
if err != nil {
return nil, err
}

return wallet.NewAccountFromSecret(secretsManager)
}

func GetAccountFromDir(dir string) (*wallet.Account, error) {
return GetAccount(dir, "")
}

// GetValidatorInfo queries ChildValidatorSet smart contract and retrieves validator info for given address
func GetValidatorInfo(validatorAddr ethgo.Address, txRelayer txrelayer.TxRelayer) (*polybft.ValidatorInfo, error) {
getValidatorMethod := contractsapi.ChildValidatorSet.Abi.GetMethod("getValidator")
Expand Down
3 changes: 2 additions & 1 deletion command/sidechain/staking/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ var (

type stakeParams struct {
accountDir string
configPath string
jsonRPC string
amount uint64
self bool
delegateAddress string
}

func (v *stakeParams) validateFlags() error {
return sidechainHelper.CheckIfDirectoryExist(v.accountDir)
return sidechainHelper.ValidateSecretFlags(v.accountDir, v.configPath)
}

type stakeResult struct {
Expand Down
15 changes: 12 additions & 3 deletions command/sidechain/staking/stake.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/0xPolygon/polygon-edge/command"
"github.com/0xPolygon/polygon-edge/command/helper"
"github.com/0xPolygon/polygon-edge/command/polybftsecrets"
sidechainHelper "github.com/0xPolygon/polygon-edge/command/sidechain"
"github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi"
"github.com/0xPolygon/polygon-edge/contracts"
Expand Down Expand Up @@ -39,9 +40,16 @@ func GetCommand() *cobra.Command {
func setFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(
&params.accountDir,
sidechainHelper.AccountDirFlag,
polybftsecrets.DataPathFlag,
"",
"the directory path where validator key is stored",
polybftsecrets.DataPathFlagDesc,
)

cmd.Flags().StringVar(
&params.configPath,
polybftsecrets.ConfigFlag,
"",
polybftsecrets.ConfigFlagDesc,
)

cmd.Flags().BoolVar(
Expand All @@ -66,6 +74,7 @@ func setFlags(cmd *cobra.Command) {
)

cmd.MarkFlagsMutuallyExclusive(sidechainHelper.SelfFlag, delegateAddressFlag)
cmd.MarkFlagsMutuallyExclusive(polybftsecrets.DataPathFlag, polybftsecrets.ConfigFlag)
}

func runPreRun(cmd *cobra.Command, _ []string) error {
Expand All @@ -78,7 +87,7 @@ func runCommand(cmd *cobra.Command, _ []string) error {
outputter := command.InitializeOutputter(cmd)
defer outputter.WriteOutput()

validatorAccount, err := sidechainHelper.GetAccountFromDir(params.accountDir)
validatorAccount, err := sidechainHelper.GetAccount(params.accountDir, params.configPath)
if err != nil {
return err
}
Expand Down
3 changes: 2 additions & 1 deletion command/sidechain/unstaking/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ var (

type unstakeParams struct {
accountDir string
configPath string
jsonRPC string
amount uint64
self bool
undelegateAddress string
}

func (v *unstakeParams) validateFlags() error {
return sidechainHelper.CheckIfDirectoryExist(v.accountDir)
return sidechainHelper.ValidateSecretFlags(v.accountDir, v.configPath)
}

type unstakeResult struct {
Expand Down
15 changes: 12 additions & 3 deletions command/sidechain/unstaking/unstake.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/0xPolygon/polygon-edge/command"
"github.com/0xPolygon/polygon-edge/command/helper"
"github.com/0xPolygon/polygon-edge/command/polybftsecrets"
sidechainHelper "github.com/0xPolygon/polygon-edge/command/sidechain"
"github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi"
"github.com/0xPolygon/polygon-edge/contracts"
Expand Down Expand Up @@ -39,9 +40,16 @@ func GetCommand() *cobra.Command {
func setFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(
&params.accountDir,
sidechainHelper.AccountDirFlag,
polybftsecrets.DataPathFlag,
"",
"the directory path where sender account secrets are stored",
polybftsecrets.DataPathFlagDesc,
)

cmd.Flags().StringVar(
&params.configPath,
polybftsecrets.ConfigFlag,
"",
polybftsecrets.ConfigFlagDesc,
)

cmd.Flags().BoolVar(
Expand All @@ -66,6 +74,7 @@ func setFlags(cmd *cobra.Command) {
)

cmd.MarkFlagsMutuallyExclusive(sidechainHelper.SelfFlag, undelegateAddressFlag)
cmd.MarkFlagsMutuallyExclusive(polybftsecrets.DataPathFlag, polybftsecrets.ConfigFlag)
}

func runPreRun(cmd *cobra.Command, _ []string) error {
Expand All @@ -78,7 +87,7 @@ func runCommand(cmd *cobra.Command, _ []string) error {
outputter := command.InitializeOutputter(cmd)
defer outputter.WriteOutput()

validatorAccount, err := sidechainHelper.GetAccountFromDir(params.accountDir)
validatorAccount, err := sidechainHelper.GetAccount(params.accountDir, params.configPath)
if err != nil {
return err
}
Expand Down
3 changes: 2 additions & 1 deletion command/sidechain/validators/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ import (

type validatorInfoParams struct {
accountDir string
configPath string
jsonRPC string
}

func (v *validatorInfoParams) validateFlags() error {
return sidechainHelper.CheckIfDirectoryExist(v.accountDir)
return sidechainHelper.ValidateSecretFlags(v.accountDir, v.configPath)
}

type validatorsInfoResult struct {
Expand Down
Loading

0 comments on commit d815a3f

Please sign in to comment.