Skip to main content

Confidential Space Enclave Signer

Confidential Space backend is used in conjunction with signatory-io/tee-signer, its counterpart running inside Google Cloud Confidential Space, a secure execution environment that provides hardware-based memory encryption and integrity verification.

All keys imported into tee-signer or generated by it never leave the enclave in a plain text form. As the enclave has no persistent storage, all sensitive data is stored by the parent instance in encrypted form. The keystone of this model is a carefully chosen Google Cloud KMS policy which permits the decryption of such data only by an actor possessing proper authentication credentials and running inside the Confidential Space environment.

Prerequisites​

For detailed setup instructions, see GCP Confidential Space Setup Guide.

You will need:

  • A Workload Identity Pool (WIP) Provider path for authentication
  • A KMS encryption key path for encrypting/decrypting private keys
  • Network access to the Confidential Space enclave running tee-signer

Configuration​

FieldEnvironment variableTypeDefaultRequiredDescription
hostCONFIDENTIAL_SPACE_HOSTstring✅Host address of the Confidential Space enclave running tee-signer
portCONFIDENTIAL_SPACE_PORTstring2000TCP port of tee-signer service
wip_provider_pathGCP_WIP_PROVIDER_PATHstring✅Workload Identity Pool Provider path for authentication
encryption_key_pathGCP_KMS_ENCRYPTION_KEY_PATHstring✅KMS key path used by enclave to encrypt/decrypt private keys
storageStorageConfigKey storage configuration

StorageConfig​

Encrypted keys can be stored in different backends. The storage configuration is optional - if omitted, local file storage will be used by default.

FieldTypeDescription
driverstringStorage driver: "file", "gcp", or "firestore"
configyaml.NodeStorage-specific configuration

Local File Storage​

For local file storage, the config field is expected to be a single string containing a full file path. Environment variables are allowed and will be expanded.

If local storage is specified without a config, the default file ${BASE_DIR}/confidential_space_keys.json will be used.

Google Cloud Firestore Storage​

For Google Cloud Firestore storage, the config field should contain:

FieldTypeRequiredDescription
application_credentialsstringOPTIONALPath to the GCP application token JSON file (overrides GOOGLE_APPLICATION_CREDENTIALS environment variable)
application_credentials_datastringOPTIONALGCP application token JSON data (overrides application_credentials)
projectstring✅GCP project ID
databasestring✅Firestore database name
tablestringCollection name (default: "encrypted_keys")

The Firestore storage driver supports both gcp and firestore as driver names for compatibility.

Example​

For complete setup instructions, see GCP Confidential Space Setup Guide.

base_dir: ${HOME}/.signatory
server:
# Address for the main HTTP server to listen on
address: :6732
# Address for the utility HTTP server to listen on
utility_address: :9583

vaults:
confidentialspace:
driver: confidentialspace
config:
host: 10.0.0.100
port: 2000
wip_provider_path: projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider
encryption_key_path: projects/my-project/locations/global/keyRings/my-keyring/cryptoKeys/my-key

Importing​

Confidential Space backend supports importing of pre-existing plain text keys in either PEM, DER or Base58 format using signatory-cli import command. The key will be passed to the enclave in open form and the latter will return its encrypted version.

Key Generation​

More secure way of getting keys into the enclave is to generate them on the enclave side using signatory-cli generate command:

Usage:
signatory-cli generate [flags]

Flags:
-h, --help help for generate
-n, --num int Number of keys to generate (default 1)
-t, --type string Key algorithm: [tz1, tz2, tz3, tz4, ed25519, secp256k1, p256, bls] (default "ed25519")
-v, --vault string Vault name for importing

Global Flags:
--base-dir string Base directory. Takes priority over one specified in config
-c, --config string Config file path (default "/etc/signatory.yaml")
--json-log Use JSON structured logs
--log string Log level: [error, warn, info, debug, trace] (default "info")

Example:

signatory-cli generate -v confidentialspace -t bls

Network Communication​

The Confidential Space backend communicates with the enclave over TCP. The enclave must be accessible from the network where Signatory is running. The communication protocol is based on CBOR-encoded RPC messages for efficiency and security.

Key Storage​

Local File Storage​

Encrypted keys are stored in a JSON file with the following structure:

[
{
"public_key_hash": "tz4...",
"encrypted_private_key": "..."
}
]

The public_key_hash field contains the Tezos address (Base58 encoded), and the encrypted_private_key field contains the KMS-encrypted private key data.

Firestore Storage​

When using Firestore storage, encrypted keys are stored as documents in a Firestore collection with the following structure:

{
"pkh": "tz4...",
"value": "..."
}

Where pkh contains the Tezos address (Base58 encoded) and value contains the KMS-encrypted private key data.