Back to Blog
Features8 min read

Per-Tenant Encryption and BYOK: How Pentestas Handles Your Sensitive Findings

P

Pentestas Team

Security Analyst

4/21/2026
Per-Tenant Encryption and BYOK: How Pentestas Handles Your Sensitive Findings

2026-04-21 · Pentestas Features

Your findings include credentials, session cookies, and full HTTP traces. Here's exactly how Pentestas protects them at rest and in transit.

Master key Production env secret Tenant A Fernet key wrapped by master Tenant B Fernet key wrapped by master Tenant C Fernet key wrapped by customer KMS BYOK (Enterprise) Finding evidence • Request bodies • Response snippets • Payload strings • AI narrative • AI impact • Remediation hints All Fernet-encrypted

One master key. One Fernet key per tenant. BYOK swap on Enterprise. No cross-tenant decryption.

This post is the engineering-level answer to "how exactly do you handle our data" — the question every InfoSec team asks before they'll sign the MSA.

💰

In Detail

The data-sensitivity model

A Pentestas scan produces multiple data classes, each handled differently:

ClassSensitivityAt-rest protection
Target URLLowNot encrypted (needed for dashboard search)
Scan configMediumFernet-encrypted with tenant key (secrets stripped pre-persist)
Finding title / severity / CVSSLowNot encrypted (needed for dashboard filter)
Finding evidence (request + response)HighFernet-encrypted with tenant key
AI narrative / impact / remediationHighFernet-encrypted with tenant key
Payload usedHighFernet-encrypted with tenant key
Stored credentials (Azure SP secret, GWS SA key, target passwords)CriticalFernet-encrypted with tenant key — never returned in API responses
Anthropic API key (BYOK)CriticalFernet-encrypted with master key
⚙️

How It Works

How the key hierarchy works

Master key

  • Stored as the MASTER_ENCRYPTION_KEY env var in the production environment.
  • Rotated annually on the major-release schedule.
  • Never logged. Never returned from any API. Never written to disk outside the environment secret store.

Tenant Fernet keys

  • Generated on first use per tenant.
  • Stored in the tenants.encryption_key column — encrypted with the master key before DB persist.
  • Used to encrypt sensitive fields on every scan row before insert.
  • Decrypted in-process per-request; plaintext never leaves the worker's memory.

Per-field encryption

  • Implementation in app/encryption/fields.py.
  • Every sensitive finding column goes through encrypt_field(fernet, plaintext) on insertdecrypt_field(fernet, ciphertext) on read.
  • The Fernet format (AES-128-CBCHMAC-SHA256 in one token) protects against both tampering and passive snooping.

BYOK — bring your own key

Enterprise customers can supply their own KMS root:

  • **AWS KMS*— ARN-based reference to a customer CMK.
  • **Azure Key Vault*— vault URIaccess policy or RBAC role.
  • **GCP Cloud KMS*— resource pathSA binding.

With BYOK, the tenant's Fernet key is wrapped by your KMS, not Pentestas's master. Revoking your KMS grant immediately denies Pentestas's infrastructure access to your findings. Pentestas staff with DB access see only ciphertext.

Key rotation

When a tenant key rotates:

  1. New Fernet key generated (or minted via KMS for BYOK).
  2. Background task re-encrypts every row for that tenant.
  3. Old key retained for 7 days (defence against rotation mistakes).
  4. After 7 days, old key is zeroised.

Rotation can be triggered on-demand by an admin or on a schedule (Enterprise).

📈

In Detail

Cross-tenant isolation

Beyond encryption, tenant isolation is enforced at three layers:

Application layer

Every authenticated request sets tenant_id context from the JWT / API key. Every DB query filters WHERE tenant_id = :tid. No authenticated request ever sees another tenant's rows.

DB layer — PostgreSQL Row-Level Security

Every tenant-scoped table has RLS enabled + forced:

ALTER TABLE scans ENABLE ROW LEVEL SECURITY;
ALTER TABLE scans FORCE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON scans
  FOR ALL
  USING (tenant_id = current_tenant_id())
  WITH CHECK (tenant_id = current_tenant_id());

The application's DB user is subject to RLS. Even if the application has a SQL-injection bug, queries against the pentestas_app user see zero rows when the tenant context isn't set. Forced RLS means the policy applies to the table owner too, not just regular users — so a SUPERUSER bug wouldn't let you bypass it.

Backup layer

DB backups are per-tenant split — a backup of tenant A cannot be restored in a location with tenant B's encryption key, because the key material doesn't export cleanly across infrastructures. Full cross-region restore requires explicit BYOK key-wrapping re-negotiation.

📦

In Detail

