> ## Documentation Index
> Fetch the complete documentation index at: https://docs.phala.com/llms.txt
> Use this file to discover all available pages before exploring further.

# KMS

> List KMS contracts, inspect their nodes and verification anchors, and retrieve app encryption keys.

`phala-cloud` v0.2.0 models KMS resources by contract. A KMS contract groups equivalent KMS node replicas that share one root key.

Every example works with both `PhalaCloud` and `AsyncPhalaCloud`. Add `await` when you use the async client.

## list\_kms\_contracts

`GET /kms`

```python theme={"system"}
list_kms_contracts() -> ListKmsContractsResponse
```

**Parameters:** None.

**Returns:** `ListKmsContractsResponse`, a paginated list of `KmsContract` objects.

Returns the available KMS contracts. This method always requests API version `2026-06-23`.

<CodeGroup>
  ```python Sync theme={"system"}
  contracts = client.list_kms_contracts()
  for contract in contracts.items:
      print(contract.slug, contract.chain_id, contract.node_count)
  ```

  ```python Async theme={"system"}
  contracts = await client.list_kms_contracts()
  for contract in contracts.items:
      print(contract.slug, contract.chain_id, contract.node_count)
  ```
</CodeGroup>

Each `KmsContract` includes the contract `id`, `slug`, `contract_address`, `chain_id`, `node_count`, `k256_pubkey`, and `ca_pubkey`. For the off-chain Phala KMS, `contract_address` is `"phala"` and `chain_id` is `0`.

## get\_kms\_contract

`GET /kms/{slug}`

```python theme={"system"}
get_kms_contract(slug: str) -> KmsContract
```

**Parameters:** `slug` accepts a contract slug or `kc_`-prefixed contract ID.

**Returns:** `KmsContract` for the resolved contract.

Returns one KMS contract by slug. A `kc_`-prefixed contract ID also resolves.

<CodeGroup>
  ```python Sync theme={"system"}
  contract = client.get_kms_contract("base")
  print(contract.contract_address)
  print(contract.k256_pubkey, contract.ca_pubkey)
  ```

  ```python Async theme={"system"}
  contract = await client.get_kms_contract("base")
  print(contract.contract_address)
  print(contract.k256_pubkey, contract.ca_pubkey)
  ```
</CodeGroup>

## list\_kms\_contract\_nodes

`GET /kms/{slug}/nodes`

```python theme={"system"}
list_kms_contract_nodes(slug: str) -> ListKmsContractNodesResponse
```

**Parameters:** `slug` accepts a contract slug or `kc_`-prefixed contract ID.

**Returns:** `ListKmsContractNodesResponse` with the contract's node replicas.

Returns the KMS node replicas under a contract, including each node's RPC URL and version.

<CodeGroup>
  ```python Sync theme={"system"}
  nodes = client.list_kms_contract_nodes("base")
  for node in nodes.items:
      print(node.slug, node.url, node.version)
  ```

  ```python Async theme={"system"}
  nodes = await client.list_kms_contract_nodes("base")
  for node in nodes.items:
      print(node.slug, node.url, node.version)
  ```
</CodeGroup>

## Legacy node methods

```python theme={"system"}
get_kms_list(
    request: GetKmsListRequest | Mapping[str, Any] | None = None,
) -> GetKmsListResponse
get_kms_info(request: KmsInfoRequest | Mapping[str, Any]) -> KmsInfo
```

`get_kms_list()` accepts optional pagination and `is_onchain` filters. `get_kms_info()` requires `kms_id`. They return the earlier node-centric KMS shapes.

Both methods are deprecated and remain pinned to API version `2026-05-22`.

Use `list_kms_contracts()`, `get_kms_contract()`, and `list_kms_contract_nodes()` for new code.

## get\_app\_env\_encrypt\_pub\_key

`GET /kms/{kms}/pubkey/{appId}`

```python theme={"system"}
get_app_env_encrypt_pub_key(
    request: KmsPubkeyRequest | Mapping[str, Any],
) -> AppEnvPubkeyResponse
```

**Parameters:** `kms` is a KMS node ID or slug, and `app_id` is a 20-byte app ID with or without the `0x` prefix.

