New:Socket for Asana Is Now Available.Learn more
Get Started

@grantex/dpdp

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@grantex/dpdp

DPDP Act 2023 & EU AI Act compliance module for AI agents using the Grantex authorization protocol

latest
Source
npmnpm
Version
0.1.1
Version published
Weekly downloads
9
80%
Maintainers
1
Weekly downloads
 
Created
Source

@grantex/dpdp

npm version License TypeScript Node.js

DPDP Act 2023 & EU AI Act compliance module for AI agents using the Grantex authorization protocol.

Table of Contents

What is @grantex/dpdp?

India's Digital Personal Data Protection Act, 2023 (DPDP Act) and the EU AI Act impose strict requirements on how personal data is collected, processed, and governed — especially when AI agents act on behalf of humans.

@grantex/dpdp bridges the Grantex delegated authorization protocol with these regulations. It provides a purpose-linked consent management layer, grievance redressal, data principal rights enforcement, and machine-readable compliance exports that satisfy both Indian and European regulatory requirements.

Key capabilities

CapabilityDescription
Consent RecordsImmutable, Ed25519-signed consent records linked to Grantex grant tokens
Purpose EnforcementRuntime checks that grant scopes satisfy declared processing purposes
Consent WithdrawalImmediate withdrawal with optional grant revocation and data deletion
Grievance RedressalFile and track grievances per DPDP Act Section 13
Data Principal RightsAccess, erasure, and portability APIs per Sections 11-13
DPDP Audit ExportStructured export for Data Protection Board of India submissions
GDPR Article 15 ExportMachine-readable data subject access request response
EU AI Act ConformanceConformance report covering Articles 9-15, 26, and 50
Region ConfigurationIndia (IN) and EU region-specific settings

Regulatory Coverage

DPDP Act 2023 Mapping

DPDP SectionRequirement@grantex/dpdp Feature
Section 4Processing for lawful purposeenforcePurpose() — runtime scope-to-purpose check
Section 5Notice to data principalcreateConsentNotice() — versioned, hashed notices
Section 6ConsentcreateConsentRecord() — Ed25519-signed consent proof
Section 6(4)Withdrawal of consentwithdrawConsent() — immediate, with grant revocation
Section 8(7)Retention limitationretentionUntil field on consent records
Section 11Right to informationgetDataPrincipalRecords() — access API
Section 12Right to correction & erasurerequestDataErasure() — erasure request
Section 13Grievance redressalfileGrievance() — 7-day resolution tracking
Section 17Record keepingrequestDpdpExport() — audit trail export

EU AI Act Mapping

EU AI Act ArticleRequirement@grantex/dpdp Feature
Article 9Risk managementCovered in conformance report
Article 10Data governancePurpose limitation + consent records
Article 11Technical documentationExport includes system documentation
Article 12Record-keepingFull audit trail with action logs
Article 13TransparencyConsent notices with purpose descriptions
Article 14Human oversightConsent method tracking (explicit-click / api-delegated)
Article 15Accuracy & securityEd25519 signatures, SHA-256 notice hashes
Article 26Deployer obligationsCompliance exports for deployers
Article 50GPAI transparencyConformance report for general-purpose AI

GDPR Cross-Compliance

GDPR ArticleRequirement@grantex/dpdp Feature
Article 6Lawful basislegalBasis field on purposes
Article 7Conditions for consentSigned consent proof with timestamp
Article 13-14Right to informationConsent notices with full disclosure
Article 15Right of accessrequestGdprExport() — Article 15 export
Article 17Right to erasurerequestDataErasure()
Article 30Records of processingrequestDpdpExport()

Installation

npm install @grantex/dpdp @grantex/sdk

@grantex/sdk is a peer dependency. You must install it alongside @grantex/dpdp.

Quick Start

import { createConsentRecord } from '@grantex/dpdp';

const record = await createConsentRecord({
  grantId: 'grant_abc123',
  dataPrincipalId: 'user_456',
  dataFiduciaryId: 'org_789',
  dataFiduciaryName: 'Acme Corp',
  purposes: [
    {
      purposeId: 'email-access',
      name: 'Email Access',
      description: 'Read and send emails on behalf of the user',
      legalBasis: 'consent',
      dataCategories: ['email', 'contacts'],
      retentionPeriod: '1 year',
      thirdPartySharing: false,
    },
  ],
  scopes: ['email:read', 'email:send'],
  consentNoticeId: 'notice_v1',
  consentNoticeContent: 'We will process your email data...',
  consentMethod: 'explicit-click',
  processingExpiresAt: new Date('2027-01-01'),
  retentionUntil: new Date('2028-01-01'),
  proofIpAddress: '192.168.1.1', // Stored as SHA-256 hash
  signingKey: ed25519PrivateKey,  // Optional Ed25519 CryptoKey
  apiKey: process.env.GRANTEX_API_KEY!,
  baseUrl: 'https://auth.grantex.dev',
});

