# Task: Sign a PDF with your cloud certificate

I want my application to do what Lacuna's "Sign a PDF with your cloud certificate" demo does: Sign a PDF with the cloud certificate your PSC keeps, reached through CloudHub, with PKI SDK on the server.

- Docs: https://docs.lacunasoftware.com/pt-br/articles/pki-sdk/cloud-certificates
- Live demo: https://try.lacunasoftware.com/en/pki-suite/sign-with-cloud-certificate
- This demo for AI agents: https://try.lacunasoftware.com/en/pki-suite/sign-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)
- 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 has been recorded for this demo yet, so none is shown here: this page doesn't guess calls. The docs and samples below show the calls; the live demo makes them.

## Patterns to copy

- Run the flow in this order: look the CPF up, which creates a signature session; send the user to their PSC's `AuthUrl`; take the `session` CloudHub adds to your redirect URI; then get the certificate and sign the hash in that session. The redirect URI must be under an origin registered for your API key, or CloudHub answers `UnauthorizedRedirectUri`.
- Only the hash goes to CloudHub: PKI SDK builds the signature around it with the same Start and Complete as a browser signing, and validates the certificate at Start so a refused one never reaches the PSC.
- Treat `session` as a bearer secret: keep it on the server, never log it, and strip it from the return page's address bar.
- The PSC decides when a session ends: match `SessionExpired` and `SessionInvalidOrAlreadyUsed` on the exception's `CodeStr`, then look the CPF up again. One session can sign several PDFs until then.
- `Lacuna.Cloudhub.Client` 1.0.0 builds its own `HttpClient` (keep one client, not one per call), takes no cancellation token, and puts the request URL, session included, in its exception messages, so never log them.

## 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.
