diff --git a/backend/src/routes/v3/secrets.ts b/backend/src/routes/v3/secrets.ts
index 1f3e239be..56573dd9f 100644
--- a/backend/src/routes/v3/secrets.ts
+++ b/backend/src/routes/v3/secrets.ts
@@ -23,7 +23,6 @@ import {
router.get(
"/raw",
query("workspaceId").exists().isString().trim(),
- query("workspaceId").exists().isString().trim(),
query("environment").exists().isString().trim(),
query("secretPath").default("/").isString().trim(),
validateRequest,
diff --git a/docs/api-reference/overview/authentication.mdx b/docs/api-reference/overview/authentication.mdx
index 8bad0114f..5fa4fbc30 100644
--- a/docs/api-reference/overview/authentication.mdx
+++ b/docs/api-reference/overview/authentication.mdx
@@ -3,32 +3,29 @@ title: "Authentication"
description: "How to authenticate with the Infisical Public API"
---
-## Essentials
+The Public API accepts multiple modes of authentication being via [Infisical Token](/documentation/platform/token) or API Key.
-The Public API accepts multiple modes of authentication being via API Key or [Infisical Token](/documentation/platform/token).
-
-- API Key: Provides full access to all endpoints representing the user without ability to encrypt/decrypt secrets in **E2EE** mode.
- [Infisical Token](/documentation/platform/token): Provides short-lived, scoped CRUD access to the secrets of a specific project and environment.
+- API Key: Provides full access to all endpoints representing the user without ability to encrypt/decrypt secrets for **E2EE** endpoints.
-
-
-The API key mode uses an API key to authenticate with the API.
+
+
+ The Infisical Token mode uses an Infisical Token to authenticate with the API.
-To authenticate requests with Infisical using the API Key, you must include an API key in the `X-API-KEY` header of HTTP requests made to the platform.
+ To authenticate requests with Infisical using the Infisical Token, you must include your Infisical Token in the `Authorization` header of HTTP requests made to the platform with the value `Bearer `.
-You can obtain an API key in User Settings > API Keys
+ You can obtain an Infisical Token in Project Settings > Service Tokens.
-
-
-
-
+ 
+
+
+ The API key mode uses an API key to authenticate with the API.
-The Infisical Token mode uses an Infisical Token to authenticate with the API.
+ To authenticate requests with Infisical using the API Key, you must include an API key in the `X-API-KEY` header of HTTP requests made to the platform.
-To authenticate requests with Infisical using the Infisical Token, you must include your Infisical Token in the `Authorization` header of HTTP requests made to the platform with the value `Bearer `.
+ You can obtain an API key in User Settings > API Keys
-You can obtain an Infisical Token in Project Settings > Service Tokens.
-
-
-
-
\ No newline at end of file
+ 
+ 
+
+
\ No newline at end of file
diff --git a/docs/api-reference/overview/encryption-modes/es-mode.mdx b/docs/api-reference/overview/encryption-modes/es-mode.mdx
deleted file mode 100644
index 2756980ac..000000000
--- a/docs/api-reference/overview/encryption-modes/es-mode.mdx
+++ /dev/null
@@ -1,92 +0,0 @@
----
-title: "ES Mode"
----
-
-Encrypted Standard (ES) mode is the easiest way to use Infisical's API. With it, you can make HTTP calls to Infisical
-to read/write secrets in plaintext.
-
-Prerequisites:
-
-- Set up and add envars to [Infisical Cloud](https://app.infisical.com).
-- Create an [Infisical Token](/documentation/platform/token) for your project and environment with write access enabled.
-- [Ensure that your project is blind-indexed](../blind-indices).
-
-Below, we showcase how to execute common CRUD operations to manage secrets in **ES** mode:
-
-
-
-
-
- ```bash
- curl --location --request GET 'http://localhost:8080/api/v3/secrets/raw?environment=dev&workspaceId=xxx' \
- --header 'Authorization: Bearer st.xxx'
-
- ```
-
-
-
-
-
-
- ```bash
- curl --location --request POST 'http://localhost:8080/api/v3/secrets/raw/SECRET_NAME' \
- --header 'Authorization: Bearer st.xxx' \
- --header 'Content-Type: application/json' \
- --data-raw '{
- "workspaceId": "xxx",
- "environment": "dev",
- "type": "shared",
- "secretValue": "SECRET_VALUE",
- "secretPath": "/"
- }'
- ```
-
-
-
-
-
-
- ```bash
- curl --location --request GET 'http://localhost:8080/api/v3/secrets/raw/SECRET_NAME?workspaceId=xxx&environment=dev&secretPath=/' \
- --header 'Authorization: Bearer st.xxx'
- ```
-
-
-
-
-
-
- ```bash
- curl --location --request PATCH 'http://localhost:8080/api/v3/secrets/raw/SECRET_NAME' \
- --header 'Authorization: Bearer st.xxx' \
- --header 'Content-Type: application/json' \
- --data-raw '{
- "workspaceId": "xxx",
- "environment": "dev",
- "type": "shared",
- "secretValue": "SECRET_VALUE",
- "secretPath": "/"
- }'
- ```
-
-
-
-
-
-
- ```bash
- curl --location --request DELETE 'http://localhost:8080/api/v3/secrets/raw/SECRET_NAME' \
- --header 'Authorization: Bearer st.xxx' \
- --header 'Content-Type: application/json' \
- --data-raw '{
- "workspaceId": "xxx",
- "environment": "dev",
- "type": "shared",
- "secretValue": "SECRET_VALUE",
- "secretPath": "/"
- }'
- ```
-
-
-
-
diff --git a/docs/api-reference/overview/encryption-modes/overview.mdx b/docs/api-reference/overview/encryption-modes/overview.mdx
deleted file mode 100644
index 84606d114..000000000
--- a/docs/api-reference/overview/encryption-modes/overview.mdx
+++ /dev/null
@@ -1,57 +0,0 @@
----
-title: "Preface"
----
-
-Each project in Infisical can be used either in **End-to-End Encrypted (E2EE)** mode or **Encrypted Standard (ES)** mode which dictates how it can be interacted with via the Infisical API.
-
-
-
- Secret operations without client-side encryption/decryption
-
-
- Secret operations with client-side encryption/decryption
-
-
-
-By default, all projects are initialized in **E2EE** mode which means the server is not able to decrypt any values because all secret encryption/decryption operations occur on the client-side. However, this has limitations around functionality and ease-of-use:
-
-- You cannot make HTTP calls to Infisical to read/write secrets in plaintext.
-- You cannot leverage non-E2EE features like native integrations and in-platform automations like dynamic secrets and secret rotation.
-
-For this reason, Infisical also provides the **ES** mode of operation to unlock the above limitations by enabling the server to decrypt your values. You can optionally switch a project to using **ES** mode
-in your Project Settings.
-
-
- Make no mistake, the limitations of **E2EE** mode do not prevent you from syncing secrets from Infisical to platforms like GitLab. They just imply
- that you have to do things the "E2EE-way" such as by embedding the Infisical CLI into your GitLab CI/CD pipelines to fetch and decrypt
- secrets on the client-side.
-
-
-## FAQ
-
-
-
- We recommend starting with **E2EE** mode and switching to **ES** mode when:
-
- - Your team needs more power out of non-E2EE features available in **ES** mode such as secret rotation, dynamic secrets, etc.
- - Your team wants an easier way to read/write secrets with Infisical.
-
-
-
- By default, all projects in Infisical are initialized to **E2EE** mode and can be switched to **ES** mode in the Project Settings by disabling end-to-end encryption.
-
-
- **ES** mode is secure and in fact what most vendors in the secret management industry are doing at the moment. In this mode, secrets are encrypted at rest by
- a series of keys, secured ultimately by a top-level `ROOT_ENCRYPTION_KEY` located on the server.
-
- If you're concerned about Infisical Cloud's ability to read your secrets if using **ES** mode in Infisical Cloud, then you may wish to
- use Infisical Cloud in **E2EE** mode or self-host Infisical on your own infrastructure and then use **ES** mode; this of course which means setting up firewalls and securing the instance yourself.
-
- As an organization, we prohibit reading any customer secrets without explicit permission; access to the `ROOT_ENCRYPTION_KEY` is restricted to one individual in the organization.
-
-
\ No newline at end of file
diff --git a/docs/api-reference/overview/examples/create-secret.mdx b/docs/api-reference/overview/examples/create-secret.mdx
deleted file mode 100644
index 4ea787ff0..000000000
--- a/docs/api-reference/overview/examples/create-secret.mdx
+++ /dev/null
@@ -1,233 +0,0 @@
----
-title: "Create secret"
-description: "How to add a secret using an Infisical Token scoped to a project and environment"
----
-
-Prerequisites:
-
-- Set up and add envars to [Infisical Cloud](https://app.infisical.com).
-- Create an [Infisical Token](/documentation/platform/token) for your project and environment with write access enabled.
-- Grasp a basic understanding of the system and its underlying cryptography [here](/api-reference/overview/introduction).
-- [Ensure that your project is blind-indexed](../blind-indices).
-
-## Flow
-
-1. [Get your Infisical Token data](/api-reference/endpoints/service-tokens/get) including a (encrypted) project key.
-2. Decrypt the (encrypted) project key with the key from your Infisical Token.
-3. Encrypt your secret with the project key
-4. [Send (encrypted) secret to Infisical](/api-reference/endpoints/secrets/create)
-
-## Example
-
-
-
-```js
-const crypto = require('crypto');
-const axios = require('axios');
-const nacl = require('tweetnacl');
-
-const BASE_URL = 'https://app.infisical.com';
-const ALGORITHM = 'aes-256-gcm';
-const BLOCK_SIZE_BYTES = 16;
-
-const encrypt = ({ text, secret }) => {
- const iv = crypto.randomBytes(BLOCK_SIZE_BYTES);
- const cipher = crypto.createCipheriv(ALGORITHM, secret, iv);
-
- let ciphertext = cipher.update(text, 'utf8', 'base64');
- ciphertext += cipher.final('base64');
- return {
- ciphertext,
- iv: iv.toString('base64'),
- tag: cipher.getAuthTag().toString('base64')
- };
-}
-
-const decrypt = ({ ciphertext, iv, tag, secret}) => {
- const decipher = crypto.createDecipheriv(
- ALGORITHM,
- secret,
- Buffer.from(iv, 'base64')
- );
- decipher.setAuthTag(Buffer.from(tag, 'base64'));
-
- let cleartext = decipher.update(ciphertext, 'base64', 'utf8');
- cleartext += decipher.final('utf8');
-
- return cleartext;
-}
-
-const createSecrets = async () => {
- const serviceToken = '';
- const serviceTokenSecret = serviceToken.substring(serviceToken.lastIndexOf('.') + 1);
-
- const secretType = 'shared'; // 'shared' or 'personal'
- const secretKey = 'some_key';
- const secretValue = 'some_value';
- const secretComment = 'some_comment';
-
- // 1. Get your Infisical Token data
- const { data: serviceTokenData } = await axios.get(
- `${BASE_URL}/api/v2/service-token`,
- {
- headers: {
- Authorization: `Bearer ${serviceToken}`
- }
- }
- );
-
- // 2. Decrypt the (encrypted) project key with the key from your Infisical Token
- const projectKey = decrypt({
- ciphertext: serviceTokenData.encryptedKey,
- iv: serviceTokenData.iv,
- tag: serviceTokenData.tag,
- secret: serviceTokenSecret
- });
-
- // 3. Encrypt your secret with the project key
- const {
- ciphertext: secretKeyCiphertext,
- iv: secretKeyIV,
- tag: secretKeyTag
- } = encrypt({
- text: secretKey,
- secret: projectKey
- });
-
- const {
- ciphertext: secretValueCiphertext,
- iv: secretValueIV,
- tag: secretValueTag
- } = encrypt({
- text: secretValue,
- secret: projectKey
- });
-
- const {
- ciphertext: secretCommentCiphertext,
- iv: secretCommentIV,
- tag: secretCommentTag
- } = encrypt({
- text: secretComment,
- secret: projectKey
- });
-
- // 4. Send (encrypted) secret to Infisical
- await axios.post(
- `${BASE_URL}/api/v3/secrets/${secretKey}`,
- {
- workspaceId: serviceTokenData.workspace,
- environment: serviceTokenData.environment,
- type: secretType,
- secretKeyCiphertext,
- secretKeyIV,
- secretKeyTag,
- secretValueCiphertext,
- secretValueIV,
- secretValueTag,
- secretCommentCiphertext,
- secretCommentIV,
- secretCommentTag
- },
- {
- headers: {
- Authorization: `Bearer ${serviceToken}`
- }
- }
- );
-}
-
-createSecrets();
-```
-
-
-
-```Python
-import base64
-import requests
-from Cryptodome.Cipher import AES
-from Cryptodome.Random import get_random_bytes
-
-
-BASE_URL = "https://app.infisical.com"
-BLOCK_SIZE_BYTES = 16
-
-
-def encrypt(text, secret):
- iv = get_random_bytes(BLOCK_SIZE_BYTES)
- secret = bytes(secret, "utf-8")
- cipher = AES.new(secret, AES.MODE_GCM, iv)
- ciphertext, tag = cipher.encrypt_and_digest(text.encode("utf-8"))
- return {
- "ciphertext": base64.standard_b64encode(ciphertext).decode("utf-8"),
- "tag": base64.standard_b64encode(tag).decode("utf-8"),
- "iv": base64.standard_b64encode(iv).decode("utf-8"),
- }
-
-
-def decrypt(ciphertext, iv, tag, secret):
- secret = bytes(secret, "utf-8")
- iv = base64.standard_b64decode(iv)
- tag = base64.standard_b64decode(tag)
- ciphertext = base64.standard_b64decode(ciphertext)
-
- cipher = AES.new(secret, AES.MODE_GCM, iv)
- cipher.update(tag)
- cleartext = cipher.decrypt(ciphertext).decode("utf-8")
- return cleartext
-
-
-def create_secrets():
- service_token = "your_service_token"
- service_token_secret = service_token[service_token.rindex(".") + 1 :]
-
- secret_type = "shared" # "shared or "personal"
- secret_key = "some_key"
- secret_value = "some_value"
- secret_comment = "some_comment"
-
- # 1. Get your Infisical Token data
- service_token_data = requests.get(
- f"{BASE_URL}/api/v2/service-token",
- headers={"Authorization": f"Bearer {service_token}"},
- ).json()
-
- # 2. Decrypt the (encrypted) project key with the key from your Infisical Token
- project_key = decrypt(
- ciphertext=service_token_data["encryptedKey"],
- iv=service_token_data["iv"],
- tag=service_token_data["tag"],
- secret=service_token_secret,
- )
-
- # 3. Encrypt your secret with the project key
- encrypted_key_data = encrypt(text=secret_key, secret=project_key)
- encrypted_value_data = encrypt(text=secret_value, secret=project_key)
- encrypted_comment_data = encrypt(text=secret_comment, secret=project_key)
-
- # 4. Send (encrypted) secret to Infisical
- requests.post(
- f"{BASE_URL}/api/v3/secrets/{secret_key}",
- json={
- "workspaceId": service_token_data["workspace"],
- "environment": service_token_data["environment"],
- "type": secret_type,
- "secretKeyCiphertext": encrypted_key_data["ciphertext"],
- "secretKeyIV": encrypted_key_data["iv"],
- "secretKeyTag": encrypted_key_data["tag"],
- "secretValueCiphertext": encrypted_value_data["ciphertext"],
- "secretValueIV": encrypted_value_data["iv"],
- "secretValueTag": encrypted_value_data["tag"],
- "secretCommentCiphertext": encrypted_comment_data["ciphertext"],
- "secretCommentIV": encrypted_comment_data["iv"],
- "secretCommentTag": encrypted_comment_data["tag"]
- },
- headers={"Authorization": f"Bearer {service_token}"},
- )
-
-
-create_secrets()
-
-```
-
-
\ No newline at end of file
diff --git a/docs/api-reference/overview/examples/delete-secret.mdx b/docs/api-reference/overview/examples/delete-secret.mdx
deleted file mode 100644
index ff2ec687c..000000000
--- a/docs/api-reference/overview/examples/delete-secret.mdx
+++ /dev/null
@@ -1,94 +0,0 @@
----
-title: "Delete secret"
-description: "How to delete a secret using an Infisical Token scoped to a project and environment"
----
-
-Prerequisites:
-
-- Set up and add envars to [Infisical Cloud](https://app.infisical.com).
-- Create either an [API Key](/api-reference/overview/authentication) or [Infisical Token](/documentation/platform/token) for your project and environment with write access enabled.
-- Grasp a basic understanding of the system and its underlying cryptography [here](/api-reference/overview/introduction).
-- [Ensure that your project is blind-indexed](../blind-indices).
-
-## Example
-
-
-
-```js
-const axios = require('axios');
-const BASE_URL = 'https://app.infisical.com';
-
-const deleteSecrets = async () => {
- const serviceToken = 'your_service_token';
- const secretType = 'shared' // 'shared' or 'personal'
- const secretKey = 'some_key'
-
- // 1. Get your Infisical Token data
- const { data: serviceTokenData } = await axios.get(
- `${BASE_URL}/api/v2/service-token`,
- {
- headers: {
- Authorization: `Bearer ${serviceToken}`
- }
- }
- );
-
- // 2. Delete secret from Infisical
- await axios.delete(
- `${BASE_URL}/api/v3/secrets/${secretKey}`,
- {
- workspaceId: serviceTokenData.workspace,
- environment: serviceTokenData.environment,
- type: secretType
- },
- {
- headers: {
- Authorization: `Bearer ${serviceToken}`
- },
- }
- );
-};
-
-deleteSecrets();
-```
-
-
-
-```Python
-import requests
-
-BASE_URL = "https://app.infisical.com"
-
-
-def delete_secrets():
- service_token = ""
- secret_type = "shared" # "shared" or "personal"
- secret_key = "some_key"
-
- # 1. Get your Infisical Token data
- service_token_data = requests.get(
- f"{BASE_URL}/api/v2/service-token",
- headers={"Authorization": f"Bearer {service_token}"},
- ).json()
-
- # 2. Delete secret from Infisical
- requests.delete(
- f"{BASE_URL}/api/v2/secrets/{secret_key}",
- json={
- "workspaceId": service_token_data["workspace"],
- "environment": service_token_data["environment"],
- "type": secret_type
- },
- headers={"Authorization": f"Bearer {service_token}"},
- )
-
-
-delete_secrets()
-
-```
-
-
-
- If using an `API_KEY` to authenticate with the Infisical API, then you should include it in the `X_API_KEY` header.
-
-
diff --git a/docs/api-reference/overview/examples/e2ee-disabled.mdx b/docs/api-reference/overview/examples/e2ee-disabled.mdx
new file mode 100644
index 000000000..9864a1ff5
--- /dev/null
+++ b/docs/api-reference/overview/examples/e2ee-disabled.mdx
@@ -0,0 +1,176 @@
+---
+title: "E2EE Disabled"
+---
+
+Using Infisical's API to read/write secrets with E2EE disabled allows you to create, update, and retrieve secrets
+in plaintext. Effectively, this means each such secret operation only requires 1 HTTP call.
+
+
+
+ Retrieve all secrets for an Infisical project and environment.
+
+
+
+ ```bash
+ curl --location --request GET 'https://app.infisical.com/api/v3/secrets/raw?environment=environment&workspaceId=workspaceId' \
+ --header 'Authorization: Bearer serviceToken'
+
+ ```
+
+
+
+
+ The ID of the workspace
+
+
+ The environment slug
+
+
+ Path to secrets in workspace
+
+
+
+ Create a secret in Infisical.
+
+
+
+ ```bash
+ curl --location --request POST 'https://app.infisical.com/api/v3/secrets/raw/secretName' \
+ --header 'Authorization: Bearer serviceToken' \
+ --header 'Content-Type: application/json' \
+ --data-raw '{
+ "workspaceId": "workspaceId",
+ "environment": "environment",
+ "type": "shared",
+ "secretValue": "secretValue",
+ "secretPath": "/"
+ }'
+ ```
+
+
+
+
+ Name of secret to create
+
+
+ The ID of the workspace
+
+
+ The environment slug
+
+
+ Value of secret
+
+
+ Comment of secret
+
+
+ Path to secret in workspace
+
+
+ The type of the secret. Valid options are “shared” or “personal”
+
+
+
+ Retrieve a secret from Infisical.
+
+
+
+ ```bash
+ curl --location --request GET 'https://app.infisical.com/api/v3/secrets/raw/secretName?workspaceId=workspaceId&environment=environment' \
+ --header 'Authorization: Bearer serviceToken'
+ ```
+
+
+
+
+ Name of secret to retrieve
+
+
+ The ID of the workspace
+
+
+ The environment slug
+
+
+ Path to secrets in workspace
+
+
+ The type of the secret. Valid options are “shared” or “personal”
+
+
+
+ Update an existing secret in Infisical.
+
+
+
+ ```bash
+ curl --location --request PATCH 'https://app.infisical.com/api/v3/secrets/raw/secretName' \
+ --header 'Authorization: Bearer serviceToken' \
+ --header 'Content-Type: application/json' \
+ --data-raw '{
+ "workspaceId": "workspaceId",
+ "environment": "environment",
+ "type": "shared",
+ "secretValue": "secretValue",
+ "secretPath": "/"
+ }'
+ ```
+
+
+
+
+ Name of secret to update
+
+
+ The ID of the workspace
+
+
+ The environment slug
+
+
+ Value of secret
+
+
+ Path to secret in workspace.
+
+
+ The type of the secret. Valid options are “shared” or “personal”
+
+
+
+ Delete a secret in Infisical.
+
+
+
+ ```bash
+ curl --location --request DELETE 'https://app.infisical.com/api/v3/secrets/raw/secretName' \
+ --header 'Authorization: Bearer serviceToken' \
+ --header 'Content-Type: application/json' \
+ --data-raw '{
+ "workspaceId": "workspaceId",
+ "environment": "environment",
+ "type": "shared",
+ "secretPath": "/"
+ }'
+ ```
+
+
+
+
+ Name of secret to update
+
+
+ The ID of the workspace
+
+
+ The environment slug
+
+
+ Path to secret in workspace.
+
+
+ The type of the secret. Valid options are “shared” or “personal”
+
+
+
\ No newline at end of file
diff --git a/docs/api-reference/overview/encryption-modes/e2ee-mode.mdx b/docs/api-reference/overview/examples/e2ee-enabled.mdx
similarity index 97%
rename from docs/api-reference/overview/encryption-modes/e2ee-mode.mdx
rename to docs/api-reference/overview/examples/e2ee-enabled.mdx
index b24ec9fb7..0cbeaabcf 100644
--- a/docs/api-reference/overview/encryption-modes/e2ee-mode.mdx
+++ b/docs/api-reference/overview/examples/e2ee-enabled.mdx
@@ -1,23 +1,16 @@
---
-title: "E2EE Mode"
+title: "E2EE Enabled"
---
-End-to-End Encrypted (E2EE) mode is the default way to use Infisical's API. With it, you must perform client-side encryption/decryption
-when reading/writing secrets via HTTP call to Infisical.
-
-Prerequisites:
-
-- Set up and add envars to [Infisical Cloud](https://app.infisical.com).
-- Create an [Infisical Token](/documentation/platform/token) for your project and environment with write access enabled.
-- Grasp a basic understanding of the system and its underlying cryptography [here](/api-reference/overview/introduction).
-- [Ensure that your project is blind-indexed](../blind-indices).
-
-Below, we showcase how to execute common CRUD operations to manage secrets in **E2EE** mode:
+Using Infisical's API to read/write secrets with E2EE enabled allows you to create, update, and retrieve secrets
+but requires you to perform client-side encryption/decryption operations. For this reason, we recommend using one of the available
+SDKs instead.
+ Retrieve all secrets for an Infisical project and environment.
```js
const crypto = require('crypto');
const axios = require('axios');
@@ -194,6 +187,7 @@ get_secrets()
+Create a secret in Infisical.
```js
const crypto = require('crypto');
const axios = require('axios');
@@ -408,6 +402,7 @@ create_secrets()
+ Retrieve a secret from Infisical.
```js
const crypto = require('crypto');
const axios = require('axios');
@@ -569,6 +564,7 @@ get_secret()
+Update an existing secret in Infisical.
```js
const crypto = require('crypto');
const axios = require('axios');
@@ -779,6 +775,7 @@ update_secret()
+ Delete a secret in Infisical.
```js
const axios = require('axios');
const BASE_URL = 'https://app.infisical.com';
diff --git a/docs/api-reference/overview/examples/note.mdx b/docs/api-reference/overview/examples/note.mdx
new file mode 100644
index 000000000..8491dfaae
--- /dev/null
+++ b/docs/api-reference/overview/examples/note.mdx
@@ -0,0 +1,54 @@
+---
+title: "Note on E2EE"
+---
+
+Each project in Infisical can have **End-to-End Encryption (E2EE)** enabled or disabled.
+
+By default, all projects have **E2EE** enabled which means the server is not able to decrypt any values because all secret encryption/decryption operations occur on the client-side; this can be (optionally) disabled. However, this has limitations around functionality and ease-of-use:
+
+- You cannot make HTTP calls to Infisical to read/write secrets in plaintext.
+- You cannot leverage non-E2EE features like native integrations and in-platform automations like dynamic secrets and secret rotation.
+
+
+
+ Example read/write secrets without client-side encryption/decryption
+
+
+ Example read/write secrets with client-side encryption/decryption
+
+
+
+## FAQ
+
+
+
+ We recommend starting with having **E2EE** enabled and disabling it if:
+
+ - You're self-hosting Infisical, so having your instance of Infisical be able to read your secrets isn't an issue.
+ - You want an easier way to read/write secrets with Infisical.
+ - You need more power out of non-E2EE features such as secret rotation, dynamic secrets, etc.
+
+
+
+ You can enable/disable E2EE for your project in Infisical in the Project Settings.
+
+
+ It is secure and in fact how most vendors in our industry are able to offer features like secret rotation. In this mode, secrets are encrypted at rest by
+ a series of keys, secured ultimately by a top-level `ROOT_ENCRYPTION_KEY` located on the server.
+
+ If you're concerned about Infisical Cloud's ability to read your secrets, then you may wish to
+ use it with **E2EE** enabled or self-host Infisical on your own infrastructure and disable E2EE there.
+
+ As an organization, we do not read any customer secrets without explicit permission; access to the `ROOT_ENCRYPTION_KEY` is restricted to one individual in the organization.
+
+
\ No newline at end of file
diff --git a/docs/api-reference/overview/examples/retrieve-secret.mdx b/docs/api-reference/overview/examples/retrieve-secret.mdx
deleted file mode 100644
index a65876253..000000000
--- a/docs/api-reference/overview/examples/retrieve-secret.mdx
+++ /dev/null
@@ -1,180 +0,0 @@
----
-title: "Retrieve secret"
-description: "How to get a secret using an Infisical Token scoped to a project and environment"
----
-
-Prerequisites:
-
-- Set up and add envars to [Infisical Cloud](https://app.infisical.com).
-- Create an [Infisical Token](/documentation/platform/token) for your project and environment.
-- Grasp a basic understanding of the system and its underlying cryptography [here](/api-reference/overview/introduction).
-- [Ensure that your project is blind-indexed](../blind-indices).
-
-## Flow
-
-1. [Get your Infisical Token data](/api-reference/endpoints/service-tokens/get) including a (encrypted) project key.
-2. [Get the secret from your project and environment](/api-reference/endpoints/secrets/read-one).
-3. Decrypt the (encrypted) project key with the key from your Infisical Token.
-4. Decrypt the (encrypted) secret
-
-## Example
-
-
-
-```js
-const crypto = require('crypto');
-const axios = require('axios');
-
-const BASE_URL = 'https://app.infisical.com';
-const ALGORITHM = 'aes-256-gcm';
-
-const decrypt = ({ ciphertext, iv, tag, secret}) => {
- const decipher = crypto.createDecipheriv(
- ALGORITHM,
- secret,
- Buffer.from(iv, 'base64')
- );
- decipher.setAuthTag(Buffer.from(tag, 'base64'));
-
- let cleartext = decipher.update(ciphertext, 'base64', 'utf8');
- cleartext += decipher.final('utf8');
-
- return cleartext;
-}
-
-const getSecret = async () => {
- const serviceToken = 'your_service_token';
- const serviceTokenSecret = serviceToken.substring(serviceToken.lastIndexOf('.') + 1);
-
- const secretType = 'shared' // 'shared' or 'personal'
- const secretKey = 'some_key';
-
- // 1. Get your Infisical Token data
- const { data: serviceTokenData } = await axios.get(
- `${BASE_URL}/api/v2/service-token`,
- {
- headers: {
- Authorization: `Bearer ${serviceToken}`
- }
- }
- );
-
- // 2. Get the secret from your project and environment
- const { data } = await axios.get(
- `${BASE_URL}/api/v3/secrets/${secretKey}?${new URLSearchParams({
- environment: serviceTokenData.environment,
- workspaceId: serviceTokenData.workspace,
- type: secretType // optional, defaults to 'shared'
- })}`,
- {
- headers: {
- Authorization: `Bearer ${serviceToken}`
- }
- }
- );
-
- const encryptedSecret = data.secret;
-
- // 3. Decrypt the (encrypted) project key with the key from your Infisical Token
- const projectKey = decrypt({
- ciphertext: serviceTokenData.encryptedKey,
- iv: serviceTokenData.iv,
- tag: serviceTokenData.tag,
- secret: serviceTokenSecret
- });
-
- // 4. Decrypt the (encrypted) secret value
-
- const secretValue = decrypt({
- ciphertext: encryptedSecret.secretValueCiphertext,
- iv: encryptedSecret.secretValueIV,
- tag: encryptedSecret.secretValueTag,
- secret: projectKey
- });
-
- console.log('secret: ', ({
- secretKey,
- secretValue
- }));
-}
-
-getSecret();
-
-```
-
-
-
-```Python
-import requests
-import base64
-from Cryptodome.Cipher import AES
-
-
-BASE_URL = "http://app.infisical.com"
-
-
-def decrypt(ciphertext, iv, tag, secret):
- secret = bytes(secret, "utf-8")
- iv = base64.standard_b64decode(iv)
- tag = base64.standard_b64decode(tag)
- ciphertext = base64.standard_b64decode(ciphertext)
-
- cipher = AES.new(secret, AES.MODE_GCM, iv)
- cipher.update(tag)
- cleartext = cipher.decrypt(ciphertext).decode("utf-8")
- return cleartext
-
-
-def get_secret():
- service_token = "your_service_token"
- service_token_secret = service_token[service_token.rindex(".") + 1 :]
-
- secret_type = "shared" # "shared" or "personal"
- secret_key = "some_key"
-
- # 1. Get your Infisical Token data
- service_token_data = requests.get(
- f"{BASE_URL}/api/v2/service-token",
- headers={"Authorization": f"Bearer {service_token}"},
- ).json()
-
- # 2. Get secret from your project and environment
- data = requests.get(
- f"{BASE_URL}/api/v3/secrets/{secret_key}",
- params={
- "environment": service_token_data["environment"],
- "workspaceId": service_token_data["workspace"],
- "type": secret_type # optional, defaults to "shared"
- },
- headers={"Authorization": f"Bearer {service_token}"},
- ).json()
-
- encrypted_secret = data["secret"]
-
- # 3. Decrypt the (encrypted) project key with the key from your Infisical Token
- project_key = decrypt(
- ciphertext=service_token_data["encryptedKey"],
- iv=service_token_data["iv"],
- tag=service_token_data["tag"],
- secret=service_token_secret,
- )
-
- # 4. Decrypt the (encrypted) secret value
- secret_value = decrypt(
- ciphertext=encrypted_secret["secretValueCiphertext"],
- iv=encrypted_secret["secretValueIV"],
- tag=encrypted_secret["secretValueTag"],
- secret=project_key,
- )
-
- print("secret: ", {
- "secret_key": secret_key,
- "secret_value": secret_value
- })
-
-
-get_secret()
-
-```
-
-
\ No newline at end of file
diff --git a/docs/api-reference/overview/examples/retrieve-secrets.mdx b/docs/api-reference/overview/examples/retrieve-secrets.mdx
deleted file mode 100644
index f237822aa..000000000
--- a/docs/api-reference/overview/examples/retrieve-secrets.mdx
+++ /dev/null
@@ -1,195 +0,0 @@
----
-title: "Retrieve secrets"
-description: "How to get all secrets using an Infisical Token scoped to a project and environment"
----
-
-Prerequisites:
-
-- Set up and add envars to [Infisical Cloud](https://app.infisical.com).
-- Create an [Infisical Token](/documentation/platform/token) for your project and environment.
-- Grasp a basic understanding of the system and its underlying cryptography [here](/api-reference/overview/introduction).
-- [Ensure that your project is blind-indexed](../blind-indices).
-
-## Flow
-
-1. [Get your Infisical Token data](/api-reference/endpoints/service-tokens/get) including a (encrypted) project key.
-2. [Get secrets for your project and environment](/api-reference/endpoints/secrets/read).
-3. Decrypt the (encrypted) project key with the key from your Infisical Token.
-4. Decrypt the (encrypted) secrets
-
-## Example
-
-
-
-```js
-const crypto = require('crypto');
-const axios = require('axios');
-
-const BASE_URL = 'https://app.infisical.com';
-const ALGORITHM = 'aes-256-gcm';
-
-const decrypt = ({ ciphertext, iv, tag, secret}) => {
- const decipher = crypto.createDecipheriv(
- ALGORITHM,
- secret,
- Buffer.from(iv, 'base64')
- );
- decipher.setAuthTag(Buffer.from(tag, 'base64'));
-
- let cleartext = decipher.update(ciphertext, 'base64', 'utf8');
- cleartext += decipher.final('utf8');
-
- return cleartext;
-}
-
-const getSecrets = async () => {
- const serviceToken = 'your_service_token';
- const serviceTokenSecret = serviceToken.substring(serviceToken.lastIndexOf('.') + 1);
-
- // 1. Get your Infisical Token data
- const { data: serviceTokenData } = await axios.get(
- `${BASE_URL}/api/v2/service-token`,
- {
- headers: {
- Authorization: `Bearer ${serviceToken}`
- }
- }
- );
-
- // 2. Get secrets for your project and environment
- const { data } = await axios.get(
- `${BASE_URL}/api/v3/secrets?${new URLSearchParams({
- environment: serviceTokenData.environment,
- workspaceId: serviceTokenData.workspace
- })}`,
- {
- headers: {
- Authorization: `Bearer ${serviceToken}`
- }
- }
- );
-
- const encryptedSecrets = data.secrets;
-
- // 3. Decrypt the (encrypted) project key with the key from your Infisical Token
- const projectKey = decrypt({
- ciphertext: serviceTokenData.encryptedKey,
- iv: serviceTokenData.iv,
- tag: serviceTokenData.tag,
- secret: serviceTokenSecret
- });
-
- // 4. Decrypt the (encrypted) secrets
- const secrets = encryptedSecrets.map((secret) => {
- const secretKey = decrypt({
- ciphertext: secret.secretKeyCiphertext,
- iv: secret.secretKeyIV,
- tag: secret.secretKeyTag,
- secret: projectKey
- });
-
- const secretValue = decrypt({
- ciphertext: secret.secretValueCiphertext,
- iv: secret.secretValueIV,
- tag: secret.secretValueTag,
- secret: projectKey
- });
-
- return ({
- secretKey,
- secretValue
- });
- });
-
- console.log('secrets: ', secrets);
-}
-
-getSecrets();
-
-```
-
-
-
-```Python
-import requests
-import base64
-from Cryptodome.Cipher import AES
-
-
-BASE_URL = "http://app.infisical.com"
-
-
-def decrypt(ciphertext, iv, tag, secret):
- secret = bytes(secret, "utf-8")
- iv = base64.standard_b64decode(iv)
- tag = base64.standard_b64decode(tag)
- ciphertext = base64.standard_b64decode(ciphertext)
-
- cipher = AES.new(secret, AES.MODE_GCM, iv)
- cipher.update(tag)
- cleartext = cipher.decrypt(ciphertext).decode("utf-8")
- return cleartext
-
-
-def get_secrets():
- service_token = "your_service_token"
- service_token_secret = service_token[service_token.rindex(".") + 1 :]
-
- # 1. Get your Infisical Token data
- service_token_data = requests.get(
- f"{BASE_URL}/api/v2/service-token",
- headers={"Authorization": f"Bearer {service_token}"},
- ).json()
-
- # 2. Get secrets for your project and environment
- data = requests.get(
- f"{BASE_URL}/api/v3/secrets",
- params={
- "environment": service_token_data["environment"],
- "workspaceId": service_token_data["workspace"],
- },
- headers={"Authorization": f"Bearer {service_token}"},
- ).json()
-
- encrypted_secrets = data["secrets"]
-
- # 3. Decrypt the (encrypted) project key with the key from your Infisical Token
- project_key = decrypt(
- ciphertext=service_token_data["encryptedKey"],
- iv=service_token_data["iv"],
- tag=service_token_data["tag"],
- secret=service_token_secret,
- )
-
- # 4. Decrypt the (encrypted) secrets
- secrets = []
- for secret in encrypted_secrets:
- secret_key = decrypt(
- ciphertext=secret["secretKeyCiphertext"],
- iv=secret["secretKeyIV"],
- tag=secret["secretKeyTag"],
- secret=project_key,
- )
-
- secret_value = decrypt(
- ciphertext=secret["secretValueCiphertext"],
- iv=secret["secretValueIV"],
- tag=secret["secretValueTag"],
- secret=project_key,
- )
-
- secrets.append(
- {
- "secret_key": secret_key,
- "secret_value": secret_value,
- }
- )
-
- print("secrets:", secrets)
-
-
-get_secrets()
-
-```
-
-
\ No newline at end of file
diff --git a/docs/api-reference/overview/examples/update-secret.mdx b/docs/api-reference/overview/examples/update-secret.mdx
deleted file mode 100644
index 49255aa79..000000000
--- a/docs/api-reference/overview/examples/update-secret.mdx
+++ /dev/null
@@ -1,229 +0,0 @@
----
-title: "Update secret"
-description: "How to update a secret using an Infisical Token scoped to a project and environment"
----
-
-Prerequisites:
-
-- Set up and add envars to [Infisical Cloud](https://app.infisical.com).
-- Create an [Infisical Token](/documentation/platform/token) for your project and environment with write access enabled.
-- Grasp a basic understanding of the system and its underlying cryptography [here](/api-reference/overview/introduction).
-- [Ensure that your project is blind-indexed](../blind-indices).
-
-## Flow
-
-1. [Get your Infisical Token data](/api-reference/endpoints/service-tokens/get) including a (encrypted) project key.
-2. Decrypt the (encrypted) project key with the key from your Infisical Token.
-3. Encrypt your updated secret with the project key
-4. [Send (encrypted) updated secret to Infical](/api-reference/endpoints/secrets/update)
-
-## Example
-
-
-
-```js
-const crypto = require('crypto');
-const axios = require('axios');
-
-const BASE_URL = 'https://app.infisical.com';
-const ALGORITHM = 'aes-256-gcm';
-const BLOCK_SIZE_BYTES = 16;
-
-const encrypt = ({ text, secret }) => {
- const iv = crypto.randomBytes(BLOCK_SIZE_BYTES);
- const cipher = crypto.createCipheriv(ALGORITHM, secret, iv);
-
- let ciphertext = cipher.update(text, 'utf8', 'base64');
- ciphertext += cipher.final('base64');
- return {
- ciphertext,
- iv: iv.toString('base64'),
- tag: cipher.getAuthTag().toString('base64')
- };
-}
-
-const decrypt = ({ ciphertext, iv, tag, secret}) => {
- const decipher = crypto.createDecipheriv(
- ALGORITHM,
- secret,
- Buffer.from(iv, 'base64')
- );
- decipher.setAuthTag(Buffer.from(tag, 'base64'));
-
- let cleartext = decipher.update(ciphertext, 'base64', 'utf8');
- cleartext += decipher.final('utf8');
-
- return cleartext;
-}
-
-const updateSecrets = async () => {
- const serviceToken = 'your_service_token';
- const serviceTokenSecret = serviceToken.substring(serviceToken.lastIndexOf('.') + 1);
-
- const secretType = 'shared' // 'shared' or 'personal'
- const secretKey = 'some_key';
- const secretValue = 'updated_value';
- const secretComment = 'updated_comment';
-
- // 1. Get your Infisical Token data
- const { data: serviceTokenData } = await axios.get(
- `${BASE_URL}/api/v2/service-token`,
- {
- headers: {
- Authorization: `Bearer ${serviceToken}`
- }
- }
- );
-
- // 2. Decrypt the (encrypted) project key with the key from your Infisical Token
- const projectKey = decrypt({
- ciphertext: serviceTokenData.encryptedKey,
- iv: serviceTokenData.iv,
- tag: serviceTokenData.tag,
- secret: serviceTokenSecret
- });
-
- // 3. Encrypt your updated secret with the project key
- const {
- ciphertext: secretKeyCiphertext,
- iv: secretKeyIV,
- tag: secretKeyTag
- } = encrypt({
- text: secretKey,
- secret: projectKey
- });
-
- const {
- ciphertext: secretValueCiphertext,
- iv: secretValueIV,
- tag: secretValueTag
- } = encrypt({
- text: secretValue,
- secret: projectKey
- });
-
- const {
- ciphertext: secretCommentCiphertext,
- iv: secretCommentIV,
- tag: secretCommentTag
- } = encrypt({
- text: secretComment,
- secret: projectKey
- });
-
- // 4. Send (encrypted) updated secret to Infisical
- await axios.patch(
- `${BASE_URL}/api/v3/secrets/${secretKey}`,
- {
- workspaceId: serviceTokenData.workspace,
- environment: serviceTokenData.environment,
- type: secretType,
- secretValueCiphertext,
- secretValueIV,
- secretValueTag,
- secretCommentCiphertext,
- secretCommentIV,
- secretCommentTag
- },
- {
- headers: {
- Authorization: `Bearer ${serviceToken}`
- }
- }
- );
-}
-
-updateSecrets();
-```
-
-
-
-```Python
-import base64
-import requests
-from Cryptodome.Cipher import AES
-from Cryptodome.Random import get_random_bytes
-
-
-BASE_URL = "https://app.infisical.com"
-BLOCK_SIZE_BYTES = 16
-
-
-def encrypt(text, secret):
- iv = get_random_bytes(BLOCK_SIZE_BYTES)
- secret = bytes(secret, "utf-8")
- cipher = AES.new(secret, AES.MODE_GCM, iv)
- ciphertext, tag = cipher.encrypt_and_digest(text.encode("utf-8"))
- return {
- "ciphertext": base64.standard_b64encode(ciphertext).decode("utf-8"),
- "tag": base64.standard_b64encode(tag).decode("utf-8"),
- "iv": base64.standard_b64encode(iv).decode("utf-8"),
- }
-
-
-def decrypt(ciphertext, iv, tag, secret):
- secret = bytes(secret, "utf-8")
- iv = base64.standard_b64decode(iv)
- tag = base64.standard_b64decode(tag)
- ciphertext = base64.standard_b64decode(ciphertext)
-
- cipher = AES.new(secret, AES.MODE_GCM, iv)
- cipher.update(tag)
- cleartext = cipher.decrypt(ciphertext).decode("utf-8")
- return cleartext
-
-
-def update_secret():
- service_token = "your_service_token"
- service_token_secret = service_token[service_token.rindex(".") + 1 :]
-
- secret_type = "shared" # "shared" or "personal"
- secret_key = "some_key"
- secret_value = "updated_value"
- secret_comment = "updated_comment"
-
- # 1. Get your Infisical Token data
- service_token_data = requests.get(
- f"{BASE_URL}/api/v2/service-token",
- headers={"Authorization": f"Bearer {service_token}"},
- ).json()
-
- # 2. Decrypt the (encrypted) project key with the key from your Infisical Token
- project_key = decrypt(
- ciphertext=service_token_data["encryptedKey"],
- iv=service_token_data["iv"],
- tag=service_token_data["tag"],
- secret=service_token_secret,
- )
-
- # 3. Encrypt your updated secret with the project key
- encrypted_key_data = encrypt(text=secret_key, secret=project_key)
- encrypted_value_data = encrypt(text=secret_value, secret=project_key)
- encrypted_comment_data = encrypt(text=secret_comment, secret=project_key)
-
- # 4. Send (encrypted) updated secret to Infisical
- requests.patch(
- f"{BASE_URL}/api/v3/secrets/{secret_key}",
- json={
- "workspaceId": service_token_data["workspace"],
- "environment": service_token_data["environment"],
- "type": secret_type,
- "secretKeyCiphertext": encrypted_key_data["ciphertext"],
- "secretKeyIV": encrypted_key_data["iv"],
- "secretKeyTag": encrypted_key_data["tag"],
- "secretValueCiphertext": encrypted_value_data["ciphertext"],
- "secretValueIV": encrypted_value_data["iv"],
- "secretValueTag": encrypted_value_data["tag"],
- "secretCommentCiphertext": encrypted_comment_data["ciphertext"],
- "secretCommentIV": encrypted_comment_data["iv"],
- "secretCommentTag": encrypted_comment_data["tag"]
- },
- headers={"Authorization": f"Bearer {service_token}"},
- )
-
-
-update_secret()
-
-```
-
-
\ No newline at end of file
diff --git a/docs/mint.json b/docs/mint.json
index 7be970770..9dba735e6 100644
--- a/docs/mint.json
+++ b/docs/mint.json
@@ -250,9 +250,9 @@
{
"group": "Examples",
"pages": [
- "api-reference/overview/encryption-modes/overview",
- "api-reference/overview/encryption-modes/es-mode",
- "api-reference/overview/encryption-modes/e2ee-mode"
+ "api-reference/overview/examples/note",
+ "api-reference/overview/examples/e2ee-disabled",
+ "api-reference/overview/examples/e2ee-enabled"
]
},
"api-reference/overview/blind-indices"