dstack SDK for Python
Project description
dstack SDK for Python
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
Blockchain helpers are optional extras:
| Extra | Pulls in | Use when |
|---|---|---|
dstack-sdk[ethereum] |
eth-account |
You want to_account / to_account_secure for Ethereum signing |
dstack-sdk[solana] |
solders |
You want to_keypair / to_keypair_secure for Solana signing |
dstack-sdk[all] |
both | You need both |
Aliases [eth] and [sol] are accepted for convenience.
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:
client = DstackClient('http://localhost:8090')
# or export DSTACK_SIMULATOR_ENDPOINT=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')
# Use a different signature algorithm (requires dstack OS >= 0.5.7)
ed_key = client.get_key('signing/key', algorithm='ed25519')
Parameters:
path(optional): Key derivation path. Defaults to""(root).purpose(optional): Included in the signature chain message; does not affect the derived key.algorithm(optional):'secp256k1'(default) or'ed25519'.
Returns: GetKeyResponse
key: Hex-encoded private keysignature_chain: Signatures proving the key was derived in a genuine TEEdecode_key()/decode_signature_chain(): Helpers that returnbytes
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: Up to 64 bytes (bytesorstr). Shorter inputs are padded with zeros; longer inputs should be hashed 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 the event logdecode_quote()/decode_event_log(): Helpers
Versioned Attestation
attest() returns a versioned attestation payload that newer verifier APIs can dispatch on without sniffing the quote format.
result = client.attest(b'user:alice:nonce123')
print(result.attestation) # hex string
print(result.decode_attestation()) # bytes
Get Instance Info
info = client.info()
print(info.app_id)
print(info.instance_id)
print(info.tcb_info)
print(info.cloud_vendor, info.cloud_product) # 0.5.7+
Returns: InfoResponse
app_id,instance_id,app_name,device_idtcb_info: TCB measurements (MRTD, RTMRs, event log, compose hash, ...)compose_hash: Hash of the app configurationapp_cert: Application certificate (PEM)key_provider_info: Key management configurationcloud_vendor/cloud_product: Cloud provider strings (empty on older OS)
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
# 0.5.7+ options below:
not_before=1700000000, # seconds since UNIX epoch
not_after=1800000000,
with_app_info=True,
)
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): Subject Alternative Namesusage_ra_tls(optional): Embed TDX quote in a certificate extension (defaultFalse)usage_server_auth(optional): Enable for server authentication (defaultTrue)usage_client_auth(optional): Enable for client authentication (defaultFalse)not_before/not_after(optional, kw-only): Validity window in seconds since UNIX epoch. Requires dstack OS >= 0.5.7.with_app_info(optional, kw-only): Embed app identity into the certificate. Requires dstack OS >= 0.5.7.
When any of the 0.5.7-only options is set, the SDK probes Version first and raises RuntimeError on older guest agents that lack it.
Returns: GetTlsKeyResponse
key: PEM-encoded private keycertificate_chain: List of PEM certificatesas_uint8array(max_length=None): Returns the DER-encoded private key bytes (handy when feeding key material into low-level crypto libraries)
Sign and Verify
Sign data using TEE-derived keys:
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 (bytesorstr). Forsecp256k1_prehashed, must be a 32-byte digest.
sign() Returns: SignResponse
signature: Hex-encoded signaturepublic_key: Hex-encoded public keysignature_chain: Signatures proving TEE origin
verify() Returns: VerifyResponse
valid: Boolean indicating if the 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')
Diagnostics
client.version() # VersionResponse(version, rev) — raises on OS < 0.5.7
client.is_reachable() # Quick connectivity probe; never raises
Async Client
For async applications, use AsyncDstackClient. The API surface is identical, but every method is a coroutine:
import asyncio
from dstack_sdk import AsyncDstackClient
async def main():
client = AsyncDstackClient()
info = await client.info()
key = await client.get_key('wallet/eth')
# Run requests concurrently
keys = await asyncio.gather(
client.get_key('user/alice'),
client.get_key('user/bob'),
)
asyncio.run(main())
AsyncDstackClient accepts the same constructor as DstackClient plus use_sync_http: bool = False for callers that need to issue sync HTTP from within an async context.
Blockchain Integration
Ethereum
from dstack_sdk.ethereum import to_account_secure
key = client.get_key('wallet/ethereum')
account = to_account_secure(key)
print(account.address)
to_account_secure(key) hashes the full key material with SHA-256 before deriving the Ethereum private key. The legacy to_account() is kept for backward compatibility but uses raw key bytes—prefer the secure variant for new code.
Solana
from dstack_sdk.solana import to_keypair_secure
key = client.get_key('wallet/solana')
keypair = to_keypair_secure(key)
print(keypair.pubkey())
Same pattern: to_keypair_secure(key) SHA-256-hashes the key material; to_keypair() is the legacy raw-bytes variant.
Deployment Utilities
These utilities are for deployment scripts, not runtime SDK operations.
Encrypted Environment Variables
The KMS returns a fresh X25519 public key (with a secp256k1 signature) that you encrypt secrets against before submitting them with your deployment. Always verify the signer before trusting the key:
from dstack_sdk import (
encrypt_env_vars,
verify_env_encrypt_public_key,
verify_env_encrypt_public_key_legacy,
EnvVar,
)
# `public_key`, `signature_v1`, `timestamp` come from KMS /GetAppEnvEncryptPubKey.
signer = verify_env_encrypt_public_key(
public_key=public_key_bytes,
signature=signature_v1_bytes,
app_id=app_id_hex,
timestamp=timestamp,
)
if signer is None:
# Fallback for older KMS builds that only emit the unprotected legacy
# signature. Vulnerable to replay; warn loudly if you must use it.
signer = verify_env_encrypt_public_key_legacy(
public_key=public_key_bytes,
signature=legacy_signature_bytes,
app_id=app_id_hex,
)
if signer is None:
raise RuntimeError('invalid KMS env-encrypt public key')
env_vars = [
EnvVar(key='DATABASE_URL', value='postgresql://...'),
EnvVar(key='API_KEY', value='secret'),
]
encrypted = await encrypt_env_vars(env_vars, public_key_hex)
# encrypt_env_vars_sync(...) is also available for non-async callers.
verify_env_encrypt_public_key returns the recovered compressed secp256k1 signer (0x-prefixed hex) on success, or None for any failure (bad length, expired/future timestamp, malformed app_id, invalid signature). The default max_age_seconds is 300; pass a larger value if your deployment workflow legitimately holds the response longer.
Calculate Compose Hash
from dstack_sdk import get_compose_hash
hash_value = get_compose_hash(app_compose_dict)
Compatibility
| Feature | Required dstack OS |
|---|---|
get_key, get_quote, get_tls_key (legacy fields), info (legacy fields) |
0.3+ |
emit_event |
0.5.0+ |
attest, sign / verify, version, is_reachable |
0.5.0+ (sign/verify require server build with the feature) |
algorithm='ed25519' on get_key, info.cloud_vendor / cloud_product, not_before / not_after / with_app_info on get_tls_key |
0.5.7+ |
verify_env_encrypt_public_key (signature_v1 with timestamp) |
Requires KMS build that emits signature_v1; legacy variant remains available |
Calls that require 0.5.7-only fields probe the Version RPC first and raise a clear RuntimeError on older guest agents.
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
Install dev dependencies and run tests with PDM:
cd sdk/python
make install
make test
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()(raw data only, no hash algorithms)- Socket path:
/var/run/tappd.sock→/var/run/dstack.sock
License
Apache License 2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dstack_sdk-0.5.4b1.tar.gz.
File metadata
- Download URL: dstack_sdk-0.5.4b1.tar.gz
- Upload date:
- Size: 32.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
06826e2759315352cb5b912b297a9138cf430c2987a561e5b19d17ee5a15ea0b
|
|
| MD5 |
713f31b69854b18c10aaf58f06f56e0e
|
|
| BLAKE2b-256 |
ac11849994fd7206110126f2941ec602f4f4b1cd15fd7aa8a44a83019c75d8c2
|
Provenance
The following attestation bundles were made for dstack_sdk-0.5.4b1.tar.gz:
Publisher:
python-sdk-release.yml on Dstack-TEE/dstack
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dstack_sdk-0.5.4b1.tar.gz -
Subject digest:
06826e2759315352cb5b912b297a9138cf430c2987a561e5b19d17ee5a15ea0b - Sigstore transparency entry: 1584565821
- Sigstore integration time:
-
Permalink:
Dstack-TEE/dstack@3b66516422d6c95c10f25be32347567f019b9c7a -
Branch / Tag:
refs/tags/python-sdk-v0.5.4b1 - Owner: https://github.com/Dstack-TEE
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-sdk-release.yml@3b66516422d6c95c10f25be32347567f019b9c7a -
Trigger Event:
push
-
Statement type:
File details
Details for the file dstack_sdk-0.5.4b1-py3-none-any.whl.
File metadata
- Download URL: dstack_sdk-0.5.4b1-py3-none-any.whl
- Upload date:
- Size: 19.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f2c122422cbe526f5e2de86b03caa8546997d26dc4609c834dc96d1030e85bb4
|
|
| MD5 |
7259bb01480d29e8a632f6401340430f
|
|
| BLAKE2b-256 |
1300bbf206d61a7ff544c8e900eed2e9332c9e5c5f1637e083a23273b68611d2
|
Provenance
The following attestation bundles were made for dstack_sdk-0.5.4b1-py3-none-any.whl:
Publisher:
python-sdk-release.yml on Dstack-TEE/dstack
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dstack_sdk-0.5.4b1-py3-none-any.whl -
Subject digest:
f2c122422cbe526f5e2de86b03caa8546997d26dc4609c834dc96d1030e85bb4 - Sigstore transparency entry: 1584565979
- Sigstore integration time:
-
Permalink:
Dstack-TEE/dstack@3b66516422d6c95c10f25be32347567f019b9c7a -
Branch / Tag:
refs/tags/python-sdk-v0.5.4b1 - Owner: https://github.com/Dstack-TEE
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-sdk-release.yml@3b66516422d6c95c10f25be32347567f019b9c7a -
Trigger Event:
push
-
Statement type: