dstack SDK for Python
January 13, 2026 · View on GitHub
Access TEE features from your Python application running inside dstack. Derive deterministic keys, generate attestation quotes, create TLS certificates, and sign data—all backed by hardware security.
Installation
pip install dstack-sdk
Quick Start
from dstack_sdk import DstackClient
client = DstackClient()
# Derive a deterministic key for your wallet
key = client.get_key('wallet/eth')
print(key.key) # Same path always returns the same key
# Generate an attestation quote
quote = client.get_quote(b'my-app-state')
print(quote.quote)
The client automatically connects to /var/run/dstack.sock. For local development with the simulator, pass the endpoint explicitly:
client = DstackClient('http://localhost:8090')
Core API
Derive Keys
get_key() derives deterministic keys bound to your application's identity (app_id). The same path always produces the same key for your app, but different apps get different keys even with the same path.
# Derive keys by path
eth_key = client.get_key('wallet/ethereum')
btc_key = client.get_key('wallet/bitcoin')
# Use path to separate keys
mainnet_key = client.get_key('wallet/eth/mainnet')
testnet_key = client.get_key('wallet/eth/testnet')
# Different algorithm
ed_key = client.get_key('signing/key', algorithm='ed25519')
Parameters:
path: Key derivation path (determines the key)purpose(optional): Included in signature chain message, does not affect the derived keyalgorithm(optional):'secp256k1'(default) or'ed25519'
Returns: GetKeyResponse
key: Hex-encoded private keysignature_chain: Signatures proving the key was derived in a genuine TEE
Generate Attestation Quotes
get_quote() creates a TDX quote proving your code runs in a genuine TEE.
quote = client.get_quote(b'user:alice:nonce123')
# Replay RTMRs from the event log
rtmrs = quote.replay_rtmrs()
print(rtmrs)
Parameters:
report_data: Exactly 64 bytes recommended. If shorter, pad with zeros. If longer, hash it first (e.g., SHA-256).
Returns: GetQuoteResponse
quote: Hex-encoded TDX quoteevent_log: JSON string of measured eventsreplay_rtmrs(): Method to compute RTMR values from event log
Get Instance Info
info = client.info()
print(info.app_id)
print(info.instance_id)
print(info.tcb_info)
Returns: InfoResponse
app_id: Application identifierinstance_id: Instance identifierapp_name: Application nametcb_info: TCB measurements (MRTD, RTMRs, event log)compose_hash: Hash of the app configurationapp_cert: Application certificate (PEM)
Generate TLS Certificates
get_tls_key() creates fresh TLS certificates. Unlike get_key(), each call generates a new random key.
tls = client.get_tls_key(
subject='api.example.com',
alt_names=['localhost'],
usage_ra_tls=True # Embed attestation in certificate
)
print(tls.key) # PEM private key
print(tls.certificate_chain) # Certificate chain
Parameters:
subject(optional): Certificate common name (e.g., domain name)alt_names(optional): List of subject alternative namesusage_ra_tls(optional): Embed TDX quote in certificate extensionusage_server_auth(optional): Enable for server authentication (default:True)usage_client_auth(optional): Enable for client authentication (default:False)
Returns: GetTlsKeyResponse
key: PEM-encoded private keycertificate_chain: List of PEM certificates
Sign and Verify
Sign data using TEE-derived keys (not yet released):
result = client.sign('ed25519', b'message to sign')
print(result.signature)
print(result.public_key)
# Verify the signature
valid = client.verify('ed25519', b'message to sign', result.signature, result.public_key)
print(valid.valid) # True
sign() Parameters:
algorithm:'ed25519','secp256k1', or'secp256k1_prehashed'data: Data to sign (bytes or string)
sign() Returns: SignResponse
signature: Hex-encoded signaturepublic_key: Hex-encoded public keysignature_chain: Signatures proving TEE origin
verify() Parameters:
algorithm: Algorithm used for signingdata: Original datasignature: Signature to verifypublic_key: Public key to verify against
verify() Returns: VerifyResponse
valid: Boolean indicating if signature is valid
Emit Events
Extend RTMR3 with custom measurements for your application's boot sequence (requires dstack OS 0.5.0+). These measurements are append-only and become part of the attestation record.
client.emit_event('config_loaded', 'production')
client.emit_event('plugin_initialized', 'auth-v2')
Parameters:
event: Event name (string identifier)payload: Event value (bytes or string)
Async Client
For async applications, use AsyncDstackClient:
from dstack_sdk import AsyncDstackClient
import asyncio
async def main():
client = AsyncDstackClient()
info = await client.info()
key = await client.get_key('wallet/eth')
# Concurrent operations
keys = await asyncio.gather(
client.get_key('user/alice'),
client.get_key('user/bob'),
)
asyncio.run(main())
Blockchain Integration
Ethereum
from dstack_sdk.ethereum import to_account
key = client.get_key('wallet/ethereum')
account = to_account(key)
print(account.address)
Solana
from dstack_sdk.solana import to_keypair
key = client.get_key('wallet/solana')
keypair = to_keypair(key)
print(keypair.public_key)
Development
For local development without TDX hardware, use the simulator:
git clone https://github.com/Dstack-TEE/dstack.git
cd dstack/sdk/simulator
./build.sh
./dstack-simulator
Then set the endpoint:
export DSTACK_SIMULATOR_ENDPOINT=http://localhost:8090
Run tests with PDM:
pdm install -d
pdm run pytest -s
Deployment Utilities
These utilities are for deployment scripts, not runtime SDK operations.
Encrypt Environment Variables
Encrypt secrets before deploying to dstack:
from dstack_sdk import encrypt_env_vars, verify_env_encrypt_public_key, EnvVar
# Get and verify the KMS public key
# (obtain public_key and signature from KMS API)
kms_identity = verify_env_encrypt_public_key(public_key_bytes, signature_bytes, app_id)
if not kms_identity:
raise RuntimeError('Invalid KMS key')
# Encrypt variables
env_vars = [
EnvVar(key='DATABASE_URL', value='postgresql://...'),
EnvVar(key='API_KEY', value='secret'),
]
encrypted = encrypt_env_vars(env_vars, public_key)
Calculate Compose Hash
from dstack_sdk import get_compose_hash
hash_value = get_compose_hash(app_compose_dict)
Migration from TappdClient
Replace TappdClient with DstackClient:
# Before
from dstack_sdk import TappdClient
client = TappdClient()
# After
from dstack_sdk import DstackClient
client = DstackClient()
Method changes:
derive_key()→get_tls_key()for TLS certificatestdx_quote()→get_quote()- Socket path:
/var/run/tappd.sock→/var/run/dstack.sock
License
Apache License 2.0