Credentials & secrets
Where CriticalPDF keeps SMTP passwords, OAuth tokens, license keys, and PDF encryption passwords — and how each is protected.
CriticalPDF deliberately splits its secrets across two places: most configuration goes in a per-user JSON file, but the sensitive credentials never touch that file — they go into the Windows Credential Manager.
The two stores
Per-user GUI config — config.json
Your desktop-app configuration lives in a per-user file:
C:\ProgramData\CriticalPDF\users\<username>\config.json
Each Windows account gets its own. It holds templates, email / SMTP settings (host, port, username — but not the password), the licence identity (licensee name, company, email, key) and the cached licence snapshot, savings-calculator costs, and UI preferences.
The file is written with an atomic temp-file-plus-rename, so a crash can’t leave it half-written, and the JSON keys are sorted deterministically so diffs stay clean.
Windows Credential Manager — the actual secrets
Three values are never written to config.json. They go into the Windows Credential Manager, DPAPI-encrypted and scoped to the Windows user:
| Secret | Used for |
|---|---|
smtpPass | Custom SMTP / Computer Team account password |
gmailToken | Gmail OAuth refresh token |
msaToken | Microsoft 365 OAuth refresh token |
When CriticalPDF loads config.json, it overlays these secret values from the Credential Manager at runtime. If you open config.json in a text editor, you will not find a password or token in it — if an older config ever had a plaintext secret, it’s migrated into the Credential Manager on first launch and scrubbed from the file.
What’s not in the Credential Manager
A couple of things people expect to be secrets live in config.json by design:
- Licence key and identity. The
licName/CompName/Email/Keyfields are inconfig.json. The cached verification result that lets you keep working offline is HMAC-signed (licSignature), so it can’t be hand-edited to forge or extend a licence. - PDF encryption passwords. Owner and user passwords for a template’s PDF encryption are part of that template’s definition, inside
config.json.
The service’s own secret
The background service has one secret of its own, in its machine-wide config:
C:\ProgramData\CriticalPDF\serviceconfig.json
EncryptionPassword is the key the service uses to seal dead-lettered captures on disk. It’s stored in serviceconfig.json as plain text:
"EncryptionPassword": "CHANGE-ME-use-a-strong-password",
The installer generates a random value. If you ever see the literal CHANGE-ME string, change it and restart the service.
Locking down the folder
config.json still contains the licence and any PDF encryption passwords, and serviceconfig.json contains the EncryptionPassword. On a machine with untrusted standard users — a shared workstation or an RDP / RDS host — review the permissions on C:\ProgramData\CriticalPDF\ and restrict read access:
# Inspect the current ACL
icacls C:\ProgramData\CriticalPDF
The DPAPI-protected Credential Manager entries are safe regardless — they’re tied to each Windows account and can’t be read by another user even with file access.
Diagnostic bundles redact secrets
Send diagnostics to support builds a zip with logs, an environment summary, and a copy of the configuration with known secret fields redacted. Review the staged bundle in Explorer before it sends — the Credential Manager entries are never included.
Revoking access
| Secret | How to revoke |
|---|---|
| Gmail OAuth | myaccount.google.com/permissions → remove CriticalPDF |
| Microsoft 365 OAuth | Your account’s privacy panel or your tenant admin’s app consent panel |
| Custom SMTP password | Rotate at the SMTP server, then update Settings → Email Settings |
| License key | Settings → Licensing → Release license to return the seat |
EncryptionPassword (service) | Edit serviceconfig.json, set a new value, restart the CriticalPDF Service. Existing dead-lettered captures sealed with the old password become unrecoverable — drain the dead-letter queue first if those captures matter. |
Was this page helpful? Let us know.