diff --git a/.circleci/config.yml b/.circleci/config.yml
index c8d510a94afa0b6656bbcae56c0530a9c2def611..629b0e2473f2c25aa76e6da51de7e67ff17020ba 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -35,6 +35,10 @@ jobs:
     steps:
       - checkout
       - run: make test_integration_bosmarmot
+      - store_artifacts:
+          path: ./.gopath_bos/src/github.com/monax/bosmarmot/monax/tests/burrow.log
+      - store_artifacts:
+          path: ./.gopath_bos/src/github.com/monax/bosmarmot/monax/tests/keys.log
 
   ensure_vendor:
     <<: *defaults
diff --git a/Gopkg.lock b/Gopkg.lock
index 4267290a7b3c05a706ffc813139ff873f0327cde..d7e39752628439460aa8c3a026c00903ffe5de30 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -474,6 +474,6 @@
 [solve-meta]
   analyzer-name = "dep"
   analyzer-version = 1
-  inputs-digest = "ecec019d5ac7140b4607333907f5a4b211fb3551f7cfe51b92e6cc8e3c515488"
+  inputs-digest = "a434dee26127011ec236d80b300051d321f012ce49cd77b1112034c15e54ac3e"
   solver-name = "gps-cdcl"
   solver-version = 1
diff --git a/client/rpc/client_test.go b/client/rpc/client_test.go
index d64ab91d48e4ba171df51ca78318a22fb14ac07d..3a8ebc42d7d11c1f5627b360097dcdd785499d84 100644
--- a/client/rpc/client_test.go
+++ b/client/rpc/client_test.go
@@ -28,31 +28,31 @@ import (
 )
 
 func TestSend(t *testing.T) {
-	mockKeyClient := mockkeys.NewMockKeyClient()
+	mockKeyClient := mockkeys.NewKeyClient()
 	mockNodeClient := mockclient.NewMockNodeClient()
 	testSend(t, mockNodeClient, mockKeyClient)
 }
 
 func TestCall(t *testing.T) {
-	mockKeyClient := mockkeys.NewMockKeyClient()
+	mockKeyClient := mockkeys.NewKeyClient()
 	mockNodeClient := mockclient.NewMockNodeClient()
 	testCall(t, mockNodeClient, mockKeyClient)
 }
 
 func TestName(t *testing.T) {
-	mockKeyClient := mockkeys.NewMockKeyClient()
+	mockKeyClient := mockkeys.NewKeyClient()
 	mockNodeClient := mockclient.NewMockNodeClient()
 	testName(t, mockNodeClient, mockKeyClient)
 }
 
 func TestPermissions(t *testing.T) {
-	mockKeyClient := mockkeys.NewMockKeyClient()
+	mockKeyClient := mockkeys.NewKeyClient()
 	mockNodeClient := mockclient.NewMockNodeClient()
 	testPermissions(t, mockNodeClient, mockKeyClient)
 }
 
 func testSend(t *testing.T,
-	nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.MockKeyClient) {
+	nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.KeyClient) {
 
 	// generate an ED25519 key and ripemd160 address
 	addressString := keyClient.NewKey("").String()
@@ -77,7 +77,7 @@ func testSend(t *testing.T,
 }
 
 func testCall(t *testing.T,
-	nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.MockKeyClient) {
+	nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.KeyClient) {
 
 	// generate an ED25519 key and ripemd160 address
 	addressString := keyClient.NewKey("").String()
@@ -110,7 +110,7 @@ func testCall(t *testing.T,
 }
 
 func testName(t *testing.T,
-	nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.MockKeyClient) {
+	nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.KeyClient) {
 
 	// generate an ED25519 key and ripemd160 address
 	addressString := keyClient.NewKey("").String()
@@ -141,7 +141,7 @@ func testName(t *testing.T,
 }
 
 func testPermissions(t *testing.T,
-	nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.MockKeyClient) {
+	nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.KeyClient) {
 
 	// generate an ED25519 key and ripemd160 address
 	addressString := keyClient.NewKey("").String()
diff --git a/cmd/burrow/commands/configure.go b/cmd/burrow/commands/configure.go
index de13421a319bce30a6291396e7fe44dfd4971c50..f1af9e0f878b70e6948a33b9a49c629b7aa08859 100644
--- a/cmd/burrow/commands/configure.go
+++ b/cmd/burrow/commands/configure.go
@@ -8,6 +8,7 @@ import (
 
 	"github.com/hyperledger/burrow/config"
 	"github.com/hyperledger/burrow/config/source"
+	"github.com/hyperledger/burrow/deployment"
 	"github.com/hyperledger/burrow/execution"
 	"github.com/hyperledger/burrow/genesis"
 	"github.com/hyperledger/burrow/genesis/spec"
@@ -37,9 +38,9 @@ func Configure(cmd *cli.Cmd) {
 		"File to output containing secret keys as JSON or according to a custom template (see --keys-template). "+
 			"Note that using this options means the keys will not be generated in the default keys instance")
 
-	keysTemplateOpt := cmd.StringOpt("z keys-template", mock.DefaultDumpKeysFormat,
+	keysTemplateOpt := cmd.StringOpt("z keys-template", deployment.DefaultDumpKeysFormat,
 		fmt.Sprintf("Go text/template template (left delim: %s right delim: %s) to generate secret keys "+
-			"file specified with --generate-keys.", mock.LeftTemplateDelim, mock.RightTemplateDelim))
+			"file specified with --generate-keys.", deployment.LeftTemplateDelim, deployment.RightTemplateDelim))
 
 	separateGenesisDoc := cmd.StringOpt("w separate-genesis-doc", "", "Emit a separate genesis doc as JSON or TOML")
 
@@ -95,13 +96,14 @@ func Configure(cmd *cli.Cmd) {
 				fatalf("Could not read GenesisSpec: %v", err)
 			}
 			if *generateKeysOpt != "" {
-				keyClient := mock.NewMockKeyClient()
+				keyClient := mock.NewKeyClient()
 				conf.GenesisDoc, err = genesisSpec.GenesisDoc(keyClient)
 				if err != nil {
 					fatalf("Could not generate GenesisDoc from GenesisSpec using MockKeyClient: %v", err)
 				}
 
-				secretKeysString, err := keyClient.DumpKeys(*keysTemplateOpt)
+				pkg := deployment.Package{Keys: keyClient.Keys()}
+				secretKeysString, err := pkg.Dump(*keysTemplateOpt)
 				if err != nil {
 					fatalf("Could not dump keys: %v", err)
 				}
diff --git a/cmd/burrow/commands/helpers.go b/cmd/burrow/commands/helpers.go
index 232c1f2eb33229e03cf56c43972d5f5c86963d91..a36ca827e80083c257a58f569c60f5f126cead58 100644
--- a/cmd/burrow/commands/helpers.go
+++ b/cmd/burrow/commands/helpers.go
@@ -23,7 +23,7 @@ func burrowConfigProvider(configFile string) source.ConfigProvider {
 	return source.FirstOf(
 		// Will fail if file doesn't exist, but still skipped it configFile == ""
 		source.File(configFile, false),
-		source.Environment(config.DefaultBurrowConfigJSONEnvironmentVariable),
+		source.Environment(config.DefaultBurrowConfigEnvironmentVariable),
 		// Try working directory
 		source.File(config.DefaultBurrowConfigTOMLFileName, true),
 		source.Default(config.DefaultBurrowConfig()))
diff --git a/cmd/burrow/commands/spec.go b/cmd/burrow/commands/spec.go
index 634006311b0a54082ed4266f7edfb2baed406b5d..6a0d3334439947e279f94703d0035c2f79f46023 100644
--- a/cmd/burrow/commands/spec.go
+++ b/cmd/burrow/commands/spec.go
@@ -17,7 +17,7 @@ func Spec(cmd *cli.Cmd) {
 		"additional GenesisSpec presets specified by other flags will be merged. GenesisSpecs appearing "+
 		"later take precedent over those appearing early if multiple --base flags are provided")
 
-	accountNamePrefixOpt := cmd.StringOpt("name-prefix", "", "Prefix added to the names of accounts in GenesisSpec")
+	accountNamePrefixOpt := cmd.StringOpt("x name-prefix", "", "Prefix added to the names of accounts in GenesisSpec")
 	fullOpt := cmd.IntOpt("f full-accounts", 0, "Number of preset Full type accounts")
 	validatorOpt := cmd.IntOpt("v validator-accounts", 0, "Number of preset Validator type accounts")
 	rootOpt := cmd.IntOpt("r root-accounts", 0, "Number of preset Root type accounts")
@@ -25,8 +25,8 @@ func Spec(cmd *cli.Cmd) {
 	participantsOpt := cmd.IntOpt("p participant-accounts", 0, "Number of preset Participant type accounts")
 	chainNameOpt := cmd.StringOpt("n chain-name", "", "Default chain name")
 
-	cmd.Spec = "[--full-accounts] [--validator-accounts] [--root-accounts] [--developer-accounts] " +
-		"[--participant-accounts] [--chain-name] [--toml] [BASE...]"
+	cmd.Spec = "[--name-prexix=<prefix for account names>][--full-accounts] [--validator-accounts] [--root-accounts] " +
+		"[--developer-accounts] [--participant-accounts] [--chain-name] [--toml] [BASE...]"
 
 	cmd.Action = func() {
 		specs := make([]spec.GenesisSpec, 0, *participantsOpt+*fullOpt)
diff --git a/config/config.go b/config/config.go
index fa0e3227d7b115e09437301b0e184cfdf9eb9283..3ce6d2f83ce83178970ed7e7bd8d7b3a0b845a11 100644
--- a/config/config.go
+++ b/config/config.go
@@ -19,7 +19,7 @@ import (
 )
 
 const DefaultBurrowConfigTOMLFileName = "burrow.toml"
-const DefaultBurrowConfigJSONEnvironmentVariable = "BURROW_CONFIG_JSON"
+const DefaultBurrowConfigEnvironmentVariable = "BURROW_CONFIG_JSON"
 const DefaultGenesisDocJSONFileName = "genesis.json"
 
 type BurrowConfig struct {
diff --git a/config/source/source.go b/config/source/source.go
index 4b35b901fa0ed76a2230854f9cf8b491521d7200..66e55e8f05c76e2b1aa69e44776b2c4e9fc6a1ad 100644
--- a/config/source/source.go
+++ b/config/source/source.go
@@ -170,12 +170,12 @@ func XDGBaseDir(configFileName string) *configSource {
 
 // Source from a single environment variable with config embedded in JSON
 func Environment(key string) *configSource {
-	jsonString := os.Getenv(key)
+	configString := os.Getenv(key)
 	return &configSource{
-		skip: jsonString == "",
-		from: fmt.Sprintf("'%s' environment variable (as JSON)", key),
+		skip: configString == "",
+		from: fmt.Sprintf("'%s' environment variable", key),
 		apply: func(baseConfig interface{}) error {
-			return FromJSONString(jsonString, baseConfig)
+			return FromString(configString, baseConfig)
 		},
 	}
 }
diff --git a/core/integration/test_wrapper.go b/core/integration/test_wrapper.go
index 7d0940d135236ebb19fe6d723b8b6c21ae3960ff..b97c7986d1463c20657b3116ded733f8eb599651 100644
--- a/core/integration/test_wrapper.go
+++ b/core/integration/test_wrapper.go
@@ -79,7 +79,7 @@ func TestWrapper(privateAccounts []acm.PrivateAccount, genesisDoc *genesis.Genes
 
 	validatorAccount := privateAccounts[0]
 	privValidator := validator.NewPrivValidatorMemory(validatorAccount, validatorAccount)
-	keyClient := mock.NewMockKeyClient(privateAccounts...)
+	keyClient := mock.NewKeyClient(privateAccounts...)
 	kernel, err := core.NewKernel(context.Background(), keyClient, privValidator, genesisDoc, tmConf, rpc.DefaultRPCConfig(),
 		nil, logger)
 	if err != nil {
diff --git a/core/kernel_test.go b/core/kernel_test.go
index e1e4d65d17c0416ae3ea0a613e35632c059915e6..5cd06d36e46d9946ea03a9f4a1832263f1ca1d24 100644
--- a/core/kernel_test.go
+++ b/core/kernel_test.go
@@ -65,7 +65,7 @@ func bootWaitBlocksShutdown(privValidator tm_types.PrivValidator, genesisDoc *ge
 	tmConf *tm_config.Config, logger *logging.Logger,
 	blockChecker func(block *tm_types.EventDataNewBlock) (cont bool)) error {
 
-	kern, err := NewKernel(context.Background(), mock.NewMockKeyClient(), privValidator, genesisDoc, tmConf,
+	kern, err := NewKernel(context.Background(), mock.NewKeyClient(), privValidator, genesisDoc, tmConf,
 		rpc.DefaultRPCConfig(), nil, logger)
 	if err != nil {
 		return err
diff --git a/deployment/config.go b/deployment/config.go
new file mode 100644
index 0000000000000000000000000000000000000000..8f1047b638d8465ae527fc887368add3842e61bd
--- /dev/null
+++ b/deployment/config.go
@@ -0,0 +1,87 @@
+package deployment
+
+import (
+	"bytes"
+	"encoding/base64"
+	"fmt"
+	"reflect"
+	"text/template"
+
+	"github.com/hyperledger/burrow/config"
+	"github.com/hyperledger/burrow/keys/mock"
+	"github.com/pkg/errors"
+	"github.com/tmthrgd/go-hex"
+)
+
+type Package struct {
+	Keys         []*mock.Key
+	BurrowConfig *config.BurrowConfig
+}
+
+const DefaultDumpKeysFormat = `{
+  "Keys": [<< range $index, $key := . >><< if $index>>,<< end >>
+    {
+      "Name": "<< $key.Name >>",
+      "Address": "<< $key.Address >>",
+      "PublicKey": "<< base64 $key.PublicKey >>",
+      "PrivateKey": "<< base64 $key.PrivateKey >>"
+    }<< end >>
+  ]
+}`
+
+const HelmDumpKeysFormat = `privateKeys:<< range $key := . >>
+  << $key.Address >>:
+    name: << $key.Name >>
+    address: << $key.Address >>
+    publicKey: << base64 $key.PublicKey >>
+    privateKey: << base64 $key.PrivateKey >><< end >>
+  `
+
+const KubernetesKeyDumpFormat = `keysFiles:<< range $index, $key := . >>
+  key-<< printf "%03d" $index >>: << base64 $key.MonaxKeysJSON >><< end >>
+keysAddresses:<< range $index, $key := . >>
+  key-<< printf "%03d" $index >>: << $key.Address >><< end >>
+validatorAddresses:<< range $index, $key := . >>
+  - << $key.Address >><< end >>
+`
+
+const LeftTemplateDelim = "<<"
+const RightTemplateDelim = ">>"
+
+var templateFuncs template.FuncMap = map[string]interface{}{
+	"base64": func(rv reflect.Value) string {
+		return encode(rv, base64.StdEncoding.EncodeToString)
+	},
+	"hex": func(rv reflect.Value) string {
+		return encode(rv, hex.EncodeUpperToString)
+	},
+}
+
+var DefaultDumpKeysTemplate = template.Must(template.New("MockKeyClient_DumpKeys").Funcs(templateFuncs).
+	Delims(LeftTemplateDelim, RightTemplateDelim).
+	Parse(DefaultDumpKeysFormat))
+
+func (pkg *Package) Dump(templateString string) (string, error) {
+	tmpl, err := template.New("DumpKeys").Delims(LeftTemplateDelim, RightTemplateDelim).Funcs(templateFuncs).
+		Parse(templateString)
+	if err != nil {
+		return "", errors.Wrap(err, "could not dump keys to template")
+	}
+	buf := new(bytes.Buffer)
+	err = tmpl.Execute(buf, pkg.Keys)
+	if err != nil {
+		return "", err
+	}
+	return buf.String(), nil
+}
+
+func encode(rv reflect.Value, encoder func([]byte) string) string {
+	switch rv.Kind() {
+	case reflect.Slice:
+		return encoder(rv.Bytes())
+	case reflect.String:
+		return encoder([]byte(rv.String()))
+	default:
+		panic(fmt.Errorf("could not convert %#v to bytes to encode", rv))
+	}
+}
diff --git a/keys/mock/key_client_mock_test.go b/deployment/config_test.go
similarity index 57%
rename from keys/mock/key_client_mock_test.go
rename to deployment/config_test.go
index 9a5cbef3f520c7c17d16592f51dfb7aae12f7227..3a159238b538bcca6274ed2370e96f0c049229bf 100644
--- a/keys/mock/key_client_mock_test.go
+++ b/deployment/config_test.go
@@ -1,28 +1,28 @@
-package mock
+package deployment
 
 import (
-	"testing"
-
 	"encoding/json"
-
 	"fmt"
+	"testing"
 
 	"github.com/hyperledger/burrow/keys"
+	"github.com/hyperledger/burrow/keys/mock"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
 
 func TestMockKeyClient_DumpKeys(t *testing.T) {
-	keyClient := NewMockKeyClient()
+	keyClient := mock.NewKeyClient()
 	_, err := keyClient.Generate("foo", keys.KeyTypeEd25519Ripemd160)
 	require.NoError(t, err)
 	_, err = keyClient.Generate("foobar", keys.KeyTypeEd25519Ripemd160)
 	require.NoError(t, err)
-	dump, err := keyClient.DumpKeys(DefaultDumpKeysFormat)
+	pkg := Package{Keys: keyClient.Keys()}
+	dump, err := pkg.Dump(DefaultDumpKeysFormat)
 	require.NoError(t, err)
 
 	// Check JSON equal
-	var keys struct{ Keys []*MockKey }
+	var keys struct{ Keys []*mock.Key }
 	err = json.Unmarshal([]byte(dump), &keys)
 	require.NoError(t, err)
 	bs, err := json.MarshalIndent(keys, "", "  ")
@@ -31,27 +31,25 @@ func TestMockKeyClient_DumpKeys(t *testing.T) {
 }
 
 func TestMockKeyClient_DumpKeysKubernetes(t *testing.T) {
-	keyClient := NewMockKeyClient()
+	keyClient := mock.NewKeyClient()
 	_, err := keyClient.Generate("foo", keys.KeyTypeEd25519Ripemd160)
 	require.NoError(t, err)
 	_, err = keyClient.Generate("foobar", keys.KeyTypeEd25519Ripemd160)
 	require.NoError(t, err)
-	dump, err := keyClient.DumpKeys(KubernetesKeyDumpFormat)
+	pkg := Package{Keys: keyClient.Keys()}
+	dump, err := pkg.Dump(KubernetesKeyDumpFormat)
 	require.NoError(t, err)
 	fmt.Println(dump)
 }
 
-func TestMockKey_MonaxKeyJSON(t *testing.T) {
-	key, err := newMockKey("monax-key-test")
-	require.NoError(t, err)
-	monaxKey := key.MonaxKeyJSON()
-	t.Logf("key is: %v", monaxKey)
-	keyJSON := &plainKeyJSON{}
-	err = json.Unmarshal([]byte(monaxKey), keyJSON)
-	require.NoError(t, err)
-	// byte length of UUID string = 16 * 2 + 4 = 36
-	assert.Len(t, keyJSON.Id, 36)
-	assert.Equal(t, key.Address.String(), keyJSON.Address)
-	assert.Equal(t, key.PrivateKey, keyJSON.PrivateKey)
-	assert.Equal(t, string(keys.KeyTypeEd25519Ripemd160), keyJSON.Type)
+func TestMockKeyClient_DumpKeysHelm(t *testing.T) {
+	keyClient := mock.NewKeyClient()
+	_, err := keyClient.Generate("foo", keys.KeyTypeEd25519Ripemd160)
+	require.NoError(t, err)
+	_, err = keyClient.Generate("foobar", keys.KeyTypeEd25519Ripemd160)
+	require.NoError(t, err)
+	pkg := Package{Keys: keyClient.Keys()}
+	dump, err := pkg.Dump(HelmDumpKeysFormat)
+	require.NoError(t, err)
+	fmt.Println(dump)
 }
diff --git a/genesis/spec/genesis_spec.go b/genesis/spec/genesis_spec.go
index 11549a0171f645cf1f2f4a194500170422cdc3c2..343b7eaf6d6072ce8caf1d3a4f892cc0a83b22cb 100644
--- a/genesis/spec/genesis_spec.go
+++ b/genesis/spec/genesis_spec.go
@@ -138,6 +138,16 @@ func (ta TemplateAccount) RealisePubKeyAndAddress(keyClient keys.KeyClient) (pub
 	return
 }
 
+func (gs *GenesisSpec) RealiseKeys(keyClient keys.KeyClient) error {
+	for _, templateAccount := range gs.Accounts {
+		_, _, err := templateAccount.RealisePubKeyAndAddress(keyClient)
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
 // Produce a fully realised GenesisDoc from a template GenesisDoc that may omit values
 func (gs *GenesisSpec) GenesisDoc(keyClient keys.KeyClient) (*genesis.GenesisDoc, error) {
 	genesisDoc := new(genesis.GenesisDoc)
diff --git a/genesis/spec/genesis_spec_test.go b/genesis/spec/genesis_spec_test.go
index 774f64c59e6f1aebde13d5b086b79028ae52e9c5..294c4ed315e600d9907ecd7d749c979d9eac1896 100644
--- a/genesis/spec/genesis_spec_test.go
+++ b/genesis/spec/genesis_spec_test.go
@@ -11,7 +11,7 @@ import (
 )
 
 func TestGenesisSpec_GenesisDoc(t *testing.T) {
-	keyClient := mock.NewMockKeyClient()
+	keyClient := mock.NewKeyClient()
 
 	// Try a spec with a single account/validator
 	amtBonded := uint64(100)
diff --git a/genesis/spec/presets_test.go b/genesis/spec/presets_test.go
index b8a40cd00be4c59e487302f48daf1db3053fc674..8e578640e8790aab8923006e7ec8d864a3cec5b5 100644
--- a/genesis/spec/presets_test.go
+++ b/genesis/spec/presets_test.go
@@ -10,7 +10,7 @@ import (
 )
 
 func TestMergeGenesisSpecAccounts(t *testing.T) {
-	keyClient := mock.NewMockKeyClient()
+	keyClient := mock.NewKeyClient()
 	gs := MergeGenesisSpecs(FullAccount("0"), ParticipantAccount("1"), ParticipantAccount("2"))
 	gd, err := gs.GenesisDoc(keyClient)
 	require.NoError(t, err)
diff --git a/keys/mock/key.go b/keys/mock/key.go
new file mode 100644
index 0000000000000000000000000000000000000000..313a118347e5be1bb6b0f8ddfbc3a45af0964b0b
--- /dev/null
+++ b/keys/mock/key.go
@@ -0,0 +1,98 @@
+package mock
+
+import (
+	"crypto/rand"
+	"encoding/json"
+	"fmt"
+
+	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/keys"
+	"github.com/pkg/errors"
+	"github.com/tendermint/go-crypto"
+	"github.com/wayn3h0/go-uuid"
+	"golang.org/x/crypto/ed25519"
+	"golang.org/x/crypto/ripemd160"
+)
+
+// Mock ed25510 key for mock keys client
+// Simple ed25519 key structure for mock purposes with ripemd160 address
+type Key struct {
+	Name       string
+	Address    acm.Address
+	PublicKey  []byte
+	PrivateKey []byte
+}
+
+func newKey(name string) (*Key, error) {
+	key := &Key{
+		Name:       name,
+		PublicKey:  make([]byte, ed25519.PublicKeySize),
+		PrivateKey: make([]byte, ed25519.PrivateKeySize),
+	}
+	// this is a mock key, so the entropy of the source is purely
+	// for testing
+	publicKey, privateKey, err := ed25519.GenerateKey(rand.Reader)
+	if err != nil {
+		return nil, err
+	}
+	copy(key.PrivateKey[:], privateKey[:])
+	copy(key.PublicKey[:], publicKey[:])
+
+	// prepend 0x01 for ed25519 public key
+	typedPublicKeyBytes := append([]byte{0x01}, key.PublicKey...)
+	hasher := ripemd160.New()
+	hasher.Write(typedPublicKeyBytes)
+	key.Address, err = acm.AddressFromBytes(hasher.Sum(nil))
+	if err != nil {
+		return nil, err
+	}
+	if key.Name == "" {
+		key.Name = key.Address.String()
+	}
+	return key, nil
+}
+
+func mockKeyFromPrivateAccount(privateAccount acm.PrivateAccount) *Key {
+	_, ok := privateAccount.PrivateKey().Unwrap().(crypto.PrivKeyEd25519)
+	if !ok {
+		panic(fmt.Errorf("mock key client only supports ed25519 private keys at present"))
+	}
+	key := &Key{
+		Name:       privateAccount.Address().String(),
+		Address:    privateAccount.Address(),
+		PublicKey:  privateAccount.PublicKey().RawBytes(),
+		PrivateKey: privateAccount.PrivateKey().RawBytes(),
+	}
+	return key
+}
+
+func (key *Key) Sign(message []byte) (acm.Signature, error) {
+	return acm.SignatureFromBytes(ed25519.Sign(key.PrivateKey, message))
+}
+
+// TODO: remove after merging keys taken from there to match serialisation
+type plainKeyJSON struct {
+	Id         []byte
+	Type       string
+	Address    string
+	PrivateKey []byte
+}
+
+// Returns JSON string compatible with that stored by monax-keys
+func (key *Key) MonaxKeysJSON() string {
+	id, err := uuid.NewRandom()
+	if err != nil {
+		return errors.Wrap(err, "could not create monax key json").Error()
+	}
+	jsonKey := plainKeyJSON{
+		Id:         []byte(id.String()),
+		Address:    key.Address.String(),
+		Type:       string(keys.KeyTypeEd25519Ripemd160),
+		PrivateKey: key.PrivateKey,
+	}
+	bs, err := json.Marshal(jsonKey)
+	if err != nil {
+		return errors.Wrap(err, "could not create monax key json").Error()
+	}
+	return string(bs)
+}
diff --git a/keys/mock/key_client.go b/keys/mock/key_client.go
new file mode 100644
index 0000000000000000000000000000000000000000..821c0c82499cb970a5f796497879e8281d9c8cc7
--- /dev/null
+++ b/keys/mock/key_client.go
@@ -0,0 +1,87 @@
+// Copyright 2017 Monax Industries Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package mock
+
+import (
+	"fmt"
+
+	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/keys"
+	"github.com/tendermint/go-crypto"
+)
+
+//---------------------------------------------------------------------
+// Mock client for replacing signing done by monax-keys
+
+// Implementation assertion
+var _ keys.KeyClient = (*KeyClient)(nil)
+
+type KeyClient struct {
+	knownKeys map[acm.Address]*Key
+}
+
+func NewKeyClient(privateAccounts ...acm.PrivateAccount) *KeyClient {
+	client := &KeyClient{
+		knownKeys: make(map[acm.Address]*Key),
+	}
+	for _, pa := range privateAccounts {
+		client.knownKeys[pa.Address()] = mockKeyFromPrivateAccount(pa)
+	}
+	return client
+}
+
+func (mkc *KeyClient) NewKey(name string) acm.Address {
+	// Only tests ED25519 curve and ripemd160.
+	key, err := newKey(name)
+	if err != nil {
+		panic(fmt.Sprintf("Mocked key client failed on key generation: %s", err))
+	}
+	mkc.knownKeys[key.Address] = key
+	return key.Address
+}
+
+func (mkc *KeyClient) Sign(signAddress acm.Address, message []byte) (acm.Signature, error) {
+	key := mkc.knownKeys[signAddress]
+	if key == nil {
+		return acm.Signature{}, fmt.Errorf("unknown address (%s)", signAddress)
+	}
+	return key.Sign(message)
+}
+
+func (mkc *KeyClient) PublicKey(address acm.Address) (acm.PublicKey, error) {
+	key := mkc.knownKeys[address]
+	if key == nil {
+		return acm.PublicKey{}, fmt.Errorf("unknown address (%s)", address)
+	}
+	pubKeyEd25519 := crypto.PubKeyEd25519{}
+	copy(pubKeyEd25519[:], key.PublicKey)
+	return acm.PublicKeyFromGoCryptoPubKey(pubKeyEd25519.Wrap())
+}
+
+func (mkc *KeyClient) Generate(keyName string, keyType keys.KeyType) (acm.Address, error) {
+	return mkc.NewKey(keyName), nil
+}
+
+func (mkc *KeyClient) HealthCheck() error {
+	return nil
+}
+
+func (mkc *KeyClient) Keys() []*Key {
+	var knownKeys []*Key
+	for _, key := range mkc.knownKeys {
+		knownKeys = append(knownKeys, key)
+	}
+	return knownKeys
+}
diff --git a/keys/mock/key_client_mock.go b/keys/mock/key_client_mock.go
deleted file mode 100644
index 47bdca9aeb9dba5840d2da98ba6c692db89c9005..0000000000000000000000000000000000000000
--- a/keys/mock/key_client_mock.go
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package mock
-
-import (
-	"bytes"
-	"crypto/rand"
-	"encoding/base64"
-	"fmt"
-	"text/template"
-
-	"encoding/json"
-
-	"reflect"
-
-	acm "github.com/hyperledger/burrow/account"
-	. "github.com/hyperledger/burrow/keys"
-	"github.com/pkg/errors"
-	"github.com/tendermint/ed25519"
-	"github.com/tendermint/go-crypto"
-	"github.com/tmthrgd/go-hex"
-	"github.com/wayn3h0/go-uuid"
-	"golang.org/x/crypto/ripemd160"
-)
-
-//---------------------------------------------------------------------
-// Mock ed25510 key for mock keys client
-
-// Simple ed25519 key structure for mock purposes with ripemd160 address
-type MockKey struct {
-	Name       string
-	Address    acm.Address
-	PublicKey  []byte
-	PrivateKey []byte
-}
-
-const DefaultDumpKeysFormat = `{
-  "Keys": [<< range $index, $key := . >><< if $index>>,<< end >>
-    {
-      "Name": "<< $key.Name >>",
-      "Address": "<< $key.Address >>",
-      "PublicKey": "<< base64 $key.PublicKey >>",
-      "PrivateKey": "<< base64 $key.PrivateKey >>"
-    }<< end >>
-  ]
-}`
-
-const KubernetesKeyDumpFormat = `keysFiles:<< range $index, $key := . >>
-  key-<< printf "%03d" $index >>: << base64 $key.MonaxKeyJSON >><< end >>
-keysAddresses:<< range $index, $key := . >>
-  key-<< printf "%03d" $index >>: << $key.Address >><< end >>
-validatorAddresses:<< range $index, $key := . >>
-  - << $key.Address >><< end >>
-`
-
-const LeftTemplateDelim = "<<"
-const RightTemplateDelim = ">>"
-
-var templateFuncs template.FuncMap = map[string]interface{}{
-	"base64": func(rv reflect.Value) string {
-		return encode(rv, base64.StdEncoding.EncodeToString)
-	},
-	"hex": func(rv reflect.Value) string {
-		return encode(rv, hex.EncodeUpperToString)
-	},
-}
-
-var DefaultDumpKeysTemplate = template.Must(template.New("MockKeyClient_DumpKeys").Funcs(templateFuncs).
-	Delims(LeftTemplateDelim, RightTemplateDelim).
-	Parse(DefaultDumpKeysFormat))
-
-func newMockKey(name string) (*MockKey, error) {
-	key := &MockKey{
-		Name:       name,
-		PublicKey:  make([]byte, ed25519.PublicKeySize),
-		PrivateKey: make([]byte, ed25519.PrivateKeySize),
-	}
-	// this is a mock key, so the entropy of the source is purely
-	// for testing
-	publicKey, privateKey, err := ed25519.GenerateKey(rand.Reader)
-	if err != nil {
-		return nil, err
-	}
-	copy(key.PrivateKey[:], privateKey[:])
-	copy(key.PublicKey[:], publicKey[:])
-
-	// prepend 0x01 for ed25519 public key
-	typedPublicKeyBytes := append([]byte{0x01}, key.PublicKey...)
-	hasher := ripemd160.New()
-	hasher.Write(typedPublicKeyBytes)
-	key.Address, err = acm.AddressFromBytes(hasher.Sum(nil))
-	if err != nil {
-		return nil, err
-	}
-	if key.Name == "" {
-		key.Name = key.Address.String()
-	}
-	return key, nil
-}
-
-func mockKeyFromPrivateAccount(privateAccount acm.PrivateAccount) *MockKey {
-	_, ok := privateAccount.PrivateKey().Unwrap().(crypto.PrivKeyEd25519)
-	if !ok {
-		panic(fmt.Errorf("mock key client only supports ed25519 private keys at present"))
-	}
-	key := &MockKey{
-		Name:       privateAccount.Address().String(),
-		Address:    privateAccount.Address(),
-		PublicKey:  privateAccount.PublicKey().RawBytes(),
-		PrivateKey: privateAccount.PrivateKey().RawBytes(),
-	}
-	return key
-}
-
-func (mockKey *MockKey) Sign(message []byte) (acm.Signature, error) {
-	var privateKey [ed25519.PrivateKeySize]byte
-	copy(privateKey[:], mockKey.PrivateKey)
-	return acm.SignatureFromBytes(ed25519.Sign(&privateKey, message)[:])
-}
-
-// TODO: remove after merging keys taken from there to match serialisation
-type plainKeyJSON struct {
-	Id         []byte
-	Type       string
-	Address    string
-	PrivateKey []byte
-}
-
-// Returns JSON string compatible with that stored by monax-keys
-func (mockKey *MockKey) MonaxKeyJSON() string {
-	id, err := uuid.NewRandom()
-	if err != nil {
-		return errors.Wrap(err, "could not create monax key json").Error()
-	}
-	jsonKey := plainKeyJSON{
-		Id:         []byte(id.String()),
-		Address:    mockKey.Address.String(),
-		Type:       string(KeyTypeEd25519Ripemd160),
-		PrivateKey: mockKey.PrivateKey,
-	}
-	bs, err := json.Marshal(jsonKey)
-	if err != nil {
-		return errors.Wrap(err, "could not create monax key json").Error()
-	}
-	return string(bs)
-}
-
-//---------------------------------------------------------------------
-// Mock client for replacing signing done by monax-keys
-
-// Implementation assertion
-var _ KeyClient = (*MockKeyClient)(nil)
-
-type MockKeyClient struct {
-	knownKeys map[acm.Address]*MockKey
-}
-
-func NewMockKeyClient(privateAccounts ...acm.PrivateAccount) *MockKeyClient {
-	client := &MockKeyClient{
-		knownKeys: make(map[acm.Address]*MockKey),
-	}
-	for _, pa := range privateAccounts {
-		client.knownKeys[pa.Address()] = mockKeyFromPrivateAccount(pa)
-	}
-	return client
-}
-
-func (mkc *MockKeyClient) NewKey(name string) acm.Address {
-	// Only tests ED25519 curve and ripemd160.
-	key, err := newMockKey(name)
-	if err != nil {
-		panic(fmt.Sprintf("Mocked key client failed on key generation: %s", err))
-	}
-	mkc.knownKeys[key.Address] = key
-	return key.Address
-}
-
-func (mkc *MockKeyClient) Sign(signAddress acm.Address, message []byte) (acm.Signature, error) {
-	key := mkc.knownKeys[signAddress]
-	if key == nil {
-		return acm.Signature{}, fmt.Errorf("Unknown address (%s)", signAddress)
-	}
-	return key.Sign(message)
-}
-
-func (mkc *MockKeyClient) PublicKey(address acm.Address) (acm.PublicKey, error) {
-	key := mkc.knownKeys[address]
-	if key == nil {
-		return acm.PublicKey{}, fmt.Errorf("Unknown address (%s)", address)
-	}
-	pubKeyEd25519 := crypto.PubKeyEd25519{}
-	copy(pubKeyEd25519[:], key.PublicKey)
-	return acm.PublicKeyFromGoCryptoPubKey(pubKeyEd25519.Wrap())
-}
-
-func (mkc *MockKeyClient) Generate(keyName string, keyType KeyType) (acm.Address, error) {
-	return mkc.NewKey(keyName), nil
-}
-
-func (mkc *MockKeyClient) HealthCheck() error {
-	return nil
-}
-
-func (mkc *MockKeyClient) DumpKeys(templateString string) (string, error) {
-	tmpl, err := template.New("DumpKeys").Delims(LeftTemplateDelim, RightTemplateDelim).Funcs(templateFuncs).
-		Parse(templateString)
-	if err != nil {
-		return "", errors.Wrap(err, "could not dump keys to template")
-	}
-	buf := new(bytes.Buffer)
-	keys := make([]*MockKey, 0, len(mkc.knownKeys))
-	for _, k := range mkc.knownKeys {
-		keys = append(keys, k)
-	}
-	err = tmpl.Execute(buf, keys)
-	if err != nil {
-		return "", err
-	}
-	return buf.String(), nil
-}
-
-func encode(rv reflect.Value, encoder func([]byte) string) string {
-	switch rv.Kind() {
-	case reflect.Slice:
-		return encoder(rv.Bytes())
-	case reflect.String:
-		return encoder([]byte(rv.String()))
-	default:
-		panic(fmt.Errorf("could not convert %#v to bytes to encode", rv))
-	}
-}
diff --git a/keys/mock/key_client_test.go b/keys/mock/key_client_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..7f74a03733c54f751bcecab7fa6abfe691dbeebf
--- /dev/null
+++ b/keys/mock/key_client_test.go
@@ -0,0 +1,26 @@
+package mock
+
+import (
+	"testing"
+
+	"encoding/json"
+
+	"github.com/hyperledger/burrow/keys"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func TestMockKey_MonaxKeyJSON(t *testing.T) {
+	key, err := newKey("monax-key-test")
+	require.NoError(t, err)
+	monaxKey := key.MonaxKeysJSON()
+	t.Logf("key is: %v", monaxKey)
+	keyJSON := &plainKeyJSON{}
+	err = json.Unmarshal([]byte(monaxKey), keyJSON)
+	require.NoError(t, err)
+	// byte length of UUID string = 16 * 2 + 4 = 36
+	assert.Len(t, keyJSON.Id, 36)
+	assert.Equal(t, key.Address.String(), keyJSON.Address)
+	assert.Equal(t, key.PrivateKey, keyJSON.PrivateKey)
+	assert.Equal(t, string(keys.KeyTypeEd25519Ripemd160), keyJSON.Type)
+}
diff --git a/rpc/v0/server/config.go b/rpc/v0/server/config.go
index f5b8130c0f7ec64517da44fc3e0ef2b3080c76ba..6db3bdbe875221c317c3d8348166ba48b90aa560 100644
--- a/rpc/v0/server/config.go
+++ b/rpc/v0/server/config.go
@@ -16,7 +16,6 @@ package server
 
 type (
 	ServerConfig struct {
-		ChainId   string
 		Bind      Bind      `toml:"bind"`
 		TLS       TLS       `toml:"TLS"`
 		CORS      CORS      `toml:"CORS"`
diff --git a/rpc/v0/server/server.go b/rpc/v0/server/server.go
index 5a6240013cdd6baa6402740bf864dedadccf934d..2ee096c5b2aef767c3d121c6a169888c94296a6d 100644
--- a/rpc/v0/server/server.go
+++ b/rpc/v0/server/server.go
@@ -120,7 +120,6 @@ func (serveProcess *ServeProcess) Start() error {
 	}
 	serveProcess.srv = srv
 	serveProcess.logger.InfoMsg("Server started.",
-		"chain_id", serveProcess.config.ChainId,
 		"address", serveProcess.config.Bind.Address,
 		"port", serveProcess.config.Bind.Port)
 	for _, c := range serveProcess.startListenChans {