console.log(record.recordId);        // 'rec_...'
console.log(record.consentNoticeHash); // SHA-256 hex string
console.log(record.consentProof.signature); // Ed25519 signature

2. Enforce Purpose Limitation

import { PurposeRegistry, enforcePurpose } from '@grantex/dpdp';

const registry = new PurposeRegistry();

registry.register({
  purposeId: 'email-access',
  name: 'Email Access',
  description: 'Read and send emails on behalf of the user',
  requiredScopes: ['email:read', 'email:send'],
  legalBasis: 'consent',
  dataCategories: ['email', 'contacts'],
  retentionPeriod: '1 year',
  thirdPartySharing: false,
});

// This will throw PurposeViolationError if scopes are insufficient
enforcePurpose(
  ['email:read', 'email:send', 'calendar:read'], // grant scopes
  'email-access',                                  // purpose to enforce
  registry,
);
import { withdrawConsent } from '@grantex/dpdp';

const confirmation = await withdrawConsent(
  'rec_001',
  'User no longer wants email processing',
  {
    revokeGrant: true,           // Also revoke the Grantex grant token
    deleteProcessedData: true,   // Request data deletion
    apiKey: process.env.GRANTEX_API_KEY!,
    baseUrl: 'https://auth.grantex.dev',
  },
);

console.log(confirmation.status);       // 'withdrawn'
console.log(confirmation.grantRevoked); // true
console.log(confirmation.withdrawnAt);  // Date

4. File a Grievance

import { fileGrievance } from '@grantex/dpdp';

const grievance = await fileGrievance(
  {
    dataPrincipalId: 'user_456',
    recordId: 'rec_001',
    type: 'unauthorized_processing',
    description: 'Agent accessed calendar data without consent',
    evidence: { auditEntries: ['audit_entry_789'] },
  },
  process.env.GRANTEX_API_KEY!,
  'https://auth.grantex.dev',
);

console.log(grievance.referenceNumber);       // 'GRV-2026-00042'
console.log(grievance.expectedResolutionBy);  // 7 days from now

5. Export Compliance Reports

import {
  requestDpdpExport,
  requestGdprExport,
  requestEuAiActExport,
} from '@grantex/dpdp';

// DPDP Act audit export
const dpdp = await requestDpdpExport(
  {
    dateFrom: new Date('2026-01-01'),
    dateTo: new Date('2026-03-31'),
    format: 'json',
    includeActionLog: true,
    includeConsentRecords: true,
  },
  apiKey,
  baseUrl,
);

// GDPR Article 15 subject access request
const gdpr = await requestGdprExport(
  {
    dateFrom: new Date('2026-01-01'),
    dateTo: new Date('2026-03-31'),
    format: 'json',
    includeActionLog: true,
    includeConsentRecords: true,
    dataPrincipalId: 'user_456',
  },
  apiKey,
  baseUrl,
);

// EU AI Act conformance report
const euAiAct = await requestEuAiActExport(
  {
    dateFrom: new Date('2026-01-01'),
    dateTo: new Date('2026-03-31'),
    format: 'json',
    includeActionLog: true,
    includeConsentRecords: true,
  },
  apiKey,
  baseUrl,
);

console.log(euAiAct.downloadUrl); // Time-limited download URL (24h expiry)

API Reference

createConsentRecord(options: CreateConsentRecordOptions): Promise<DPDPConsentRecord>

Create a DPDP consent record linked to a Grantex grant token.

  • Validates all mandatory purpose fields
  • Computes SHA-256 hash of consent notice content
  • Signs the record with Ed25519 if a signing key is provided
  • IP addresses are stored as SHA-256 hashes (never plaintext)

getConsentRecord(recordId: string, apiKey: string, baseUrl: string): Promise<DPDPConsentRecord>

Fetch a single consent record by ID.

listConsentRecords(principalId: string, apiKey: string, baseUrl: string): Promise<DPDPConsentRecord[]>

List all consent records for a data principal.

new ConsentRegistry()

In-memory immutable consent registry with caching.

MethodDescription
register(record)Register a consent record (immutable — cannot be re-registered)
get(recordId)Get a consent record by ID
listForPrincipal(principalId)List records for a data principal
markWithdrawn(recordId, reason)Mark a record as withdrawn
getStats()Get registry statistics

