Digital Certificate Compliance Module
A production module inside an internal operations platform — built to track, validate, and surface the compliance status of hundreds of digital certificates across a multi-client accounting firm. The module spans a filesystem scanning pipeline, encrypted credential storage, RBAC-gated operations, and an audit trail for every sensitive action.
The compliance problem
Digital certificates in Brazil are legally required for almost every operational task that touches government systems — issuing invoices, submitting payroll data, signing tax filings, accessing federal portals. For an accounting firm managing dozens of client companies, this means hundreds of certificates across two types: software certificates (A1, stored as encrypted files) and hardware tokens (A3, stored on physical USB devices).
Each certificate has an expiration date. When it expires, it becomes legally invalid — the company cannot sign anything. In practice this means: a certificate expires on a Friday, the client calls Monday morning because they cannot issue invoices, and now the accounting team is scrambling to renew it retroactively.
Before this module, the firm tracked certificate expiry in a spreadsheet. Manually. One person kept it updated when they remembered. When that person was on vacation, the spreadsheet went stale. When someone left the firm, institutional knowledge of where certificates were stored left with them.
The engineering problem was not “store a list of certificates.” That is a CRUD table. The real problem was: how do you automatically discover, parse, and track certificates that live in a directory tree managed by a legacy ERP — across hundreds of client folders, with inconsistent organization, mixed naming conventions, and credentials stored in various formats the system does not control?
Operational dashboard
The compliance team's primary view — KPIs updated after each scan, immediate attention list sorted by urgency, and a scan trigger gated by permission.
| Company | Document | Expires | Status |
|---|---|---|---|
| Acme Comercial Ltda | 12.345.678/0001-95 | 29/05/2026 | EXPIRES TOMORROW |
| Beta Soluções SA | 98.765.432/0001-11 | 02/06/2026 | 4 DAYS |
| Gama Indústria Ltda | 11.222.333/0001-44 | 15/05/2026 | EXPIRED |
Two certificate types, two different workflows
One of the first architectural decisions was recognizing that A1 and A3 certificates have fundamentally different management workflows — and designing the module to handle both cleanly.
A1 — Software certificates
Stored as .pfx or .p12 files on a server. Password-protected. Discovered automatically by the scanning pipeline, which walks the filesystem, parses each file using the node-forge library, and extracts certificate metadata — owner, document (CPF/CNPJ), expiry date, issuer, serial number — without human intervention.
A3 — Hardware tokens
Stored on a physical USB device. Cannot be discovered by scanning — they are registered manually by authorized operators. The operator enters the certificate details and PIN through the platform. The PIN is encrypted before storage and retrievable only by users with the certificates.password.reveal permission.
This distinction matters throughout the system: A3 certificates are never auto-updated by scans. A1 certificates are never manually created. Deactivating an A1 certificate happens automatically when the scan no longer finds its file on disk. Deactivating an A3 certificate requires an explicit operator action.
The scanning pipeline
The scan is the most operationally complex piece of this module. It is a data pipeline that runs on demand, walks a directory tree, handles every edge case gracefully, and updates the certificate database without human intervention.
The pipeline handles real-world messiness gracefully. A folder with a wrong password creates a wrong_password verification — visible in the Verificações view — without blocking the rest of the scan. A folder with the same certificate copied to multiple locations is deduplicated by serial number so the database stays clean.
The deactivation step runs only after all upserts are complete — by design. During the scan, a certificate not yet processed is indistinguishable from one that no longer exists. Only after the full scan can the system confidently mark a record as stale.
Scan issues surface in the Verificações view — each one categorized, linked to its source paths, and marked open or resolved after the next successful scan.
Security architecture
Certificate passwords are operationally sensitive — they unlock credentials used to sign legal documents. The module treats credential management as a security concern at the architecture level, not a UI toggle.
AES-256-GCM encryption at write time
Every password — whether discovered during a scan or entered by an operator — is encrypted with AES-256-GCM before it reaches the database. A random 96-bit IV is generated per encryption, so no two ciphertexts are identical even for the same password. The GCM authentication tag detects any tampering with the stored ciphertext. Plain-text passwords never appear in logs, database columns, or API responses — except the single reveal endpoint.
Permission-gated reveal endpoint
Revealing a password requires the certificates.password.reveal permission — which is not included in general certificate access. The API route validates this before the use case runs. Every reveal attempt (successful or not) is written to the audit log with the actor's email and the outcome reason.
Scan is a privileged write operation
Triggering a scan requires certificates.scan.run — a separate permission from certificate read access. This prevents any authenticated user from triggering a filesystem-intensive operation on the server.
Audit trail on every sensitive action
Every certificate creation, update, deactivation, and password reveal is recorded in the audit log — including failed attempts. A user attempting to reveal a password for a non-existent certificate ID creates a password_revealed log entry with success: false, reason: not_found. This creates a forensic record, not just a success log.
Clean architecture inside the module
The module follows the same four-layer structure as every other module in the platform, with one addition: a scanning sub-module with its own independent domain.
The scanning sub-module is a deliberate design decision. The scanning pipeline has its own domain vocabulary (batches, verifications, candidate resolution) that would contaminate the certificate management domain if mixed together. Keeping them separate means: the certificate module works correctly even if the scanning infrastructure is unavailable. The scan produces certificates; it does not define what a certificate is.
The ICP-Brasil parsing detail
Brazilian certificates issued under ICP-Brasil standards embed identity information in specific ASN.1 extensions not found in generic X.509 certificates. The OID 2.16.76.1.3.2 carries the name of the natural person legally responsible for the company — the responsável.
Extracting this field requires parsing OtherName structures inside the Subject Alternative Name extension — ASN.1 traversal that goes beyond what the node-forge library exposes through its standard API. The adapter handles this with explicit tree walking, silently ignoring malformed extensions rather than failing the parse.
Why does this matter? For compliance monitoring, showing the responsible person's name alongside the company name and document gives the accounting team the context they need to identify who to contact when a certificate is about to expire.
The legacy database bridge
The firm's legacy ERP holds the canonical list of active client companies. The “Companies without certificates” KPI cross-references that list against the certificate database — flagging companies that have no certificate registered in the platform.
This integration uses a raw pg.Pool connection to the legacy PostgreSQL database, separate from the platform's Prisma client. The repository class is typed as read-only by contract: its interface has no write methods, and the SQL is a single parameterized SELECT. If the legacy database is unavailable (the connection pool is null), the repository returns legacyAvailable: false and the KPI card renders in a graceful disabled state rather than failing the page.
What this module required
This is not a module you design by reading framework documentation. The operational edge cases — what to do with three certificates in one folder, how to detect when a certificate file has been removed from disk, how to handle the same cert copied to a backup location, what it means when CNPJ validation fails — come from understanding how accounting firms actually organize their client data.
The encryption choices (AES-256-GCM over simpler alternatives), the audit design (logging failures, not just successes), the deactivation timing (after upserts, not during), the dual sub-module boundary (scanning vs. management) — none of these are obvious from the requirements document. They are the result of thinking through the operational consequences of each decision before writing the code.
Understanding compliance systems, certificate authority chains, and ICP-Brasil standards well enough to know which X.509 fields to extract — and which ASN.1 OIDs carry the data that the accounting team actually needs — that context does not come from building web applications. It comes from spending years inside the operational workflows this system was built to replace.
Confidentiality
This module is documented as a private case study. All screenshots are fictional representations — no real client data, company names, or certificate contents are shown. Architecture decisions, security design, and implementation details reflect the real system.