Confidential Space Enclave Signer
This backend is in beta and is expected to ship in Signatory v1.3.0 prior to the Tezos Seoul protocol activation. See Protocol Seoul.
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
Field | Environment variable | Type | Default | Required | Description |
---|---|---|---|---|---|
host | CONFIDENTIAL_SPACE_HOST | string | ✅ | Host address of the Confidential Space enclave running tee-signer | |
port | CONFIDENTIAL_SPACE_PORT | string | 2000 | TCP port of tee-signer service | |
wip_provider_path | GCP_WIP_PROVIDER_PATH | string | ✅ | Workload Identity Pool Provider path for authentication | |
encryption_key_path | GCP_KMS_ENCRYPTION_KEY_PATH | string | ✅ | KMS key path used by enclave to encrypt/decrypt private keys | |
storage | StorageConfig | Key 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.
Field | Type | Description |
---|---|---|
driver | string | Storage driver: "file", "gcp", or "firestore" |
config | yaml.Node | Storage-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:
Field | Type | Required | Description |
---|---|---|---|
application_credentials | string | OPTIONAL | Path to the GCP application token JSON file (overrides GOOGLE_APPLICATION_CREDENTIALS environment variable) |
application_credentials_data | string | OPTIONAL | GCP application token JSON data (overrides application_credentials) |
project | string | ✅ | GCP project ID |
database | string | ✅ | Firestore database name |
table | string | Collection 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.