createConsentNotice(options: CreateConsentNoticeOptions): Promise<ConsentNotice>

Register a versioned consent notice with the Grantex auth service.

validateNotice(notice: ConsentNotice): string[]

Validate a consent notice has all required fields. Returns an array of error strings (empty if valid).

computeNoticeHash(content: string): Promise<string>

Compute SHA-256 hash of consent notice content. Returns a hex-encoded string.

Withdrawal

withdrawConsent(recordId: string, reason: string, options: WithdrawConsentOptions): Promise<WithdrawalConfirmation>

Withdraw consent for a consent record. Options:

OptionTypeDescription
revokeGrantbooleanAlso revoke the linked Grantex grant token
deleteProcessedDatabooleanRequest deletion of data processed under this consent
apiKeystringGrantex API key
baseUrlstringGrantex auth service base URL

Purpose Registry

new PurposeRegistry()

Maps named purposes to required scopes.

MethodDescription
register(purpose)Register a named purpose with required scopes
get(purposeId)Get a registered purpose
listAll()List all registered purposes
getScopesForPurpose(purposeId)Get scopes required for a purpose
toConsentPurpose(purposeId)Convert to a ConsentPurpose for consent records

Purpose Enforcement

enforcePurpose(grantScopes: string[], purposeId: string, purposeRegistry: PurposeRegistry): void

Check that a grant token's scopes satisfy a declared processing purpose. Throws PurposeViolationError if scopes are insufficient.

checkPurposeCompliance(record: DPDPConsentRecord): string[]

Validate that a consent record has proper purpose definitions. Returns an array of error strings (empty if compliant).

Data Principal Rights

getDataPrincipalRecords(principalId: string, apiKey: string, baseUrl: string): Promise<DataPrincipalRecords>

Fetch all consent records belonging to a data principal (DPDP Section 11).

requestDataErasure(principalId: string, apiKey: string, baseUrl: string): Promise<ErasureRequest>

Submit a data erasure request for a data principal (DPDP Section 12).

Grievances

fileGrievance(params: FileGrievanceParams, apiKey: string, baseUrl: string): Promise<Grievance>

File a grievance against a data fiduciary (DPDP Section 13).

getGrievanceStatus(grievanceId: string, apiKey: string, baseUrl: string): Promise<Grievance>

Check the status of a filed grievance.

generateReferenceNumber(): string

Generate a grievance reference number in format GRV-YYYY-XXXXXXXXXXXXXXXX, where the suffix is 16 lowercase hex characters drawn from a cryptographically strong source (64 bits of entropy). The older 5-digit format was enumerable and has been removed.

calculateExpectedResolution(fromDate?: Date): Date

Calculate the expected resolution date (7 calendar days from the given date).

Compliance Exports

requestDpdpExport(params, apiKey, baseUrl): Promise<ComplianceExportResult>

Request a DPDP audit export containing consent records, action logs, and summary.

requestGdprExport(params, apiKey, baseUrl): Promise<ComplianceExportResult>

Request a GDPR Article 15 data subject access request export.

requestEuAiActExport(params, apiKey, baseUrl): Promise<ComplianceExportResult>

Request an EU AI Act conformance report covering all defined articles.

getExportStatus(exportId, apiKey, baseUrl): Promise<ComplianceExportResult>

Get the status and download URL of a previously requested export.

EU_AI_ACT_ARTICLES

Constant array of EU AI Act articles covered by the conformance report:

ArticleTitle
9Risk Management System
10Data and Data Governance
11Technical Documentation
12Record-keeping
13Transparency
14Human Oversight
15Accuracy, Robustness, Cybersecurity
26Obligations of Deployers
50Transparency for GPAI

Regions

REGION_IN: RegionConfig

India region configuration — DPDP Act settings, 11 supported languages.

REGION_EU: RegionConfig

European Union region configuration — GDPR + EU AI Act settings, 24 supported languages.

REGIONS: Record<string, RegionConfig>

All supported regions keyed by region code.

getRegion(code: string): RegionConfig | undefined

Get region config by region code (case-insensitive).

Errors

All errors extend DpdpError and include a code string and optional statusCode.

Error ClassCodeDescription
DpdpError(varies)Base error class
ConsentRequiredErrorCONSENT_REQUIREDNo consent record exists for the operation
PurposeViolationErrorPURPOSE_VIOLATIONGrant scopes do not satisfy the required purpose
WithdrawalErrorWITHDRAWAL_ERRORConsent withdrawal failed
GrievanceErrorGRIEVANCE_ERRORGrievance filing or retrieval failed
ExportErrorEXPORT_ERRORCompliance export failed

