# DSP Web SDK

The DSP Web SDK enables integration with the Virtru Data Security Platform (DSP).
It provides tools for encrypting and decrypting TDF (Trusted Data Format) content, as well as managing Attribute-Based Access Control (ABAC) operations.

## Overview
The DSP Web SDK is designed to help developers secure sensitive data in web applications by leveraging the Trusted Data Format (TDF) and Attribute-Based Access Control (ABAC). Key features include:
- Easy encryption and decryption of data using TDF.
- Fine-grained access control with ABAC policies.
- Seamless integration with DSP services for key management and policy enforcement.
- Support for modern web frameworks and environments.

## Table of Contents
- [DSP Web SDK](#dsp-web-sdk)
  - [Overview](#overview)
  - [Table of Contents](#table-of-contents)
  - [Installation](#installation)
  - [Usage](#usage)
  - [Testing](#testing)
    - [Linting](#linting)

## Installation
Install the SDK using your preferred package manager. This will add the SDK as a dependency to your project, making its APIs available for import.

> **Note:** The package name is subject to change before public release.

```sh
# Using npm
npm install @virtru/dsp-sdk

```

## Usage

The following example demonstrates how to authenticate with DSP, initialize the platform client, and perform common operations such as tagging and fetching configuration.

```typescript
import { DSP, type Interceptor } from '@virtru/dsp-sdk';

const authInterceptor: Interceptor = (next) => async (req) => {
  req.header.set('Authorization', 'Bearer access-token');
  return next(req);
};

const dsp = new DSP({
  platformUrl: '/api',
  interceptors: [authInterceptor],
});

// Tag PDP
const taggingResponse = await dsp.services.v2.taggingPDPService.tag({});

// List policy attributes
const attributesResponse = await dsp.services.v1.attributes.listAttributes({});


// Encrypts string into a NanoTDF
const tdf = await dsp.createNanoTDF({
  source: {
    type: "buffer",
    location: new TextEncoder().encode("hello world"),
  },
});

const encrypted = await new Response(tdf).arrayBuffer();

// Decrypts the NanoTDF back to plaintext
const stream = await dsp.read({
  source: {
    type: "buffer",
    location: encrypted,
  },
});

const decrypted = await new Response(stream).text();
console.log(decrypted); // "hello world"

```

### FIPS Mode

The SDK supports FIPS 140-2 compliant cryptography using a validated BoringSSL WASM module. To enable FIPS mode:

```typescript
import { AuthProviders, DSP } from '@virtru/dsp-sdk';
import { FipsCryptoService } from '@virtru/dsp-sdk/fips';

// Create auth provider with FIPS crypto service
const authProvider = await AuthProviders.clientSecretAuthProvider(
  {
    clientId: 'your-client-id',
    clientSecret: 'your-client-secret',
    oidcOrigin: 'https://oidc-endpoint',
    exchange: 'client',
  },
  FipsCryptoService  // Use FIPS-validated crypto
);

// Initialize DSP with FIPS mode enabled
const dsp = new DSP({
  authProvider, // Backward-compatible. Prefer interceptors for new integrations.
  platformUrl: 'https://dsp-platform-url',
  useFips: true,  // Enables FIPS mode
});

// Check if FIPS is enabled
console.log('FIPS enabled:', dsp.fipsEnabled);  // true
```

When FIPS mode is enabled, TDF3/ZTDF cryptographic operations (encryption, decryption, signing, key generation) use the FIPS-validated BoringSSL WASM module instead of Web Crypto API (`crypto.subtle`). NanoTDF operations are not covered by FIPS mode and continue to use `crypto.subtle`.

**Note:** FIPS mode only supports RSA keys; EC (Elliptic Curve) operations are not available in FIPS mode.

Refer to the API documentation for a complete list of available methods and configuration options.

## Testing

This section is intended for repository maintainers and contributors.

The test setup is split into:
- **Unit tests** (`test:unit`): run in Vitest `jsdom` mode and do **not** require Playwright.
- **Integration/browser tests** (`test:integration`): run in Chromium via Playwright.

To run the unit suite:

```bash
pnpm run build-fips-crypto
pnpm run copy-wasm
pnpm test:unit
```

To run the browser/integration suite:

```bash
pnpm test:integration
```

To run both:

```bash
pnpm test
```

### Integration Tests

Integration tests verify end-to-end encrypt/decrypt operations against a live DSP server, including FIPS mode compliance testing.

**Required environment variables:**
```bash
export DSP_PLATFORM_URL="http://localhost:8080"      # DSP platform URL
export CLIENT_ID="your-client-id"                    # OAuth client ID
export CLIENT_SECRET="your-client-secret"            # OAuth client secret
export OIDC_ENDPOINT="http://localhost:8888/auth/realms/opentdf"  # OIDC endpoint
```

**Run integration tests:**
```bash
pnpm run build-fips-crypto
pnpm run copy-wasm
pnpm test:integration
```

**Run all tests (unit + integration):**
```bash
pnpm test
```

Integration tests include FIPS compliance verification to ensure `crypto.subtle` is not used when FIPS mode is enabled (validating that only FIPS-certified BoringSSL WASM is used for cryptographic operations).


### Linting

- ESLint is used for linting. To check for linting errors:
  ```bash
  pnpm lint
  ```
- To automatically fix linting errors:
  ```bash
  pnpm lint:fix
  ```

## Code Generation (For Maintainers)

This section is for maintainers who need to regenerate TypeScript code from protobuf definitions.

### Purpose

The SDK includes TypeScript code that is generated from protobuf definitions in the `data-security-platform` repository. This generated code lives in `src/gen/` and is checked into version control. The code generation process is manual to ensure CI builds succeed without requiring access to the DSP repository.

### Prerequisites

- Node.js (version 22 or higher)
- buf CLI installed (https://buf.build/docs/installation)
- Access to the `data-security-platform` repository

### Setup

1. Clone the `data-security-platform` repository as a sibling to this monorepo:

```bash
cd ../../  # Navigate to parent directory containing js-lib-monorepo
git clone git@github.com:virtru-corp/data-security-platform.git
```

Your directory structure should look like:
```
virtru-corp/
├── js-lib-monorepo/
│   └── libraries/
│       └── dsp-sdk/
└── data-security-platform/
    └── ext/
```

### Running Code Generation

From the `dsp-sdk` directory, run:

```bash
buf generate ../../../data-security-platform/ext \
  --path ../../../data-security-platform/ext/virtru/policy/certificates \
  --path ../../../data-security-platform/ext/virtru/policy/objects.proto \
  --path ../../../data-security-platform/ext/virtru/common
```

This will regenerate the TypeScript files in `src/gen/`.

#### Clone and Generate

From the `dsp-sdk` directory, run:

```bash
pnpm run update-protos
```

This will clone to DSP repo for you, and generate protos, copy them over and update the license within them.

### When to Regenerate

You only need to regenerate the code when:
- Proto definitions in the `data-security-platform` repository change
- New proto files are added that the SDK needs to consume
- Proto dependencies are updated

After regenerating, commit the updated files in `src/gen/` to version control.
