Authentication

Each MPC node in the TSM is controlled by an SDK. When the SDK is initiated, it must be authenticated. When the authentication succeeds, the SDK is logged into the MPC node on a given application. The MPC node can have many applications. SDKs that are logged into the same application have access to the same keys.

The following types of authentication are supported:

Authenticaton with API Keys

Assuming that the MPC node URL is https://node.tsm.sepior.net and that the MPC node is configured to accept the API key apikey , you can log in like this:

config := tsm.Configuration{URL: "https://node.tsm.sepior.net"}
config = config.WithAPIKeyAuthentication("apikey")
node, err := tsm.NewClient(config)

SDK authentication using an API key requires that the MPC node has been configured to accept the API key, and the actual application that this API key maps to, is specified in the TSM configuration. See this section for more about how to configure API key authentication in the TSM.

See this for a full example with API key authentication.

Authentication with TLS Certificate (mTLS)

As an alternative to API key authentication, the SDK can authenticate using a TLS certificate. This means that the connection between the SDK and the MPC node will be secured using a 2-way TLS connection.

This can be done like this:

clientKey := "/path/to/client.key"
clientCrt := "/path/to/client.crt"
config := tsm.Configuration{URL: "https://node.tsm.sepior.net"}
config, err = config.WithMTLSAuthentication(clientKey, clientCrt, nil)
node, err := tsm.NewClient(config)

SDK authentication using mTLS requires that the certificate authority (CA) that issued the client certificate has been registered in the MPC node configuration. See this for more about how to configure the mTLS connection in the MPC node configuration.

OCSP

OCSP Stapling parameter

The third parameter in WithMTLSAuthentication(keyFile, certFile string, ocspStapling *OCSPStaplingConfiguration) is used for OCSP stapling. If set, the client certificate will be stapled with an OCSP response. The ocspStapling parameter has the type:

type OCSPStaplingConfiguration struct {
	// PEM certificate file containing trusted root CAs used for validating the client certificate.
	// If empty, the system certificate store is used.
	RootCAFile string
	// Lifetime of cached OCSP responses, e.g "1h30m". A value of 0 means that ValidUntil from the OCSP response
	// is used, otherwise the value of CacheTTL is used if it comes before ValidUntil.
	CacheTTL string
	// Use this URL for all OCSP responders, regardless of what the certificate says.
	ResponderURL string
}

WithOCSPValidation

The SDK can do OCSP validation on certificates. The MPC node configuration of OCSP is described here. In the SDK you will need to add:

// WithOCSPValidation enables OCSP validation of the MPC node certificate.
newConfig := config.WithOCSPValidation(ocspConfig)

Where the parameter is of type:

type OCSPConfiguration struct {
	// Require the TSM node to send a stapled OCSP response, otherwise validation will fail.
	RequireStapling bool
	// If true then only the leaf certificate is validated. Otherwise, the entire chain is validated.
	ValidateLeafOnly bool
	// Lifetime of cached OCSP responses, e.g "1h30m". A value of 0 means that ValidUntil from the OCSP response
	// is used, otherwise the value of CacheTTL is used if it comes before ValidUntil.
	CacheTTL string
	// Use this URL for all OCSP responders, regardless of what the certificate says.
	ResponderURL string
}

WithRootCAFile

If the TSM node uses a certificate which you need to accept in the SDK, you can use:

// WithRootCAFile specifies a file containing PEM certificates of the trusted root CAs used to validate the MPC node
// certificate. If not set, the system certificate store is used.		
config := tsm.Configuration{URL: "https://host:port"}.WithRootCAFile(caFileName)

To specify a corresponding CA file.

Public Key Pinning

Public Key Pinning can be used to verify that the server provides a certificate matching a given public key. This means that the SDK will only accept a connection with the MPC node that has the exact private key that corresponds to this public key.

For example (ignoring error handling):

// Extract the MPC node public key from certificate

nodeCertPEM, err := os.ReadFile("/path/to/node.crt")
block, rest := pem.Decode(nodeCertPEM)
if block == nil || len(rest) != 0 {
	panic(err)
}
cert, err := x509.ParseCertificate(block.Bytes)
nodePKIXPublicKey, err := x509.MarshalPKIXPublicKey(cert.PublicKey)

// Create node SDK with mTLS authentication and public key pinning

clientKey := "/path/to/client.key"
clientCrt := "/path/to/client.crt"
config, err := tsm.Configuration{URL: "https://node.tsm.sepior.net"}.WithPublicKeyPinning(nodePKIXPublicKey)
node, err := tsm.NewClient(config)

Authentication with OIDC

The SDK can also authenticate using an OIDC access token:

config := tsm.Configuration{URL: "https://node.tsm.sepior.net"}
config, err = config.WithOIDCAccessTokenAuthentication(accessToken)

The accessToken is obtained from the login process performed at the OIDC identity provider.

The OIDC authentication is configured on the MPC node. The node can, e.g., be configured up to accept Microsoft accounts, or Google accounts from a particular application domain, or it can be configured to accept a custom OIDC provider. See this section for more about how to configure OIDC authentication on an MPC node.

The MPC node derives the application from the audience field in the access token. This means that two SDKs that each authenticates with their own OIDC access token, will have access to the same set of keys in the TSM, if their access tokens were issued for the same audience.


What’s Next