PurposeViolationError additionally exposes a missingScopes: string[] property.

Type Definitions

DPDPConsentRecord

interface DPDPConsentRecord {
  recordId: string;
  grantId: string;
  dataPrincipalId: string;
  dataPrincipalDID?: string;
  dataFiduciaryId: string;
  dataFiduciaryName: string;
  purposes: ConsentPurpose[];
  scopes: string[];
  consentNoticeId: string;
  consentNoticeHash: string;            // SHA-256 of notice content
  consentGivenAt: Date;
  consentMethod: 'explicit-click' | 'api-delegated';
  processingExpiresAt: Date;
  retentionUntil: Date;
  consentProof: ConsentProof;
  status: 'active' | 'withdrawn' | 'expired';
  withdrawnAt?: Date;
  withdrawnReason?: string;
  lastAccessedAt?: Date;
  accessCount: number;
  actions: ConsentAction[];
}

ConsentPurpose

interface ConsentPurpose {
  purposeId: string;
  name: string;
  description: string;
  legalBasis: 'consent' | 'legitimate-interest' | 'contract';
  dataCategories: string[];
  retentionPeriod: string;
  thirdPartySharing: boolean;
  thirdParties?: string[];
}

ConsentProof

interface ConsentProof {
  ipAddress?: string;   // SHA-256 hash of IP (never plaintext)
  userAgent?: string;
  sessionId?: string;
  signedAt: Date;
  signature: string;    // Ed25519 over canonical record payload
}

Grievance

interface Grievance {
  grievanceId: string;
  dataPrincipalId: string;
  recordId: string;
  type: 'unauthorized_processing' | 'withdrawal_refused' | 'data_breach' | 'other';
  description: string;
  evidence?: { auditEntries?: string[] };
  status: 'submitted' | 'under_review' | 'resolved' | 'escalated';
  referenceNumber: string;              // GRV-YYYY-NNNNN
  expectedResolutionBy: Date;           // 7 calendar days
  resolvedAt?: Date;
  resolution?: string;
}

ComplianceExportRequest

interface ComplianceExportRequest {
  type: 'dpdp-audit' | 'gdpr-article-15' | 'eu-ai-act-conformance';
  dateFrom: Date;
  dateTo: Date;
  format: 'json' | 'csv';
  includeActionLog: boolean;
  includeConsentRecords: boolean;
  dataPrincipalId?: string;
}

ComplianceExportResult

interface ComplianceExportResult {
  exportId: string;
  type: string;
  status: 'complete';
  recordCount: number;
  data: unknown;
  downloadUrl?: string;
  downloadExpiresAt?: Date;             // 24-hour expiry
}

RegionConfig

interface RegionConfig {
  regionCode: string;
  regionName: string;
  dataResidencyRequired: boolean;
  consentMinAge: number;
  grievanceResolutionDays: number;
  defaultLanguage: string;
  supportedLanguages: string[];
  regulatoryAuthority: string;
  regulatoryUrl: string;
}

Security Considerations

Every consent record can be signed with an Ed25519 key. The signature covers a canonical JSON payload containing grantId, dataPrincipalId, dataFiduciaryId, purposes, scopes, consentNoticeHash, and consentGivenAt. This makes consent records tamper-evident and verifiable by any party holding the organization's public key.

PII Protection

IP addresses provided in consent proofs are hashed with SHA-256 before being sent to the server. The raw IP address never leaves the client. Other PII fields like user agent strings are stored as-is but can be omitted.

Consent notice content is hashed with SHA-256 and stored alongside the consent record. This ensures that any modification to the notice text after consent was given is detectable.

Immutability

Consent records are immutable after creation. The ConsentRegistry enforces this by freezing records and rejecting duplicate registrations. Withdrawal creates a new state transition rather than modifying the original record.

Data Isolation

The ConsentRegistry.listForPrincipal() method ensures a data principal can only access their own records. Cross-principal access is prevented at both the client registry and server API levels.

Withdrawal Irreversibility

Once consent is withdrawn, it cannot be undone through the API. A new consent record must be created if processing is to resume.

PackageDescription
@grantex/sdkCore TypeScript SDK for Grantex
@grantex/expressExpress.js middleware
@grantex/gatewayReverse-proxy gateway
@grantex/mcpMCP server for Claude Desktop
@grantex/langchainLangChain integration
@grantex/vercel-aiVercel AI SDK integration
@grantex/conformanceConformance test suite
@grantex/cliCLI tool

License

Apache-2.0. See LICENSE.

Keywords

grantex

FAQs

Package last updated on 25 Jun 2026

Related posts