How the LGPD PDF Export Flow Uses LGPD_SIGNING_KEY and organizations.legal_name in DeskcommCRM
The LGPD PDF export flow embeds the organization's legal name in the document footer and conditionally applies a PAdES digital signature when the LGPD_SIGNING_KEY environment variable is configured, falling back to SHA‑256 integrity hashing when signing is unavailable.
The DeskcommCRM repository implements a legally‑compliant data export pipeline for Brazil's Lei Geral de Proteção de Dados (LGPD). This system ensures that every PDF export correctly identifies the data controller while providing cryptographic assurances through either PAdES signing or transparent unsigned warnings with hash verification.
Rendering the PDF with organizations.legal_name
The export process begins in lib/lgpd/pdf-renderer.tsx, where the React‑PDF component LgpdExportPdf constructs the final document. This component receives an ExportPayload object that includes organization_legal_name, populated directly from the organizations.legal_name database column.
Injecting the Controller Identity
The renderer explicitly guarantees that only the organization's registered legal name appears in the footer, preventing any white‑label branding from obscuring the data controller's identity. The implementation fixes the footer text using the fixed prop:
<View style={styles.footer} fixed>
<Text>
Controlador: {data.organization_legal_name || "—"} …
</Text>
</View>
This pattern appears at lines 44‑48 of the renderer file, ensuring the PDF footer displays the controller name exactly as stored in the database schema. The pipeline deliberately separates this rendering logic from the signing layer to guarantee the legal attribution always succeeds regardless of cryptographic configuration.
Configuring Digital Signing with LGPD_SIGNING_KEY
The workers/lgpd-export-worker.ts orchestrator coordinates the signing phase by consulting lib/lgpd/pades-signer.ts to evaluate whether PAdES signing is available.
Detecting Signing Configuration
The isPadesConfigured() function checks for the presence and validity of the signing key:
export function isPadesConfigured(): boolean {
const key = process.env.LGPD_SIGNING_KEY;
return Boolean(key && key.length > 10);
}
When this function returns false, the worker instructs the renderer to display an unsigned warning banner. This banner, defined at lines 32‑38 of lib/lgpd/pdf-renderer.tsx, alerts recipients that the document lacks a PAdES signature. The design ensures the system never falsely claims a legally signed document when the LGPD_SIGNING_KEY is absent.
The PAdES Signing Implementation
When isPadesConfigured() returns true, the worker invokes signPdfPades(buffer) from lib/lgpd/pades-signer.ts. The current implementation operates as a stub that prepares for full PAdES compliance while maintaining audit trails.
Stub Behavior and Integrity Verification
Even when the signing key is present, the current code returns an unsigned result while logging a SHA‑256 hash for integrity verification:
export async function signPdfPades(buffer: Buffer): Promise<SignResult> {
if (!isPadesConfigured()) {
return {
signed: buffer,
sha256: sha256Hex(buffer),
signed_pades: false,
warning: "pades_key_missing",
};
}
// TODO: real PAdES signing once a certificate is provisioned
return {
signed: buffer,
sha256: sha256Hex(buffer),
signed_pades: false,
warning: "pades_key_missing",
};
}
The function returns a SignResult object containing the buffer, its SHA‑256 hash, a boolean signed_pades flag, and an optional warning string. This result structure allows the worker at lines 172‑184 of workers/lgpd-export-worker.ts to store both the PDF and its integrity hash in Supabase storage, creating a verifiable audit trail regardless of signature status.
Complete Export Pipeline Architecture
The flow follows a strict separation between rendering and signing:
- Export Request: The worker receives a request containing the organization ID
- Data Collection:
lib/lgpd/export-collector.ts(referenced but not shown) assembles theExportPayloadincludingorganization_legal_name - PDF Generation:
renderLgpdPdfcreates the buffer with the legal name fixed in the footer - Signing Decision:
isPadesConfigured()checksLGPD_SIGNING_KEY - Signature Application:
signPdfPadeseither stubs or (future) applies PAdES, always returning SHA‑256 hashes - Storage: The resulting buffer and metadata upload to Supabase with signed download URLs
This architecture ensures that rendering succeeds independently of signing infrastructure, preventing system failures from blocking legally required data exports.
Practical Implementation Examples
Checking Signing Configuration
import { isPadesConfigured } from "@/lib/lgpd/pades-signer";
if (isPadesConfigured()) {
console.log("PAdES signing will be attempted.");
} else {
console.log("LGPD_SIGNING_KEY missing – PDF will carry an unsigned warning.");
}
Rendering with Conditional Warnings
import { renderLgpdPdf } from "@/lib/lgpd/pdf-renderer";
import { isPadesConfigured } from "@/lib/lgpd/pades-signer";
const pdfBuffer = await renderLgpdPdf(exportPayload, {
unsignedWarning: !isPadesConfigured(),
});
Processing the Signature Result
import { signPdfPades } from "@/lib/lgpd/pades-signer";
const signResult = await signPdfPades(pdfBuffer);
console.log("SHA‑256:", signResult.sha256);
console.log("Signed?", signResult.signed_pades);
// Upload to Supabase
await admin.storage.upload(pdfPath, signResult.signed, {
contentType: "application/pdf",
});
Summary
- The
organizations.legal_namevalue from the database populates the PDF footer vialib/lgpd/pdf-renderer.tsx, ensuring transparent identification of the data controller. LGPD_SIGNING_KEYdrives theisPadesConfigured()check inlib/lgpd/pades-signer.ts, determining whether the system attempts PAdES signing or adds an unsigned warning banner.- The current
signPdfPadesimplementation provides SHA‑256 integrity hashing even when actual signing is stubbed, maintaining auditability. - The
workers/lgpd-export-worker.tsorchestrates the complete flow, separating rendering concerns from cryptographic operations to guarantee export availability.
Frequently Asked Questions
What happens if LGPD_SIGNING_KEY is not set?
The PDF exports successfully but includes an unsigned warning banner in the rendered output. The signPdfPades function returns the original buffer with signed_pades: false and a SHA‑256 hash for integrity verification, stored alongside the document in Supabase for audit purposes.
How does the system source the organization legal name?
The organization_legal_name field originates from the organizations.legal_name database column, passed through the ExportPayload interface defined in lib/lgpd/export-collector.ts. The React‑PDF component in lib/lgpd/pdf-renderer.tsx renders this value in the footer using a fixed position to prevent pagination issues.
Is the PAdES signing currently functional?
No. According to the source code in lib/lgpd/pades-signer.ts, the signPdfPades function contains a TODO comment indicating that real PAdES signing awaits certificate provisioning. The function currently returns the unsigned buffer with a SHA‑256 hash regardless of whether LGPD_SIGNING_KEY is present.
Where are the signed PDFs stored?
The workers/lgpd-export-worker.ts uploads the result to Supabase storage using the admin client, storing the buffer returned by signPdfPades along with its metadata. The worker then generates signed download URLs for secure recipient access, with the SHA‑256 hash preserved for integrity validation.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →