mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Finish preliminary backwards-compatible transition from user encryption scheme v1 to v2 with argon2 and protected key
This commit is contained in:
@@ -6,22 +6,50 @@ Infisical stores a range of data namely user, secrets, keys, organization, proje
|
||||
|
||||
## Users
|
||||
|
||||
The `User` model includes the fields `email`, `firstName`, `lastName`, `publicKey`, `encryptedPrivateKey`, `iv`, `tag`, `salt`, `verifier`, and `refreshVersion`.
|
||||
The `User` model includes the fields `email`, `firstName`, `lastName`, `publicKey`, `encryptionVersion`, `protectedKey`, `protectedKeyIV`, `protectedKeyTag`, `encryptedPrivateKey`, `iv`, `tag`, `salt`, `verifier`, and `refreshVersion`.
|
||||
|
||||
Infisical makes a usability-security tradeoff to give users convenient access to public-private key pairs across different devices upon login, solving key-storage and transfer challenges across device and browser mediums, in exchange for it storing `encryptedPrivateKey`. In any case, private keys are symmetrically encrypted locally by user passwords which are not sent to the server — this is done with SRP.
|
||||
Infisical makes a usability-security tradeoff that is to give users convenient access to public-private key pairs across different devices upon login, solving key-storage and transfer challenges across device and browser mediums, in exchange for it storing `encryptedPrivateKey`.
|
||||
|
||||
<Note>
|
||||
`encryptedPrivateKey` is obtained by symmetrically encrypting the user's
|
||||
private key locally with a protected key which is encrypted by the key derived
|
||||
from the user's password and salt. Encryption is done via `AES256-GCM` and key
|
||||
derivation via `argon2id`. The user's password is not sent to the server —
|
||||
this is done with SRP.
|
||||
</Note>
|
||||
|
||||
## Secrets
|
||||
|
||||
The `Secret` model includes the fields `workspace`, `type`, `user`, `environment`, `secretKeyCiphertext`, `secretKeyIV`, `secretKeyTag`, `secretKeyHash`, `secretValueCiphertext`, `secretValueIV`, `secretValueTag`, and `secretValueHash`.
|
||||
The `Secret` model includes the fields `workspace`, `type`, `user`, `environment`, `secretKeyCiphertext`, `secretKeyIV`, `secretKeyTag`, `secretValueCiphertext`, `secretValueIV`, and `secretValueTag`.
|
||||
|
||||
Each secret is symmetrically encrypted by the key of the project that it belongs to; that key's encrypted copies are stored in a separate `Key` collection.
|
||||
|
||||
## Keys
|
||||
## Project Keys
|
||||
|
||||
The `Key` model includes the fields `encryptedKey`, `nonce`, `sender`, `receiver`, and `workspace`.
|
||||
|
||||
Infisical stores copies of project keys, one for each member of a project, encrypted under each member's public key.
|
||||
|
||||
## Bots
|
||||
|
||||
The `Bot` model contains the fields `name`, `workspace`, `isActive`, `publicKey`, `encryptedPrivateKey`, `iv`, and `tag`.
|
||||
|
||||
Each project comes with a bot that has its own public-private key pair; its private key is encrypted by the server's symmetric key. If needed, a user can opt-in to share their project key with the bot (i.e. Infisical) to give the platform access to the project's secrets.
|
||||
|
||||
<Note>
|
||||
Sharing secrets with Infisical so they can be synced to integrations like
|
||||
Vercel, GitHub, and Netlify is something we make sure users consent to before
|
||||
opting in.
|
||||
</Note>
|
||||
|
||||
## Organizations and Workspaces
|
||||
|
||||
The `Organization`, `Workspace`, `MembershipOrg`, and `Membership` models contain enrollment information for organizations and projects; they are used to check if users are authorized to retrieve select secrets.
|
||||
|
||||
## Service Tokens
|
||||
|
||||
The `ServiceTokenData` model contains data for service tokens that enable users to fetch secrets from a particular project and environment; each service token data record includes an (encrypted) copy of the project key that it is bound to as well as a validation hash for `bcrypt`.
|
||||
|
||||
## API Keys
|
||||
|
||||
The `APIKeyData` model contains data for API keys that enable users to interact with [Infisical's Open API](https://infisical.com/docs/api-reference/overview/introduction); each API key data record includes a validation hash for `bcrypt`.
|
||||
|
||||
@@ -4,7 +4,11 @@ title: "Mechanics"
|
||||
|
||||
## Signup
|
||||
|
||||
During account signup, a user confirms their email address via OTP, generates a public-private key pair to be stored locally (private keys are symmetrically encrypted by the user's newly-made password), and forwards SRP-related values and user identifier information to the server. This includes `email`, `firstName`, `lastName`, `publicKey`, `encryptedPrivateKey`, `iv`, `tag`, `salt`, `verifier`, and `organizationName`.
|
||||
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 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 under a write-only class `SecurityClient` that appends the token 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.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user