Security of the Authello System

Authello uses browser-side envelope encryption for organisation vault data. The implementation is based on the Web Crypto API, AES-GCM, PBKDF2-HMAC-SHA-256, and P-256 ECDH for invite key exchange.

Our security decisions are designed to give Authello strong, practical protection without making the product harder to use than it needs to be. We choose well-supported browser encryption modules, strong modern algorithms, fast enough loading, reliable recovery paths, and a user experience that teams can live with every day. Some steps, such as asking for your password before unlocking vault material, can feel annoying. We understand that. They are included because they protect the keys that protect your vault, and we try to keep that friction proportionate.

AES-256-GCM

Vault secrets and wrapped keys are encrypted with AES-GCM using 256-bit keys and 12-byte random IVs generated in the browser.

PBKDF2 unlock

Password-based unlock keys are derived with PBKDF2-HMAC-SHA-256, 600,000 iterations, and a 16-byte random salt, following OWASP guidance for PBKDF2-HMAC-SHA-256.

P-256 invites

User invite access uses ECDH on the P-256 curve to derive an AES-GCM wrapping key for sharing encrypted key material.

Why We Publish This

We publish this design because customers should be able to understand what Authello protects, what it does not protect, and where the trust boundaries sit. Security should not depend on secrecy of the design. We avoid publishing secrets or operational details that would help an attacker, but we are comfortable describing the algorithms, storage model, and important limitations.

Can Authello Read Vault Passwords?

In the intended design, Authello cannot read stored vault passwords or OTP seeds without the user's required key material. A database leak exposes encrypted blobs, IVs, salts, wrapped keys, and metadata, not plaintext vault secrets. SQL admin access sees encrypted blobs, not plaintext vault secrets. A normal backend compromise should still see encrypted blobs unless the attacker can also change the JavaScript delivered to users, capture keys while a vault is unlocked, or compromise a user's device or browser session.

OTP seeds are encrypted like vault passwords. They must be decryptable by authorised users so one-time passcodes can be generated, but they are stored as encrypted ciphertext rather than plaintext.

Envelope Encryption in Plain English

Envelope encryption means the data is locked inside one envelope, and the key to that envelope is locked inside another envelope. In Authello, vault records are encrypted with an organisation data key. That data key is then encrypted, or wrapped, so only authorised users with the right account password and key material can unlock it in their browser.

This makes team access easier to manage: Authello can store encrypted records and encrypted key material, while admins can grant or remove access by changing who receives usable encrypted key material.

Encrypted Vault Design

Each organisation has a data encryption key, or DEK. Shared passwords and OTP secrets are encrypted in the browser with that DEK before being sent to Authello. The server stores encrypted ciphertext, IVs, key metadata, relationship data, and limited record metadata, not plaintext vault secrets.

The organisation DEK is wrapped with a key encryption key, or KEK. Each authorised user has encrypted KEK material for the organisation. To unlock vault data, the browser derives a password-based key, decrypts the user's KEK, decrypts the organisation DEK, and then decrypts the allowed vault records.

What the Server Stores

Account login passwords are stored as bcrypt password hashes with cost factor 12. OWASP says bcrypt should use a work factor of 10 or more, so Authello's cost factor is above that minimum. Because bcrypt has a 72-byte input limit, account passwords are limited to 72 characters.

Vault passwords and OTP secrets are different: authorised users need to retrieve them later, so they are stored as encrypted ciphertext rather than one-way hashes.

At Authello, we keep key creation, wrapping, unlock, and reveal flows in the browser during normal use. We avoid plaintext key logging and design the server-side application flow so it does not need plaintext vault secrets.

Algorithms and Parameters

Authello's browser crypto uses the Web Crypto API. Vault records are encrypted with AES-GCM. Fresh DEKs and KEKs are generated as 32 random bytes, giving 256-bit symmetric keys. AES-GCM IVs are generated with crypto.getRandomValues as 12 random bytes.

