User initialization

Initialization by program

To start creating and using keys on a TSM you need to be a user. That user can be created by an administrator. The code below show how to create an initial administrator on an empty TSM. Using the credentials of this administrator a (key) user can be created. Two files containing the credentials of the administrator and the key user respectively will written.

package main

import (
	"fmt"
	"gitlab.com/sepior/go-tsm-sdk/sdk/tsm"
	"net/url"
	"os"
	"time"
)


func main() {
	servers := []string{"https://tsm-node1.example.com", "https://tsm-node2.example.com", "https://tsm-node3.example.com"}
	var nodes []tsm.Node
	for _, s := range servers {
		u, err := url.Parse(s)
		if err != nil {
			panic(err)
		}
		nodes = append(nodes, tsm.NewURLNode(*u, tsm.NullAuthenticator{}))
	}
	client :=  tsm.NewClient(3,1,nodes)
	ac := tsm.NewAdminClient(client)

	version, err := ac.TSMVersion()
	if err != nil {
		fmt.Println("Could not ping. Retrying...")
		time.Sleep(time.Second)
		version, err = ac.TSMVersion()
	}
	if err != nil {
		fmt.Println("Could not ping servers")
		panic(err)
	}
	fmt.Printf("TSM version: %s\n", version)

	fmt.Println("Creating initial admin")
	uc := tsm.NewUsersClient(client)
	adminCreds, err := uc.CreateInitialAdmin()
	if err != nil {
		fmt.Printf("Could not create initial admin: %s\n", err)
		fmt.Println("Exiting. We expect the TSM has already been initialized.")
		return
	}
	adminJson, err := adminCreds.Encode()
	if err != nil{
		panic(err)
	}
	err = os.WriteFile("admin.json", []byte(adminJson), 0666)
	if err != nil{
		panic(err)
	}
	admClient, err := tsm.NewPasswordClientFromCredentials(3,1,adminCreds)
	if err != nil {
		panic(err)
	}

	fmt.Println("Creating key user")
	uc = tsm.NewUsersClient(admClient)
	userCreds, err := uc.CreatePasswordUser("user", "")
	userJson, err := userCreds.Encode()
	if err != nil{
		panic(err)
	}
	err = os.WriteFile("user.json", []byte(userJson), 0666)
	if err != nil{
		panic(err)
	}
}

πŸ“˜

Note:

Please don't forget to update the https://tsm-node.example.com with the URLs that you have in your credentials JSON file.

Initialization by the TSMCli tool

An alternative to creating users by writing the program above is to use the TSM Cli tool. The TSM Cli tool enables different tasks that are relevant during the setup of the MPC nodes. Setting up users can be done with the following two commands which does the same as the program above.

./tsmcli user:createinitial -server=http://localhost:8080 -server=http://localhost:8081 -server=http://localhost:8082 -out=admin.json
./tsmcli user:create -credentials=admin.json -out=user.json

The first command will create the initial administrators on the nodes specified and write the credentials to the admin.json file.

The second command will then use these admin credentials to create a key user and write the credentials of the created user to the user.json file.

Create Initial Admin Account from Configuration

The initial admin account can also be created by adding an initialization section to the config files of the MPC nodes. Following this the key users will have to be created using one of the two above methods.

# This section is used for initializing the server with values specified in the configuration instead of other sources.
[Initializers]
  # The following two entries can be used to bootstrap the node to a specific Administrator name and password. If used, both
  # entries must be set in which case the administrator will be created with the specified password. This will only work if
  # an administrator has not already been created.
  AdministratorUsername = ""
  AdministratorPassword = ""

User Credential file format

Both the user and the admin credential file have the same format. It contains the username, followed by a list of the servers for which the credential file is valid. After this is a list of password for each of the servers in the server list. Note that the username must be the same across servers, but the password do not.

{
    "userID": "username",
    "urls": [
        "http://localhost:8080",
        "http://localhost:8081",
        "http://localhost:8082"
    ],
    "passwords": [
        "Password for first node",
        "Password for second node",
        "Password for third node"
    ]
}