# Task: Firmar por lotes (Certificado en la nube, con CloudHub)

I want my application to do what Lacuna's "Firmar por lotes (Certificado en la nube, con CloudHub)" demo does: Firme varios PDF con una sola autorización del certificado en la nube que custodia su PSC, al que se accede mediante CloudHub, con PKI SDK en el servidor.

- Docs: https://docs.lacunasoftware.com/en-us/articles/cloudhub/pades-signature
- Live demo: https://try.lacunasoftware.com/es/pki-suite/sign-a-batch-with-cloud-certificate
- This demo for AI agents: https://try.lacunasoftware.com/es/pki-suite/sign-a-batch-with-cloud-certificate.md

## Samples

- .NET (aspnet-mvc): [Sign a PDF with a cloud certificate using CloudHub](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/dotnet/mvc/PkiSuiteAspNetMvcSample/Controllers/PadesCloudHubSdkController.cs)
- .NET (aspnet-mvc): [Sign a PDF with a cloud certificate (OAuth flow) using PKI SDK](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/dotnet/mvc/PkiSuiteAspNetMvcSample/Controllers/PadesCloudOauthSdkController.cs)
- .NET (aspnet-mvc): [Sign a PDF with a cloud certificate (password flow) using PKI SDK](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/dotnet/mvc/PkiSuiteAspNetMvcSample/Controllers/PadesCloudPwdSdkController.cs)
- Java (spring-boot): [Sign a PDF with a cloud certificate using CloudHub](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/java/springmvc/src/main/java/com/lacunasoftware/pkisuite/controller/PadesSignatureCloudhubRestController.java)
- Node.js (express): [Sign a PDF with a cloud certificate using CloudHub](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/nodejs/expressmvc/routes/pades-signature-cloudhub-restpki.js)
- PHP (php): [Sign a PDF with a cloud certificate using CloudHub](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/php/plain/public/pades-signature-cloudhub-rest/index.php)

## Call sequence

No call sequence is recorded for this demo, so none is shown here: this page doesn't guess calls. There is no CloudHub sandbox to record against, and authorizing the signatures at the PSC needs the certificate's holder. The docs and samples below show the calls; the live demo makes them.

## Patterns to copy

- Sign a batch in one Signature session: look the CPF up once, send the user to their PSC once, and sign every PDF in the session CloudHub hands back. CloudHub has no batch call, so each PDF goes through the same Start, CloudHub sign-hash and Complete as a single file, one PDF at a time, and only each PDF's hash leaves your server.
- Read the certificate once, in the session, before the first Start, and prepare every PDF with it; Start validates it, so a certificate that can't sign is refused before the PSC is asked to sign anything.
- The PSC decides when the session ends, 15 minutes by default: if it ends mid-batch (`SessionExpired` or `SessionInvalidOrAlreadyUsed` on the exception's `CodeStr`), fail the PDFs not signed yet with that code, keep the signed ones, and look the CPF up again for the rest. A PDF that fails for any other reason fails alone.
- Treat `session` as a bearer secret: keep it on the server, never log it, and strip it from the return page's address bar. Several pages can share one return page by naming themselves in the redirect URI, checked against an allow-list, so the return page's Start over leads back to the right one.
- Count the Batch against your per-IP limit for all its PDFs before the first Start, so it is never refused halfway.

## What to do

Implement this in my project with its existing stack, language, framework and conventions, following the call sequence and the patterns above, and adapting the samples rather than copying them whole. Ask me before adding any dependency or package. Keep API keys and private keys out of the browser and out of the repository.