**Returns:** `AppEnvPubkeyResponse` with `public_key` and `signature`.

Returns the public key used to encrypt environment variables for an app.

<CodeGroup>
  ```python Sync theme={"system"}
  key = client.get_app_env_encrypt_pub_key({
      "kms": "phala",
      "app_id": "ff22c67f5d3b4c8a9e1f0a2b3c4d5e6f7a8b9c0d",
  })
  print(key.public_key, key.signature)
  ```

  ```python Async theme={"system"}
  key = await client.get_app_env_encrypt_pub_key({
      "kms": "phala",
      "app_id": "ff22c67f5d3b4c8a9e1f0a2b3c4d5e6f7a8b9c0d",
  })
  print(key.public_key, key.signature)
  ```
</CodeGroup>

## next\_app\_ids

`GET /kms/phala/next_app_id`

```python theme={"system"}
next_app_ids(
    request: NextAppIdsRequest | Mapping[str, Any] | None = None,
) -> NextAppIdsResponse
```

**Parameters:** `counts` requests 1 to 20 IDs and defaults to `1`.

**Returns:** `NextAppIdsResponse` with the reserved `app_id` and `nonce` pairs.

Reserves app IDs from the Phala KMS for deterministic provisioning.

```python theme={"system"}
reserved = client.next_app_ids({"counts": 3})
print(reserved.model_dump())
```

## get\_kms\_on\_chain\_detail

`GET /kms/on-chain/{chain}`

```python theme={"system"}
get_kms_on_chain_detail(
    request: KmsOnChainDetailRequest | Mapping[str, Any],
) -> GetKmsOnChainDetailResponse
```

**Parameters:** `chain` is the chain name, such as `"base"` or `"ethereum"`.

**Returns:** `GetKmsOnChainDetailResponse` with the chain and its KMS contracts.

Returns the contracts, registered devices, OS images, and verification anchors for an on-chain KMS.

```python theme={"system"}
detail = client.get_kms_on_chain_detail({"chain": "base"})
for contract in detail.contracts:
    print(contract.contract_address)
    print(contract.k256_pubkey, contract.ca_pubkey)
```

## Compute and verify mr\_config\_id

The SDK exports byte-oriented and hex-oriented helpers:

```python theme={"system"}
get_mr_config_id(
    compose_hash: bytes,
    app_id: bytes,
    key_provider_type: KeyProviderKind,
    key_provider_id: bytes,
) -> bytes
get_mr_config_id_hex(
    compose_hash_hex: str,
    app_id_hex: str,
    key_provider_type: KeyProviderKind,
    key_provider_id_hex: str = "",
) -> str
get_mr_config_id_v1(compose_hash: bytes) -> bytes
verify_mr_config_id(
    mr_config_id_hex: str,
    compose_hash_hex: str,
    app_id_hex: str,
    key_provider_type: KeyProviderKind,
    key_provider_id_hex: str = "",
) -> bool
```

For `key_provider_type="kms"`, set `key_provider_id_hex` to the contract's `k256_pubkey`, not its `ca_pubkey`.

```python theme={"system"}
from phala_cloud import get_mr_config_id_hex, verify_mr_config_id

mr_config_id = get_mr_config_id_hex(
    compose_hash_hex="0x<64-hex-characters>",
    app_id_hex="0xff22c67f5d3b4c8a9e1f0a2b3c4d5e6f7a8b9c0d",
    key_provider_type="kms",
    key_provider_id_hex="0x<kms-key-provider-id>",
)

matches = verify_mr_config_id(
    mr_config_id,
    "0x<64-hex-characters>",
    "0xff22c67f5d3b4c8a9e1f0a2b3c4d5e6f7a8b9c0d",
    "kms",
    "0x<kms-key-provider-id>",
)
```

Use `get_mr_config_id()` for byte inputs and `get_mr_config_id_v1()` for the V1 compose-hash-only format.

## Related

* [CVM Configuration](/phala-cloud/references/cloud-python-sdk/cvm-configuration)
* [Error Handling](/phala-cloud/references/cloud-python-sdk/error-handling)