In transit

  • **Public APIweb UI*— TLS 1.3 (TLS 1.2 accepted for legacy clients, disabled for Enterprise tenants on request). HSTS preload. OCSP stapling.
  • **Internal services (web ↔ DB, web ↔ Redis, worker ↔ anthropic)*— internal Docker network, not exposed externally. Anthropic traffic egresses on TLS 1.3.
  • **Agent ↔ platform*— WebSocket over TLS 1.2+. Strict cert pinning to *.pentestas.com — agents refuse connections that don't match.
⚠️

In Detail

Credential handling

Target credentials (paths to the system under test)

  • Stored in scan.config JSONB temporarily.
  • Passed to the Celery worker as part of the task message.
  • **Not persisted to the DB after the worker starts.*The config column is rewritten post-scan to remove target_username, target_password, cookies, custom_headers, and oauth_refresh fields.
  • Rescans must re-supply credentials (via RescanRequest body) because they're genuinely not saved.

Azure / GWS / cloud credentials

  • Stored encrypted per-tenant in tenants.azure_credentials_encsimilar columns.
  • Decrypted in-process per scan.
  • Never returned in API responses beyond "configured: yes / no"credential type.

Anthropic API keys (BYOK)

  • Stored encrypted with the master key (not the tenant key) in tenants.anthropic_api_key_enc.
  • Decrypted in-worker only during AI analysis.
  • Never logged, never returned.
📊

In Detail

Data retention

PlanScan + finding retentionBackup retention
Free365 days30 days
Pro3 years90 days
EnterpriseUnlimited (customer-configurable)7 years (customer-configurable)

Retention boundaries auto-purge expired scans. Purges cascade: delete scan → delete findings, reports, attack chains, agent dispatch records.

For regulated entities with specific retention obligations (PCI, HIPAA's 6-year recommendation, SEC 17a-4 for financial records, etc.), Enterprise retention is configurable per data class.

📝

Audit Trail

Audit logging

Every security-relevant action writes an audit row:

  • Loginfailed-login attempts (with IPUA).
  • Role change / user invitation / user removal.
  • API-key create / revoke.
  • Scan create / cancel / delete.
  • Agent create / disable / delete.
  • Settings changes (including credential updates).
  • CIS benchmark run, Azure scan dispatch, scheduled-scan modification.

Retention: 365 days on Pro, unlimited on Enterprise. Exportable via API or CSV. Ingest into your own SIEM on every scan completion via webhook.

📝

Compliance

Infrastructure compliance

  • **SOC 2 Type II*— ProEnterprise. Report available under NDA.
  • **ISO 27001*— certified; certificate on request.
  • **GDPR*— data-processor on your behalf; DPA template available.
  • **CCPA*— covered under the DPA.
  • **HIPAA*— BAA available on BusinessEnterprise.
  • **PCI DSS*— Level 4 merchant programme; not a Level 1 service provider but compatible with customer CDE programmes.
  • **FedRAMP / HIPAA High / DoD IL5*— not available; custom deployment on-prem or air-gapped is the supported path for those regimes.
🔥

In Detail

Responsible disclosure

Security issues in Pentestas itself: security@pentestas.com. PGP key at https://pentestas.com/.well-known/pgp-key.txt. We respond within 24 hours. Accepted reports are credited in our security hall of fame.

💰

In Detail

Incident response (ours)

If Pentestas suspects a tenant-affecting breach:

  1. Triage within 1 hour of detection.
  2. Notification to affected tenant admins within 4 hours if confirmed.
  3. Public disclosure within 7 days (with remediation status) unless law enforcement requests delay.
  4. Full post-mortem published within 30 days.

Tenant-admin email contact is enforced during onboarding. If you haven't verified a security contact, your first invoice will remind you to.

⚙️

In Detail

The tl;dr for procurement

  • Tenant isolation: applicationDB (RLS)backup. Three-layer.
  • Field-level encryption with per-tenant Fernet keys.
  • BYOK supported on Enterprise. Customer KMS revocation = immediate denial.
  • TLS 1.3 for all external; mutual auth for agent connections.
  • Target credentials never persisted post-scan start.
  • SOC 2 Type II, ISO 27001, BAA-compatible.

This is the level of detail your procurement team needs. The long-form in Encryption docs has the full specifics.

Evaluate Pentestas against your procurement checklist

Request SOC 2 report under NDA via hello@pentestas.com.

Start your AI pentest
📚

More Reading

Further reading

Alexander Sverdlov

Alexander Sverdlov

Founder of Pentestas. Author of 2 information security books, cybersecurity speaker at the largest cybersecurity conferences in Asia and a United Nations conference panelist. Former Microsoft security consulting team member, external cybersecurity consultant at the Emirates Nuclear Energy Corporation.