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

# CDR SDK Overview

> Learn how to integrate Confidential Data Rails (CDR) into your application using the CDR SDK.

<Note>
  These docs track the Aeneid release of `@piplabs/cdr-sdk` (`v0.1.1`).
  The SDK is installable from source today and is not yet published to npm.
</Note>

<Card title="Building with an AI agent? Install the CDR Skill" icon="robot" href="https://github.com/jacob-tucker/cdr-skill">
  Drop-in skill for Claude and other agents, plus three end-to-end examples
  covering the on-chain secret, encrypted file, and IP-gated flows. The fastest
  way to get a working CDR integration.
</Card>

## What is CDR?

**Confidential Data Rails (CDR)** is Story's application layer for threshold-encrypted data on Story L1. Under the hood, it uses the validator network's DKG-generated public key so you can encrypt secrets such that no single party ever holds the complete decryption key. Data can only be decrypted when a threshold number of validators collectively provide partial decryptions, with access control enforced on-chain via smart contracts. The validator-side DKG and partial decryption flows run inside `story-kernel` TEEs (Intel SGX enclaves).

CDR enables powerful use cases like:

* **Secret sharing** - encrypt and share secrets that only specific wallets can decrypt
* **Encrypted file delivery** - keep large files off-chain while storing the encrypted file key on-chain
* **Data marketplaces** - sell access to encrypted data with on-chain payment enforcement
* **IP-gated content** - tie encrypted data to IP Assets and require license tokens to decrypt

## Security and Trust Model

* **Confidentiality** - Vault payloads stay encrypted unless a threshold number
  of validators participate in decryption and the read condition passes.
* **Metadata visibility** - Vault UUIDs, condition addresses, transactions, and
  any off-chain storage pointers you disclose are not hidden by CDR.
* **Availability** - Reads can fail if enough validators do not respond before
  timeout. In that case, retry the read request or increase `timeoutMs`.
* **Forward secrecy / revocation** - Treat CDR ciphertext as bound to the
  access rules and validator set in effect when you encrypted it. If your
  access model changes, rotate or re-encrypt the content at the application
  layer.
* **Release posture** - The current public release runs on Aeneid testnet.
  Build and test integrations there, but do not treat it as a production
  confidentiality environment.

## What Ships in the Aeneid Release

The current SDK surface is centered around two workflows:

* **Data key vaults** via `uploadCDR` / `accessCDR` for small secrets stored directly on-chain
* **Encrypted files** via `uploadFile` / `downloadFile` for off-chain content with on-chain key management

The Aeneid release also includes:

* `observer`, `uploader`, and `consumer` sub-clients
* Two DKG query backends: `evm-events` (default) and `cosmos-abci`
* Storage providers for Helia, gateway-backed IPFS, Storacha, and Synapse
* Validator registration, attestation queries, and SGX attestation verification utilities

## How It Works

CDR revolves around **vaults**. Each vault stores encrypted data and has two configurable access control conditions:

* **Write Condition** - determines who can store encrypted data in the vault
* **Read Condition** - determines who can request decryption of the vault's data

<Note>
  When `msg.sender` equals the configured condition address, the CDR contract
  bypasses the condition check. If you set your wallet address as the condition
  address, only that wallet can operate; other callers revert because an EOA
  does not implement `checkWriteCondition` / `checkReadCondition`.
</Note>

<Note>
  The SDK validates condition addresses by default. If you intentionally use an
  EOA with `allocate()`, pass `skipConditionValidation: true`.
</Note>

There are two common ways to use a vault:

* **On-chain secret**: store the encrypted bytes directly in the vault
* **Off-chain file**: store an encrypted file in a storage backend and keep the
  encrypted AES key plus content pointer in the vault

### Data Key Vault Flow

1. **Allocate** a vault on-chain with your desired read/write conditions
2. **Fetch** the DKG global public key from the validator network
3. **Encrypt** your data locally using TDH2 threshold encryption
4. **Write** the encrypted ciphertext to the vault on-chain

