Responsible Disclosure
Security at VettID
If you've found a vulnerability, please tell us before you tell the world.
Please do not file public GitHub issues for security findings.
Public disclosure of a confidentiality, integrity, or attestation defect can compromise live users. Use the encrypted channel below.
How to report
Email us at the address below. Encrypt with the PGP key further down if your report contains exploit details, user identifiers, or anything you wouldn't want in a mailbox compromise.
Acknowledgement target: 72 hours. Triage + fix timeline depends on severity — see below.
What to include
- What you found — type of issue, affected component, version / git SHA if you have one.
- How you found it — steps to reproduce, proof-of-concept if available.
- What an attacker could do with it — your read on impact.
- Any thoughts on remediation (optional but appreciated).
Scope
In scope for disclosure:
- The vault enclave (vettid-vault: supervisor, per-vault processes, parent forwarder), its attestation chain, release sealing and the signed release manifest.
- The mobile app (Android, iOS; in development) — credential handling, pairing, session crypto, key storage, device attestation.
- The desktop app (Tauri; in development) — session establishment, capability gating, IPC.
- The agent connector (being rebuilt) — pairing flow, LEASH signing, message encryption.
- The account site and member API at
account.vettid.org, and the relay at relay.vettid.org (vettid-relay).
- The admin site and admin API (private; access is restricted to VettID's own network).
- The web surfaces at
vettid.org, including the vault release log.
Out of scope:
- Denial-of-service issues against unmoderated public endpoints.
- Findings that require physical access to an already-unlocked device.
- Social engineering of operators or other users.
- Issues in third-party dependencies that don't materially affect VettID's threat model — report those upstream first, then us if there's a VettID-specific configuration issue.
- Reports generated by automated scanners without a verified impact analysis.
Severity and response
- Critical (remote key extraction, attestation bypass, owner-data exposure): immediate triage, hotfix within days.
- High (privilege escalation, capability bypass, session key compromise vectors): triage in 72 hours, fix in days.
- Medium (incomplete isolation, sensitive metadata leakage, auth quality issues): triage in a week, fix in the next deploy cycle.
- Low (defense-in-depth gaps, hardening): triage on a best-effort basis.
We will keep you in the loop through triage, fix, and deploy. If you want public credit on a published advisory, say so in your report.
Vault releases
Every production vault release VettID runs will be listed in a signed manifest, and your vault only opens in the release you approved. No production release has been published yet. The vault release log will show each release's measurements, source, changes, security fixes, status and end date.
Safe harbor
We will not pursue legal action against researchers who:
- Make a good-faith effort to avoid privacy violations, service interruption, or data destruction during research.
- Give us a reasonable window to remediate before public disclosure.
- Don't access, modify, or destroy data belonging to other users.
- Don't run automated tooling that materially affects service availability.
If you're not sure whether something you want to try falls within these guidelines, email us first.
PGP key
The fingerprint and full ASCII-armored block are below. The same key is published to keys.openpgp.org for verification.
Copy the block below and import with gpg --import. The same key is also published to the Proton key directory (auto-fetched by gpg --auto-key-locate wkd security@vettid.org) for cross-verification.
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: ProtonMail
xjMEahS+BxYJKwYBBAHaRw8BAQdABGU4csmGUZsEkB11Y3anH1Hnn0YoQsPC
7J4F3VUKX2TNKVNlY3VyaXR5QHZldHRpZC5vcmcgPFNlY3VyaXR5QHZldHRp
ZC5vcmc+wsARBBMWCgCDBYJqFL4HAwsJBwkQFSOMA7QE2utFFAAAAAAAHAAg
c2FsdEBub3RhdGlvbnMub3BlbnBncGpzLm9yZ75OD21JsyGQ2ZExpa44dE+V
TKTQnElEsbCdVhKRI4ziAxUKCAQWAAIBAhkBApsDAh4BFiEE4jqD1ngoLNee
leX3FSOMA7QE2usAAJQ6AP9IdAUyA104D7TMmChgR6PyopWHjjnE5E7TA81P
fkrLPAEArrnwYBLo75n5wvUZijDFotiQYtcqhEtfd2dW+/VktwjCwB4EEBYI
AJAFgmoUvkMFgwDtTgAJENgGwa9ZeOjHNRQAAAAAABwAEHNhbHRAbm90YXRp
b25zLm9wZW5wZ3Bqcy5vcmcOkqeC8y8+0pMk2wm0RnKSLBxvcGVucGdwLWNh
QHByb3Rvbi5tZSA8b3BlbnBncC1jYUBwcm90b24ubWU+FiEECoZS/l1TOGBX
iZ/p2AbBr1l46McAAGDEAQCtUWPkQVWsQrBRRGGyBICUr+6tSW11TcyVoJh1
Ylyp8QD9EI5YT7Au2h0bcpkmWYFek4qVEiESqdtiDrHJObGqKgjOOARqFL4H
EgorBgEEAZdVAQUBAQdAGmt3mrBESbspOJCVKm0wyU4iwPdO7YDBfr8wc9zE
TjIDAQgHwr4EGBYKAHAFgmoUvgcJEBUjjAO0BNrrRRQAAAAAABwAIHNhbHRA
bm90YXRpb25zLm9wZW5wZ3Bqcy5vcmcjbF1qe03HyUX8l5gXCaW+qZmA6HWp
KyIuXBYJv9anCQKbDBYhBOI6g9Z4KCzXnpXl9xUjjAO0BNrrAABGcgD/Tm0K
dfUPJp1chfcTSDeC7O4JCyaDLFrTpBgfNxobpSgBALaLBd69bz7GrelAbCQa
4NmY7qOgnCF9OITO5oZgl98F
=9vw7
-----END PGP PUBLIC KEY BLOCK-----
Cryptography at a glance
The short version: VettID is built so that everything between your devices, your vault and your connections is encrypted end to end, with a post-quantum hybrid key exchange. This is the design as it is specified and implemented in the published code; it runs in testing, and no production release serves members yet. The details, from the vault messaging spec:
- Key exchange: hybrid post-quantum. Every end-to-end key agreement combines ML-KEM-768 with X25519 in HPKE (RFC 9180; the X-Wing construction,
MLKEM768X25519). An attacker has to break both, so traffic recorded today stays protected against a future quantum computer (“harvest now, decrypt later”). This covers messages, session handshakes, the Protean Credential and its one-time keys, and the keys for calls (calls are in development).
- Encryption: ChaCha20-Poly1305 for sealed messages, XChaCha20-Poly1305 for sessions and for your vault's stored state. Key derivation: HKDF-SHA-256.
- PIN and password: Argon2id. Your vault key also depends on a secret sealed to the enclave, so stolen vault data can't be brute-forced against PINs anywhere else.
- Signatures: Ed25519, not yet post-quantum. A future quantum computer could forge signatures from then on, but signatures can't be used to read recorded traffic. Hybrid Ed25519 + ML-DSA-65 is planned; every format carries a suite or version number, so the switch is an upgrade, not a redesign.
- Safety codes: new connections and paired devices compare a 6-digit code. Each side commits to its part before seeing the other's, so no one in the middle can steer the codes into matching (about one chance in a million per attempt).
- Sealing: each vault is sealed to one enclave release, through an AWS KMS key that decrypts only for an enclave attested as that release. The enclave checks the key's policy before sealing to it.
- Releases: the release manifest is signed (ECDSA P-256) by one of two keys pinned in every app and release image, one in AWS KMS and one on an offline hardware token. Builds are reproducible, and the release log will list each production release's measurements.
- Devices: enrollment and unlock require Android hardware key attestation, verified inside the enclave; the enclave also verifies iOS App Attest, for the iOS app, which is not released.
- Transport: TLS on every hop, under the end-to-end layer; the relay offers hybrid post-quantum TLS. The one classical exception: an account-recovery code is sealed to your browser with P-256 for its short (48-hour) life.
What we log
Honest disclosure of what the operator side can see.
Running today:
- Website: standard access logs and TLS fingerprints for traffic analysis; email addresses are never logged. The privacy notice has the detail.
- Account site (
account.vettid.org): your name, email, membership state, terms acceptance, subscription and sign-in events, kept in an audit log. What a request for early access records is in the privacy notice.
- Relay (
relay.vettid.org): mailbox identifiers, the keys that sign requests, timing and padded message sizes. Not who a mailbox belongs to, and not what is in a message.
Built, and not yet serving members. No production vault exists yet. This is what the vault service is built to record, and what it records in testing:
- Enclave host (AWS EC2, outside the enclave): it forwards encrypted bytes and never parses them. TLS to the relay ends inside the enclave, so the host sees byte counts and timing on a few connections shared by all vaults, when a vault is enrolled, unlocked or locked, and the size of its encrypted state. No payload content.
- Enclave (where your plaintext lives): its operational log records only service events — a vault id, when it was locked and why (for example idle or shutdown), and error classes. Never keys, PINs, tokens, signatures, plaintext, or what your vault did.
- Your vault’s audit log and activity feed: kept inside your vault, encrypted with the rest of its state, tamper-evident (hash-chained), and sent only to your own devices. VettID cannot read them, and your vault tells VettID nothing about its activity beyond content-free lifecycle events (enrolled, unlocked, locked, moved to a new release, deleted) and a content-free alert if a copy of your credential is presented by someone else.
- Member API (
account.vettid.org): which member enrolled, unlocked or locked a vault, and when, plus routing records (vault id, enclave instance, release). Never your PIN, why an unlock failed, your mailbox, or anything inside the vault.
- Vault storage (S3): your vault's state, encrypted under a key derived from your PIN, and a small header sealed to the release you approved. Opaque to the operator.
Because VettID runs both the enclave hosts and the relay, it could correlate their timing. We disclose that residual metadata rather than hide it.
What the operator will not be able to see: any decrypted payload, your vault contents, your PIN or credential password, your session keys, your credential values. That rests on the enclave's attestation and on AWS KMS and Nitro behaving as documented, not on our promise.