ts-hanko
v0.1.0
Published
TypeScript primitives for Brazilian-compliant PAdES, CAdES and XAdES signature workflows.
Downloads
20
Readme
ts-hanko
TypeScript/Node.js primitives for Brazilian digital signature workflows, inspired by pyHanko's PDF-signing focus.
This is not a full pyHanko port yet. The current package establishes the core shape for an integrator model in Brazil:
- Brazilian signature level policy: simple, advanced and qualified.
- Use-case based compliance assessment for private contracts, enforceable electronic instruments, public administration, invoices, health documents, real-estate workflows and long-term records.
- Document use-case classifier for selecting the report
useCasefrom portal facts such as long-retention contracts, CPC art. 784 electronic enforcement instruments, Lei 14.620/14.711 credit or guarantee workflows, invoices, controlled prescriptions, registry/real-estate transfers, notarial/court workflows and public-administration interactions. - Consigned-credit/payroll-loan evidence gates for Lei 10.820/2003 as amended by Lei 15.179/2025 and regulated by Decreto 12.564/2025, including qualified ICP-Brasil, homologated advanced, biometric proof-of-life and institutional digital-signature paths.
- Public-administration interaction classifier for selecting the minimum simple, advanced or qualified level under Lei 14.063/2020 and Decreto 10.543/2020 criteria.
- Brazilian validation report builder that combines signature verification, audit-trail status, long-term evidence, integrator controls and VALIDAR/ITI results.
- CNJ 180-oriented audit-trail assessment for registry and real-estate workflows, including signer e-mail, IP, date/time, consent, SHA-256 hash and document-version evidence.
- Advanced-signature evidence assessment for OTP, biometric, gov.br and ICP-Brasil-assisted envelope flows, including consent, signer-control method, technical metadata and audit hash-chain checks.
- Minimum audit-trail evidence assessment from the viability PDF section 5.4, including signer identity, chronological events, IP/user-agent/session/device metadata, TLS/OAuth/biometric identity proof, SHA-256 hashes, hash chain and platform ICP-Brasil audit signature.
- Qualified-signature flow assessment for the viability PDF section 5.3 PSC/Web PKI sequence, covering intake, signed access links, PSC/OAuth or local-token operation, timestamping, PAdES packaging, ITI validation and final persistence.
- Signing-ceremony assessment for ordered envelope flows, including signer count, required signer completion, signature events, envelope completion and chronological order.
- gov.br silver/gold identity evidence assessment for OAuth claims, token integrity, nonce/state binding and signed-document linkage.
- Cryptographic-strength checks for signer digest/signature algorithms and RSA/ECDSA public-key parameters.
- LGPD-oriented privacy and retention controls for biometric evidence, geolocation evidence, anonymization/erasure workflows, proof-preserving retention policies, legal hold and operator contracts.
- SaaS platform assurance checks for tenant isolation, Brazilian/cloud data residency, KMS/HSM key protection, immutable logs, monitoring and security validation.
- Operational risk assurance for PSC outage fallback, regulatory change, litigation readiness, incident response and PSC lock-in mitigation.
- Digital custody evidence checks for signed-artifact retention, validation evidence, immutable encrypted storage, LGPD retention/legal hold, LTA renewal and integrity monitoring.
- Notarial/court-critical evidence gates for authority protocol, qualified B-LTA proof, external validation, chain of custody, legal hold and PL 4/2025 monitoring.
- Provider portfolio assurance for the viability PDF's PSC/AC and ACT supplier plan, including fallback coverage, formal proposals, SLA/commercial evidence and driver-adapter readiness.
- Provider conformance evidence gates for PSC/AC/ACT onboarding, including accreditation, adapter smoke checks, credential/hash-signing or RFC 3161 timestamp tests, captured provider evidence, failover and sample report binding.
- Conformance corpus evidence gates for release regression samples, including PAdES/CAdES/XAdES and B-B/B-T/B-LT/B-LTA coverage, negative/tampered samples, external VALIDAR/ITI and Adobe evidence, artifact hashes and CI inclusion.
- MVP exit-readiness assessment for the viability PDF's technical, legal and operational release gates, including structured legal-review artifacts.
- Legal-source evidence assessment that binds compliance reports and production release packs to recent checks of official Brazilian legal and technical references.
- PAdES PDF signing facade using
ETSI.CAdES.detachedplaceholders and CMS signer adapters, including policy-aware RSA and ECDSA PKCS#12 plus PEM/DER key signing. - PDF metadata preparation for title, author, subject, keywords, creator, producer and document dates before signing.
- Standalone PDF text and QR stamping for pre-signature visible Brazilian signing context, including signer, reason, date, custom lines, SHA-256 document hash and VALIDAR-style QR targets.
- External raw-signature CMS builder for PSC/HSM/cloud-certificate integrations that return PKCS#1/ECDSA signature bytes instead of a full CMS object, including interrupted prepare/complete flows for asynchronous PSC authorization.
- Local Web PKI bridge adapter for browser/native A1/A3 token flows, including signed-attributes handoff, returned-certificate binding checks and Brazilian qualified-flow evidence mapping.
- Ordered multi-signer PAdES helper and PDF envelope workflow for sequential PSC/HSM/Web PKI approval signatures with Brazilian evidence packages.
- Provider-neutral callback, REST/JSON and CSC
signatures/signHashcloud-signature adapters that turn PSC/HSM transaction APIs into the library's external signer contract and capture provider evidence. - Sequential provider failover driver for PSC/HSM/cloud-signature integrations, recording selected-provider and failed-provider evidence for the viability PDF's 2+ PSC fallback strategy.
- PKCS#11/HSM external signer adapter for Node integrations that use a vendor module such as
pkcs11js, without adding a native dependency to the core package. - PAdES B-LT DSS/VRI evidence embedding and B-LTA document timestamps for timestamped PDFs.
- Detached CAdES B-B/B-T/B-LT/B-LTA signing and verification for non-PDF files, including CMS
contentType/messageDigestsigned-attribute checks andsigningCertificateV2signer-certificate hash validation. - XAdES-BES/B-B, B-T, B-LT and B-LTA XML signing and verification for XML/fiscal-style workflows.
- PDF signature inspection, signature dictionary validation,
/ByteRangevalidation, PDF/Mversus CMSsigningTimeconsistency checks and CMSSignedDatametadata extraction. - PDF trailer/encryption inspection that reports Standard Security Handler metadata and an explicit encrypted-PDF support assessment while keeping encrypted write paths fail-closed.
- Visible PDF signature appearances for signer, date, reason, location, hash and envelope metadata.
- PDF DocMDP/FieldMDP update-control metadata, signature-field
/Lockdictionaries, seed values, inspection and completed-signature seed-value validation for VALIDAR-friendly PAdES output. - VALIDAR readiness assessment, JSON/QR integration artifacts, descriptor helpers, healthcare OID metadata, health-document evidence gates, developer-guide evidence inspection and sample-validation evidence runner for release checks.
- Electronic-invoice evidence gates for fiscal XML identity, tax-authority authorization, XAdES qualified signatures and original XML preservation.
- RFC 3161 timestamp request/response helpers, TimeStampToken parsing/validation, a PAdES B-T timestamp-provider adapter and ACT failover wrapper.
- ICP-Brasil ACT timestamp validation for RFC 3161 tokens, including T3/T4 timestamp certificate-policy checks.
- ITI signature-policy repository helpers for resolving current CAdES/XAdES/PAdES policy artifacts and SHA-256 files.
- Certificate evidence helpers for OCSP, CA issuer and CRL endpoint discovery plus offline chain validation.
- CRL/OCSP validation-evidence freshness assessment for long-term evidence reports and LTA renewal planning.
- ICP-Brasil signer trust validation that combines official ITI trust-store loading, chain validation, certificate validity, keyUsage/EKU evidence and DOC-ICP-04 signer policy checks, rejecting electronic seal/application/timestamp policies as signer evidence.
- Brazilian validation orchestration helpers that combine PAdES/CAdES/XAdES verification output with trust checks, policy digest checks, DOC-ICP-15 audit records and compliance reports.
- pyHanko-style validation summary helpers for PAdES, CAdES and XAdES that collapse detailed verifier output into a stable
valid/indeterminate/invalidstatus, baseline profile, LTV flags, signer subjects and actionable issues. - Validation-evidence coverage assessment that checks whether embedded certificates and CRL/OCSP evidence actually match the signer certificate chain.
- CRL issuer and OCSP responder assurance assessment that checks whether revocation evidence was issued by the chain issuer or by an authorized delegated OCSP responder.
ts-hankoCLI for PDF signing, inspection, verification and VALIDAR readiness checks from JSON inputs.- Hash-chained audit trail with optional platform signature.
- DOC-ICP-15-style signature generation and verification audit records for PAdES, CAdES and XAdES outputs.
- Simple/advanced electronic-signature envelope evidence packages for clickwrap, OTP, biometric, gov.br and ICP-Brasil-assisted flows.
- LTA renewal orchestration that collects/merges refreshed validation evidence, embeds it and appends renewal timestamps for PAdES, CAdES and XAdES.
- Certificate helpers for parsing X.509 metadata, keyUsage/EKU, detecting ICP-Brasil markers and classifying DOC-ICP-04 certificate policy OIDs such as A1/A3/T3 plus Resolução 211 electronic seal (
SE-S/SE-H) and application (AE-S/AE-H) types.
Install
npm install ts-hankoFor local development:
npm install
npm run verifynpm run verify runs the release gate used by CI: TypeScript checks, the full Vitest suite, the ESM/CJS declaration build and an npm pack --dry-run package manifest check. The GitHub Actions workflow runs the same gate on Node 20 and 22.
CLI
The package installs a ts-hanko binary for inspection and validation workflows:
ts-hanko inspect-pdf signed.pdf --parse-cms=false
ts-hanko fetch-icp-brasil-trust-store icp-brasil-trust-store.json --trust-store-pinning trust-pins.json
ts-hanko fetch-icp-brasil-signature-policy pades-policy.json --format PAdES --profile B-T --at 2026-05-24T00:00:00.000Z
ts-hanko collect-validation-evidence signer.pem validation-evidence --trust-store icp-brasil-trust-store.json --include-ocsp=false
ts-hanko validate-icp-brasil-certificate signer.pem --trust-store icp-brasil-trust-store.json --validation-evidence validation-evidence/evidence.json --require-fresh-revocation-evidence --require-revocation-responder-assurance --report-fragment-output signer-trust.json
ts-hanko verify-pdf signed.pdf --trust-store icp-brasil-trust-store.json --trust-store-pinning trust-pins.json --check-chain --validate-icp-brasil-certificate --modification-policy doc_mdp --brazil-report compliance-input.json
ts-hanko inspect-icp-brasil-trust-store icp-brasil-trust-store.json --trust-store-pinning trust-pins.json
ts-hanko add-pdf-field template.pdf prepared.pdf --field-name Sig1 --readable-field-name "Assinatura do cliente" --widget-rect 20,20,180,70 --seed-value seed.json --field-mdp-action include --field-mdp-fields Sig1
ts-hanko sign-pdf input.pdf signed.pdf --p12 signer.p12 --passphrase "$P12_PASS" --field-name Sig1 --visible --widget-rect 20,20,180,70 --use-case private_contract --icp-brasil --icp-brasil-chain-trusted
ts-hanko sign-pdf input.pdf signed-key.pdf --key signer.key --cert signer.pem --chain-cert issuer.pem --field-name Sig1 --use-case private_contract --icp-brasil --icp-brasil-chain-trusted
ts-hanko sign-pdf input.pdf signed-bt.pdf --p12 signer.p12 --passphrase-file .p12-pass --pades-profile B-T --timestamp-url https://tsa.example/timestamp
ts-hanko sign-pdf input.pdf signed-lta.pdf --p12 signer.p12 --passphrase-file .p12-pass --pades-profile B-LTA --timestamp-url https://act-primary.example/timestamp --timestamp-url https://act-backup.example/timestamp --validation-evidence evidence.json
ts-hanko sign-cades contract.bin contract.p7s --p12 signer.p12 --passphrase-file .p12-pass --cades-profile B-T --icp-brasil-signature-policy --timestamp-url https://tsa.example/timestamp
ts-hanko sign-cades contract.bin contract-key.p7s --key signer.key --cert signer.pem --chain-cert issuer.pem --use-case private_contract
ts-hanko verify-cades contract.bin contract.p7s --trust-store icp-brasil-trust-store.json --check-chain --validate-icp-brasil-certificate --validate-signature-policy --brazil-report compliance-input.json
ts-hanko sign-xades invoice.xml invoice-signed.xml --key signer.key --cert signer.pem --xades-profile B-T --timestamp-url https://tsa.example/timestamp --reference-xpath "/*"
ts-hanko verify-xades invoice-signed.xml --cert signer.pem --trust-store icp-brasil-trust-store.json --validate-icp-brasil-certificate --use-case electronic_invoice --accepted-by-parties --audit-trail-hash-chain --brazil-report compliance-input.json
ts-hanko plan-lta-renewal --profile B-LTA --signer-cert signer.pem --validation-evidence evidence.json --archive-timestamp-count 1 --now 2026-05-24T00:00:00.000Z --fail-when-due
ts-hanko timestamp-pdf unsigned.pdf timestamped.pdf --timestamp-url https://tsa.example/timestamp --field-name DocTS1 --readable-field-name "Timestamp de documento"
ts-hanko renew-pades-lta signed-lta.pdf renewed-lta.pdf --timestamp-url https://tsa.example/timestamp
ts-hanko collect-and-renew-pades-lta signed-bt.pdf signed-lta.pdf signer.pem --issuer-cert issuer.pem --validation-evidence evidence.json --timestamp-url https://tsa.example/timestamp --evidence-output-dir refreshed-evidence
ts-hanko renew-cades-lta contract.bin contract-lta.p7s contract-renewed.p7s --timestamp-url https://tsa.example/timestamp
ts-hanko collect-and-renew-cades-lta contract.bin contract-bt.p7s contract-lta.p7s signer.pem --issuer-cert issuer.pem --validation-evidence evidence.json --timestamp-url https://tsa.example/timestamp
ts-hanko renew-xades-lta invoice-lta.xml invoice-renewed.xml --timestamp-url https://tsa.example/timestamp
ts-hanko collect-and-renew-xades-lta invoice-bt.xml invoice-lta.xml signer.pem --issuer-cert issuer.pem --validation-evidence evidence.json --timestamp-url https://tsa.example/timestamp
ts-hanko validar-readiness readiness-input.json --report-fragment-output readiness-report.json
ts-hanko validar-qr-artifact validar-qr.json --descriptor-output descriptor.json
ts-hanko validar-samples validar-samples.json --report-fragment-output validar-report.json
ts-hanko inspect-validar-developer-guide
ts-hanko mvp-readiness mvp-readiness.json --report-fragment-output mvp-report.json
ts-hanko interoperability-evidence interoperability.json --report-fragment-output interoperability-report.json
ts-hanko conformance-corpus conformance-corpus.json --report-fragment-output conformance-corpus-report.json
ts-hanko legal-source-evidence legal-sources.json --report-fragment-output legal-sources-report.json
ts-hanko fetch-legal-source-evidence --report-input compliance-input.json --source-file "viabilityAnalysis:/path/to/viability.pdf" --evidence-output legal-sources.json --report-fragment-output legal-sources-report.json
ts-hanko provider-portfolio provider-portfolio.json --report-fragment-output provider-portfolio-report.json
ts-hanko provider-conformance provider-conformance.json --report-fragment-output provider-conformance-report.json
ts-hanko digital-custody digital-custody.json --report-fragment-output digital-custody-report.json
ts-hanko health-document-evidence health-document.json --report-fragment-output health-document-report.json
ts-hanko electronic-invoice-evidence electronic-invoice.json --report-fragment-output electronic-invoice-report.json
ts-hanko notarial-court-evidence notarial-court.json --report-fragment-output notarial-court-report.json
ts-hanko consigned-credit-evidence consigned-credit.json --report-fragment-output consigned-credit-report.json
ts-hanko govbr-evidence govbr-evidence.json --report-fragment-output govbr-report.json
ts-hanko brazil-report compliance-input.json --report-fragment validar-report.json --report-fragment interoperability-report.json --report-fragment provider-portfolio-report.json --report-fragment mvp-report.json --report-fragment govbr-report.json
ts-hanko brazil-release-pack release-pack.json --preset mvp_release --report-fragment validar-report.json --report-fragment interoperability-report.json --report-fragment conformance-corpus-report.json --report-fragment provider-portfolio-report.json --report-fragment provider-conformance-report.json --report-fragment mvp-report.json --pack-output release-pack-report.json --checklist-output release-checklist.json
ts-hanko brazil-release-dossier-template release-pack-report.json --template-output release-dossier-template.json
ts-hanko brazil-release-dossier-seal release-dossier-template.json --pack release-pack-report.json --sealed-output sealed-dossier.json
ts-hanko brazil-release-dossier sealed-dossier.json --dossier-output release-dossier-report.jsontimestamp-pdf appends a standalone PAdES /DocTimeStamp with optional internal and readable field names before or after approval signing.
All commands print JSON. fetch-icp-brasil-trust-store downloads the ITI AC archive, verifies the published SHA-512 hash by default, optionally applies pinning and writes an auditable snapshot JSON. fetch-icp-brasil-signature-policy resolves the selected ITI DOC-ICP-15.03 signature-policy artifact for PAdES, CAdES or XAdES, verifies its published digest sidecar and writes a --signature-policy JSON file. Signing commands can also resolve the policy directly with --icp-brasil-signature-policy; the CLI derives AD-RB/AD-RT/AD-RC/AD-RA from the selected baseline profile, or accepts --signature-policy-kind for an explicit override. collect-validation-evidence follows AIA caIssuers, CRL Distribution Points and OCSP endpoints from a signer certificate, writes certificate/CRL/OCSP files plus an evidence.json manifest with per-file SHA-256 and byte-length entries, and exits with code 2 when the optional coverage assessment fails. Later --validation-evidence consumers verify those hashes before using the files, while still accepting the legacy file-list manifest shape. Applications can use createCmsValidationEvidenceManifestEntry, inspectCmsValidationEvidenceManifestEntry and assertCmsValidationEvidenceManifestEntry to apply the same hash-binding rules outside the CLI. validate-icp-brasil-certificate builds a reusable validation context from --issuer-cert, --trusted-cert, --trust-store, --validation-evidence, --check-date and revocation policy options, validates the signer certificate against ICP-Brasil policy/key-usage/trust rules, and can write a report signature fragment with --report-fragment-output; use --require-fresh-revocation-evidence to reject expired CRL/OCSP material at the validation time, --require-revocation-responder-assurance to reject CRL/OCSP evidence from unauthorized responders, --verify-revocation-responder-signatures to cryptographically verify responder signatures when responder certificates are available, and --require-revocation-next-update=false only when the governing policy accepts revocation evidence without a next refresh boundary. verify-pdf, verify-cades and verify-xades can read ICP-Brasil trust anchors from --trust-store, using those snapshots, and --trust-store-pinning applies source, root, digest and max-age controls before the snapshot is trusted. When --validate-icp-brasil-certificate or the related signer trust policy flags are present, those verification commands validate signer certificates with the same reusable context and merge trust, freshness and responder-assurance evidence into --brazil-report signatures. verify-pdf also reports inspected DSS/VRI and document timestamp evidence, excludes /DocTimeStamp signatures from approval-signature pass/fail counts, and folds DSS plus valid document timestamp evidence into --brazil-report signatures for PAdES B-LT/B-LTA assessment. verify-pdf, verify-cades and verify-xades can pass --validate-signature-policy to fetch the embedded policy URI, verify the policy digest and check the selected ITI repository artifact; use --signature-policy-kind, --signature-policy-status, --signature-policy-at, --signature-policy-oid, --signature-policy-url and repeated --signature-policy-header "Name: value" to pin the check. inspect-icp-brasil-trust-store reports snapshot counts, warnings and pinning results, exiting with code 2 when the pinning assessment fails. set-pdf-metadata writes document info metadata from flags or JSON before signing. stamp-pdf draws a standalone visible text stamp before signing, including signer/context lines and the original document SHA-256 hash; stamp-pdf-qr embeds a QR-code PNG for VALIDAR-style target URLs or other retrieval links. add-pdf-field prepares an empty /FT /Sig field and can attach seed-value JSON plus FieldMDP /Lock metadata for later VALIDAR-friendly signing. sign-pdf and sign-cades accept either --p12 signer.p12 or loose key material with --key private-key.pem|der --cert signer.pem|der plus repeated --chain-cert issuer.pem|der; sign-xades exposes XML/XAdES with --key, --cert, --reference-xpath and --signature-location-xpath. The renew-pades-lta, renew-cades-lta and renew-xades-lta commands append the next archive/document timestamp to existing long-term artifacts. Signing and renewal commands accept common signature metadata/evidence options where applicable, including --signature-policy, timestamp options and --validation-evidence. validar-qr-artifact reads a QR/health manifest, emits the QR target URL, descriptor fetch URL, descriptor JSON, health OID metadata and readiness result, and can write the descriptor JSON with --descriptor-output. validar-readiness can write a { "validarReadiness": ... } report fragment with --report-fragment-output. validar-samples reads a sample manifest, posts each sample to a configured VALIDAR-compatible HTTP endpoint, normalizes provider responses into externalValidation evidence, exits with code 2 when the batch is not passing, and can write a { "externalValidation": ... } fragment for brazil-report. mvp-readiness combines VALIDAR/ITI sample evidence, Adobe Reader/Acrobat validation evidence, legal-review evidence and operational pilot metrics into the viability-analysis release gate, and can write a { "mvpReadiness": ... } report fragment for brazil-report. interoperability-evidence checks artifact-level sample coverage across PAdES/CAdES/XAdES, requires external VALIDAR/ITI pass evidence and Adobe Reader/Acrobat evidence for PAdES samples, and can write a { "interoperability": ... } report fragment. conformance-corpus checks release regression samples across required formats and baseline profiles, negative/tampered cases, SHA-256-or-stronger artifact hashes, external VALIDAR/ITI report URLs, PAdES Adobe evidence and CI inclusion, and can write a { "conformanceCorpus": ... } fragment now required by the MVP, qualified and production release-pack presets. legal-source-evidence turns a governed review manifest for official laws, ITI documents, VALIDAR guidance and the viability analysis into a { "legalSourceEvidence": ... } fragment; fetch-legal-source-evidence can create that manifest from registered source URLs, from a --report-input compliance report's required source IDs and local --source-file sourceId:path artifacts, recording HTTP status, SHA-256, ETag and Last-Modified metadata before writing the same report fragment. Production release packs require that fragment to cover the report sources, remain inside the configured freshness window and have no changed, unreachable or mismatched source checks. govbr-evidence assesses verified gov.br OAuth/OpenID evidence for silver/gold advanced-signature use and can write a { "govBrIdentity": ... } report fragment with --report-fragment-output. brazil-report reads a BrazilianComplianceReportInput JSON evidence pack, merges repeated --report-fragment files and exits with code 2 unless the generated report is compliant; verify-pdf, verify-cades and verify-xades also accept --brazil-report compliance-input.json plus repeated --report-fragment, use the verified signatures as the report signatures and treat the JSON signature entries as per-signature evidence overrides. brazil-release-pack reads a nested { "report": ... } or flat report input, merges repeated report fragments, applies a release preset such as mvp_release, qualified_signature_release or production_release, can write a release checklist with --checklist-output, and exits with code 2 when required release evidence is missing even if the base document report only emitted warnings. For PAdES/CAdES/XAdES B-T and renewal commands, pass --timestamp-url to call a RFC 3161 TSA/ACT endpoint, and repeat --timestamp-url to try multiple ACT endpoints in order; optional timestamp settings include --timestamp-policy-oid, --timestamp-hash, --timestamp-timeout-ms and repeated --timestamp-header "Name: value". Use --timestamp-token token.tsr only when a token has already been obtained. For B-LT or B-LTA, pass --validation-evidence evidence.json; paths inside the manifest are resolved relative to the manifest file:
{
"certificateFiles": ["signer.pem", "issuer.cer"],
"crlFiles": ["issuer.crl"],
"ocspResponseFiles": ["issuer.ocsp"]
}The plan-lta-renewal command derives the next long-term renewal action from the baseline profile, signer certificate, CRL/OCSP validation-evidence manifest, archive timestamp count and optional policy or algorithm deadlines. Pass --fail-when-due when a scheduler or CI job should exit with code 2 once the safety window has started. The collect-and-renew-pades-lta, collect-and-renew-cades-lta and collect-and-renew-xades-lta commands perform a full LTA lifecycle step in one run: collect or merge current validation evidence for the signer chain, embed that evidence as PAdES DSS, CMS or XAdES LT material, append the archive/document timestamp, report evidence freshness/deadlines and optionally write a refreshed manifest with --evidence-output-dir.
The verify-pdf, verify-cades and verify-xades outputs include a validationSummary object for log, dashboard and release-gate use. It preserves the detailed verifier payload while adding a stable status, bottomLine, inferred baseline profile, LTV flags, signer subjects and normalized issues.
For mvp-readiness, legal evidence may be supplied as legacy booleans or as structured reviewArtifacts with document hashes, review dates, reviewers, evidence URLs, source ids and explicit coverage for qualified, advanced, simple, audit-trail and LGPD review.
For digital-custody, evidence should bind the signed artifact to its hash, validation evidence, audit trail, immutable encrypted storage, LGPD retention/legal hold controls, LTA renewal schedule, integrity monitoring and customer export package.
For health-document-evidence, controlled prescriptions need the VALIDAR descriptor and QR fetch URL, signed prescription file URL, health document and professional OID metadata, professional registration and UF, trusted qualified ICP-Brasil signature evidence, VALIDAR readiness/external validation, LGPD health-data controls and audit/retention evidence.
For electronic-invoice-evidence, fiscal XML workflows need the document type and fiscal key, issuer CNPJ and matching signer certificate evidence, schema validation, tax-authority authorization protocol, XAdES signature coverage, trusted qualified ICP-Brasil signer evidence, verified signature policy, external validation and original XML preservation.
For consigned-credit-evidence, payroll-deducted credit workflows need digital formalization plus worker identity evidence and one accepted signature path: trusted qualified ICP-Brasil signature, federal/judicial homologated advanced signature with stored technical proof, advanced signature with biometric proof of life and LGPD biometric consent/legal-basis evidence, or institutional digital signature in a secure authenticated environment with MFA and proof-ready technical evidence.
For notarial-court-evidence, critical notarial or judicial workflows need the authority/court/notarial office, protocol or filing receipt, act or case id, trusted qualified PAdES B-LTA proof, external validation, chain-of-custody evidence, 30-year retention/legal hold, mapped legal requirement, PL 4/2025 review and legal/admissibility review.
A validar-samples manifest supplies the endpoint and the regression samples that should be sent to the external VALIDAR/Verificador-compatible service:
{
"endpoint": "https://validar.example.test/api/validate",
"headers": {
"authorization": "Bearer token"
},
"minimumPassRate": 1,
"samples": [
{
"id": "contract-pades",
"name": "contract.pdf",
"documentHash": "sha256:...",
"format": "PDF"
}
]
}provider-portfolio accepts a PSC/AC/ACT supplier manifest, checks fallback coverage, formal proposals, production SLA/commercial evidence and driver-adapter readiness, and can write a { "providerPortfolioAssurance": ... } fragment for brazil-report or brazil-release-pack. provider-conformance records per-provider onboarding evidence: accreditation URL, implemented adapter, health check, credential authorization or RFC 3161 timestamp test, valid signature or token output, captured request/transaction evidence, failover test and sample report hash binding. It can write a { "providerConformance": ... } fragment that brazil-report includes as a provider conformance control; qualified_signature_release and production_release require it, including ACT conformance when reported signatures are timestamped or long-term. conformance-corpus is the stricter release regression gate for actual sample artifacts; samples can provide artifactPath, artifactFile or path so the CLI computes and checks artifactHash from the file bytes. Its report fragment is required by the MVP, qualified-signature and production release presets. brazil-release-pack --checklist-output writes a checklist of missing evidence artifacts and command hints for unresolved release controls, such as VALIDAR preflight, conformance-corpus samples, provider conformance and legal-source evidence. brazil-release-dossier-template creates a fill-in dossier manifest from that release pack, with expected evidence kinds and file paths. brazil-release-dossier-seal reads that manifest, computes byte lengths, hashes and inferred evidence kinds from the local files, and writes an archival sealed manifest with a canonical dossierHash. brazil-release-dossier then verifies the sealed dossier and fails when required checklist items are unresolved, uncovered, weakly hash-bound, backed by the wrong evidence kind or changed after sealing.
Use --passphrase-file instead of --passphrase when the secret should not appear in shell history. verify-pdf, validate-icp-brasil-certificate, validar-readiness, validar-samples, mvp-readiness, interoperability-evidence, conformance-corpus, provider-portfolio, provider-conformance, govbr-evidence, brazil-report and brazil-release-pack exit with code 2 when the checked signatures, signer certificate, readiness controls, sample-validation batch, MVP release evidence, artifact interoperability evidence, conformance corpus, provider portfolio/conformance evidence, gov.br evidence, full compliance report or release evidence pack fail, which makes them usable in CI and release gates.
Compliance Model
The compliance layer is based on the supplied viability PDF plus current official references:
- MP 2.200-2/2001 - ICP-Brasil legal presumption for qualified signatures.
- Lei 14.063/2020 - simple, advanced and qualified signature taxonomy.
- Lei 10.820/2003 - payroll-deducted credit operations and digital formalization requirements.
- Lei 15.179/2025 - digital payroll-credit operations, qualified signatures and advanced biometric proof-of-life evidence.
- Decreto 12.564/2025 - biometric identity verification, biometric-data consent and electronic/digital signature requirements for consigned-credit operations.
- Decreto 10.543/2020 - public administration signature levels.
- Lei 13.709/2018 (LGPD) - personal-data protection, sensitive-data treatment and controller/operator duties.
- Código Civil - civil prescription and enforcement rules used for evidence-retention planning.
- Código de Processo Civil, art. 784, §4º - electronic extrajudicial enforcement instruments and provider-backed integrity.
- Lei 9.514/1997 - real-estate financing and fiduciary alienation workflows.
- Lei 14.620/2023 - electronic signatures for enforceable instruments and real-estate financing contexts.
- Lei 14.711/2023 - guarantee and registry modernization relevant to durable credit workflows.
- PL 4/2025 - pending Civil Code reform to monitor for electronic-signature and electronic-notarial risk changes.
- ITI DOC-ICP-15 - ICP-Brasil digital signature concepts, validation and audit requirements.
- ITI DOC-ICP-15.02 - ICP-Brasil general-use profiles for CAdES, XAdES and PAdES.
- ITI DOC-ICP-03 - ICP-Brasil accreditation criteria for entities such as ACs and PSCs.
- Resolução CG ICP-Brasil 216/2025 - current ICP-Brasil accreditation updates, including adequate pre-operational audit-report evidence for regulated providers.
- Instrução Normativa ITI 32/2025 - current ICP-Brasil audit criteria, operational audit reporting and nonconformity action-plan expectations.
- ITI DOC-ICP-04 - ICP-Brasil certificate-policy OID table for certificate types such as A3/A4, electronic seals, application, T3/T4 and equipment certificates.
- ITI DOC-ICP-04.01 - ICP-Brasil OID assignment arcs for certificate policies and mandatory certificate attributes.
- ITI Documentos Principais - current DOC-ICP index.
- ITI Artefatos de Assinatura Digital - current repository pages for CAdES, XAdES and PAdES signature policy artifacts.
- ITI Autoridades de Carimbo do Tempo - current list of ICP-Brasil accredited ACT providers.
- ITI Certificados das ACs da ICP-Brasil - official compacted current/complete AC certificate archives and SHA-512 hashes.
- Verificador de Conformidade ITI - official DOC-ICP-15 conformance checker.
- VALIDAR ITI - current official validation service for ICP-Brasil and gov.br signatures.
- VALIDAR Guia do Desenvolvedor - technical guidance for document formats, accepted signature patterns, QR Code parameters, healthcare OIDs and PDF MDP update-control behavior.
The default architecture follows the recommended integrator path from the PDF: the application orchestrates signatures and evidence, while ICP-Brasil certificate issuance, cloud signing custody and timestamp authorities remain with accredited providers.
assessBrazilianProviderAssurance checks that operating model explicitly. It verifies whether an integrator keeps user private-key custody outside the platform, whether qualified flows use accredited AC/PSC providers, whether timestamped or long-term flows use accredited ACT evidence, whether PSC/AC or platform key custody has credentialing, HSM and audit-readiness evidence, and whether fallback providers, operator contracts and platform key protection are documented. Pass its result as providerAssurance to createBrazilianComplianceReport, or pass raw providerEvidence and timestampProviderEvidence so the report can derive the summarized provider_assurance control from PSC and ACT validation evidence.
assessBrazilianProviderPortfolioAssurance models the supplier-portfolio work from the viability PDF. For qualified or long-term releases, it checks whether the selected PSC/AC and ACT set covers the recommended fallback plan, whether formal proposals were collected, whether production providers have contract, SLA and volume-pricing evidence, and whether the driver abstraction is backed by API or adapter evidence.
Example: Compliance Assessment
import { assessBrazilianSignatureCompliance } from "ts-hanko";
const assessment = assessBrazilianSignatureCompliance(
{
identifiesSigner: true,
attachedOrAssociatedToDocument: true,
acceptedByParties: true,
uniquelyLinkedToSigner: true,
exclusiveSignerControl: true,
tamperEvident: true,
auditTrailHashChain: true,
timestamped: true,
timestampAuthorityAccredited: true
},
"private_contract"
);
console.log(assessment.level); // "advanced"
console.log(assessment.recommendedPadesProfile); // "B-T"For federal public-administration flows, classify the concrete interaction before building the report:
import { classifyBrazilianPublicAdministrationInteraction } from "ts-hanko";
const publicInteraction = classifyBrazilianPublicAdministrationInteraction({
containsProtectedInformation: true,
financialOrEconomicImpact: true
});
console.log(publicInteraction.minimumLevel); // "advanced"
console.log(publicInteraction.useCase); // "public_administration_standard"For a portal that handles multiple document families, classify the document first and pass the resulting useCase into the report:
import { classifyBrazilianDocumentUseCase } from "ts-hanko";
const documentClass = classifyBrazilianDocumentUseCase({
cpc784ElectronicEnforceableTitle: true,
civilCodeReformPl4Monitoring: true
});
console.log(documentClass.useCase); // "enforceable_electronic_instrument"
console.log(documentClass.requirement.recommendedPadesProfile); // "B-LT"
console.log(documentClass.warnings);Example: Brazilian Validation Report
import { createBrazilianComplianceReport } from "ts-hanko";
const report = createBrazilianComplianceReport({
useCase: "long_term_private_contract",
retentionYears: 30,
signatures: [
{
format: "PAdES",
profile: "B-LTA",
signerSubject: "CN=Signer",
integrityValid: true,
timestamped: true,
timestampAuthorityAccredited: true,
longTermValidationEvidence: true,
archiveTimestamped: true,
signaturePolicyOid: "2.16.76.1.7.1.12.1.1",
signaturePolicyDigestVerified: true,
evidence: { acceptedByParties: true }
}
],
auditTrail: { valid: true, signed: true, signedByPlatformIcpBrasil: true },
externalValidation: { provider: "VALIDAR", status: "passed", protocol: "sample-123" },
integratorAssurance: { model: "integrator", doesNotCustodyUserPrivateKeys: true },
privacy: {
retentionYears: 30,
hasAnonymizationPlan: true,
preservesDocumentHashAfterAnonymization: true,
hasOperatorContracts: true,
hasDpoContact: true,
dataResidency: "AWS sa-east-1 / Sao Paulo"
}
});
console.log(report.overallStatus); // "compliant"
console.log(report.controls.map((control) => [control.id, control.status]));Use createBrazilianReleaseEvidencePack when the release gate should require product-level evidence that the document report treats as recommended:
import {
assessBrazilianReleaseEvidenceDossier,
attachBrazilianReleaseEvidenceDossierManifestHash,
createBrazilianReleaseEvidenceDossierTemplateFromPack,
createBrazilianReleaseEvidenceChecklistFromPack,
createBrazilianReleaseEvidenceDossierArtifactFromBytes,
createBrazilianReleaseEvidencePack,
verifyBrazilianReleaseEvidenceDossierManifestHash
} from "ts-hanko";
const pack = createBrazilianReleaseEvidencePack({
preset: "mvp_release",
reportInput: {
...reportInput,
validarReadiness,
externalValidation,
mvpReadiness
}
});
console.log(pack.valid);
console.log(pack.controls.map((control) => [control.id, control.status]));
const checklist = createBrazilianReleaseEvidenceChecklistFromPack(pack);
console.log(checklist.missingItemIds);
console.log(checklist.nextActions);
const template = createBrazilianReleaseEvidenceDossierTemplateFromPack(pack);
console.log(template.artifacts.map((artifact) => [artifact.checklistItemId, artifact.evidenceKind]));
const dossier = assessBrazilianReleaseEvidenceDossier({
pack,
artifacts: [
createBrazilianReleaseEvidenceDossierArtifactFromBytes({
id: "validar-report",
checklistItemId: "release_external_validation",
fileName: "validar-report.json",
artifact: validarReportJson
})
]
});
console.log(dossier.valid);
const sealedDossier = attachBrazilianReleaseEvidenceDossierManifestHash({
sealedAt: new Date().toISOString(),
pack,
artifactCount: dossier.artifactCount,
artifacts: dossier.items.flatMap((item) => item.artifacts)
});
console.log(verifyBrazilianReleaseEvidenceDossierManifestHash(sealedDossier));For ICP-Brasil signatures, the report includes a signature_policy_identifier control. It fails when a policy-based PAdES/CAdES/XAdES signature does not expose a DOC-ICP-15.03 policy identifier, when supplied ITI repository evidence shows the policy artifact was not VIGENTE/applicable at the signing time, when the AD-RB/AD-RT/AD-RC/AD-RA kind does not match the reported baseline profile, or when policy hash verification fails. For PAdES, the report can infer AD-RB/AD-RT/AD-RC/AD-RA from the current DOC-ICP-15.03 v9.1 policy OID families even when a caller only supplies the embedded OID. It warns when the policy hash was not independently checked against the referenced policy artifact.
When certificate-policy metadata is available, the qualified-chain control also checks the signer certificate family. For qualified signer evidence, DOC-ICP-04 signing policies (A1, A2, A3, A4) satisfy the signer-certificate policy check; timestamp, equipment, metrology, confidentiality, electronic seal (SE-S/SE-H) or specific-application (AE-S/AE-H) certificate policies do not. When signerKeyUsages, signerExtendedKeyUsageOids or ICP-Brasil certificate policy metadata are supplied, the report also adds signer_certificate_usage and fails certificates that lack digitalSignature/contentCommitment, are limited to timestamping/OCSP signing, or expose a non-signer ICP-Brasil policy family.
When verification metadata includes CMS algorithm OIDs and signer certificate key parameters, the report adds a cryptographic_strength control. assessBrazilianCryptographicStrength rejects SHA-1 and RSA keys below 2048 bits, accepts SHA-256/SHA-384/SHA-512 digest evidence, and treats RSA-2048+, ECDSA P-256/P-384-style curves and the current ICP-Brasil PAdES Ed25519/Ed448 OIDs as recognized Brazilian compliance evidence.
When documentHash is supplied on createBrazilianComplianceReport, the report adds a document_hash_evidence control. It accepts algorithm-prefixed SHA-256, SHA-384 or SHA-512 hexadecimal values, rejects SHA-1, and fails malformed or truncated hash evidence. Supplying a report-level hash is recommended even when the audit trail also contains per-event document hashes.
For long-term reports, pass validationEvidenceFreshness on each signature when CRL/OCSP material was inspected with assessCmsValidationEvidenceFreshness. The report adds a validation_evidence_freshness control and fails long-retention evidence when the revocation material was expired, missing required nextUpdate data or issued after the validation time. Pass validationEvidenceCoverage from assessCmsValidationEvidenceCoverage when the report should also prove that embedded certificates and CRL/OCSP responses actually match the signer certificate chain. Pass validationEvidenceResponderAssurance from assessCmsValidationEvidenceResponderAssurance when the report should fail CRLs whose issuer is not the certificate issuer, or OCSP BasicResponses whose responder is neither the issuer nor a delegated OCSP responder certificate with id-kp-OCSPSigning.
For simple or advanced envelope signatures, pass advancedSignatureEvidence when the audit trail was checked with assessBrazilianAdvancedSignatureEvidence or produced by createElectronicSignatureEvidencePackage, createMultiSignerElectronicSignatureEvidencePackage or signPdfEnvelopeWithExternalSigners. For multi-signer envelopes, pass signerResults.map((result) => result.advancedEvidence). The report adds an advanced_signature_evidence control covering the hash chain, core envelope events, consent, identity method, signer technical metadata and document hash evidence.
When the stricter minimum audit trail from the viability PDF should be enforced, pass auditTrailMinimumEvidence from assessBrazilianAuditTrailMinimumEvidence or from an evidence package. The report adds an audit_trail_minimum_evidence control covering signer identity, chronological events, IP/user-agent/session/device metadata, TLS/OAuth/biometric identity proof, SHA-256 hashes, hash chain and platform audit-trail signature.
For qualified ICP-Brasil flows, pass qualifiedSignatureFlow from assessBrazilianQualifiedSignatureFlow. It turns the PDF section 5.3 sequence into controls: document upload and SHA-256 intake, WORM/envelope persistence, notification with a unique signed JWT link, signer identification method alignment, cloud PSC OAuth/PKCE authorization or local Web PKI token/PIN evidence, accredited RFC 3161 timestamping, PAdES packaging with certificate and long-term evidence, ITI/DOC-ICP-15 validation sampling, final PDF storage and platform ICP-A1 audit-trail signature.
For ordered envelope ceremonies, pass signingCeremony from assessBrazilianSigningCeremony, derive it from an evidence package with assessEvidencePackageSigningCeremony, or let signPdfEnvelopeWithExternalSigners create it automatically. The report adds signing-ceremony controls that fail when required signers declined or stayed pending, signer order is inconsistent, audit signature events are missing or inconsistent, the envelope completion event is absent, or the completed signer count does not match the reported PDF signatures. Multi-signer evidence treats signers as required by default; set required: false for optional witnesses or observers whose decline should remain in the audit trail without failing ceremony completion.
To produce the chain-trust evidence used by that control, validate the signer certificate against trust anchors supplied by your application or load the current ITI repository material first:
import {
assertIcpBrasilTrustStorePins,
createCertificateValidationContext,
createIcpBrasilTrustStoreSnapshot,
fetchIcpBrasilTrustStore,
icpBrasilTrustValidationToReportSignatureEvidence,
loadIcpBrasilTrustStoreSnapshot,
validateIcpBrasilSignerCertificate
} from "ts-hanko";
const trustStore = await fetchIcpBrasilTrustStore({
pinning: {
requireArchiveHashVerified: true,
allowedArchiveUrls: [
"https://acraiz.icpbrasil.gov.br/credenciadas/CertificadosAC-ICP-Brasil/ACcompactado.zip"
],
minimumRootCertificateCount: 1,
requiredRootVersions: [12, 13],
maxAgeDays: 7
}
});
const snapshot = createIcpBrasilTrustStoreSnapshot(trustStore);
const cachedTrustStore = loadIcpBrasilTrustStoreSnapshot(JSON.stringify(snapshot));
assertIcpBrasilTrustStorePins(cachedTrustStore, {
requireArchiveHashVerified: true,
maxAgeDays: 7
});
const validationContext = createCertificateValidationContext({
trustStore: cachedTrustStore,
validationEvidence: { crls: [crlBytes] },
requireRevocationEvidence: true,
checkDate: new Date()
});
const trust = await validateIcpBrasilSignerCertificate({
certificate: signerCertificatePem,
validationContext
});
const signatureEvidence = icpBrasilTrustValidationToReportSignatureEvidence(trust);fetchIcpBrasilTrustStore downloads ITI's current compacted AC certificate ZIP, verifies the published SHA-512 hash, discovers current AC-Raiz certificate links from the gov.br repository page and returns trustedCertificates plus issuerCertificates in the format accepted by createCertificateValidationContext or directly by validateIcpBrasilSignerCertificate. createCertificateValidationContext is the pyHanko-style reusable validation context for trust anchors, issuer certificates, CRL/OCSP evidence, validation date and revocation policy. Set requireFreshRevocationEvidence: true to make validateIcpBrasilSignerCertificate fail stale revocation material and surface validationEvidenceFreshness in report evidence; set requireRevocationResponderAssurance: true to fail unauthorized CRL/OCSP responders and surface validationEvidenceResponderAssurance. createIcpBrasilTrustStoreSnapshot and loadIcpBrasilTrustStoreSnapshot let applications persist that material in their governed cache, while assessIcpBrasilTrustStorePins/assertIcpBrasilTrustStorePins enforce expected source URLs, archive hash evidence, root fingerprints, root versions, root count and maximum age. The fetcher is injectable so production systems can add caching, pinning, mTLS, proxying or offline repository mirrors.
Example: Privacy and Retention
import { assessBrazilianPrivacyEvidence, recommendBrazilianEvidenceRetention } from "ts-hanko";
const retention = recommendBrazilianEvidenceRetention("registry_or_real_estate_transfer");
const privacy = assessBrazilianPrivacyEvidence({
useCase: "registry_or_real_estate_transfer",
retentionYears: retention.recommendedRetentionYears,
hasLegalBasisForProcessing: true,
containsBiometricData: true,
biometricConsent: true,
hasSensitiveDataLegalBasis: true,
largeScaleSensitiveDataProcessing: true,
hasDataProtectionImpactAssessment: true,
containsGeolocation: true,
geolocationConsent: true,
hasAnonymizationPlan: true,
preservesDocumentHashAfterAnonymization: true,
hasOperatorContracts: true,
hasDpoContact: true
});
console.log(retention.recommendedRetentionYears); // 30
console.log(privacy.valid); // truePrivacy controls cover the LGPD evidence called out in the feasibility analysis: processing legal basis, sensitive-data legal basis for biometrics, RIPD/DPIA evidence for biometric or large-scale sensitive-data processing, retention horizon, geolocation consent, anonymization/minimization that preserves hashes, customer-configurable retention policies, data-subject erasure workflows that preserve proof evidence, deletion/anonymization audit records, legal hold for disputed long-retention evidence, operator contracts and DPO contact.
Example: VALIDAR QR Descriptor
import {
assessBrazilianValidarReadiness,
createValidarDescriptorFetchUrl,
createValidarHealthMetadataArtifact,
createValidarHealthOidMetadata,
createValidarPrescriptionDescriptor,
createValidarQrCodeIntegrationArtifact,
createValidarQrCodeTargetUrl,
fetchValidarPrescriptionDescriptor,
runBrazilianValidarSampleValidation
} from "ts-hanko";
const descriptor = createValidarPrescriptionDescriptor({
signatureFiles: ["https://health.example.test/prescricoes/rx-123.pdf"]
});
const qrCodeTargetUrl = createValidarQrCodeTargetUrl({
baseUrl: "https://health.example.test/validar",
type: "prescricao",
parameters: { document: "rx-123" }
});
const validarFetchUrl = createValidarDescriptorFetchUrl({
qrCodeUrl: qrCodeTargetUrl,
secretCode: "XIU8789Y"
});
const fetchedDescriptor = await fetchValidarPrescriptionDescriptor({
url: validarFetchUrl
});
const healthOids = createValidarHealthOidMetadata({
professionalCouncil: "CFM",
documentType: "prescription"
});
const healthMetadata = createValidarHealthMetadataArtifact({
professionalCouncil: "CFM",
professionalRegistration: "123456",
professionalState: "SP",
documentType: "prescription",
documentIdentifier: "rx-123"
});
const readiness = assessBrazilianValidarReadiness({
documentFormat: "PDF",
signatures: [
{
format: "PAdES",
profile: "B-T",
usesIcpBrasilCertificate: true,
signaturePolicyKind: "AD-RT",
docMdpPresent: true,
docMdpPermission: 2
}
],
prescriptionDescriptorValid: true,
qrDescriptorFetchUrlValid: true,
...healthMetadata.readiness
});
const qrIntegration = createValidarQrCodeIntegrationArtifact({
baseUrl: "https://health.example.test/validar",
type: "prescricao",
parameters: { document: "rx-123" },
secretCode: "XIU8789Y",
signatureFiles: ["https://health.example.test/prescricoes/rx-123.pdf"],
signatures: [
{
format: "PAdES",
profile: "B-T",
usesIcpBrasilCertificate: true,
signaturePolicyKind: "AD-RT",
docMdpPresent: true,
docMdpPermission: 2
}
],
healthMetadata: {
professionalCouncil: "CFM",
professionalRegistration: "123456",
professionalState: "SP",
documentType: "prescription",
documentIdentifier: "rx-123"
}
});
console.log(descriptor.prescription.signatureFiles[0].url);
console.log(validarFetchUrl);
console.log(fetchedDescriptor.signatureFileUrls);
console.log(healthOids.document?.oid); // "2.16.76.1.12.1.1"
console.log(healthMetadata.valid); // true
console.log(readiness.valid); // true
console.log(qrIntegration.valid); // true
const validarSamples = await runBrazilianValidarSampleValidation({
provider: "VALIDAR",
samples: [{ id: "rx-123", name: "rx-123.pdf", readiness }],
validateSample: async (sample) => {
const result = await submitToYourValidarClient(sample);
return {
status: result.ok ? "passed" : "failed",
protocol: result.protocol,
reportUrl: result.reportUrl,
messages: result.messages
};
}
});
console.log(validarSamples.externalValidation.status);fetchValidarPrescriptionDescriptor performs the expected descriptor GET, validates the returned JSON and maps the developer-guide 401 and 404 responses to actionable diagnostics. createValidarHealthMetadataArtifact records the health professional council, registration/state OIDs, optional specialty OID and health-document OID in a structured artifact that can be attached to the envelope/audit record and reused as readiness input. inspectValidarDeveloperGuide and fetchValidarDeveloperGuideEvidence turn the public guide itself into auditable evidence, recording source URL, ETag/Last-Modified headers, SHA-256 hash, accepted formats, RB/RT PAdES policy guidance, QR descriptor parameters, MDP guidance and whether a public machine validation API is documented. assessBrazilianValidarReadiness is a preflight helper for the viability analysis requirement to sample documents against VALIDAR/Verificador ITI. It checks accepted submission formats, PAdES/XAdES/CAdES signature pattern evidence, ICP-Brasil policy evidence aligned with the declared baseline profile, PDF MDP update-control metadata and health-document descriptor/OID evidence before the external validation call is made. JSON descriptor submissions now pass readiness when the application/validador-iti+json descriptor is valid and the referenced artifact evidence follows the PDF/PAdES, XML/XAdES or P7S/CAdES route. For direct or JSON-referenced PAdES PDF submissions, it enforces the current VALIDAR developer-guide expectation that ICP-Brasil policy-based signatures use AD-RB or AD-RT. runBrazilianValidarSampleValidation then wraps the application-provided VALIDAR/ITI client, enforces readiness by default, aggregates per-sample pass/warning/fail counts and returns externalValidation evidence ready for createBrazilianComplianceReport. createValidarHttpSampleValidationClient supplies the default HTTP adapter used by the CLI when a VALIDAR-compatible endpoint is available. The CLI inspect-validar-developer-guide, validar-readiness and validar-samples commands can also write or print evidence so preflight, public-guide and external-validation results can be attached to release records before a later brazil-report run.
For release gates, pass the VALIDAR batch or its externalValidation object to createBrazilianMvpReadinessInputFromValidationEvidence or assessBrazilianMvpReadinessFromValidationEvidence. These helpers convert the sample counts into the viability analysis MVP technical evidence fields and combine them with the required Adobe Reader, legal and operational evidence. Adobe evidence can still be a simple adobeReaderValidationPassed boolean, but release packs can now preserve structured adobeReaderValidation details such as viewer, version, validation time, report URL, signature counts and messages:
{
"adobeReaderValidation": {
"status": "passed",
"viewer": "Adobe Acrobat",
"version": "2026.001",
"performedAt": "2026-05-24T12:10:00.000Z",
"reportUrl": "https://evidence.example.test/adobe/acr-1",
"signatureCount": 2,
"validSignatureCount": 2,
"invalidSignatureCount": 0,
"messages": ["All signatures are valid."]
}
}Use assessBrazilianArtifactInteroperability when the release pack needs artifact-level coverage rather than only aggregate sample counts. It checks expected PAdES/CAdES/XAdES samples, requires each sample to be bound to a SHA-256-or-stronger artifact hash, requires VALIDAR/Verificador ITI pass evidence per sample by default, and requires Adobe Reader/Acrobat validation for PAdES samples. Use createBrazilianInteroperabilitySampleEvidence or the CLI artifactPath field to compute the hash from the sampled file:
import {
assessBrazilianArtifactInteroperability,
createBrazilianInteroperabilitySampleEvidence
} from "ts-hanko";
const padesSample = createBrazilianInteroperabilitySampleEvidence({
id: "contract-pades-bt",
format: "PAdES",
artifact: signedPdfBytes,
externalValidation: { provider: "VALIDAR", status: "passed", protocol: "VAL-123" },
adobeReaderValidation: {
status: "passed",
viewer: "Adobe Acrobat",
signatureCount: 1,
validSignatureCount: 1,
invalidSignatureCount: 0
}
});
const interoperability = assessBrazilianArtifactInteroperability({
expectedFormats: ["PAdES", "CAdES", "XAdES"],
samples: [padesSample]
});Example: Audit Trail
import { appendAuditEvent, verifyAuditTrail } from "ts-hanko";
const trail = appendAuditEvent([], {
type: "envelope.created",
documentHash: "sha256:...",
actor: { id: "sender-1", role: "sender" }
});
const signedTrail = appendAuditEvent(trail, {
type: "signature.completed",
documentHash: "sha256:...",
actor: { id: "signer-1", role: "signer" },
ipAddress: "203.0.113.10"
});
console.log(verifyAuditTrail(signedTrail).valid); // trueFor DOC-ICP-15 signature-generation and verification records, convert low-level verification output first:
import {
appendBrazilianSignatureAuditRecord,
cadesVerificationToBrazilianSignatureAuditRecord
} from "ts-hanko";
const record = cadesVerificationToBrazilianSignatureAuditRecord(verification, {
document: originalPayload,
signature: cadesSignature
});
const auditTrail = appendBrazilianSignatureAuditRecord([], record, {
actor: { id: "validator-1", role: "validator" }
});The same report input shape can be passed to the CLI when compliance evidence is assembled outside the signing process:
ts-hanko brazil-report compliance-input.json --report-fragment signer-trust.json --report-fragment mvp-report.jsonFor a complete compliance-facing validation result, use the orchestration helpers:
import { createBrazilianCadesValidationReport } from "ts-hanko";
const validation = await createBrazilianCadesValidationReport({
verification: cadesVerification,
document: originalPayload,
signatureBytes: cadesSignature,
useCase: "private_contract",
trust: {
trustedCertificates: [icpBrasilRootPem],
issuerCertificates: [intermediateCertificatePem],
checkDate: new Date()
},
signaturePolicy: {
expectedOid: "2.16.76.1.7.1.1.2.4"
},
audit: {
trail: existingAuditTrail,
actor: { id: "validator-1", role: "validator" }
},
auditTrailReport: { valid: true, signed: true },
externalValidation: { provider: "VALIDAR", status: "passed" },
integratorAssurance: { model: "integrator", doesNotCustodyUserPrivateKeys: true }
});
console.log(validation.signaturePolicy?.valid);
console.log(validation.signerTrust?.valid);
console.log(validation.report.overallStatus);Example: Simple/Advanced Envelope Evidence
import {
createElectronicSignatureEvidencePackage,
createMultiSignerElectronicSignatureEvidencePackage,
verifyElectronicSignatureEvidencePackage
} from "ts-hanko";
const evidencePackage = createElectronicSignatureEvidencePackage({
envelopeId: "env-123",
sender: { id: "sender-1", role: "sender" },
signer: {
id: "signer-1",
name: "Maria Silva",
email: "[email protected]",
cpf: "12345678909",
method: "email_otp"
},
documents: [{ id: "doc-1", name: "contract.pdf", version: "v1", data: contractPdf }],
notificationChannel: "email",
consentText: "I have read and agree to sign this document electronically.",
technical: {
ipAddress: "203.0.113.10",
userAgent: "Mozilla/5.0",
sessionId: "session-123",
deviceFingerprint: "device-abc"
}
});
console.log(evidencePackage.complianceEvidence.auditTrailHashChain); // true
console.log(evidencePackage.advancedEvidence.valid); // true when advanced evidence controls pass
console.log(evidencePackage.auditTrailMinimumEvidence.valid); // true when the section 5.4 minimum trail is complete
console.log(evidencePackage.auditTrailReport.cnj180?.valid); // true when registry-grade audit fields are present
console.log(verifyElectronicSignatureEvidencePackage(evidencePackage).valid); // true
console.log(assessEvidencePackageSigningCeremony(evidencePackage).valid); // trueFor ordered envelopes with more than one signer, use createMultiSignerElectronicSignatureEvidencePackage. It records the shared document evidence once, then appends per-signer signature.requested, notification, opening, consent, identity and completion events in signing order. Each signerResults entry includes that signer's compliance evidence, advanced-evidence assessment and minimum audit-trail assessment; declined signers are recorded with signature.declined instead of being treated as completed signatures.
By default every signer in a multi-signer envelope is required. Optional witnesses or observers can be declared with required: false; their decline is still recorded as signature.declined, but assessEvidencePackageSigningCeremony does not treat that decline as a failed required completion.
const multiSignerPackage = createMultiSignerElectronicSignatureEvidencePackage({
envelopeId: "env-456",
sender: { id: "sender-1", role: "sender" },
documents: [{ id: "doc-1", name: "contract.pdf", version: "v1", data: contractPdf }],
notificationChannel: "email",
signers: [
{
order: 1,
signer: { id: "signer-1", email: "