back to overview
For enterprise·9 min read

Zero-knowledge credential vaulting: how we protect applicant passports

The threat model for applicant data, per-user envelope encryption, audit logging, and how Opaige's identity vault maps to SOC 2, GDPR, and the due-diligence questionnaires your security team will send us.

The threat model you actually have to defend against

AES-256
Per-applicant encryption
GCM mode, unique data key per user
0
Opaige staff who can read credentials
Architectural guarantee, not a policy
90 days
Master key rotation cadence
Re-wrap without bulk decryption
100%
Decryption events audited
Append-only, HMAC-signed log lines

Before we talk about encryption, we have to be honest about what's being protected. Visa portal credentials are not social-media passwords — they unlock an identity that contains passport number, date of birth, travel history, sometimes biometrics, sometimes tax records, and a full picture of an applicant's movements for the next ten years. If an attacker compromises a credential store for a visa automation platform, the downstream risk is identity theft at passport-grade severity, not just a rebooked flight.

The specific threats we designed against:

  • Database exfiltration. A dump of our Postgres must not expose any applicant credential in plaintext, even if the attacker has the database-level encryption key.
  • Insider read. No Opaige engineer, operator, or support agent should be able to see an applicant's portal password, at any point, through any interface.
  • Worker compromise. If one Playwright worker is compromised, that incident must not grant access to credentials belonging to applicants it never processed.
  • Audit traceability. Every decryption event — even authorised — must produce a signed log line that a compliance team can read in sequence.

Envelope encryption, per-applicant

1
Applicant submits credentials over TLS 1.3
Portal password travels HTTPS-only from the applicant's browser to our API. Never logged, never cached in transit.
2
API generates a fresh data key (DK) for this applicant
AES-256-GCM key unique to this applicant. Used once — to encrypt the credential. Never reused across applicants.
3
Credential encrypted with DK → ciphertext + IV + GCM tag
The portal password becomes opaque ciphertext. The raw plaintext is immediately discarded from memory.
4
DK wrapped by KMS master key → encrypted data key (EDK)
The data key itself is encrypted by a KMS-managed master key. The master key never leaves the KMS boundary. Only ciphertext and EDK are stored in the database.
5
Database row: ciphertext + IV + tag + EDK + EDK key ID
A database dump exposes none of these fields in usable form. To decrypt, an attacker needs the KMS master key — which is not in the database.

A database dump contains none of those fields in usable form. To decrypt even one credential, an attacker would need access to the KMS master key, not just the database. Because each applicant has a unique data key, compromising one applicant's session cannot cascade to the rest.

Decryption happens only inside the worker

The architectural property that closes the insider-read threat
No web endpoint can decrypt a credential. No admin panel shows them. No operator console shows them. No log line contains them. The inability to look up a customer's VFS password is not a gap in our tooling — it is the property we are selling.

Plaintext credentials exist exactly three places, for exactly as long as they need to:

  • In the applicant's browser when they first submit them — HTTPS in transit, TLS 1.3.
  • In memory of a single Playwright worker process when it is logging into the portal on behalf of that applicant. The plaintext is zeroed the moment login completes.
  • In the actual portal's credential form where they are typed. Not our surface.

We cannot look up a customer's VFS password for them — and that is deliberate.

Audit logging without the nuisance factor

Every decryption event writes an append-only audit row with the data key ID, the reason (usually a worker run ID), a timestamp, and the IP and process that performed the decrypt. These rows are signed with a separate HMAC so a database-level attacker cannot edit history without leaving a trace.

For B2B customers in regulated industries — EORs, relocation platforms, immigration law firms — the audit trail ships as a queryable report via a dedicated endpoint. Your compliance team can diff yesterday's decrypts against their expected work and flag anomalies without waiting on an Opaige human to pull logs.

How this maps to compliance frameworks

Control / Article
Opaige implementation
SOC 2 — CC6 (Logical Access)
Per-user data keys; no plaintext storage
✓ Envelope encryption — each applicant isolated
SOC 2 — CC7 (System Ops)
Audit log for every decryption event
✓ Append-only, HMAC-signed, queryable by customer
GDPR Art. 32 (Encryption)
Encryption at rest + in transit
✓ AES-256-GCM at rest, TLS 1.3 in transit
GDPR Art. 28 (Processor DPA)
Standard DPA with sub-processor list
✓ DPA available; sub-processor list published
ISO 27001 A.10 (Cryptography)
KMS-managed master keys, 90-day rotation
✓ Re-wrap via KMS — no bulk decryption on rotate

We are happy to walk an enterprise security team through the implementation, share the specific KMS provider, and provide evidence bundles for an audit. Email security@opaige.com.