Signed Compliance Reports
Compliance edition
This feature ships with Tayra.Compliance and requires a Compliance edition license. See Licensing for the edition comparison.
Tayra signs every compliance report (Article 15 data subject access, Article 30 PII inventory, Article 33/34 breach notification) with an ECDSA P-256 detached signature. An auditor or regulator can verify the signature offline against the embedded public key to prove the report was generated by a specific Tayra deployment at the recorded moment and has not been tampered with since.
Report signing is opt-in within the Compliance edition - reports are returned unsigned by default. Register an ECDSA P-256 keypair as shown below to turn it on.
Why detached signatures
A regulator typically asks two questions when handed a compliance report:
- Did this come from your production system? - answered by the signature being valid against your published public key.
- Has it been edited since you generated it? - answered by the signature still verifying against the canonical bytes of the report.
A detached signature solves both without requiring a third-party timestamp authority. The public key bundled in the signature lets verification run offline; you keep the private key under your custody (HSM, Azure Key Vault, AWS KMS, or a plain file mounted into your deployment).
Wiring
services.AddTayra(opts => opts.LicenseKey = key)
.AddCompliance(opts => { /* ... */ });
services.AddTayraReportSigning(opts =>
opts.UseEcdsaP256(privateKeyPem, publicKeyPem));UseEcdsaP256 accepts the PEM formats produced by openssl ecparam or .NET's ECDsa.ExportPkcs8PrivateKeyPem() / ECDsa.ExportSubjectPublicKeyInfoPem().
After this call, the existing IDataSubjectAccessService, IBreachNotificationService, and IPiiInventoryService automatically return signed copies of their reports - no callsite changes required.
What gets signed
| Report | Type | Signed property |
|---|---|---|
DataSubjectAccessReport | Article 15 / 20 | Signature |
BreachNotificationReport | Article 33 / 34 | Signature |
PiiInventoryReport | Article 30 | Signature |
The ReportSignature value carries:
SignedAt- UTC moment the signature was producedAlgorithm- currently"ECDSA-P256-SHA256"PublicKey- Base64 SubjectPublicKeyInfo of the public keySignature- Base64 of the raw signature bytes
Canonicalization
The signed bytes are produced by stripping the existing signature (so the chain is idempotent) and serializing the report with deterministic System.Text.Json settings (camelCase, no indentation, UTF-8). Two reports with identical logical content therefore produce identical canonical bytes regardless of whether one of them was previously signed.
Verifying a report
A downstream service that ingests reports (audit pipeline, regulator portal, internal compliance review) can register only the verifier - no private key required:
services.AddTayraReportVerification();
// then resolve IReportVerifiervar verifier = sp.GetRequiredService<IReportVerifier>();
if (!verifier.Verify(report))
{
throw new SecurityException("Compliance report failed verification");
}Verification checks the algorithm identifier, parses the embedded public key, recomputes the canonical bytes from the report (with the signature stripped), and compares against the stored signature.
Key custody
Tayra never generates or stores the keypair on your behalf - that is intentional. Keep the private key in:
- a hardware security module (HSM)
- a managed KMS (Azure Key Vault, AWS KMS, GCP Cloud KMS)
- a sealed file mounted as a Kubernetes secret or read from environment
Rotate the keypair on the same cadence as your other production secrets. Reports signed with an older key remain verifiable as long as you publish the corresponding public key alongside.
Tamper detection
Any modification to a signed report - replacing a value, reordering a list, even editing whitespace - changes the canonical bytes and the signature stops verifying. The verifier returns false rather than throwing so callers can decide whether to log, alert, or reject.
See Also
- Compliance Reports - HTML / Markdown / JSON rendering of signed reports
- Audit Trail - the persistent, hash-chained audit trail (orthogonal to report signing - both ship in Compliance)
- Licensing - Compliance edition feature comparison