User-password wrapping uses PBKDF2 with SHA-256, 600,000 iterations, a 16-byte random salt, and an AES-GCM 256-bit derived key. The OWASP Password Storage Cheat Sheet recommends 600,000 or more iterations for PBKDF2-HMAC-SHA-256 where PBKDF2 is used. These encrypted values are Base64-encoded before being submitted to the application.

Password Guessing and Brute Force

Encryption does not magically make weak passwords strong. A nation-state, criminal group, or well-funded attacker with GPU capacity can still attack weak user passwords if they obtain password hashes or encrypted key material. Authello reduces this risk with bcrypt cost factor 12 for account login passwords, PBKDF2-HMAC-SHA-256 with 600,000 iterations for vault unlock wrapping, password complexity rules, breach checks during password creation, and login throttling.

We record security activity for sensitive vault actions and use application logging to help detect abuse. As we expand security event logging, we will continue keeping plaintext vault passwords, OTP seeds, recovery phrases, DEKs, KEKs, and user account passwords out of logs.

Invites and Team Access

When an admin invites a user, Authello uses classical ECDH with the P-256 elliptic curve. The invite flow exchanges browser-generated ECDH public keys, derives an AES-GCM 256-bit shared wrapping key, and uses that key to encrypt key material for the invited user.

Group and organisation permissions are enforced separately from encryption using Laravel and Spatie role/permission checks. Encryption protects vault contents; permissions decide which authenticated users should be offered access to groups, records, and encrypted key material.

Access Control and IDOR

IDOR means insecure direct object reference. It is the bug class where a user changes an ID in a URL or request and gets another user's record. Encryption helps protect vault contents, but it does not replace authorisation checks. Authello must still verify the authenticated user belongs to the organisation and group before returning records, encrypted key material, or metadata.

At Authello, sensitive vault routes check group membership, group permissions, and record-to-group relationships server-side instead of trusting hidden fields, browser state, or client-side filtering. Automated access-control tests keep this boundary visible.

Metadata Design Choice

Authello does not encrypt every piece of metadata. The server needs some metadata to list groups, sort and search records, show ownership and sharing state, enforce permissions, and support admin workflows. This is a deliberate product and security trade-off: vault secrets and OTP seeds are encrypted, while limited operational metadata remains available to the application.

Metadata can still be sensitive. We aim to collect only the metadata needed for the product to work, avoid putting secrets into names or descriptions, and treat metadata access as part of the authorisation model.

Vault Reveal Controls

Vault records are blurred or hidden by default on screen to reduce visual recognition and casual shoulder-surfing risk. Passwords and OTPs must be intentionally revealed or copied by an authorised user after the browser vault is unlocked.

Unlocked KEK and DEK material is held by the browser vault helper, shown with a countdown in the authenticated interface, and cleared by manual lock or after 10 minutes of deliberate-user-input inactivity.

Browser and Script Protections

Authello sends a Content Security Policy header on application responses. Scripts are limited to approved sources and nonce-authorised inline scripts, objects are blocked, framing is restricted, form targets are limited, and unsafe-eval is not allowed.

CORS is useful for controlling which origins can read browser responses, but it is not the main protection against frontend tampering. For vault pages, the stronger controls are CSP, HTTPS, same-origin delivery, minimised and reviewed third-party script exposure, careful dependency review, and keeping plaintext keys and secrets out of logs.

Authello uses Laravel Blade escaping by default for output, CSRF tokens for state-changing forms and fetch requests, and server-side validation for incoming data. Database content is not trusted simply because it came from the database. Where JavaScript renders dynamic content, it should prefer text assignment over HTML insertion unless the HTML has been deliberately sanitised.

XSS (cross-site scripting) remains one of the most important risks for a browser-encrypted vault. A successful XSS on an unlocked vault page could read what the user can read. That is why CSP, escaping, input validation, output encoding, dependency review, minimising third-party JavaScript on vault pages, and automated tests for script-safety patterns matter.

