Security & Encryption
Understand the encryption boundary
PermitCore protects license storage, account access, and tenant boundaries in different ways. “Zero-knowledge” describes the default browser-created license workflow; it does not describe every operation the service performs.
| Workflow | What happens | Who can recover the key? |
|---|---|---|
| Admin-created license | Your browser generates and encrypts the key with your passphrase before submitting ciphertext and a lookup hash. | Someone with the passphrase or your configured recovery material. |
| Validation / activation | The app sends the plaintext license key over HTTPS in the POST body. The server hashes it for lookup without decrypting stored ciphertext. | This operation does not recover your passphrase or decrypt the stored key. |
| Store-issued license | The server generates the key for checkout delivery and stores protected delivery material using server-managed encryption. | The service can decrypt that material for authorized delivery or customer key reveal. |
| Optional passphrase escrow | You explicitly send your passphrase for encryption with a server-managed key. | The service can recover it. Enabling escrow changes the zero-knowledge boundary. |
Keep license keys, API keys, passphrases, and webhook secrets out of application logs and analytics. Using POST avoids URL/access-log exposure; it does not stop your own code or middleware from logging request bodies.
Protect your account
- Enable MFA in Settings → Security and save the backup codes separately from your authenticator.
- Give teammates custom roles containing only the menus and actions they need. See Account & team.
- Keep admin API keys on trusted servers, in a secret store. Never ship them inside a desktop app, browser bundle, mobile app, or public repository.
- Store your encryption passphrase in a password manager and configure recovery before distributing keys.
- Subscribe to
license.abuse_suspectedwebhooks and review unusual activation or login activity.
Feature availability depends on your plan. A hidden menu can also mean your custom role does not have access; ask a Company Admin to check both before troubleshooting an integration.
Browser-created licenses and passphrase recovery
- The browser creates a random key in the format
PERMIT-XXXX-XXXX-XXXX-XXXX. - PBKDF2-SHA256 derives a 256-bit encryption key from your passphrase and tenant salt, using 600,000 iterations.
- AES-256-GCM encrypts the license key with a random IV. The browser sends ciphertext, IV, and the SHA-256 lookup input.
- The server applies HMAC-SHA256 with a server-held secret before storing the lookup value.
- For validation, the server receives the customer-supplied plaintext key transiently, recomputes that lookup value, and checks the license restrictions.
A stolen database alone does not contain the passphrase needed to decrypt browser-created keys, or the server secret needed to check guesses against the HMAC lookup values. Protecting the browser, passphrase, and server secrets remains necessary.
Keep the original passphrase
The passphrase is needed to reveal or copy encrypted keys. Changing your account password does not change it. Losing it does not stop online validation of keys your customers already hold, but you may lose the ability to retrieve their plaintext from the admin panel.
Recovery key
Under Settings → Security → Passphrase Recovery, configure the browser-based recovery option and save the generated recovery key securely. Recovery requires the matching recovery material; simply resetting your login password cannot decrypt old license ciphertext.
Optional escrow
Escrow sends the passphrase to the service for server-managed encryption. Use it only if this recovery model fits your organization's requirements. It allows service-side recovery and therefore removes the zero-knowledge property for that passphrase.
Technical security reference
| Area | Implementation | Integration consequence |
|---|---|---|
| License ciphertext | AES-256-GCM; browser PBKDF2-SHA256 derivation | Retain the passphrase and recovery material. |
| License lookup | SHA-256 followed by server-keyed HMAC-SHA256 | Send the original key in an HTTPS POST body. |
| Passwords | Argon2id | Use unique passwords and MFA. |
| Access tokens | RS256 JWT signatures and rotating refresh tokens | Use the supported login/refresh flow; never embed a signing secret in clients. |
| Offline tokens | ECDSA P-256 / SHA-256 signatures | Verify with the trusted public key and enforce token expiry/binding. |
| Tenant isolation | Application authorization plus PostgreSQL row-level policies on protected tenant tables | Admin operations remain scoped to your tenant. Self-hosted installations must use the restricted app database role. |
| Webhook authenticity | HMAC-SHA256 over the raw body | Verify the signature and deduplicate event IDs. A signature alone does not prevent replay. |
Rate limits
Public endpoints have per-IP controls in addition to the tenant's plan allowance and per-license abuse checks. A higher plan allowance does not remove a per-IP restriction. Handle HTTP 429, honor Retry-After when present, and avoid synchronizing every customer's checks at the same moment. See error handling.
Operational security
Production uses HTTPS, security headers, dependency scanning, and encrypted database backups. For current infrastructure and data-residency information, see the security page. For data-processing terms and subprocessors, see the DPA and privacy policy.
Report a suspected vulnerability to [email protected]. Include affected URLs, reproduction steps, and impact; do not include real customer keys or unrelated personal data.
Backups and business continuity
Backups recover account data. Offline tokens and signing-key export address whether your software can keep verifying licenses without a live service. Plan for these separately.
Your own recovery package
- Keep account-data exports and license-key exports separately, along with the passphrase/recovery material needed to use encrypted keys. The account-data ZIP contains license metadata, not key material.
- Keep your product identifiers, integration configuration, and trusted signing public keys with your release records.
- Test the offline flow before a customer needs it; a machine without network access cannot fetch its first public key.
- For self-hosting, back up both the database and required deployment secrets, then test a restore in an isolated environment.
Available continuity options
| Option | What it provides | Limit |
|---|---|---|
| Offline activation (Professional+) | A signed token verified on the customer's machine. | Only works until that token expires and cannot learn about revocation while fully offline. |
| Signing-key export (Enterprise) | Your own copy of signing material for independent issuance. | Protect the private key; anyone holding it can issue tokens trusted by your software. |
| Self-hosting (Enterprise) | Your own deployment, database, and operational control. | You operate and recover the infrastructure. See the deployment guide. |
Rotation versus compromise
Rotate creates a new active signing key and keeps the previous key available as deprecated for verifying older tokens. Regenerate marks the prior key compromised and revokes tracked tokens. Online verification can apply that change immediately; a disconnected app with an old public key cannot discover it until it reconnects or its token expires. Preserve the relationship between a token's kid and its verification key.
These mechanisms do not make every existing online license permanently offline-capable. Issue and distribute the required tokens or deploy your continuity solution before relying on it.
Company single sign-on
Company SSO lets an existing team member sign in through a configured identity provider. It is separate from customer license validation and Store customer accounts.
- Open Company Settings → SSO and choose an available provider.
- Create the corresponding application in that provider's console.
- Copy the redirect URI shown in PermitCore exactly into the provider settings.
- Enter the client ID and secret, configure any required domain restrictions, and save.
- Create the teammate's PermitCore user record in your tenant before their first SSO sign-in.
- Test with a non-owner account before rolling it out to the team.
SSO does not automatically create a user in your tenant and does not disable password sign-in. An identity-provider-only policy cannot disable a separate PermitCore password login. Keep an administrator recovery path available.
Country and IP restrictions
Set Allowed Countries in a license's metadata using comma-separated ISO country codes such as US, DE, GB. An empty list means no country restriction. Both validate and activate check the configured restrictions.
The country is inferred from the request IP. A VPN or proxy can change the apparent country; this is not proof of residence or a complete compliance control. If a legitimate customer is blocked, check their exit IP and the license's allowed countries before changing the policy. IP allowlists provide a separate network restriction.