Security & Audit
How keys are protected, what's logged, and what notifications signers receive.
Key storage
| Key material | Storage |
|---|---|
| CA private key | Encrypted in database (Fernet/AES via Frappe Password field) |
| Signer's keystore | Encrypted in database (Fernet/AES via Frappe Password field) |
| Signer's keystore password | Encrypted in database (Fernet/AES via Frappe Password field) |
No private key material is stored as files on disk. During the signing operation, keys are written to a temporary file, used, and deleted immediately. The Frappe encryption key (in site_config.json) is the master secret protecting everything; treat it like the root encryption secret of the site.
Audit trail — Signature Log
Every signing attempt (success or failure) is recorded in Signature Log with:
| Field | Detail |
|---|---|
| Document reference | DocType + name (e.g., Sales Order / SO-0042) |
| Signer | User + full name |
| Certificate serial | The X.509 serial used |
| Timestamp | When the signing occurred |
| IP address | Where the signing originated |
| Status | Success / Failed |
| SHA-256 hash | Of the signed PDF — detects post-signing file tampering |
| Error message | If failed |
The Signature Log is append-only — no edits, no deletes via the desk UI.
Email notifications
After every successful signing, the signer receives an email containing:
- Which document was signed (with link)
- When it was signed (UTC + signer's timezone)
- From which IP address
- Which certificate was used (serial)
The email includes a warning to contact the administrator immediately if the signing wasn't initiated by them. This is the primary tripwire if 2FA is bypassed or credentials are stolen.
2FA enforcement
2FA is the second factor that gates every signing. Without it, a stolen password would allow unlimited signings.
- Set per-DocType in Signable DocTypes → Require 2FA (recommended: always on)
- Enforced globally for signers via System Settings → Two Factor Authentication
- TOTP via authenticator app — no SMS option (SIM-swap risk)
CA private key — operational guidance
Your CA private key is the trust anchor. If compromised, an attacker could issue fake certificates that look like they came from you.
- The key is stored encrypted in the database (Frappe Password field)
- The Frappe encryption key (in
site_config.json) is the actual secret — back up separately, restrict file permissions - Rotate the CA every 5–10 years; plan a transition where both old and new CAs are trusted by verifiers
- For higher security, consider an air-gapped CA — generate certificates offline and import to the database
Auditing checklist
| Question | Where to look |
|---|---|
| Who signed document X? | Document form → "Signed by" field, or Signature Log |
| Did anyone fail to sign in the last 24 hours? | Signature Log → filter Status = Failed, Date = today |
| Are there expired certificates still on the system? | Signing Certificate List → filter Status = Expired |
| Has the CRL been published recently? | Signing Settings → CRL Last Generated timestamp |
| Has the CA private key been accessed recently? | Frappe Activity Log on Signing Settings DocType |
Backup considerations
- Database (encrypted at rest by your hosting provider) contains all key material
site_config.jsoncontains the Frappe encryption key — back up separately, restrict to fewest people- A backup without the encryption key is useless — you can't decrypt keystores
- Test your restore process annually
Related
- Verifying a Signature — integrity guarantees in detail
- Signers & Certificates — revocation flow