Signup

During account signup, a user confirms their email address via OTP, generates a public-private key pair to be stored locally, generates a user salt, generates a 256-bit key, and enters their password.

The 256-bit key is used to encrypt the private key; the 256-bit key itself is then encrypted by a key generated from the user’s password and salt with key derivation function argon2id. The resulting, 256-bit key is known as the protected key.

The encrypted private key, protected key, user identifier information, and SRP details are forwarded to the server.

Once authenticated via SRP, a user is issued a JWT and refresh token. The JWT token is stored in browser memory and is appended to all future outbound requests requiring authentication. The refresh token is stored in an HttpOnly cookie and included in future requests to /api/token for JWT token renewal. This design side-steps potential XSS attacks on local storage.

Infisical authenticates users using the SRP protocol. With SRP, the server can authenticate users without ever seeing their passwords.

Invitation

After signing up, a user can invite other users to their organization to partake in projects — An invitation here consists of an email verification link sent to the invitee to confirm their identity if they’ve not previously signed up to Infisical. Both organization and project invites authorize invitees for resources but project invites differ in that they also involve sharing project keys by encrypting them under the invitees’ public keys.

Pushing/Pulling Secrets

To push secrets, a sender randomly-generates a symmetric encryption key, uses that key to encrypt their secret keys and values separately, asymmetrically encrypts the key with the receivers’ public keys, and uploads the encrypted secrets and keys to the server.

To pull secrets, a receiver obtains encrypted secret keys and values and their encrypted copy of the project key to decrypt the secrets from the server — they asymmetrically decrypt the key using their private key and use the decrypted key to decrypt the secrets. This public-key mechanism prevents the server-side from reading any secrets.

When dealing with individual secrets (e.g. pulling one secret by name) or creating new secrets, a user passes the name of the secret to the server which is then converted to a blind index by applying argon2id with the name of the secret and a 128-bit random salt unique to each project; the salt itself is encrypted by the server key and stored in the database.

Infisical ensures that the name of any secret is never stored in plaintext and instead only a blind index generated from the name. It is infeasible to reverse back a blind index to the name of a secret without knowledge of the server key.

Bot

To use some features like integrations, users must opt out of E2EE (this means sharing access to secrets with Infisical).

Infisical employs the concept of a bot which is a cryptographic abstraction for how Infisical interacts with secrets when users opt out of E2EE. In this model, each project is assigned a bot with its own public-private key pair where each bot’s private key is stored symmetrically encrypted under the server key. When a user opts out of E2EE, they share the project key with the bot by encrypting a copy of it under the public key of the bot.

When users wish to sync secrets from a project and environment Infisical to other platform integrations like Vercel or GitHub, Infisical decrypts the intended secrets and uses the integration platform’s APIs to send secrets over. It should be noted that opting out of E2EE is optional and it is entirely possible to use Infisical to manage secrets across your team and infrastructure without opting out of E2EE.