Recovery Material

During organisation creation, Authello generates a 10-word recovery phrase. That phrase is used in the browser to wrap recovery key material. Authello does not store the plain recovery phrase, so losing it can prevent encrypted data recovery.

Important Limits

This is browser-side encryption, not a claim that every risk is removed. The normal server-side app flow should not need to decrypt vault secrets, but users still need to trust their browser, device, extensions, and the JavaScript delivered by Authello.

Risks that encryption alone cannot solve include keyloggers, malware, malicious browser extensions, phishing, shoulder surfing, unlocked unattended devices, XSS (cross-site scripting), compromised dependencies, insider misuse, weak account passwords, stolen MFA access, or a bad deployment that serves malicious JavaScript while the vault is unlocked.

Manual vault lock and idle timeout clear Authello's in-page vault state, sessionStorage vault state, and worker-held key material. Browser memory itself is ultimately controlled by the browser and operating system, so users should treat an unlocked browser session as sensitive until it is locked, logged out, or the browser is closed.

Authello's service worker caches static application assets such as build files, icons, and the web manifest. It is not intended to cache vault record responses or decrypted secrets.

Authello does not implement Kyber, ML-KEM, or another post-quantum key-establishment algorithm. The invite key exchange is P-256 ECDH.

Diffie-Hellman in Plain English

Diffie-Hellman key exchange lets two parties agree a shared secret over an untrusted network without sending that secret directly. Authello uses Elliptic Curve Diffie-Hellman (ECDH) on the P-256 curve for invite key exchange, then uses the derived secret as an AES-GCM wrapping key for encrypted key material.

In transport protocols, an ephemeral form often called ECDHE uses fresh throwaway Diffie-Hellman keys for each session. That supports forward secrecy: if one session key is later compromised, other sessions are not automatically exposed. Authello's invite flow uses fresh browser-generated key material for invites, but stored vault encryption is not the same thing as a Signal-style ratchet or a TLS session, so we do not describe vault storage as forward-secret.

Security Recommendations

Use strong unique account passwords, enable MFA, keep browsers and operating systems updated, limit browser extensions on devices used for vault access, remove users promptly when they leave, review group permissions regularly, and store recovery phrases offline in a secure place.

At Authello, we continue hardening our side of the model: strict content security policy, minimised third-party scripts on vault pages, dependency review, no plaintext secret logging, careful XSS prevention, clear key-version metadata, step-up authentication for sensitive actions, brute-force monitoring, audit logging, and routine access-control testing.

What Users Should Protect

Users and admins should protect account passwords, MFA methods, trusted devices, recovery phrases, browser sessions, and admin permissions. Encryption works best alongside careful access reviews, prompt offboarding, strong device security, and sensible group permissions.

Future Improvements

Authello is considering Argon2id for account password hashing where the hosting environment supports it. Argon2id is OWASP's preferred modern password hashing option, while bcrypt remains acceptable when configured with a suitable work factor. This is an evaluation item, not a committed migration.

Separately, Authello will continue watching post-quantum cryptography and weighing whether a stronger key-establishment solution is needed in future, including lattice-based standards such as ML-KEM, derived from Kyber. That work is separate from password hashing and depends on browser support, implementation maturity, and clear migration paths.

Some security engineers prefer X25519 for elliptic-curve Diffie-Hellman because it is simpler and has fewer implementation pitfalls. P-256 is not considered broken, is widely supported by the Web Crypto API, and currently works for Authello's browser invite flow. A move to X25519 would be worth evaluating if browser support and migration paths make it practical.

We will keep testing the operational details around logout and memory clearing: whether logout clears vault state, whether worker-held keys are cleared, whether frontend state objects are reset, whether IndexedDB or caches are storing anything sensitive, and whether service workers are involved in any vault-sensitive response caching.