diff --git a/backend/package-lock.json b/backend/package-lock.json
index b51aa7cf0..38c1126cc 100644
--- a/backend/package-lock.json
+++ b/backend/package-lock.json
@@ -28,6 +28,7 @@
"express-validator": "^6.14.2",
"handlebars": "^4.7.7",
"helmet": "^5.1.1",
+ "js-yaml": "^4.1.0",
"jsonwebtoken": "^9.0.0",
"jsrp": "^0.2.4",
"libsodium-wrappers": "^0.7.10",
@@ -3698,8 +3699,7 @@
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
"node_modules/array-flatten": {
"version": "1.1.1",
@@ -6638,7 +6638,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
- "dev": true,
"dependencies": {
"argparse": "^2.0.1"
},
@@ -14980,8 +14979,7 @@
"argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
"array-flatten": {
"version": "1.1.1",
@@ -17197,7 +17195,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
- "dev": true,
"requires": {
"argparse": "^2.0.1"
}
diff --git a/backend/package.json b/backend/package.json
index 08f5a815c..b9359f680 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -5,7 +5,7 @@
"scripts": {
"start": "npm run build && node build/index.js",
"dev": "nodemon",
- "swagger-autogen": "node ./swagger.ts",
+ "swagger-autogen": "node ./swagger/index.ts",
"build": "rimraf ./build && tsc && cp -R ./src/templates ./build",
"lint": "eslint . --ext .ts",
"lint-and-fix": "eslint . --ext .ts --fix",
@@ -94,6 +94,7 @@
"express-validator": "^6.14.2",
"handlebars": "^4.7.7",
"helmet": "^5.1.1",
+ "js-yaml": "^4.1.0",
"jsonwebtoken": "^9.0.0",
"jsrp": "^0.2.4",
"libsodium-wrappers": "^0.7.10",
diff --git a/backend/api-documentation.json b/backend/spec.json
similarity index 79%
rename from backend/api-documentation.json
rename to backend/spec.json
index 79cf0eb3b..188365290 100644
--- a/backend/api-documentation.json
+++ b/backend/spec.json
@@ -5,6 +5,16 @@
"description": "List of all available APIs that can be consumed",
"version": "1.0.0"
},
+ "servers": [
+ {
+ "url": "https://infisical.com",
+ "description": "Production server"
+ },
+ {
+ "url": "http://localhost:8080",
+ "description": "Local server"
+ }
+ ],
"paths": {
"/api/v1/secret/{secretId}/secret-versions": {
"get": {
@@ -43,6 +53,43 @@
}
}
},
+ "/api/v1/secret/{secretId}/secret-versions/rollback": {
+ "post": {
+ "description": "",
+ "parameters": [
+ {
+ "name": "secretId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK"
+ },
+ "400": {
+ "description": "Bad Request"
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "version": {
+ "example": "any"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
"/api/v1/secret-snapshot/{secretSnapshotId}": {
"get": {
"description": "",
@@ -126,6 +173,43 @@
}
}
},
+ "/api/v1/workspace/{workspaceId}/secret-snapshots/rollback": {
+ "post": {
+ "description": "",
+ "parameters": [
+ {
+ "name": "workspaceId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK"
+ },
+ "400": {
+ "description": "Bad Request"
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "version": {
+ "example": "any"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
"/api/v1/workspace/{workspaceId}/logs": {
"get": {
"description": "",
@@ -476,7 +560,11 @@
"post": {
"description": "",
"parameters": [],
- "responses": {}
+ "responses": {
+ "200": {
+ "description": "OK"
+ }
+ }
}
},
"/api/v1/bot/{workspaceId}": {
@@ -1997,6 +2085,35 @@
}
}
},
+ "/api/v2/users/me": {
+ "get": {
+ "summary": "Retrieve the current user on the request",
+ "description": "Retrieve the current user on the request",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "$ref": "#/components/schemas/CurrentUser",
+ "description": "Current user on request"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request"
+ }
+ },
+ "security": [
+ {
+ "apiKeyAuth": []
+ }
+ ]
+ }
+ },
"/api/v2/workspace/{workspaceId}/secrets": {
"post": {
"description": "",
@@ -2080,7 +2197,8 @@
},
"/api/v2/workspace/{workspaceId}/encrypted-key": {
"get": {
- "description": "",
+ "summary": "Return encrypted project key",
+ "description": "Return encrypted project key",
"parameters": [
{
"name": "workspaceId",
@@ -2088,17 +2206,34 @@
"required": true,
"schema": {
"type": "string"
- }
+ },
+ "description": "ID of project"
}
],
"responses": {
"200": {
- "description": "OK"
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ProjectKey"
+ },
+ "description": "Encrypted project key for the given project"
+ }
+ }
+ }
},
"400": {
"description": "Bad Request"
}
- }
+ },
+ "security": [
+ {
+ "apiKeyAuth": []
+ }
+ ]
}
},
"/api/v2/workspace/{workspaceId}/service-token-data": {
@@ -2124,7 +2259,7 @@
}
}
},
- "/api/v2/secret/batch-create/workspace/{workspaceId}/environment/{environmentName}": {
+ "/api/v2/secret/batch-create/workspace/{workspaceId}/environment/{environment}": {
"post": {
"description": "",
"parameters": [
@@ -2137,7 +2272,7 @@
}
},
{
- "name": "environmentName",
+ "name": "environment",
"in": "path",
"required": true,
"schema": {
@@ -2166,7 +2301,7 @@
}
}
},
- "/api/v2/secret/workspace/{workspaceId}/environment/{environmentName}": {
+ "/api/v2/secret/workspace/{workspaceId}/environment/{environment}": {
"post": {
"description": "",
"parameters": [
@@ -2179,47 +2314,7 @@
}
},
{
- "name": "environmentName",
- "in": "path",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "OK"
- }
- },
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "secret": {
- "example": "any"
- }
- }
- }
- }
- }
- }
- },
- "patch": {
- "description": "",
- "parameters": [
- {
- "name": "workspaceId",
- "in": "path",
- "required": true,
- "schema": {
- "type": "string"
- }
- },
- {
- "name": "environmentName",
+ "name": "environment",
"in": "path",
"required": true,
"schema": {
@@ -2397,6 +2492,230 @@
}
}
},
+ "/api/v2/secret/workspace/{workspaceId}/environment/{environmentName}": {
+ "patch": {
+ "description": "",
+ "parameters": [
+ {
+ "name": "workspaceId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "environmentName",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK"
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "secret": {
+ "example": "any"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/api/v2/secrets/": {
+ "post": {
+ "summary": "Create new secret(s)",
+ "description": "Create one or many secrets for a given project and environment.",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Secret"
+ },
+ "description": "Array of newly-created secrets for the given project and environment"
+ }
+ }
+ }
+ }
+ },
+ "security": [
+ {
+ "apiKeyAuth": []
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "workspaceId": {
+ "type": "string",
+ "description": "ID of project"
+ },
+ "environment": {
+ "type": "string",
+ "description": "Environment within project"
+ },
+ "secrets": {
+ "$ref": "#/components/schemas/CreateSecret",
+ "description": "Secret(s) to create - object or array of objects"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "get": {
+ "summary": "Read secrets",
+ "description": "Read secrets from a project and environment",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Secret"
+ },
+ "description": "Array of secrets for the given project and environment"
+ }
+ }
+ }
+ }
+ },
+ "security": [
+ {
+ "apiKeyAuth": []
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "workspaceId": {
+ "type": "string",
+ "description": "ID of project"
+ },
+ "environment": {
+ "type": "string",
+ "description": "Environment within project"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "patch": {
+ "summary": "Update secret(s)",
+ "description": "Update secret(s)",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Secret"
+ },
+ "description": "Array of newly-updated secrets for the given project and environment"
+ }
+ }
+ }
+ }
+ },
+ "security": [
+ {
+ "apiKeyAuth": []
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "secrets": {
+ "$ref": "#/components/schemas/UpdateSecret",
+ "description": "Secret(s) to update - object or array of objects"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "summary": "Delete secret(s)",
+ "description": "Delete one or many secrets by their ID(s)",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Secret"
+ },
+ "description": "Array of deleted secrets"
+ }
+ }
+ }
+ }
+ },
+ "security": [
+ {
+ "apiKeyAuth": []
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "secretIds": {
+ "type": "string",
+ "description": "ID(s) of secrets - string or array of strings"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
"/api/v2/service-token/": {
"get": {
"description": "",
@@ -2557,11 +2876,243 @@
}
},
"components": {
+ "schemas": {
+ "CurrentUser": {
+ "type": "object",
+ "properties": {
+ "_id": {
+ "type": "string",
+ "example": ""
+ },
+ "email": {
+ "type": "string",
+ "example": ""
+ },
+ "firstName": {
+ "type": "string",
+ "example": ""
+ },
+ "lastName": {
+ "type": "string",
+ "example": ""
+ },
+ "publicKey": {
+ "type": "string",
+ "example": ""
+ },
+ "encryptedPrivateKey": {
+ "type": "string",
+ "example": ""
+ },
+ "updatedAt": {
+ "type": "string",
+ "example": ""
+ },
+ "createdAt": {
+ "type": "string",
+ "example": ""
+ }
+ }
+ },
+ "ProjectKey": {
+ "type": "object",
+ "properties": {
+ "encryptedkey": {
+ "type": "string",
+ "example": ""
+ },
+ "nonce": {
+ "type": "string",
+ "example": ""
+ },
+ "sender": {
+ "type": "object",
+ "properties": {
+ "publicKey": {
+ "type": "string",
+ "example": ""
+ }
+ }
+ },
+ "receiver": {
+ "type": "string",
+ "example": ""
+ },
+ "workspace": {
+ "type": "string",
+ "example": ""
+ }
+ }
+ },
+ "CreateSecret": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "example": "shared"
+ },
+ "secretKeyCiphertext": {
+ "type": "string",
+ "example": ""
+ },
+ "secretKeyIV": {
+ "type": "string",
+ "example": ""
+ },
+ "secretKeyTag": {
+ "type": "string",
+ "example": ""
+ },
+ "secretValueCiphertext": {
+ "type": "string",
+ "example": ""
+ },
+ "secretValueIV": {
+ "type": "string",
+ "example": ""
+ },
+ "secretValueTag": {
+ "type": "string",
+ "example": ""
+ },
+ "secretCommentCiphertext": {
+ "type": "string",
+ "example": ""
+ },
+ "secretCommentIV": {
+ "type": "string",
+ "example": ""
+ },
+ "secretCommentTag": {
+ "type": "string",
+ "example": ""
+ }
+ }
+ },
+ "UpdateSecret": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "example": ""
+ },
+ "secretKeyCiphertext": {
+ "type": "string",
+ "example": ""
+ },
+ "secretKeyIV": {
+ "type": "string",
+ "example": ""
+ },
+ "secretKeyTag": {
+ "type": "string",
+ "example": ""
+ },
+ "secretValueCiphertext": {
+ "type": "string",
+ "example": ""
+ },
+ "secretValueIV": {
+ "type": "string",
+ "example": ""
+ },
+ "secretValueTag": {
+ "type": "string",
+ "example": ""
+ },
+ "secretCommentCiphertext": {
+ "type": "string",
+ "example": ""
+ },
+ "secretCommentIV": {
+ "type": "string",
+ "example": ""
+ },
+ "secretCommentTag": {
+ "type": "string",
+ "example": ""
+ }
+ }
+ },
+ "Secret": {
+ "type": "object",
+ "properties": {
+ "_id": {
+ "type": "string",
+ "example": ""
+ },
+ "version": {
+ "type": "number",
+ "example": 1
+ },
+ "workspace": {
+ "type": "string",
+ "example": ""
+ },
+ "type": {
+ "type": "string",
+ "example": "shared"
+ },
+ "user": {},
+ "secretKeyCiphertext": {
+ "type": "string",
+ "example": ""
+ },
+ "secretKeyIV": {
+ "type": "string",
+ "example": ""
+ },
+ "secretKeyTag": {
+ "type": "string",
+ "example": ""
+ },
+ "secretValueCiphertext": {
+ "type": "string",
+ "example": ""
+ },
+ "secretValueIV": {
+ "type": "string",
+ "example": ""
+ },
+ "secretValueTag": {
+ "type": "string",
+ "example": ""
+ },
+ "secretCommentCiphertext": {
+ "type": "string",
+ "example": ""
+ },
+ "secretCommentIV": {
+ "type": "string",
+ "example": ""
+ },
+ "secretCommentTag": {
+ "type": "string",
+ "example": ""
+ },
+ "updatedAt": {
+ "type": "string",
+ "example": ""
+ },
+ "createdAt": {
+ "type": "string",
+ "example": ""
+ }
+ }
+ }
+ },
"securitySchemes": {
"bearerAuth": {
"type": "http",
"scheme": "bearer",
- "bearerFormat": "JWT"
+ "bearerFormat": "JWT",
+ "description": "This security definition uses the HTTP 'bearer' scheme, which allows the client to authenticate using a JSON Web Token (JWT) that is passed in the Authorization header of the request."
+ },
+ "apiKeyAuth": {
+ "type": "apiKey",
+ "in": "header",
+ "name": "X-API-Key",
+ "description": "This security definition uses an API key, which is passed in the header of the request as the value of the \"X-API-Key\" header. The client must provide a valid key in order to access the API."
}
}
}
diff --git a/backend/src/app.ts b/backend/src/app.ts
index aa7ac9b28..8cefd31ac 100644
--- a/backend/src/app.ts
+++ b/backend/src/app.ts
@@ -8,7 +8,7 @@ import cookieParser from 'cookie-parser';
import dotenv from 'dotenv';
import swaggerUi = require('swagger-ui-express');
// eslint-disable-next-line @typescript-eslint/no-var-requires
-const swaggerFile = require('../api-documentation.json')
+const swaggerFile = require('../spec.json')
dotenv.config();
@@ -41,7 +41,8 @@ import {
integrationAuth as v1IntegrationAuthRouter
} from './routes/v1';
import {
- secret as v2SecretRouter,
+ users as v2UsersRouter,
+ secret as v2SecretRouter, // begin to phase out
secrets as v2SecretsRouter,
workspace as v2WorkspaceRouter,
serviceTokenData as v2ServiceTokenDataRouter,
@@ -103,6 +104,7 @@ app.use('/api/v1/integration', v1IntegrationRouter);
app.use('/api/v1/integration-auth', v1IntegrationAuthRouter);
// v2 routes
+app.use('/api/v2/users', v2UsersRouter);
app.use('/api/v2/workspace', v2WorkspaceRouter); // TODO: turn into plural route
app.use('/api/v2/secret', v2SecretRouter); // stop supporting, TODO: revise
app.use('/api/v2/secrets', v2SecretsRouter);
diff --git a/backend/src/controllers/v1/authController.ts b/backend/src/controllers/v1/authController.ts
index defd03d8a..882db688f 100644
--- a/backend/src/controllers/v1/authController.ts
+++ b/backend/src/controllers/v1/authController.ts
@@ -170,10 +170,11 @@ export const logout = async (req: Request, res: Response) => {
* @param res
* @returns
*/
-export const checkAuth = async (req: Request, res: Response) =>
- res.status(200).send({
+export const checkAuth = async (req: Request, res: Response) => {
+ return res.status(200).send({
message: 'Authenticated'
});
+}
/**
* Return new token by redeeming refresh token
diff --git a/backend/src/controllers/v2/index.ts b/backend/src/controllers/v2/index.ts
index 1651c09ee..bc6848590 100644
--- a/backend/src/controllers/v2/index.ts
+++ b/backend/src/controllers/v2/index.ts
@@ -1,3 +1,4 @@
+import * as usersController from './usersController';
import * as workspaceController from './workspaceController';
import * as serviceTokenDataController from './serviceTokenDataController';
import * as apiKeyDataController from './apiKeyDataController';
@@ -5,6 +6,7 @@ import * as secretController from './secretController';
import * as secretsController from './secretsController';
export {
+ usersController,
workspaceController,
serviceTokenDataController,
apiKeyDataController,
diff --git a/backend/src/controllers/v2/secretsController.ts b/backend/src/controllers/v2/secretsController.ts
index 69cacd75c..31ad0d94c 100644
--- a/backend/src/controllers/v2/secretsController.ts
+++ b/backend/src/controllers/v2/secretsController.ts
@@ -21,6 +21,53 @@ import { BadRequestError } from '../../utils/errors';
* @param res
*/
export const createSecrets = async (req: Request, res: Response) => {
+ /*
+ #swagger.summary = 'Create new secret(s)'
+ #swagger.description = 'Create one or many secrets for a given project and environment.'
+
+ #swagger.security = [{
+ "apiKeyAuth": []
+ }]
+
+ #swagger.requestBody = {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "workspaceId": {
+ "type": "string",
+ "description": "ID of project",
+ },
+ "environment": {
+ "type": "string",
+ "description": "Environment within project"
+ },
+ "secrets": {
+ $ref: "#/components/schemas/CreateSecret",
+ "description": "Secret(s) to create - object or array of objects"
+ }
+ }
+ }
+ }
+ }
+ }
+
+ #swagger.responses[200] = {
+ content: {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ $ref: "#/components/schemas/Secret"
+ },
+ "description": "Array of newly-created secrets for the given project and environment"
+ }
+ }
+ }
+ }
+ */
const channel = req.headers?.['user-agent']?.toLowerCase().includes('mozilla') ? 'web' : 'cli';
const { workspaceId, environment } = req.body;
@@ -150,6 +197,49 @@ export const createSecrets = async (req: Request, res: Response) => {
* @returns
*/
export const getSecrets = async (req: Request, res: Response) => {
+ /*
+ #swagger.summary = 'Read secrets'
+ #swagger.description = 'Read secrets from a project and environment'
+
+ #swagger.security = [{
+ "apiKeyAuth": []
+ }]
+
+ #swagger.requestBody = {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "workspaceId": {
+ "type": "string",
+ "description": "ID of project"
+ },
+ "environment": {
+ "type": "string",
+ "description": "Environment within project"
+ }
+ }
+ }
+ }
+ }
+ }
+
+ #swagger.responses[200] = {
+ content: {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ $ref: "#/components/schemas/Secret"
+ },
+ "description": "Array of secrets for the given project and environment"
+ }
+ }
+ }
+ }
+ */
const { workspaceId, environment } = req.query;
let userId: Types.ObjectId | undefined = undefined // used for getting personal secrets for user
@@ -217,6 +307,48 @@ export const getSecrets = async (req: Request, res: Response) => {
* @param res
*/
export const updateSecrets = async (req: Request, res: Response) => {
+
+ // TODO: fix update secret schema
+
+ /*
+ #swagger.summary = 'Update secret(s)'
+ #swagger.description = 'Update secret(s)'
+
+ #swagger.security = [{
+ "apiKeyAuth": []
+ }]
+
+ #swagger.requestBody = {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "secrets": {
+ $ref: "#/components/schemas/UpdateSecret",
+ "description": "Secret(s) to update - object or array of objects"
+ }
+ }
+ }
+ }
+ }
+ }
+
+ #swagger.responses[200] = {
+ content: {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ $ref: "#/components/schemas/Secret"
+ },
+ "description": "Array of newly-updated secrets for the given project and environment"
+ }
+ }
+ }
+ }
+ */
const channel = req.headers?.['user-agent']?.toLowerCase().includes('mozilla') ? 'web' : 'cli';
// TODO: move type
@@ -384,6 +516,45 @@ export const updateSecrets = async (req: Request, res: Response) => {
* @param res
*/
export const deleteSecrets = async (req: Request, res: Response) => {
+ /*
+ #swagger.summary = 'Delete secret(s)'
+ #swagger.description = 'Delete one or many secrets by their ID(s)'
+
+ #swagger.security = [{
+ "apiKeyAuth": []
+ }]
+
+ #swagger.requestBody = {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "secretIds": {
+ "type": "string",
+ "description": "ID(s) of secrets - string or array of strings"
+ },
+ }
+ }
+ }
+ }
+ }
+
+ #swagger.responses[200] = {
+ content: {
+ "application/json": {
+ schema: {
+ "type": "array",
+ "items": {
+ $ref: "#/components/schemas/Secret"
+ },
+ "description": "Array of deleted secrets"
+ }
+ }
+ }
+ }
+ */
const channel = req.headers?.['user-agent']?.toLowerCase().includes('mozilla') ? 'web' : 'cli';
const toDelete = req.secrets.map((s: any) => s._id);
diff --git a/backend/src/controllers/v2/usersController.ts b/backend/src/controllers/v2/usersController.ts
new file mode 100644
index 000000000..faac8f646
--- /dev/null
+++ b/backend/src/controllers/v2/usersController.ts
@@ -0,0 +1,44 @@
+import { Request, Response } from 'express';
+import * as Sentry from '@sentry/node';
+import {
+ User
+} from '../../models';
+
+export const getMe = async (req: Request, res: Response) => {
+ /*
+ #swagger.summary = "Retrieve the current user on the request"
+ #swagger.description = "Retrieve the current user on the request"
+
+ #swagger.security = [{
+ "apiKeyAuth": []
+ }]
+
+ #swagger.responses[200] = {
+ content: {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ $ref: "#/components/schemas/CurrentUser",
+ "description": "Current user on request"
+ }
+ }
+ }
+ }
+ */
+ let user;
+ try {
+ user = await User
+ .findById(req.user._id)
+ .select('+publicKey +encryptedPrivateKey');
+ } catch (err) {
+ Sentry.setUser({ email: req.user.email });
+ Sentry.captureException(err);
+ return res.status(400).send({
+ message: 'Failed to get user'
+ });
+ }
+
+ return res.status(200).send({
+ user
+ });
+}
\ No newline at end of file
diff --git a/backend/src/controllers/v2/workspaceController.ts b/backend/src/controllers/v2/workspaceController.ts
index 0dbdfa076..6acec644d 100644
--- a/backend/src/controllers/v2/workspaceController.ts
+++ b/backend/src/controllers/v2/workspaceController.ts
@@ -169,6 +169,34 @@ export const pullSecrets = async (req: Request, res: Response) => {
};
export const getWorkspaceKey = async (req: Request, res: Response) => {
+ /*
+ #swagger.summary = 'Return encrypted project key'
+ #swagger.description = 'Return encrypted project key'
+
+ #swagger.security = [{
+ "apiKeyAuth": []
+ }]
+
+ #swagger.parameters['workspaceId'] = {
+ "description": "ID of project",
+ "required": true,
+ "type": "string"
+ }
+
+ #swagger.responses[200] = {
+ content: {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ $ref: "#/components/schemas/ProjectKey"
+ },
+ "description": "Encrypted project key for the given project"
+ }
+ }
+ }
+ }
+ */
let key;
try {
const { workspaceId } = req.params;
diff --git a/backend/src/routes/v2/index.ts b/backend/src/routes/v2/index.ts
index 8bea42620..a30c72642 100644
--- a/backend/src/routes/v2/index.ts
+++ b/backend/src/routes/v2/index.ts
@@ -1,3 +1,4 @@
+import users from './users';
import secret from './secret'; // stop-supporting
import secrets from './secrets';
import workspace from './workspace';
@@ -5,6 +6,7 @@ import serviceTokenData from './serviceTokenData';
import apiKeyData from './apiKeyData';
export {
+ users,
secret,
secrets,
workspace,
diff --git a/backend/src/routes/v2/users.ts b/backend/src/routes/v2/users.ts
new file mode 100644
index 000000000..dba107b15
--- /dev/null
+++ b/backend/src/routes/v2/users.ts
@@ -0,0 +1,16 @@
+import express from 'express';
+const router = express.Router();
+import {
+ requireAuth
+} from '../../middleware';
+import { usersController } from '../../controllers/v2';
+
+router.get(
+ '/me',
+ requireAuth({
+ acceptedAuthModes: ['jwt']
+ }),
+ usersController.getMe
+);
+
+export default router;
\ No newline at end of file
diff --git a/backend/swagger.ts b/backend/swagger.ts
deleted file mode 100644
index 0505bb813..000000000
--- a/backend/swagger.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-// eslint-disable-next-line @typescript-eslint/no-var-requires
-const swaggerAutogen = require('swagger-autogen')({ openapi: '3.0.0' });
-
-const doc = {
- info: {
- title: 'Infisical API',
- description: 'List of all available APIs that can be consumed',
- },
- host: ['https://infisical.com'],
- securityDefinitions: {
- bearerAuth: {
- type: 'http',
- scheme: 'bearer',
- bearerFormat: 'JWT'
- }
- }
-};
-
-const outputFile = './api-documentation.json';
-const endpointsFiles = ['./src/app.ts'];
-
-swaggerAutogen(outputFile, endpointsFiles, doc);
\ No newline at end of file
diff --git a/backend/swagger/index.ts b/backend/swagger/index.ts
new file mode 100644
index 000000000..2b8bc4f62
--- /dev/null
+++ b/backend/swagger/index.ts
@@ -0,0 +1,116 @@
+/* eslint-disable @typescript-eslint/no-var-requires */
+const swaggerAutogen = require('swagger-autogen')({ openapi: '3.0.0' });
+const fs = require('fs').promises;
+const yaml = require('js-yaml');
+const { secretSchema } = require('./schemas/index.ts');
+
+/**
+ * Generates OpenAPI specs for all Infisical API endpoints:
+ * - spec.json in /backend for api-serving
+ * - spec.yaml in /docs for API reference
+ */
+const generateOpenAPISpec = async () => {
+ const doc = {
+ info: {
+ title: 'Infisical API',
+ description: 'List of all available APIs that can be consumed',
+ },
+ host: ['https://infisical.com'],
+ servers: [
+ {
+ url: 'https://infisical.com',
+ description: 'Production server'
+ },
+ {
+ url: 'http://localhost:8080',
+ description: 'Local server'
+ }
+ ],
+ securityDefinitions: {
+ bearerAuth: {
+ type: 'http',
+ scheme: 'bearer',
+ bearerFormat: 'JWT',
+ description: "This security definition uses the HTTP 'bearer' scheme, which allows the client to authenticate using a JSON Web Token (JWT) that is passed in the Authorization header of the request."
+ },
+ apiKeyAuth: {
+ type: 'apiKey',
+ in: 'header',
+ name: 'X-API-Key',
+ description: 'This security definition uses an API key, which is passed in the header of the request as the value of the "X-API-Key" header. The client must provide a valid key in order to access the API.'
+ }
+ },
+ definitions: {
+ CurrentUser: {
+ _id: '',
+ email: '',
+ firstName: '',
+ lastName: '',
+ publicKey: '',
+ encryptedPrivateKey: '',
+ updatedAt: '',
+ createdAt: ''
+ },
+ ProjectKey: {
+ encryptedkey: '',
+ nonce: '',
+ sender: {
+ publicKey: ''
+ },
+ receiver: '',
+ workspace: ''
+ },
+ CreateSecret: {
+ type: 'shared',
+ secretKeyCiphertext: '',
+ secretKeyIV: '',
+ secretKeyTag: '',
+ secretValueCiphertext: '',
+ secretValueIV: '',
+ secretValueTag: '',
+ secretCommentCiphertext: '',
+ secretCommentIV: '',
+ secretCommentTag: ''
+ },
+ UpdateSecret: {
+ id: '',
+ secretKeyCiphertext: '',
+ secretKeyIV: '',
+ secretKeyTag: '',
+ secretValueCiphertext: '',
+ secretValueIV: '',
+ secretValueTag: '',
+ secretCommentCiphertext: '',
+ secretCommentIV: '',
+ secretCommentTag: ''
+ },
+ Secret: {
+ _id: '',
+ version: 1,
+ workspace : '',
+ type: 'shared',
+ user: null,
+ secretKeyCiphertext: '',
+ secretKeyIV: '',
+ secretKeyTag: '',
+ secretValueCiphertext: '',
+ secretValueIV: '',
+ secretValueTag: '',
+ secretCommentCiphertext: '',
+ secretCommentIV: '',
+ secretCommentTag: '',
+ updatedAt: '',
+ createdAt: ''
+ }
+ }
+ };
+
+ const outputJSONFile = '../spec.json';
+ const outputYAMLFile = '../docs/spec.yaml';
+ const endpointsFiles = ['../src/app.ts'];
+
+ const spec = await swaggerAutogen(outputJSONFile, endpointsFiles, doc);
+ await fs.writeFile(outputYAMLFile, yaml.dump(spec.data));
+}
+
+generateOpenAPISpec();
diff --git a/backend/swagger/schemas/index.ts b/backend/swagger/schemas/index.ts
new file mode 100644
index 000000000..b0b427fce
--- /dev/null
+++ b/backend/swagger/schemas/index.ts
@@ -0,0 +1,6 @@
+/* eslint-disable @typescript-eslint/no-var-requires */
+const secretSchema = require('./secretSchema.ts');
+
+module.exports = {
+ secretSchema
+}
\ No newline at end of file
diff --git a/backend/swagger/schemas/secretSchema.ts b/backend/swagger/schemas/secretSchema.ts
new file mode 100644
index 000000000..85c6ce017
--- /dev/null
+++ b/backend/swagger/schemas/secretSchema.ts
@@ -0,0 +1,11 @@
+const secretSchema = {
+ _id: {
+ type: 'string',
+ format: 'objectId'
+ },
+ version: {
+ type: 'number'
+ }
+}
+
+module.exports = secretSchema;
\ No newline at end of file
diff --git a/docs/api-reference/endpoints/secrets/read.mdx b/docs/api-reference/endpoints/secrets/read.mdx
index 4305f192c..c88fb0ec7 100644
--- a/docs/api-reference/endpoints/secrets/read.mdx
+++ b/docs/api-reference/endpoints/secrets/read.mdx
@@ -1,4 +1,4 @@
---
-title: "Read"
+title: "Retrieve"
openapi: "GET /api/v2/secrets/"
---
diff --git a/docs/api-reference/endpoints/users/me.mdx b/docs/api-reference/endpoints/users/me.mdx
new file mode 100644
index 000000000..9273f0ca6
--- /dev/null
+++ b/docs/api-reference/endpoints/users/me.mdx
@@ -0,0 +1,4 @@
+---
+title: "Get Current User"
+openapi: "GET /api/v2/users/me"
+---
diff --git a/docs/api-reference/endpoints/workspaces/workspace-key.mdx b/docs/api-reference/endpoints/workspaces/workspace-key.mdx
new file mode 100644
index 000000000..2658676a3
--- /dev/null
+++ b/docs/api-reference/endpoints/workspaces/workspace-key.mdx
@@ -0,0 +1,4 @@
+---
+title: "Get Project Key"
+openapi: "GET /api/v2/workspace/{workspaceId}/encrypted-key"
+---
diff --git a/docs/api-reference/overview/authentication.mdx b/docs/api-reference/overview/authentication.mdx
index 27a2dc134..8cc218253 100644
--- a/docs/api-reference/overview/authentication.mdx
+++ b/docs/api-reference/overview/authentication.mdx
@@ -1,3 +1,11 @@
---
title: "Authentication"
---
+
+To authenticate requests with Infisical, you must include an API key in the `X-API-KEY` header of HTTP requests made to the platform. You can obtain an API key from your user settings.
+
+
+ It's important to keep your API key secure, as it grants access to your
+ secrets in Infisical. For added security, consider rotating your API key on a
+ regular basis.
+
diff --git a/docs/api-reference/overview/examples/create-secrets.mdx b/docs/api-reference/overview/examples/create-secrets.mdx
new file mode 100644
index 000000000..94f830094
--- /dev/null
+++ b/docs/api-reference/overview/examples/create-secrets.mdx
@@ -0,0 +1,64 @@
+---
+title: "Create secrets"
+---
+
+In this example, we demonstrate how to add secrets to 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.
+5. Encrypt your secrets with the project key.
+6. Send (encrypted) secrets 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 WORKSPACE_KEY = "3a7a243eb62078c13f09203e75e8cb32";
+
+const secretKey = "SOME_KEY";
+const secretValue = "SOME_VALUE";
+
+// encrypt key of secret
+const {
+ ciphertext: secretKeyCiphertext,
+ iv: secretKeyIV,
+ tag: secretKeyTag,
+} = aes.encrypt(secretKey, WORKSPACE_KEY);
+
+// encrypt value of secret
+const {
+ ciphertext: secretValueCiphertext,
+ iv: secretValueIV,
+ tag: secretValueTag,
+} = aes.encrypt(secretKey, WORKSPACE_KEY);
+
+// construct request body
+const secret = {
+ secretKeyCiphertext,
+ secretKeyIV,
+ secretKeyTag,
+ secretValueCiphertext,
+ secretValueIV,
+ secretValueTag,
+};
+```
+
+
+ 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.
+
+
diff --git a/docs/api-reference/overview/examples/retrieve-secrets.mdx b/docs/api-reference/overview/examples/retrieve-secrets.mdx
new file mode 100644
index 000000000..2a314e65d
--- /dev/null
+++ b/docs/api-reference/overview/examples/retrieve-secrets.mdx
@@ -0,0 +1,10 @@
+---
+title: "Retrieve secrets"
+---
+
+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. Get secrets for a project and environment.
+6. Decrypt the secrets in your project.
diff --git a/docs/api-reference/overview/examples/update-secrets.mdx b/docs/api-reference/overview/examples/update-secrets.mdx
new file mode 100644
index 000000000..b302710a3
--- /dev/null
+++ b/docs/api-reference/overview/examples/update-secrets.mdx
@@ -0,0 +1,10 @@
+---
+title: "Update secrets"
+---
+
+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
diff --git a/docs/api-reference/overview/introduction.mdx b/docs/api-reference/overview/introduction.mdx
index 9632e3788..f93ba91fe 100644
--- a/docs/api-reference/overview/introduction.mdx
+++ b/docs/api-reference/overview/introduction.mdx
@@ -1,3 +1,19 @@
---
title: "Introduction"
---
+
+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
+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.
+
+## Concepts
+
+Using Infisical's API to manage secrets requires a basic understanding of the system and its underlying cryptography detailed [here](/security/overview).
+
+- Each user has a public/private key pair that is stored with the platform; private keys are encrypted locally by the user's password before being sent off to the server during the account signup process.
+- Each (encrypted) secret belongs to a project and environment.
+- 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.
diff --git a/docs/api-reference/overview/usage.mdx b/docs/api-reference/overview/usage.mdx
new file mode 100644
index 000000000..9f23080c7
--- /dev/null
+++ b/docs/api-reference/overview/usage.mdx
@@ -0,0 +1,18 @@
+---
+title: "Usage"
+---
+
+Prerequisites:
+
+- Set up and add envars to [Infisical Cloud](https://app.infisical.com) or your self-hosted instance.
+- Obtain an API Key in your user settings to be included in requests to the Infisical API.
+
+Using Infisical's API to manage secrets requires a basic understanding of the system and its underlying cryptography detailed [here](/security/overview).
+
+## Concepts
+
+- Each user has a public/private key pair that is stored with the platform; private keys are encrypted locally by the user's password before being sent off to the server during the account signup process.
+- Each (encrypted) secret belongs to a project and environment.
+- 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.
diff --git a/docs/mint.json b/docs/mint.json
index 363b27a3e..39a3726d9 100644
--- a/docs/mint.json
+++ b/docs/mint.json
@@ -21,6 +21,16 @@
"to": "#F8B7BD"
}
},
+ "api": {
+ "baseUrl": [
+ "https://app.infisical.com",
+ "http://localhost:8080"
+ ],
+ "auth": {
+ "method": "api-key",
+ "name": "X-API-KEY"
+ }
+ },
"topbarLinks": [
{ "name": "Log In", "url": "https://app.infisical.com/login" }
],
@@ -134,12 +144,32 @@
"group": "Overview",
"pages": [
"api-reference/overview/introduction",
- "api-reference/overview/authentication"
+ "api-reference/overview/authentication",
+ {
+ "group": "Examples",
+ "pages": [
+ "api-reference/overview/examples/create-secrets",
+ "api-reference/overview/examples/retrieve-secrets",
+ "api-reference/overview/examples/update-secrets"
+ ]
+ }
]
},
{
"group": "Endpoints",
"pages": [
+ {
+ "group": "Users",
+ "pages": [
+ "api-reference/endpoints/users/me"
+ ]
+ },
+ {
+ "group": "Projects",
+ "pages": [
+ "api-reference/endpoints/workspaces/workspace-key"
+ ]
+ },
{
"group": "Secrets",
"pages": [
diff --git a/docs/spec.yaml b/docs/spec.yaml
index a0271395b..dd62f167b 100644
--- a/docs/spec.yaml
+++ b/docs/spec.yaml
@@ -4,7 +4,10 @@ info:
description: List of all available APIs that can be consumed
version: 1.0.0
servers:
+ - url: https://infisical.com
+ description: Production server
- url: http://localhost:8080
+ description: Local server
paths:
/api/v1/secret/{secretId}/secret-versions:
get:
@@ -1270,6 +1273,24 @@ paths:
description: OK
'400':
description: Bad Request
+ /api/v2/users/me:
+ get:
+ summary: Retrieve the current user on the request
+ description: Retrieve the current user on the request
+ parameters: []
+ responses:
+ '200':
+ description: OK
+ content:
+ application/json:
+ schema:
+ type: object
+ $ref: '#/components/schemas/CurrentUser'
+ description: Current user on request
+ '400':
+ description: Bad Request
+ security:
+ - apiKeyAuth: []
/api/v2/workspace/{workspaceId}/secrets:
post:
description: ''
@@ -1321,18 +1342,29 @@ paths:
description: Bad Request
/api/v2/workspace/{workspaceId}/encrypted-key:
get:
- description: ''
+ summary: Return encrypted project key
+ description: Return encrypted project key
parameters:
- name: workspaceId
in: path
required: true
schema:
type: string
+ description: ID of project
responses:
'200':
description: OK
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/ProjectKey'
+ description: Encrypted project key for the given project
'400':
description: Bad Request
+ security:
+ - apiKeyAuth: []
/api/v2/workspace/{workspaceId}/service-token-data:
get:
description: ''
@@ -1513,57 +1545,122 @@ paths:
example: any
/api/v2/secrets/:
post:
- description: ''
+ summary: Create new secret(s)
+ description: Create one or many secrets for a given project and environment.
parameters: []
responses:
'200':
description: OK
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/Secret'
+ description: >-
+ Array of newly-created secrets for the given project and
+ environment
+ security:
+ - apiKeyAuth: []
requestBody:
+ required: true
content:
application/json:
schema:
type: object
properties:
- secrets:
- example: any
workspaceId:
- example: any
+ type: string
+ description: ID of project
environment:
- example: any
+ type: string
+ description: Environment within project
+ secrets:
+ $ref: '#/components/schemas/CreateSecret'
+ description: Secret(s) to create - object or array of objects
get:
- description: ''
- parameters:
- - name: workspaceId
- in: query
- schema:
- type: string
- - name: environment
- in: query
- schema:
- type: string
- responses:
- '200':
- description: OK
- patch:
- description: ''
+ summary: Read secrets
+ description: Read secrets from a project and environment
parameters: []
responses:
'200':
description: OK
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/Secret'
+ description: Array of secrets for the given project and environment
+ security:
+ - apiKeyAuth: []
requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ workspaceId:
+ type: string
+ description: ID of project
+ environment:
+ type: string
+ description: Environment within project
+ patch:
+ summary: Update secret(s)
+ description: Update secret(s)
+ parameters: []
+ responses:
+ '200':
+ description: OK
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/Secret'
+ description: >-
+ Array of newly-updated secrets for the given project and
+ environment
+ security:
+ - apiKeyAuth: []
+ requestBody:
+ required: true
content:
application/json:
schema:
type: object
properties:
secrets:
- example: any
+ $ref: '#/components/schemas/UpdateSecret'
+ description: Secret(s) to update - object or array of objects
delete:
- description: ''
+ summary: Delete secret(s)
+ description: Delete one or many secrets by their ID(s)
parameters: []
responses:
'200':
description: OK
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/Secret'
+ description: Array of deleted secrets
+ security:
+ - apiKeyAuth: []
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ secretIds:
+ type: string
+ description: ID(s) of secrets - string or array of strings
/api/v2/service-token/:
get:
description: ''
@@ -1665,26 +1762,183 @@ paths:
description: OK
components:
schemas:
- secret:
+ CurrentUser:
+ type: object
+ properties:
+ _id:
+ type: string
+ example: ''
+ email:
+ type: string
+ example: ''
+ firstName:
+ type: string
+ example: ''
+ lastName:
+ type: string
+ example: ''
+ publicKey:
+ type: string
+ example: ''
+ encryptedPrivateKey:
+ type: string
+ example: ''
+ updatedAt:
+ type: string
+ example: ''
+ createdAt:
+ type: string
+ example: ''
+ ProjectKey:
+ type: object
+ properties:
+ encryptedkey:
+ type: string
+ example: ''
+ nonce:
+ type: string
+ example: ''
+ sender:
+ type: object
+ properties:
+ publicKey:
+ type: string
+ example: ''
+ receiver:
+ type: string
+ example: ''
+ workspace:
+ type: string
+ example: ''
+ CreateSecret:
type: object
properties:
type:
type: string
- example: object
- properties:
- type: object
- properties:
- test:
- type: object
- properties:
- type:
- type: string
- example: integer
- description:
- type: string
- example: '123'
+ example: shared
+ secretKeyCiphertext:
+ type: string
+ example: ''
+ secretKeyIV:
+ type: string
+ example: ''
+ secretKeyTag:
+ type: string
+ example: ''
+ secretValueCiphertext:
+ type: string
+ example: ''
+ secretValueIV:
+ type: string
+ example: ''
+ secretValueTag:
+ type: string
+ example: ''
+ secretCommentCiphertext:
+ type: string
+ example: ''
+ secretCommentIV:
+ type: string
+ example: ''
+ secretCommentTag:
+ type: string
+ example: ''
+ UpdateSecret:
+ type: object
+ properties:
+ id:
+ type: string
+ example: ''
+ secretKeyCiphertext:
+ type: string
+ example: ''
+ secretKeyIV:
+ type: string
+ example: ''
+ secretKeyTag:
+ type: string
+ example: ''
+ secretValueCiphertext:
+ type: string
+ example: ''
+ secretValueIV:
+ type: string
+ example: ''
+ secretValueTag:
+ type: string
+ example: ''
+ secretCommentCiphertext:
+ type: string
+ example: ''
+ secretCommentIV:
+ type: string
+ example: ''
+ secretCommentTag:
+ type: string
+ example: ''
+ Secret:
+ type: object
+ properties:
+ _id:
+ type: string
+ example: ''
+ version:
+ type: number
+ example: 1
+ workspace:
+ type: string
+ example: ''
+ type:
+ type: string
+ example: shared
+ user: {}
+ secretKeyCiphertext:
+ type: string
+ example: ''
+ secretKeyIV:
+ type: string
+ example: ''
+ secretKeyTag:
+ type: string
+ example: ''
+ secretValueCiphertext:
+ type: string
+ example: ''
+ secretValueIV:
+ type: string
+ example: ''
+ secretValueTag:
+ type: string
+ example: ''
+ secretCommentCiphertext:
+ type: string
+ example: ''
+ secretCommentIV:
+ type: string
+ example: ''
+ secretCommentTag:
+ type: string
+ example: ''
+ updatedAt:
+ type: string
+ example: ''
+ createdAt:
+ type: string
+ example: ''
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
+ description: >-
+ This security definition uses the HTTP 'bearer' scheme, which allows the
+ client to authenticate using a JSON Web Token (JWT) that is passed in
+ the Authorization header of the request.
+ apiKeyAuth:
+ type: apiKey
+ in: header
+ name: X-API-Key
+ description: >-
+ This security definition uses an API key, which is passed in the header
+ of the request as the value of the "X-API-Key" header. The client must
+ provide a valid key in order to access the API.