Walkthrough:
[Encrypt a Secret](/developers/cdr-sdk/encrypt-and-decrypt#encrypt-a-secret).

### Encrypted File Flow

**Upload (data owner):**

1. **Encrypt** the file locally with an AES key
2. **Upload** the encrypted file to a storage backend such as IPFS
3. **Encrypt** the AES key plus CID through CDR and write the resulting vault
   payload

**Download (authorized reader):**

1. **Read** the vault and recover the AES key payload through threshold
   decryption
2. **Download** the encrypted file from storage
3. **Decrypt** the file client-side with the recovered AES key

Walkthrough:
[Encrypt and Download a File](/developers/cdr-sdk/encrypt-and-decrypt#encrypt-and-download-a-file).

### Decryption Flow

1. **Generate** an ephemeral keypair for the decryption session
2. **Submit** a read request on-chain (validated against the read condition)
3. **Collect** partial decryptions from validators until you meet threshold
4. **Combine** the partials client-side to recover the original data key

Plaintext encryption and final decryption happen **client-side**. Validators only produce TEE-confined partial decryptions, and neither the CDR contract nor validators ever see your plaintext data.

## Access Control Patterns

### Wallet Address (Simple)

Set your wallet address as the read/write condition. Only you can encrypt/decrypt.

```typescript theme={null}
await uploader.allocate({
  updatable: false,
  writeConditionAddr: userAddress, // only you can write
  readConditionAddr: userAddress, // only you can read
  writeConditionData: "0x",
  readConditionData: "0x",
  skipConditionValidation: true,
});
```

For an end-to-end example, see
[Encrypt a Secret](/developers/cdr-sdk/encrypt-and-decrypt#encrypt-a-secret).

<Note>
  This EOA shortcut is most useful with `allocate()`. The high-level
  `uploadCDR()` / `uploadFile()` helpers validate condition contracts and
  therefore use the deployed owner-only condition contract in the examples.
</Note>

### License Token (IP-Gated)

Use the deployed `LicenseReadCondition` contract on Aeneid and encode
`abi.encode(licenseTokenAddress, ipId)` as `readConditionData`. The vault
writer typically uses the deployed `OwnerWriteCondition` contract so only the
uploader can write, while readers must present valid Story license token IDs in
`accessAuxData`.

Technical walkthrough:
[How the Story License Read Pattern Works](/developers/cdr-sdk/ip-asset-vaults#how-the-story-license-read-pattern-works).

### Custom Condition Contracts

Deploy your own condition contract implementing `checkReadCondition` and `checkWriteCondition` for advanced access control like:

* **Fixed fee** - pay a one-time fee to unlock read access
* **Time-based** - access only during a specific time window
* **Marketplace** - listing owner controls writes, purchasers can read

### Condition Helpers

The SDK includes helper encoders for common access patterns:

```typescript theme={null}
import { conditions } from "@piplabs/cdr-sdk";

conditions.ownerOnly({ address: conditionAddr, owner: "0x..." });
conditions.custom({ address: conditionAddr, conditionData: "0x..." });
conditions.open({ address: conditionAddr });
conditions.tokenGate({ address: conditionAddr, token: "0x...", minBalance: 1n });
conditions.merkle({ address: conditionAddr, root: "0x..." });
```

<Note>
  On Aeneid, `ownerOnly()` and `custom()` are the practical built-in patterns
  today. `open()`, `tokenGate()`, and `merkle()` help encode condition data,
  but you still need to deploy a matching condition contract yourself.
  `conditions.storyLicense()` is not available yet.
</Note>

For the deployed Story license-gated pattern, see
[How the Story License Read Pattern Works](/developers/cdr-sdk/ip-asset-vaults#how-the-story-license-read-pattern-works).

## Next Steps

<CardGroup cols={2}>
  <Card title="Setup" icon="gear" href="/developers/cdr-sdk/setup">
    Install the SDK from source and initialize the client for Aeneid.
  </Card>

  <Card title="Runtime Config" icon="sliders" href="/developers/cdr-sdk/advanced-configuration">
    DKG backends, validation RPCs, system addresses, and release notes.
  </Card>

  <Card title="Encrypt & Decrypt" icon="lock" href="/developers/cdr-sdk/encrypt-and-decrypt">
    Use both the on-chain secret and encrypted-file workflows.
  </Card>

  <Card title="IP Asset Vaults" icon="certificate" href="/developers/cdr-sdk/ip-asset-vaults">
    Configure license-gated reads with Story license tokens on Aeneid.
  </Card>

  <Card title="SDK Reference" icon="book" href="/sdk-reference/cdr/overview">
    Full API reference for every CDR SDK method.
  </Card>

  <Card title="CDR Skill & Examples" icon="robot" href="https://github.com/jacob-tucker/cdr-skill">
    Install the CDR skill for your AI agent and explore three end-to-end examples.
  </Card>
</CardGroup>
