Cross-Border Transfers
Manage and validate cross-border data transfers in compliance with NDPA 2023 Section 41
Overview
The Cross-Border Transfers component provides tools for assessing, documenting, and managing the transfer of personal data outside Nigeria. Under the NDPA 2023, transferring personal data to another country requires that adequate safeguards are in place.
NDPA Section 41 — Transfer of Personal Data
The NDPA 2023 permits the transfer of personal data to a foreign country only where the NDPC has determined that the country or territory ensures an adequate level of protection, or where appropriate safeguards have been provided by the controller or processor, including binding corporate rules, standard contractual clauses, or an approved code of conduct.
Installation
Install the NDPR Toolkit package which includes the Cross-Border Transfer components:
pnpm add @tantainnovative/ndpr-toolkitProduction Readiness
Use this checklist when moving Cross-Border Transfers from demo mode into a customer-facing workflow. Pair the UI package with the source templates in @tantainnovative/ndpr-recipes so validation, persistence, and audit behavior live in your own backend.
Implementation checklist
- Record destination country, recipient, categories, transfer mechanism, safeguards, and approval status.
- Require review before new vendors, subprocessors, regions, or data categories are used.
- Link transfers to ROPA records, DPIAs, vendor risk reviews, and contract evidence.
- Track NDPC approval needs, standard clauses, binding rules, and supplementary safeguards.
- Reassess transfers when countries, vendors, infrastructure, or legal mechanisms change.
Backend notes
- Use the recipes Drizzle adapter as the persistence reference for transfer records.
- Run validateTransfer and assessTransferRisk in API handlers before records are marked approved.
- Store safeguard evidence and approval dates with the transfer, not only in external contract folders.
- Model transfer status separately from vendor status so a vendor can be approved while a transfer is blocked.
Testing notes
- Create adequate, safeguard-based, and high-risk transfers and confirm warnings and approval requirements.
- Submit records missing destination, mechanism, data categories, or safeguard evidence to validation.
- Update destination country or mechanism and verify risk assessment recalculates.
- Verify only authorized users can approve, archive, or export transfer records.
Common mistakes
- Treating cloud hosting region as a minor configuration detail instead of a transfer record input.
- Approving a vendor once and failing to reassess new subprocessors or destination countries.
- Keeping standard clauses or safeguard evidence outside the system of record.
- Letting teams export data internationally before legal review is complete.
Import
Import from the main package:
import {
CrossBorderTransferManager,
useCrossBorderTransfer,
validateTransfer,
assessTransferRisk,
isNDPCApprovalRequired,
} from '@tantainnovative/ndpr-toolkit';Components
The Cross-Border Transfers module includes two primary components:
CrossBorderTransferManager
A comprehensive component for assessing, documenting, and managing cross-border data transfers. It evaluates adequacy status of destination countries, identifies required safeguards, and helps maintain compliance records.
import { CrossBorderTransferManager, useCrossBorderTransfer } from '@tantainnovative/ndpr-toolkit';
function TransferManagement() {
const { transfers, addTransfer, getSummary } = useCrossBorderTransfer();
return (
<CrossBorderTransferManager
transfers={transfers}
onAdd={addTransfer}
summary={getSummary()}
/>
);
}API Reference
CrossBorderTransferManager Props
| Prop | Type | Default | Description |
|---|---|---|---|
| transfers | CrossBorderTransfer[] | Required | List of cross-border transfers to display |
| onAdd | (transfer: Omit<CrossBorderTransfer, 'id' | 'createdAt' | 'updatedAt'>) => void | — | Callback when a new transfer is added |
| onUpdate | (id: string, updates: Partial<CrossBorderTransfer>) => void | — | Callback when a transfer is updated |
| onArchive | (id: string) => void | — | Callback when a transfer is archived (NDPA prefers soft-delete over hard-delete) |
| summary | CrossBorderSummary | — | Compliance summary data (computed from transfers when omitted) |
| title | string | "Cross-Border Data Transfer Manager" | Title displayed on the manager |
| description | string | NDPA Part VIII text | Description text displayed on the manager |
| className | string | "" | Custom CSS class for the manager container |
| buttonClassName | string | "" | Custom CSS class for buttons |
| showSummary | boolean | true | Whether to show the compliance summary section |
| showTIA | boolean | true | Whether to show the Transfer Impact Assessment section in the form |
| classNames | CrossBorderTransferManagerClassNames | — | Override class names for individual sections; takes priority over className / buttonClassName |
| unstyled | boolean | false | When true, removes all default styling so consumers can style from scratch using classNames |
Types
type TransferMechanism =
| 'adequacy_decision'
| 'standard_clauses'
| 'binding_corporate_rules'
| 'ndpc_authorization'
| 'explicit_consent'
| 'contract_performance'
| 'public_interest'
| 'legal_claims'
| 'vital_interests';
type AdequacyStatus = 'adequate' | 'inadequate' | 'pending_review' | 'unknown';
interface CrossBorderTransfer {
id: string;
destinationCountry: string;
destinationCountryCode?: string;
adequacyStatus: AdequacyStatus;
transferMechanism: TransferMechanism;
dataCategories: string[];
includesSensitiveData: boolean;
estimatedDataSubjects?: number;
recipientOrganization: string;
recipientContact: {
name: string;
email: string;
phone?: string;
address?: string;
};
purpose: string;
safeguards: string[];
riskAssessment: string;
riskLevel: 'low' | 'medium' | 'high';
ndpcApproval?: {
required: boolean;
applied: boolean;
approved?: boolean;
referenceNumber?: string;
appliedAt?: number;
approvedAt?: number;
};
tiaCompleted: boolean;
tiaReference?: string;
frequency: 'one_time' | 'periodic' | 'continuous';
startDate: number;
endDate?: number;
status: 'active' | 'suspended' | 'terminated' | 'pending_approval';
createdAt: number;
updatedAt: number;
reviewDate?: number;
}
interface CrossBorderSummary {
totalActiveTransfers: number;
byMechanism: Record<TransferMechanism, number>;
byAdequacy: Record<AdequacyStatus, number>;
pendingApproval: CrossBorderTransfer[];
dueForReview: CrossBorderTransfer[];
missingTIA: CrossBorderTransfer[];
highRiskTransfers: CrossBorderTransfer[];
lastUpdated: number;
}Lite variant (read-only)
For read-only transfer surfaces such as compliance dashboards and transparency pages, use CrossBorderTransferManagerLite from the new /cross-border/lite subpath. It renders the same transfer list and summary as the Full component, with no Add, Edit, or Terminate affordances and — crucially — without importing the 624-row country adequacy dataset. It ships at 5.6 KB instead of 53.3 KB (an 89% saving, minified and pre-gzip). Lite reads transfer.adequacyStatus directly from each record rather than recomputing it.
import { CrossBorderTransferManagerLite } from '@tantainnovative/ndpr-toolkit/cross-border/lite';
<CrossBorderTransferManagerLite
transfers={transfers}
onTransferClick={(transfer) => router.push(`/cross-border/${transfer.id}`)}
/>See the Lite vs Full Managers guide for migration notes, side-by-side examples, and the full bundle-size table.
Best Practices
- Assess First: Always complete a transfer assessment before initiating any cross-border data transfer.
- Document Safeguards: Keep records of all safeguards implemented for each transfer, including signed contractual clauses.
- Monitor Adequacy: Regularly check whether destination countries maintain their adequacy status with the NDPC.
- Data Minimisation: Only transfer the minimum personal data necessary for the stated purpose.
- Inform Data Subjects: Your privacy policy should clearly state which countries data may be transferred to and why.