# Data Access Patterns

## <mark style="color:green;">DataRef</mark> driven Access Pattern

There are two ways to access data from supplier, IPFS encrypted and Signature Gated mode

#### Chossing Correct Mode

* dataRef starts with ipfs\:// ⇒ **IPFS Encrypted Mode**
* dataRef starts with http\:// or https\:// ⇒ **API Signature-Gated Mode**

***

## 1. Public Access Mode (disclosed: true)

**Condition**: When the consent record contains { disclosed: true, dataRef: "..." }

**Behavior**:

* Data is **publicly accessible** without any cryptographic protection
* No EIP-712 signatures required
* No ECDH encryption/decryption needed
* Consumer can directly fetch data using the dataRef URI
* Suitable for non-sensitive, publicly shareable datasets

**Example Consent Record**:

```
{
  agreementId: "0x...",
  supplier: "did:pkh:0xSUPPLIER",
  consumer: "did:pkh:0xCONSUMER",
  disclosed: true, // ← Public access flag
  dataRef: "ipfs://bafybeipublicdata..."
  ....
}
```

***

## 2. Restricted Access Mode (disclosed: false)

When disclosed: false (or undefined), the protocol uses secure access based on dataRef scheme:

### A. Signature Gated Api Mode

**Consumer Flow**:

1. Sign EIP-712 ConsentRecord structure containing:
   * supplier: Supplier's blockchain address
   * agreementContract: Agreement contract address
   * agreementId: The specific agreement identifier
2. Attach signature to API request headers:
   * X-Signature: EIP-712 signature
   * X-Consent-ID: The onchain id of associated consent record

**Supplier Flow**:

1. Extract signature and identifiers from request headers
2. Recover signer from EIP-712 signature
3. Verify:
   * Signer matches consent consumer
4. Serve data if verification passes, otherwise reject

{% hint style="info" %}
Supplier and Consumer doesn't need to have a DID Document when using signature based verification
{% endhint %}

**Consumer Code**:

```typescript
import { IPublicClient, IWalletClient } from "@permission-io/protocol-sdk";
import { createDataConsumerSignature } from "@permission-io/protocol-sdk/data";

const walletClient = // Consumer Wallet for signature creation

const sig = await createDataConsumerSignature(
  { consentRecordId: BigInt(consentId) },
  {
    wallet: walletClient,
    public: publicClient,
  },
);
```

**Supplier Code**:

```typescript
import { verifyDataConsumerSignature } from "@permission-io/protocol-sdk/data";

const isValid = await verifyDataConsumerSignature(
  {
    consentRecordId: BigInt(consentId),
    signature: signatureHex as Hex,
  },
  {
    public: publicClient as IPublicClient,
  },
);

if(isValid)
  // Allow data access
else
  // return 401 status

```

**Api Request Example:**

```javascript
const signature = "0x..."

const response = await fetch("https://api.yourservice.com/data", {
  headers: {
    "x-signature": signature,
    "x-consent-id": "1"
  },
});
```

**Api Middleware Example**

```typescript
import { parseRequestHeaders} from "@permission-io/protocol-sdk/data";

middleware((request)=>{
    const parsed = parseRequestHeaders(request.headers)
    if(parsed){
        const {signature, consentId} = parsed;
        // Logic to return data    
    }else {
        throw UnauthorizedException()
    }
})
```

### B. IPFS Encrypted Mode&#x20;

{% hint style="warning" %}
Consumer and Supplier must have DID Documents so public keys can be extracted for encryption
{% endhint %}

**Condition**: open: false AND dataRef.startsWith("ipfs\://")

**Supplier Flow**:

1. Extract consumer's public key from DID Document (keyAgreement section)
2. Generate ECDH shared secret: secp256k1.getSharedSecret(supplierPrivKey, consumerPubKey)
3. Encrypt data with AES-256-GCM using SHA256(sharedSecret) as key
4. Upload envelope JSON to IPFS: { ciphertext, iv, authTag }
5. Set dataRef to the IPFS CID

**Consumer Flow**:

1. Fetch encrypted envelope from IPFS using the CID
2. Extract supplier's public key from DID Document
3. Generate same ECDH shared secret: secp256k1.getSharedSecret(consumerPrivKey, supplierPubKey)
4. Decrypt using AES-256-GCM with authenticated verification

{% hint style="info" %}
Public key of the DID subject can be found in DID document under **keyAgreement**
{% endhint %}

**Code for Supplier Encryption:**

```typescript
import { fetchPublicKey, encryptData } from "@permission-io/protocol-sdk/data";

// Private key of data supplier/controller
const supplierPrivateKey = "0x..."

const dataToEncrypt = "Hellow World!"

const consumerPublicKey = await fetchPublicKey({
  did: consumerDid,
  clients: { public: publicClient },
});

// Encrypt the data
const encrypted= encryptData({
  data: dataToEncrypt,
  consumerPublicKey,
  supplierPrivateKey,
});

const cid = await publishToIPFS(JSON.stringify(encrypted));
// The generated cid will be put in dataRef inside consent record
// e.g ipfs://bafybeicn7i3soqdgr7dwnrwytgq4zxy7a5jpkizrvhm5mv6bgjd32wm3q4

```

**Code for Consumer Decryption:**

```typescript
import { fetchPublicKey, decryptData } from "@permission-io/protocol-sdk/data";

// Private key of data consumer
const consumerPrivateKey = "0x..."

const dataToDecrypt = {
  cipherText: "0x0..",
  iv: "0x.."
}

const supplierPublicKey = await fetchPublicKey({
  did: supplierDid,
  clients: { public: publicClient },
});

// Decrypt the data
const decrypted = decryptData({
  ciphertext: dataToDecrypt.ciphertext,
  iv: dataToDecrypt.iv,
  supplierPublicKey,
  consumerPrivateKey,
});

```

{% hint style="info" %}
Need to fetch file data from IPFS E.g\
<https://docs.ipfs.tech/quickstart/retrieve/#ipfs-retrieval-methods>
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.permission.ai/permission-protocol/v1-protocol/data-access-patterns.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
