mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Complete v1 API reference docs, pre-launch
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: "Roll Back to Version"
|
||||
openapi: "POST /api/v1/secret/{secretId}/secret-versions/rollback"
|
||||
---
|
||||
4
docs/api-reference/endpoints/secrets/versions.mdx
Normal file
4
docs/api-reference/endpoints/secrets/versions.mdx
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: "Get Versions"
|
||||
openapi: "GET /api/v1/secret/{secretId}/secret-versions"
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: "Delete Membership"
|
||||
openapi: "DELETE /api/v2/workspace/{workspaceId}/memberships/{membershipId}"
|
||||
---
|
||||
4
docs/api-reference/endpoints/workspaces/logs.mdx
Normal file
4
docs/api-reference/endpoints/workspaces/logs.mdx
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: "Get Logs"
|
||||
openapi: "GET /api/v1/workspace/{workspaceId}/logs"
|
||||
---
|
||||
4
docs/api-reference/endpoints/workspaces/memberships.mdx
Normal file
4
docs/api-reference/endpoints/workspaces/memberships.mdx
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: "Get Memberships"
|
||||
openapi: "GET /api/v2/workspace/{workspaceId}/memberships"
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: "Roll Back to Snapshot"
|
||||
openapi: "POST /api/v1/workspace/{workspaceId}/secret-snapshots/rollback"
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: "Get Snapshots"
|
||||
openapi: "GET /api/v1/workspace/{workspaceId}/secret-snapshots"
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: "Update Membership"
|
||||
openapi: "PATCH /api/v2/workspace/{workspaceId}/memberships/{membershipId}"
|
||||
---
|
||||
@@ -1,4 +1,4 @@
|
||||
---
|
||||
title: "Get Project Key"
|
||||
title: "Get Key"
|
||||
openapi: "GET /api/v2/workspace/{workspaceId}/encrypted-key"
|
||||
---
|
||||
|
||||
@@ -13,52 +13,140 @@ Prerequisites:
|
||||
|
||||
1. Get your (encrypted) private key.
|
||||
2. Decrypt your (encrypted) private key with your password.
|
||||
3. Get the project key for the project.
|
||||
4. Decrypt the project key with your private key.
|
||||
5. Encrypt your secrets with the project key.
|
||||
6. Send (encrypted) secrets to the Infical API
|
||||
3. Get the (encrypted) project key for the project.
|
||||
4. Decrypt the (encrypted) project key with your private key.
|
||||
5. Encrypt your secret(s) with the project key.
|
||||
6. Send (encrypted) secret(s) to the Infical API
|
||||
|
||||
## Example
|
||||
|
||||
```js
|
||||
const axios = require("axios");
|
||||
const aes = require("aes-256-gcm");
|
||||
const nacl = require("tweetnacl");
|
||||
nacl.util = require("tweetnacl-util");
|
||||
const crypto = require('crypto');
|
||||
const axios = require('axios');
|
||||
|
||||
const WORKSPACE_KEY = "3a7a243eb62078c13f09203e75e8cb32";
|
||||
const ALGORITHM = 'aes-256-gcm';
|
||||
const BLOCK_SIZE_BYTES = 16;
|
||||
|
||||
const secretKey = "SOME_KEY";
|
||||
const secretValue = "SOME_VALUE";
|
||||
const encrypt = (
|
||||
text,
|
||||
secret
|
||||
) => {
|
||||
const iv = crypto.randomBytes(BLOCK_SIZE_BYTES);
|
||||
const cipher = crypto.createCipheriv(ALGORITHM, secret, iv);
|
||||
|
||||
// encrypt key of secret
|
||||
const {
|
||||
ciphertext: secretKeyCiphertext,
|
||||
iv: secretKeyIV,
|
||||
tag: secretKeyTag,
|
||||
} = aes.encrypt(secretKey, WORKSPACE_KEY);
|
||||
let ciphertext = cipher.update(text, 'utf8', 'base64');
|
||||
ciphertext += cipher.final('base64');
|
||||
return {
|
||||
ciphertext,
|
||||
iv: iv.toString('base64'),
|
||||
tag: cipher.getAuthTag().toString('base64')
|
||||
};
|
||||
}
|
||||
|
||||
// encrypt value of secret
|
||||
const {
|
||||
ciphertext: secretValueCiphertext,
|
||||
iv: secretValueIV,
|
||||
tag: secretValueTag,
|
||||
} = aes.encrypt(secretKey, WORKSPACE_KEY);
|
||||
const decrypt = (ciphertext, iv, tag, secret) => {
|
||||
const decipher = crypto.createDecipheriv(
|
||||
ALGORITHM,
|
||||
secret,
|
||||
Buffer.from(iv, 'base64')
|
||||
);
|
||||
decipher.setAuthTag(Buffer.from(tag, 'base64'));
|
||||
|
||||
// construct request body
|
||||
const secret = {
|
||||
secretKeyCiphertext,
|
||||
secretKeyIV,
|
||||
secretKeyTag,
|
||||
secretValueCiphertext,
|
||||
secretValueIV,
|
||||
secretValueTag,
|
||||
};
|
||||
let cleartext = decipher.update(ciphertext, 'base64', 'utf8');
|
||||
cleartext += decipher.final('utf8');
|
||||
|
||||
return cleartext;
|
||||
}
|
||||
|
||||
const createSecrets = async () => {
|
||||
const API_KEY = 'your_api_key';
|
||||
const PSWD = 'your_pswd';
|
||||
const WORKSPACE_ID = 'your_workspace_id';
|
||||
|
||||
const SECRET_KEY = 'SOME_KEY';
|
||||
const SECRET_VALUE = 'SOME_VALUE';
|
||||
|
||||
// 1. get (encrypted) private key
|
||||
const user = await axios.get(
|
||||
'https://api.infisical.com/api/v2/users/me', {
|
||||
headers: {
|
||||
'X-API-KEY': API_KEY
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 2. decrypt your (encrypted) private key with your password
|
||||
const privateKey = decrypt({
|
||||
ciphertext: user.encryptedPrivateKey,
|
||||
iv: user.iv,
|
||||
tag: user.tag,
|
||||
secret: PSWD.slice(0, 32).padStart(32, '0');
|
||||
});
|
||||
|
||||
// 3. get the (encrypted) project key for the project
|
||||
const encryptedProjectKey = await axios.get(
|
||||
`https://api.infisical.com/api/v2/workspace/${WORKSPACE_ID}`, {
|
||||
headers: {
|
||||
'X-API-KEY': API_KEY
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 4. decrypt the project key with your private key
|
||||
const projectKey = nacl.box.open(
|
||||
util.decodeBase64(encryptedProjectKey),
|
||||
util.decodeBase64(projectKey.nonce),
|
||||
util.decodeBase64(projectKey.sender.publicKey),
|
||||
util.decodeBase64(privateKey)
|
||||
);
|
||||
|
||||
// 5. encrypt your secret(s) with the project key
|
||||
const {
|
||||
ciphertext: secretKeyCiphertext,
|
||||
iv: secretKeyIV,
|
||||
tag: secretKeyTag
|
||||
} = encrypt(SECRET_KEY, projectKey);
|
||||
|
||||
const {
|
||||
ciphertext: secretValueCiphertext,
|
||||
iv: secretValueIV,
|
||||
tag: secretValueTag
|
||||
} = encrypt(SECRET_VALUE, projectKey);
|
||||
|
||||
const secret = {
|
||||
secretKeyCiphertext,
|
||||
secretKeyIV,
|
||||
secretKeyTag,
|
||||
secretValueCiphertext,
|
||||
secretValueIV,
|
||||
secretValueTag
|
||||
}
|
||||
|
||||
// 6. Send (encrypted) secret(s) to the Infisical API
|
||||
await axios.post(
|
||||
`https://api.infisical.com/api/v2/secrets`,
|
||||
{
|
||||
workspaceId: WORKSPACE_ID,
|
||||
environment: 'dev',
|
||||
secrets: secret
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
'X-API-KEY': API_KEY
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
createSecrets();
|
||||
```
|
||||
|
||||
<Info>
|
||||
This example uses [TweetNaCl.js](https://tweetnacl.js.org/#/), a port of
|
||||
TweetNacl/Nacl, to perform asymmeric decryption of the project key but there
|
||||
are ports of NaCl in every major language.
|
||||
|
||||
are ports of NaCl available in every major language.
|
||||
</Info>
|
||||
<Tip>
|
||||
It can be useful to perform steps 1-4 ahead of time and store away your
|
||||
private key (and even project key) for later use. The Infisical CLI works by
|
||||
securely storing your private key via your OS keyring.
|
||||
</Tip>
|
||||
|
||||
34
docs/api-reference/overview/examples/delete-secrets.mdx
Normal file
34
docs/api-reference/overview/examples/delete-secrets.mdx
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
title: "Delete secrets"
|
||||
---
|
||||
|
||||
In this example, we demonstrate how to delete secrets
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- Set up and add envars to [Infisical Cloud](https://app.infisical.com)
|
||||
- Grasp a basic understanding of the system and its underlying cryptography [here](/api-reference/overview/introduction).
|
||||
|
||||
## Example
|
||||
|
||||
```js
|
||||
const deleteSecrets = async () => {
|
||||
const API_KEY = "your_api_key";
|
||||
const SECRET_ID = "ID"; // ID of secret to delete
|
||||
|
||||
// 6. Send ID(s) of secret(s) to delete to the Infisical API
|
||||
await axios.delete(
|
||||
`https://api.infisical.com/api/v2/secrets`,
|
||||
{
|
||||
secretIds: SECRET_ID,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
"X-API-KEY": API_KEY,
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
deleteSecrets();
|
||||
```
|
||||
@@ -2,9 +2,141 @@
|
||||
title: "Retrieve secrets"
|
||||
---
|
||||
|
||||
In this example, we demonstrate how to retrieve secrets from a project and environment.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- Set up and add envars to [Infisical Cloud](https://app.infisical.com)
|
||||
- Grasp a basic understanding of the system and its underlying cryptography [here](/api-reference/overview/introduction).
|
||||
|
||||
## Flow
|
||||
|
||||
1. Get your (encrypted) private key.
|
||||
2. Decrypt your (encrypted) private key with your password.
|
||||
3. Get the project key for the project.
|
||||
4. Decrypt the project key with your private key.
|
||||
3. Get the (encrypted) project key for the project.
|
||||
4. Decrypt the (encrypted) project key with your private key.
|
||||
5. Get secrets for a project and environment.
|
||||
6. Decrypt the secrets in your project.
|
||||
6. Decrypt the (encrypted) secrets
|
||||
|
||||
## Example
|
||||
|
||||
```js
|
||||
const crypto = require('crypto');
|
||||
const axios = require('axios');
|
||||
|
||||
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 retrieveSecrets = async () => {
|
||||
const API_KEY = 'your_api_key';
|
||||
const PSWD = 'your_pswd';
|
||||
const WORKSPACE_ID = 'your_workspace_id';
|
||||
|
||||
// 1. get (encrypted) private key
|
||||
const user = await axios.get(
|
||||
'https://api.infisical.com/api/v2/users/me', {
|
||||
headers: {
|
||||
'X-API-KEY': API_KEY
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 2. decrypt your (encrypted) private key with your password
|
||||
const privateKey = decrypt({
|
||||
ciphertext: user.encryptedPrivateKey,
|
||||
iv: user.iv,
|
||||
tag: user.tag,
|
||||
secret: PSWD.slice(0, 32).padStart(32, '0');
|
||||
});
|
||||
|
||||
// 3. get the (encrypted) project key for the project
|
||||
const encryptedProjectKey = await axios.get(
|
||||
`https://api.infisical.com/api/v2/workspace/${WORKSPACE_ID}`, {
|
||||
headers: {
|
||||
'X-API-KEY': API_KEY
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 4. decrypt the project key with your private key
|
||||
const projectKey = nacl.box.open(
|
||||
util.decodeBase64(encryptedProjectKey),
|
||||
util.decodeBase64(projectKey.nonce),
|
||||
util.decodeBase64(projectKey.sender.publicKey),
|
||||
util.decodeBase64(privateKey)
|
||||
);
|
||||
|
||||
// 5. get (encrypted) secrets for a project and environment.
|
||||
const encryptedSecrets = await axios.get(
|
||||
'https://api.infisical.com/api/v2/secrets', {
|
||||
headers: {
|
||||
'X-API-KEY': API_KEY
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 6. decrypt the (encrypted) secrets
|
||||
const secrets = encryptedSecrets.map((encryptedSecret) => {
|
||||
const secretKey = decrypt({
|
||||
ciphertext: encryptedSecret.secretKeyCiphertext,
|
||||
iv: encryptedSecret.secretKeyIV,
|
||||
tag: encryptedSecret.secretKeyTag
|
||||
secret: projectKey
|
||||
});
|
||||
const secretValue = decrypt({
|
||||
ciphertext: encryptedSecret.secretValueCiphertext,
|
||||
iv: encryptedSecret.secretValueIV,
|
||||
tag: encryptedSecret.secretValueTag
|
||||
secret: projectKey
|
||||
});
|
||||
|
||||
return ({
|
||||
secretKey,
|
||||
secretValue
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
retrieveSecrets();
|
||||
```
|
||||
|
||||
<Info>
|
||||
This example uses [TweetNaCl.js](https://tweetnacl.js.org/#/), a port of
|
||||
TweetNacl/Nacl, to perform asymmeric decryption of the project key but there
|
||||
are ports of NaCl available in every major language.
|
||||
</Info>
|
||||
<Tip>
|
||||
It can be useful to perform steps 1-4 ahead of time and store away your
|
||||
private key (and even project key) for later use. The Infisical CLI works by
|
||||
securely storing your private key via your OS keyring.
|
||||
</Tip>
|
||||
|
||||
@@ -2,9 +2,151 @@
|
||||
title: "Update secrets"
|
||||
---
|
||||
|
||||
In this example, we demonstrate how to update secrets
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- Set up and add envars to [Infisical Cloud](https://app.infisical.com)
|
||||
- Grasp a basic understanding of the system and its underlying cryptography [here](/api-reference/overview/introduction).
|
||||
|
||||
## Flow
|
||||
|
||||
1. Get your (encrypted) private key.
|
||||
2. Decrypt your (encrypted) private key with your password.
|
||||
3. Get the project key for the project.
|
||||
4. Decrypt the project key with your private key.
|
||||
5. Encrypt your secrets with the project key.
|
||||
6. Send (encrypted) updated secrets to the Infical API
|
||||
5. Encrypt your secret(s) with the project key.
|
||||
6. Send (encrypted) updated secret(s) to the Infical API
|
||||
|
||||
## Example
|
||||
|
||||
```js
|
||||
const crypto = require('crypto');
|
||||
const axios = require('axios');
|
||||
|
||||
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 API_KEY = 'your_api_key';
|
||||
const PSWD = 'your_pswd';
|
||||
const WORKSPACE_ID = 'your_workspace_id';
|
||||
|
||||
const SECRET_ID = 'ID' // ID of secret to update
|
||||
const SECRET_KEY = 'SOME_KEY';
|
||||
const SECRET_VALUE = 'SOME_VALUE';
|
||||
|
||||
// 1. get (encrypted) private key
|
||||
const user = await axios.get(
|
||||
'https://api.infisical.com/api/v2/users/me', {
|
||||
headers: {
|
||||
'X-API-KEY': API_KEY
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 2. decrypt your (encrypted) private key with your password
|
||||
const privateKey = decrypt({
|
||||
ciphertext: user.encryptedPrivateKey,
|
||||
iv: user.iv,
|
||||
tag: user.tag,
|
||||
secret: PSWD.slice(0, 32).padStart(32, '0');
|
||||
});
|
||||
|
||||
// 3. get the (encrypted) project key for the project
|
||||
const encryptedProjectKey = await axios.get(
|
||||
`https://api.infisical.com/api/v2/workspace/${WORKSPACE_ID}`, {
|
||||
headers: {
|
||||
'X-API-KEY': API_KEY
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 4. decrypt the project key with your private key
|
||||
const projectKey = nacl.box.open(
|
||||
util.decodeBase64(encryptedProjectKey),
|
||||
util.decodeBase64(projectKey.nonce),
|
||||
util.decodeBase64(projectKey.sender.publicKey),
|
||||
util.decodeBase64(privateKey)
|
||||
);
|
||||
|
||||
// 5. encrypt your secret(s) with the project key
|
||||
const {
|
||||
ciphertext: secretKeyCiphertext,
|
||||
iv: secretKeyIV,
|
||||
tag: secretKeyTag
|
||||
} = encrypt(SECRET_KEY, projectKey);
|
||||
|
||||
const {
|
||||
ciphertext: secretValueCiphertext,
|
||||
iv: secretValueIV,
|
||||
tag: secretValueTag
|
||||
} = encrypt(SECRET_VALUE, projectKey);
|
||||
|
||||
const secret = {
|
||||
id: SECRET_ID,
|
||||
secretKeyCiphertext,
|
||||
secretKeyIV,
|
||||
secretKeyTag,
|
||||
secretValueCiphertext,
|
||||
secretValueIV,
|
||||
secretValueTag
|
||||
}
|
||||
|
||||
// 6. Send (encrypted) secret(s) to the Infisical API
|
||||
await axios.patch(
|
||||
`https://api.infisical.com/api/v2/secrets`,
|
||||
{
|
||||
secrets: secret
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
'X-API-KEY': API_KEY
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
updateSecrets();
|
||||
```
|
||||
|
||||
<Info>
|
||||
This example uses [TweetNaCl.js](https://tweetnacl.js.org/#/), a port of
|
||||
TweetNacl/Nacl, to perform asymmeric decryption of the project key but there
|
||||
are ports of NaCl available in every major language.
|
||||
</Info>
|
||||
<Tip>
|
||||
It can be useful to perform steps 1-4 ahead of time and store away your
|
||||
private key (and even project key) for later use. The Infisical CLI works by
|
||||
securely storing your private key via your OS keyring.
|
||||
</Tip>
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
title: "Introduction"
|
||||
---
|
||||
|
||||
<Warning>
|
||||
Infisical's REST API is currently unavailable and scheduled to go live on Jan
|
||||
16!
|
||||
</Warning>
|
||||
|
||||
Infisical's REST API provides users an alternative way to programmatically access and manage
|
||||
secrets via HTTP requests. This can be useful for automating tasks, such as
|
||||
secrets via HTTPS requests. This can be useful for automating tasks, such as
|
||||
rotating credentials, or for integrating secret management into a larger system.
|
||||
|
||||
With the REST API, users can create, read, update, and delete secrets, as well as manage access control, query audit logs, and more.
|
||||
@@ -17,3 +22,10 @@ Using Infisical's API to manage secrets requires a basic understanding of the sy
|
||||
- Each project has an (encrypted) project key used to encrypt the secrets within that project; Infisical stores copies of the project key, for each member of that project, encrypted under each member's public key.
|
||||
- Secrets are encrypted symmetrically by your copy of the project key belonging to the project containing.
|
||||
- Infisical uses AES256-GCM and [TweetNaCl.js](https://tweetnacl.js.org/#/) for symmetric and asymmetric encryption/decryption operations.
|
||||
|
||||
<Info>
|
||||
Infisical's system ensures greater security such that secrets are
|
||||
encrypted/decrypted on the client-side but requires users to properly
|
||||
implement cryptographic operations to maintain end-to-end encryption (E2EE).
|
||||
We're
|
||||
</Info>
|
||||
|
||||
Reference in New Issue
Block a user