mirror of
https://github.com/Infisical/infisical.git
synced 2025-03-29 22:02:57 +00:00
Complete v1 API reference docs, pre-launch
This commit is contained in:
@ -18,7 +18,8 @@
|
|||||||
"paths": {
|
"paths": {
|
||||||
"/api/v1/secret/{secretId}/secret-versions": {
|
"/api/v1/secret/{secretId}/secret-versions": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "",
|
"summary": "Return secret versions",
|
||||||
|
"description": "Return secret versions",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"name": "secretId",
|
"name": "secretId",
|
||||||
@ -26,10 +27,13 @@
|
|||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
},
|
||||||
|
"description": "ID of secret"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "offset",
|
"name": "offset",
|
||||||
|
"description": "Number of versions to skip",
|
||||||
|
"required": false,
|
||||||
"in": "query",
|
"in": "query",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@ -37,6 +41,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "limit",
|
"name": "limit",
|
||||||
|
"description": "Maximum number of versions to return",
|
||||||
|
"required": false,
|
||||||
"in": "query",
|
"in": "query",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@ -45,17 +51,39 @@
|
|||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK"
|
"description": "OK",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"secretVersions": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/SecretVersion"
|
||||||
|
},
|
||||||
|
"description": "Secret versions"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"400": {
|
"400": {
|
||||||
"description": "Bad Request"
|
"description": "Bad Request"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api/v1/secret/{secretId}/secret-versions/rollback": {
|
"/api/v1/secret/{secretId}/secret-versions/rollback": {
|
||||||
"post": {
|
"post": {
|
||||||
"description": "",
|
"summary": "Roll back secret to a version.",
|
||||||
|
"description": "Roll back secret to a version.",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"name": "secretId",
|
"name": "secretId",
|
||||||
@ -63,25 +91,47 @@
|
|||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
},
|
||||||
|
"description": "ID of secret"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK"
|
"description": "OK",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"secret": {
|
||||||
|
"type": "object",
|
||||||
|
"$ref": "#/components/schemas/Secret",
|
||||||
|
"description": "Secret rolled back to"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"400": {
|
"400": {
|
||||||
"description": "Bad Request"
|
"description": "Bad Request"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
"requestBody": {
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"version": {
|
"version": {
|
||||||
"example": "any"
|
"type": "integer",
|
||||||
|
"description": "Version of secret to roll back to"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,7 +165,8 @@
|
|||||||
},
|
},
|
||||||
"/api/v1/workspace/{workspaceId}/secret-snapshots": {
|
"/api/v1/workspace/{workspaceId}/secret-snapshots": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "",
|
"summary": "Return project secret snapshot ids",
|
||||||
|
"description": "Return project secret snapshots ids",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"name": "workspaceId",
|
"name": "workspaceId",
|
||||||
@ -123,10 +174,13 @@
|
|||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
},
|
||||||
|
"description": "ID of project"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "offset",
|
"name": "offset",
|
||||||
|
"description": "Number of secret snapshots to skip",
|
||||||
|
"required": false,
|
||||||
"in": "query",
|
"in": "query",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@ -134,6 +188,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "limit",
|
"name": "limit",
|
||||||
|
"description": "Maximum number of secret snapshots to return",
|
||||||
|
"required": false,
|
||||||
"in": "query",
|
"in": "query",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@ -142,12 +198,33 @@
|
|||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK"
|
"description": "OK",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"secretSnapshots": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/SecretSnapshot"
|
||||||
|
},
|
||||||
|
"description": "Project secret snapshots"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"400": {
|
"400": {
|
||||||
"description": "Bad Request"
|
"description": "Bad Request"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api/v1/workspace/{workspaceId}/secret-snapshots/count": {
|
"/api/v1/workspace/{workspaceId}/secret-snapshots/count": {
|
||||||
@ -175,8 +252,8 @@
|
|||||||
},
|
},
|
||||||
"/api/v1/workspace/{workspaceId}/secret-snapshots/rollback": {
|
"/api/v1/workspace/{workspaceId}/secret-snapshots/rollback": {
|
||||||
"post": {
|
"post": {
|
||||||
"summary": "Roll back project secrets to those captured in a secret snapshot version",
|
"summary": "Roll back project secrets to those captured in a secret snapshot version.",
|
||||||
"description": "Roll back project secrets to those captured in a secret snapshot version",
|
"description": "Roll back project secrets to those captured in a secret snapshot version.",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"name": "workspaceId",
|
"name": "workspaceId",
|
||||||
@ -194,11 +271,16 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "array",
|
"type": "object",
|
||||||
"items": {
|
"properties": {
|
||||||
"$ref": "#/components/schemas/Secret"
|
"secrets": {
|
||||||
},
|
"type": "array",
|
||||||
"description": "Array of secrets captured in the secret snapshot"
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/Secret"
|
||||||
|
},
|
||||||
|
"description": "Secrets rolled back to"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -232,18 +314,31 @@
|
|||||||
},
|
},
|
||||||
"/api/v1/workspace/{workspaceId}/logs": {
|
"/api/v1/workspace/{workspaceId}/logs": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "",
|
"summary": "Return project (audit) logs",
|
||||||
|
"description": "Return project (audit) logs",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"name": "workspaceId",
|
"name": "workspaceId",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true,
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": "ID of project"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "userId",
|
||||||
|
"description": "ID of project member",
|
||||||
|
"required": false,
|
||||||
|
"in": "query",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "offset",
|
"name": "offset",
|
||||||
|
"description": "Number of logs to skip",
|
||||||
|
"required": false,
|
||||||
"in": "query",
|
"in": "query",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@ -251,6 +346,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "limit",
|
"name": "limit",
|
||||||
|
"description": "Maximum number of logs to return",
|
||||||
|
"required": false,
|
||||||
"in": "query",
|
"in": "query",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@ -258,20 +355,21 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sortBy",
|
"name": "sortBy",
|
||||||
"in": "query",
|
"description": "Order to sort the logs by",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "string"
|
"type": "string",
|
||||||
}
|
"enum": [
|
||||||
},
|
"oldest",
|
||||||
{
|
"recent"
|
||||||
"name": "userId",
|
]
|
||||||
"in": "query",
|
},
|
||||||
"schema": {
|
"required": false,
|
||||||
"type": "string"
|
"in": "query"
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "actionNames",
|
"name": "actionNames",
|
||||||
|
"description": "Names of log actions (comma-separated)",
|
||||||
|
"required": false,
|
||||||
"in": "query",
|
"in": "query",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@ -280,12 +378,33 @@
|
|||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK"
|
"description": "OK",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"logs": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/Log"
|
||||||
|
},
|
||||||
|
"description": "Project logs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"400": {
|
"400": {
|
||||||
"description": "Bad Request"
|
"description": "Bad Request"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api/v1/action/{actionId}": {
|
"/api/v1/action/{actionId}": {
|
||||||
@ -2117,8 +2236,13 @@
|
|||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/components/schemas/CurrentUser",
|
"properties": {
|
||||||
"description": "Current user on request"
|
"user": {
|
||||||
|
"type": "object",
|
||||||
|
"$ref": "#/components/schemas/CurrentUser",
|
||||||
|
"description": "Current user on request"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2279,6 +2403,170 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/v2/workspace/{workspaceId}/memberships": {
|
||||||
|
"get": {
|
||||||
|
"summary": "Return project memberships",
|
||||||
|
"description": "Return project memberships",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "workspaceId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": "ID of project"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"memberships": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/Membership"
|
||||||
|
},
|
||||||
|
"description": "Memberships of project"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v2/workspace/{workspaceId}/memberships/{membershipId}": {
|
||||||
|
"delete": {
|
||||||
|
"summary": "Delete project membership",
|
||||||
|
"description": "Delete project membership",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "workspaceId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": "ID of project"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "membershipId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": "ID of membership"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"membership": {
|
||||||
|
"$ref": "#/components/schemas/Membership",
|
||||||
|
"description": "Deleted membership"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"patch": {
|
||||||
|
"summary": "Update project membership",
|
||||||
|
"description": "Update project membership",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "workspaceId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": "ID of project"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "membershipId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": "ID of membership"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"membership": {
|
||||||
|
"$ref": "#/components/schemas/Membership",
|
||||||
|
"description": "Updated membership"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"role": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Role of membership - either admin or member"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/v2/secret/batch-create/workspace/{workspaceId}/environment/{environment}": {
|
"/api/v2/secret/batch-create/workspace/{workspaceId}/environment/{environment}": {
|
||||||
"post": {
|
"post": {
|
||||||
"description": "",
|
"description": "",
|
||||||
@ -2565,11 +2853,16 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "array",
|
"type": "object",
|
||||||
"items": {
|
"properties": {
|
||||||
"$ref": "#/components/schemas/Secret"
|
"secrets": {
|
||||||
},
|
"type": "array",
|
||||||
"description": "Array of newly-created secrets for the given project and environment"
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/Secret"
|
||||||
|
},
|
||||||
|
"description": "Newly-created secrets for the given project and environment"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2608,18 +2901,49 @@
|
|||||||
"get": {
|
"get": {
|
||||||
"summary": "Read secrets",
|
"summary": "Read secrets",
|
||||||
"description": "Read secrets from a project and environment",
|
"description": "Read secrets from a project and environment",
|
||||||
"parameters": [],
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "workspaceId",
|
||||||
|
"description": "ID of project",
|
||||||
|
"required": true,
|
||||||
|
"in": "query",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "environment",
|
||||||
|
"description": "Environment within project",
|
||||||
|
"required": true,
|
||||||
|
"in": "query",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "content",
|
||||||
|
"in": "query",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "array",
|
"type": "object",
|
||||||
"items": {
|
"properties": {
|
||||||
"$ref": "#/components/schemas/Secret"
|
"secrets": {
|
||||||
},
|
"type": "array",
|
||||||
"description": "Array of secrets for the given project and environment"
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/Secret"
|
||||||
|
},
|
||||||
|
"description": "Secrets for the given project and environment"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2629,27 +2953,7 @@
|
|||||||
{
|
{
|
||||||
"apiKeyAuth": []
|
"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": {
|
"patch": {
|
||||||
"summary": "Update secret(s)",
|
"summary": "Update secret(s)",
|
||||||
@ -2661,11 +2965,16 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "array",
|
"type": "object",
|
||||||
"items": {
|
"properties": {
|
||||||
"$ref": "#/components/schemas/Secret"
|
"secrets": {
|
||||||
},
|
"type": "array",
|
||||||
"description": "Array of newly-updated secrets for the given project and environment"
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/Secret"
|
||||||
|
},
|
||||||
|
"description": "Updated secrets"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2703,11 +3012,16 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "array",
|
"type": "object",
|
||||||
"items": {
|
"properties": {
|
||||||
"$ref": "#/components/schemas/Secret"
|
"secrets": {
|
||||||
},
|
"type": "array",
|
||||||
"description": "Array of deleted secrets"
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/Secret"
|
||||||
|
},
|
||||||
|
"description": "Deleted secrets"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2942,6 +3256,52 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Membership": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"user": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"_id": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"firstName": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"lastName": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"publicKey": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"updatedAt": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"workspace": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "admin"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"ProjectKey": {
|
"ProjectKey": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -3127,6 +3487,187 @@
|
|||||||
"example": ""
|
"example": ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"Log": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"_id": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"_id": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"firstName": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"lastName": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"workspace": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"actionNames": {
|
||||||
|
"type": "array",
|
||||||
|
"example": [
|
||||||
|
"addSecrets"
|
||||||
|
],
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "addSecrets"
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"workspace": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"payload": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"oldSecretVersion": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"newSecretVersion": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"channel": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "cli"
|
||||||
|
},
|
||||||
|
"ipAddress": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "192.168.0.1"
|
||||||
|
},
|
||||||
|
"updatedAt": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SecretSnapshot": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"workspace": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"version": {
|
||||||
|
"type": "number",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"secretVersions": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"_id": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SecretVersion": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"_id": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"secret": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"version": {
|
||||||
|
"type": "number",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"workspace": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"environment": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"isDeleted": {
|
||||||
|
"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": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"securitySchemes": {
|
"securitySchemes": {
|
||||||
|
@ -58,11 +58,16 @@ export const createSecrets = async (req: Request, res: Response) => {
|
|||||||
content: {
|
content: {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "array",
|
"type": "object",
|
||||||
"items": {
|
"properties": {
|
||||||
$ref: "#/components/schemas/Secret"
|
"secrets": {
|
||||||
},
|
"type": "array",
|
||||||
"description": "Array of newly-created secrets for the given project and environment"
|
"items": {
|
||||||
|
$ref: "#/components/schemas/Secret"
|
||||||
|
},
|
||||||
|
"description": "Newly-created secrets for the given project and environment"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -205,36 +210,32 @@ export const getSecrets = async (req: Request, res: Response) => {
|
|||||||
"apiKeyAuth": []
|
"apiKeyAuth": []
|
||||||
}]
|
}]
|
||||||
|
|
||||||
#swagger.requestBody = {
|
#swagger.parameters['workspaceId'] = {
|
||||||
"required": true,
|
"description": "ID of project",
|
||||||
"content": {
|
"required": true,
|
||||||
"application/json": {
|
"type": "string"
|
||||||
"schema": {
|
}
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
#swagger.parameters['environment'] = {
|
||||||
"workspaceId": {
|
"description": "Environment within project",
|
||||||
"type": "string",
|
"required": true,
|
||||||
"description": "ID of project"
|
"type": "string"
|
||||||
},
|
}
|
||||||
"environment": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Environment within project"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#swagger.responses[200] = {
|
#swagger.responses[200] = {
|
||||||
content: {
|
content: {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "array",
|
"type": "object",
|
||||||
"items": {
|
"properties": {
|
||||||
$ref: "#/components/schemas/Secret"
|
"secrets": {
|
||||||
},
|
"type": "array",
|
||||||
"description": "Array of secrets for the given project and environment"
|
"items": {
|
||||||
|
$ref: "#/components/schemas/Secret"
|
||||||
|
},
|
||||||
|
"description": "Secrets for the given project and environment"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -307,9 +308,6 @@ export const getSecrets = async (req: Request, res: Response) => {
|
|||||||
* @param res
|
* @param res
|
||||||
*/
|
*/
|
||||||
export const updateSecrets = async (req: Request, res: Response) => {
|
export const updateSecrets = async (req: Request, res: Response) => {
|
||||||
|
|
||||||
// TODO: fix update secret schema
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#swagger.summary = 'Update secret(s)'
|
#swagger.summary = 'Update secret(s)'
|
||||||
#swagger.description = 'Update secret(s)'
|
#swagger.description = 'Update secret(s)'
|
||||||
@ -339,15 +337,20 @@ export const updateSecrets = async (req: Request, res: Response) => {
|
|||||||
content: {
|
content: {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "array",
|
"type": "object",
|
||||||
"items": {
|
"properties": {
|
||||||
$ref: "#/components/schemas/Secret"
|
"secrets": {
|
||||||
},
|
"type": "array",
|
||||||
"description": "Array of newly-updated secrets for the given project and environment"
|
"items": {
|
||||||
|
$ref: "#/components/schemas/Secret"
|
||||||
|
},
|
||||||
|
"description": "Updated secrets"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
const channel = req.headers?.['user-agent']?.toLowerCase().includes('mozilla') ? 'web' : 'cli';
|
const channel = req.headers?.['user-agent']?.toLowerCase().includes('mozilla') ? 'web' : 'cli';
|
||||||
|
|
||||||
@ -544,12 +547,17 @@ export const deleteSecrets = async (req: Request, res: Response) => {
|
|||||||
#swagger.responses[200] = {
|
#swagger.responses[200] = {
|
||||||
content: {
|
content: {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
schema: {
|
"schema": {
|
||||||
"type": "array",
|
"type": "object",
|
||||||
"items": {
|
"properties": {
|
||||||
$ref: "#/components/schemas/Secret"
|
"secrets": {
|
||||||
},
|
"type": "array",
|
||||||
"description": "Array of deleted secrets"
|
"items": {
|
||||||
|
$ref: "#/components/schemas/Secret"
|
||||||
|
},
|
||||||
|
"description": "Deleted secrets"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,13 @@ export const getMe = async (req: Request, res: Response) => {
|
|||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
$ref: "#/components/schemas/CurrentUser",
|
"properties": {
|
||||||
"description": "Current user on request"
|
"user": {
|
||||||
|
"type": "object",
|
||||||
|
$ref: "#/components/schemas/CurrentUser",
|
||||||
|
"description": "Current user on request"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import * as Sentry from '@sentry/node';
|
import * as Sentry from '@sentry/node';
|
||||||
|
import { Types } from 'mongoose';
|
||||||
import {
|
import {
|
||||||
Workspace,
|
Workspace,
|
||||||
|
Secret,
|
||||||
Membership,
|
Membership,
|
||||||
MembershipOrg,
|
MembershipOrg,
|
||||||
Integration,
|
Integration,
|
||||||
@ -242,4 +244,222 @@ export const getWorkspaceServiceTokenData = async (
|
|||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
serviceTokenData
|
serviceTokenData
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return memberships for workspace with id [workspaceId]
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const getWorkspaceMemberships = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Return project memberships'
|
||||||
|
#swagger.description = 'Return project memberships'
|
||||||
|
|
||||||
|
#swagger.security = [{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}]
|
||||||
|
|
||||||
|
#swagger.parameters['workspaceId'] = {
|
||||||
|
"description": "ID of project",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"memberships": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
$ref: "#/components/schemas/Membership"
|
||||||
|
},
|
||||||
|
"description": "Memberships of project"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
let memberships;
|
||||||
|
try {
|
||||||
|
const { workspaceId } = req.params;
|
||||||
|
|
||||||
|
memberships = await Membership.find({
|
||||||
|
workspace: workspaceId
|
||||||
|
}).populate('user', '+publicKey');
|
||||||
|
} catch (err) {
|
||||||
|
Sentry.setUser({ email: req.user.email });
|
||||||
|
Sentry.captureException(err);
|
||||||
|
return res.status(400).send({
|
||||||
|
message: 'Failed to get workspace members'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(200).send({
|
||||||
|
memberships
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete workspace membership with id [membershipId]
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const deleteWorkspaceMembership = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Delete project membership'
|
||||||
|
#swagger.description = 'Delete project membership'
|
||||||
|
|
||||||
|
#swagger.security = [{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}]
|
||||||
|
|
||||||
|
#swagger.parameters['workspaceId'] = {
|
||||||
|
"description": "ID of project",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.parameters['membershipId'] = {
|
||||||
|
"description": "ID of membership",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"membership": {
|
||||||
|
$ref: "#/components/schemas/Membership",
|
||||||
|
"description": "Deleted membership"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
let membership;
|
||||||
|
try {
|
||||||
|
const {
|
||||||
|
membershipId
|
||||||
|
} = req.params;
|
||||||
|
|
||||||
|
membership = await Membership.findByIdAndDelete(membershipId);
|
||||||
|
|
||||||
|
if (!membership) throw new Error('Failed to delete workspace membership');
|
||||||
|
|
||||||
|
await Key.deleteMany({
|
||||||
|
receiver: membership.user,
|
||||||
|
workspace: membership.workspace
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
Sentry.setUser({ email: req.user.email });
|
||||||
|
Sentry.captureException(err);
|
||||||
|
return res.status(400).send({
|
||||||
|
message: 'Failed to delete workspace membership'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(200).send({
|
||||||
|
membership
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update role of membership with id [membershipId] to role [role]
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const updateWorkspaceMembership = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Update project membership'
|
||||||
|
#swagger.description = 'Update project membership'
|
||||||
|
|
||||||
|
#swagger.security = [{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}]
|
||||||
|
|
||||||
|
#swagger.parameters['workspaceId'] = {
|
||||||
|
"description": "ID of project",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.parameters['membershipId'] = {
|
||||||
|
"description": "ID of membership",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.requestBody = {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"role": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Role of membership - either admin or member",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"membership": {
|
||||||
|
$ref: "#/components/schemas/Membership",
|
||||||
|
"description": "Updated membership"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
let membership;
|
||||||
|
try {
|
||||||
|
const {
|
||||||
|
membershipId
|
||||||
|
} = req.params;
|
||||||
|
const { role } = req.body;
|
||||||
|
|
||||||
|
membership = await Membership.findByIdAndUpdate(
|
||||||
|
membershipId,
|
||||||
|
{
|
||||||
|
role
|
||||||
|
}, {
|
||||||
|
new: true
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
Sentry.setUser({ email: req.user.email });
|
||||||
|
Sentry.captureException(err);
|
||||||
|
return res.status(400).send({
|
||||||
|
message: 'Failed to update workspace membership'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(200).send({
|
||||||
|
membership
|
||||||
|
});
|
||||||
}
|
}
|
@ -10,6 +10,51 @@ import { EESecretService } from '../../services';
|
|||||||
* @param res
|
* @param res
|
||||||
*/
|
*/
|
||||||
export const getSecretVersions = async (req: Request, res: Response) => {
|
export const getSecretVersions = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Return secret versions'
|
||||||
|
#swagger.description = 'Return secret versions'
|
||||||
|
|
||||||
|
#swagger.security = [{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}]
|
||||||
|
|
||||||
|
#swagger.parameters['secretId'] = {
|
||||||
|
"description": "ID of secret",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.parameters['offset'] = {
|
||||||
|
"description": "Number of versions to skip",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.parameters['limit'] = {
|
||||||
|
"description": "Maximum number of versions to return",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
schema: {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"secretVersions": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
$ref: "#/components/schemas/SecretVersion"
|
||||||
|
},
|
||||||
|
"description": "Secret versions"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
let secretVersions;
|
let secretVersions;
|
||||||
try {
|
try {
|
||||||
const { secretId } = req.params;
|
const { secretId } = req.params;
|
||||||
@ -44,6 +89,54 @@ import { EESecretService } from '../../services';
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const rollbackSecretVersion = async (req: Request, res: Response) => {
|
export const rollbackSecretVersion = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Roll back secret to a version.'
|
||||||
|
#swagger.description = 'Roll back secret to a version.'
|
||||||
|
|
||||||
|
#swagger.security = [{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}]
|
||||||
|
|
||||||
|
#swagger.parameters['secretId'] = {
|
||||||
|
"description": "ID of secret",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.requestBody = {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"version": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "Version of secret to roll back to"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
schema: {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"secret": {
|
||||||
|
"type": "object",
|
||||||
|
$ref: "#/components/schemas/Secret",
|
||||||
|
"description": "Secret rolled back to"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
let secret;
|
let secret;
|
||||||
try {
|
try {
|
||||||
const { secretId } = req.params;
|
const { secretId } = req.params;
|
||||||
|
@ -19,6 +19,51 @@ import { getLatestSecretVersionIds } from '../../helpers/secretVersion';
|
|||||||
* @param res
|
* @param res
|
||||||
*/
|
*/
|
||||||
export const getWorkspaceSecretSnapshots = async (req: Request, res: Response) => {
|
export const getWorkspaceSecretSnapshots = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Return project secret snapshot ids'
|
||||||
|
#swagger.description = 'Return project secret snapshots ids'
|
||||||
|
|
||||||
|
#swagger.security = [{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}]
|
||||||
|
|
||||||
|
#swagger.parameters['workspaceId'] = {
|
||||||
|
"description": "ID of project",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.parameters['offset'] = {
|
||||||
|
"description": "Number of secret snapshots to skip",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.parameters['limit'] = {
|
||||||
|
"description": "Maximum number of secret snapshots to return",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
schema: {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"secretSnapshots": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
$ref: "#/components/schemas/SecretSnapshot"
|
||||||
|
},
|
||||||
|
"description": "Project secret snapshots"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
let secretSnapshots;
|
let secretSnapshots;
|
||||||
try {
|
try {
|
||||||
const { workspaceId } = req.params;
|
const { workspaceId } = req.params;
|
||||||
@ -79,8 +124,8 @@ export const getWorkspaceSecretSnapshotsCount = async (req: Request, res: Respon
|
|||||||
*/
|
*/
|
||||||
export const rollbackWorkspaceSecretSnapshot = async (req: Request, res: Response) => {
|
export const rollbackWorkspaceSecretSnapshot = async (req: Request, res: Response) => {
|
||||||
/*
|
/*
|
||||||
#swagger.summary = 'Roll back project secrets to those captured in a secret snapshot version'
|
#swagger.summary = 'Roll back project secrets to those captured in a secret snapshot version.'
|
||||||
#swagger.description = 'Roll back project secrets to those captured in a secret snapshot version'
|
#swagger.description = 'Roll back project secrets to those captured in a secret snapshot version.'
|
||||||
|
|
||||||
#swagger.security = [{
|
#swagger.security = [{
|
||||||
"apiKeyAuth": []
|
"apiKeyAuth": []
|
||||||
@ -113,11 +158,16 @@ export const rollbackWorkspaceSecretSnapshot = async (req: Request, res: Respons
|
|||||||
content: {
|
content: {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
schema: {
|
schema: {
|
||||||
"type": "array",
|
"type": "object",
|
||||||
"items": {
|
"properties": {
|
||||||
$ref: "#/components/schemas/Secret"
|
"secrets": {
|
||||||
},
|
"type": "array",
|
||||||
"description": "Array of secrets captured in the secret snapshot"
|
"items": {
|
||||||
|
$ref: "#/components/schemas/Secret"
|
||||||
|
},
|
||||||
|
"description": "Secrets rolled back to"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -276,6 +326,72 @@ export const rollbackWorkspaceSecretSnapshot = async (req: Request, res: Respons
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const getWorkspaceLogs = async (req: Request, res: Response) => {
|
export const getWorkspaceLogs = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Return project (audit) logs'
|
||||||
|
#swagger.description = 'Return project (audit) logs'
|
||||||
|
|
||||||
|
#swagger.security = [{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}]
|
||||||
|
|
||||||
|
#swagger.parameters['workspaceId'] = {
|
||||||
|
"description": "ID of project",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.parameters['userId'] = {
|
||||||
|
"description": "ID of project member",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.parameters['offset'] = {
|
||||||
|
"description": "Number of logs to skip",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.parameters['limit'] = {
|
||||||
|
"description": "Maximum number of logs to return",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.parameters['sortBy'] = {
|
||||||
|
"description": "Order to sort the logs by",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"@enum": ["oldest", "recent"]
|
||||||
|
},
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.parameters['actionNames'] = {
|
||||||
|
"description": "Names of log actions (comma-separated)",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
schema: {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"logs": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
$ref: "#/components/schemas/Log"
|
||||||
|
},
|
||||||
|
"description": "Project logs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
let logs
|
let logs
|
||||||
try {
|
try {
|
||||||
const { workspaceId } = req.params;
|
const { workspaceId } = req.params;
|
||||||
|
@ -2,6 +2,7 @@ import requireAuth from './requireAuth';
|
|||||||
import requireBotAuth from './requireBotAuth';
|
import requireBotAuth from './requireBotAuth';
|
||||||
import requireSignupAuth from './requireSignupAuth';
|
import requireSignupAuth from './requireSignupAuth';
|
||||||
import requireWorkspaceAuth from './requireWorkspaceAuth';
|
import requireWorkspaceAuth from './requireWorkspaceAuth';
|
||||||
|
import requireMembershipAuth from './requireMembershipAuth';
|
||||||
import requireOrganizationAuth from './requireOrganizationAuth';
|
import requireOrganizationAuth from './requireOrganizationAuth';
|
||||||
import requireIntegrationAuth from './requireIntegrationAuth';
|
import requireIntegrationAuth from './requireIntegrationAuth';
|
||||||
import requireIntegrationAuthorizationAuth from './requireIntegrationAuthorizationAuth';
|
import requireIntegrationAuthorizationAuth from './requireIntegrationAuthorizationAuth';
|
||||||
@ -16,6 +17,7 @@ export {
|
|||||||
requireBotAuth,
|
requireBotAuth,
|
||||||
requireSignupAuth,
|
requireSignupAuth,
|
||||||
requireWorkspaceAuth,
|
requireWorkspaceAuth,
|
||||||
|
requireMembershipAuth,
|
||||||
requireOrganizationAuth,
|
requireOrganizationAuth,
|
||||||
requireIntegrationAuth,
|
requireIntegrationAuth,
|
||||||
requireIntegrationAuthorizationAuth,
|
requireIntegrationAuthorizationAuth,
|
||||||
|
57
backend/src/middleware/requireMembershipAuth.ts
Normal file
57
backend/src/middleware/requireMembershipAuth.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import { Request, Response, NextFunction } from 'express';
|
||||||
|
import { UnauthorizedRequestError } from '../utils/errors';
|
||||||
|
import {
|
||||||
|
Membership,
|
||||||
|
} from '../models';
|
||||||
|
import { validateMembership } from '../helpers/membership';
|
||||||
|
|
||||||
|
type req = 'params' | 'body' | 'query';
|
||||||
|
/**
|
||||||
|
* Validate membership with id [membershipId] and that user with id
|
||||||
|
* [req.user._id] can modify that membership.
|
||||||
|
* @param {Object} obj
|
||||||
|
* @param {String[]} obj.acceptedRoles - accepted workspace roles for JWT auth
|
||||||
|
* @param {String[]} obj.location - location of [workspaceId] on request (e.g. params, body) for parsing
|
||||||
|
*/
|
||||||
|
const requireMembershipAuth = ({
|
||||||
|
acceptedRoles,
|
||||||
|
location = 'params'
|
||||||
|
}: {
|
||||||
|
acceptedRoles: string[];
|
||||||
|
location?: req;
|
||||||
|
}) => {
|
||||||
|
return async (
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const { membershipId } = req[location];
|
||||||
|
|
||||||
|
const membership = await Membership.findById(membershipId);
|
||||||
|
|
||||||
|
if (!membership) throw new Error('Failed to find target membership');
|
||||||
|
|
||||||
|
const userMembership = await Membership.findOne({
|
||||||
|
workspace: membership.workspace
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!userMembership) throw new Error('Failed to validate own membership')
|
||||||
|
|
||||||
|
const targetMembership = await validateMembership({
|
||||||
|
userId: req.user._id.toString(),
|
||||||
|
workspaceId: membership.workspace.toString(),
|
||||||
|
acceptedRoles
|
||||||
|
});
|
||||||
|
|
||||||
|
req.targetMembership = targetMembership;
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
return next(UnauthorizedRequestError({
|
||||||
|
message: 'Unable to validate workspace membership'
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default requireMembershipAuth;
|
@ -4,7 +4,7 @@ import { body, param } from 'express-validator';
|
|||||||
import { requireAuth, validateRequest } from '../../middleware';
|
import { requireAuth, validateRequest } from '../../middleware';
|
||||||
import { membershipController } from '../../controllers/v1';
|
import { membershipController } from '../../controllers/v1';
|
||||||
|
|
||||||
router.get( // used for CLI (deprecate)
|
router.get( // used for old CLI (deprecate)
|
||||||
'/:workspaceId/connect',
|
'/:workspaceId/connect',
|
||||||
requireAuth({
|
requireAuth({
|
||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
|
@ -3,6 +3,7 @@ const router = express.Router();
|
|||||||
import { body, param, query } from 'express-validator';
|
import { body, param, query } from 'express-validator';
|
||||||
import {
|
import {
|
||||||
requireAuth,
|
requireAuth,
|
||||||
|
requireMembershipAuth,
|
||||||
requireWorkspaceAuth,
|
requireWorkspaceAuth,
|
||||||
validateRequest
|
validateRequest
|
||||||
} from '../../middleware';
|
} from '../../middleware';
|
||||||
@ -67,4 +68,54 @@ router.get(
|
|||||||
workspaceController.getWorkspaceServiceTokenData
|
workspaceController.getWorkspaceServiceTokenData
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// TODO: /POST to create membership
|
||||||
|
|
||||||
|
router.get( // new - TODO: rewire dashboard to this route
|
||||||
|
'/:workspaceId/memberships',
|
||||||
|
param('workspaceId').exists().trim(),
|
||||||
|
validateRequest,
|
||||||
|
requireAuth({
|
||||||
|
acceptedAuthModes: ['jwt']
|
||||||
|
}),
|
||||||
|
requireWorkspaceAuth({
|
||||||
|
acceptedRoles: [ADMIN, MEMBER],
|
||||||
|
}),
|
||||||
|
workspaceController.getWorkspaceMemberships
|
||||||
|
);
|
||||||
|
|
||||||
|
router.delete( // TODO - rewire dashboard to this route
|
||||||
|
'/:workspaceId/memberships/:membershipId',
|
||||||
|
param('workspaceId').exists().trim(),
|
||||||
|
param('membershipId').exists().trim(),
|
||||||
|
validateRequest,
|
||||||
|
requireAuth({
|
||||||
|
acceptedAuthModes: ['jwt']
|
||||||
|
}),
|
||||||
|
requireWorkspaceAuth({
|
||||||
|
acceptedRoles: [ADMIN],
|
||||||
|
}),
|
||||||
|
requireMembershipAuth({
|
||||||
|
acceptedRoles: [ADMIN]
|
||||||
|
}),
|
||||||
|
workspaceController.deleteWorkspaceMembership
|
||||||
|
);
|
||||||
|
|
||||||
|
router.patch( // TODO - rewire dashboard to this route
|
||||||
|
'/:workspaceId/memberships/:membershipId',
|
||||||
|
param('workspaceId').exists().trim(),
|
||||||
|
param('membershipId').exists().trim(),
|
||||||
|
body('role').exists().isString().trim().isIn([ADMIN, MEMBER]),
|
||||||
|
validateRequest,
|
||||||
|
requireAuth({
|
||||||
|
acceptedAuthModes: ['jwt']
|
||||||
|
}),
|
||||||
|
requireWorkspaceAuth({
|
||||||
|
acceptedRoles: [ADMIN],
|
||||||
|
}),
|
||||||
|
requireMembershipAuth({
|
||||||
|
acceptedRoles: [ADMIN]
|
||||||
|
}),
|
||||||
|
workspaceController.updateWorkspaceMembership
|
||||||
|
);
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
1
backend/src/types/express/index.d.ts
vendored
1
backend/src/types/express/index.d.ts
vendored
@ -8,6 +8,7 @@ declare global {
|
|||||||
user: any;
|
user: any;
|
||||||
workspace: any;
|
workspace: any;
|
||||||
membership: any;
|
membership: any;
|
||||||
|
targetMembership: any;
|
||||||
organization: any;
|
organization: any;
|
||||||
membershipOrg: any;
|
membershipOrg: any;
|
||||||
integration: any;
|
integration: any;
|
||||||
|
@ -53,6 +53,19 @@ const generateOpenAPISpec = async () => {
|
|||||||
updatedAt: '',
|
updatedAt: '',
|
||||||
createdAt: ''
|
createdAt: ''
|
||||||
},
|
},
|
||||||
|
Membership: {
|
||||||
|
user: {
|
||||||
|
_id: '',
|
||||||
|
email: '',
|
||||||
|
firstName: '',
|
||||||
|
lastName: '',
|
||||||
|
publicKey: '',
|
||||||
|
updatedAt: '',
|
||||||
|
createdAt: ''
|
||||||
|
},
|
||||||
|
workspace: '',
|
||||||
|
role: 'admin'
|
||||||
|
},
|
||||||
ProjectKey: {
|
ProjectKey: {
|
||||||
encryptedkey: '',
|
encryptedkey: '',
|
||||||
nonce: '',
|
nonce: '',
|
||||||
@ -103,6 +116,61 @@ const generateOpenAPISpec = async () => {
|
|||||||
secretCommentTag: '',
|
secretCommentTag: '',
|
||||||
updatedAt: '',
|
updatedAt: '',
|
||||||
createdAt: ''
|
createdAt: ''
|
||||||
|
},
|
||||||
|
Log: {
|
||||||
|
_id: '',
|
||||||
|
user: {
|
||||||
|
_id: '',
|
||||||
|
email: '',
|
||||||
|
firstName: '',
|
||||||
|
lastName: ''
|
||||||
|
},
|
||||||
|
workspace: '',
|
||||||
|
actionNames: [
|
||||||
|
'addSecrets'
|
||||||
|
],
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
name: 'addSecrets',
|
||||||
|
user: '',
|
||||||
|
workspace: '',
|
||||||
|
payload: [
|
||||||
|
{
|
||||||
|
oldSecretVersion: '',
|
||||||
|
newSecretVersion: ''
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
channel: 'cli',
|
||||||
|
ipAddress: '192.168.0.1',
|
||||||
|
updatedAt: '',
|
||||||
|
createdAt: ''
|
||||||
|
},
|
||||||
|
SecretSnapshot: {
|
||||||
|
workspace: '',
|
||||||
|
version: 1,
|
||||||
|
secretVersions: [
|
||||||
|
{
|
||||||
|
_id: ''
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
SecretVersion: {
|
||||||
|
_id: '',
|
||||||
|
secret: '',
|
||||||
|
version: 1,
|
||||||
|
workspace: '',
|
||||||
|
type: '',
|
||||||
|
user: '',
|
||||||
|
environment: '',
|
||||||
|
isDeleted: '',
|
||||||
|
secretKeyCiphertext: '',
|
||||||
|
secretKeyIV: '',
|
||||||
|
secretKeyTag: '',
|
||||||
|
secretValueCiphertext: '',
|
||||||
|
secretValueIV: '',
|
||||||
|
secretValueTag: '',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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"
|
openapi: "GET /api/v2/workspace/{workspaceId}/encrypted-key"
|
||||||
---
|
---
|
||||||
|
@ -13,52 +13,140 @@ Prerequisites:
|
|||||||
|
|
||||||
1. Get your (encrypted) private key.
|
1. Get your (encrypted) private key.
|
||||||
2. Decrypt your (encrypted) private key with your password.
|
2. Decrypt your (encrypted) private key with your password.
|
||||||
3. Get the project key for the project.
|
3. Get the (encrypted) project key for the project.
|
||||||
4. Decrypt the project key with your private key.
|
4. Decrypt the (encrypted) project key with your private key.
|
||||||
5. Encrypt your secrets with the project key.
|
5. Encrypt your secret(s) with the project key.
|
||||||
6. Send (encrypted) secrets to the Infical API
|
6. Send (encrypted) secret(s) to the Infical API
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const axios = require("axios");
|
const crypto = require('crypto');
|
||||||
const aes = require("aes-256-gcm");
|
const axios = require('axios');
|
||||||
const nacl = require("tweetnacl");
|
|
||||||
nacl.util = require("tweetnacl-util");
|
|
||||||
|
|
||||||
const WORKSPACE_KEY = "3a7a243eb62078c13f09203e75e8cb32";
|
const ALGORITHM = 'aes-256-gcm';
|
||||||
|
const BLOCK_SIZE_BYTES = 16;
|
||||||
|
|
||||||
const secretKey = "SOME_KEY";
|
const encrypt = (
|
||||||
const secretValue = "SOME_VALUE";
|
text,
|
||||||
|
secret
|
||||||
|
) => {
|
||||||
|
const iv = crypto.randomBytes(BLOCK_SIZE_BYTES);
|
||||||
|
const cipher = crypto.createCipheriv(ALGORITHM, secret, iv);
|
||||||
|
|
||||||
// encrypt key of secret
|
let ciphertext = cipher.update(text, 'utf8', 'base64');
|
||||||
const {
|
ciphertext += cipher.final('base64');
|
||||||
ciphertext: secretKeyCiphertext,
|
return {
|
||||||
iv: secretKeyIV,
|
ciphertext,
|
||||||
tag: secretKeyTag,
|
iv: iv.toString('base64'),
|
||||||
} = aes.encrypt(secretKey, WORKSPACE_KEY);
|
tag: cipher.getAuthTag().toString('base64')
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// encrypt value of secret
|
const decrypt = (ciphertext, iv, tag, secret) => {
|
||||||
const {
|
const decipher = crypto.createDecipheriv(
|
||||||
ciphertext: secretValueCiphertext,
|
ALGORITHM,
|
||||||
iv: secretValueIV,
|
secret,
|
||||||
tag: secretValueTag,
|
Buffer.from(iv, 'base64')
|
||||||
} = aes.encrypt(secretKey, WORKSPACE_KEY);
|
);
|
||||||
|
decipher.setAuthTag(Buffer.from(tag, 'base64'));
|
||||||
|
|
||||||
// construct request body
|
let cleartext = decipher.update(ciphertext, 'base64', 'utf8');
|
||||||
const secret = {
|
cleartext += decipher.final('utf8');
|
||||||
secretKeyCiphertext,
|
|
||||||
secretKeyIV,
|
return cleartext;
|
||||||
secretKeyTag,
|
}
|
||||||
secretValueCiphertext,
|
|
||||||
secretValueIV,
|
const createSecrets = async () => {
|
||||||
secretValueTag,
|
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>
|
<Info>
|
||||||
This example uses [TweetNaCl.js](https://tweetnacl.js.org/#/), a port of
|
This example uses [TweetNaCl.js](https://tweetnacl.js.org/#/), a port of
|
||||||
TweetNacl/Nacl, to perform asymmeric decryption of the project key but there
|
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>
|
</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"
|
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.
|
1. Get your (encrypted) private key.
|
||||||
2. Decrypt your (encrypted) private key with your password.
|
2. Decrypt your (encrypted) private key with your password.
|
||||||
3. Get the project key for the project.
|
3. Get the (encrypted) project key for the project.
|
||||||
4. Decrypt the project key with your private key.
|
4. Decrypt the (encrypted) project key with your private key.
|
||||||
5. Get secrets for a project and environment.
|
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"
|
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.
|
1. Get your (encrypted) private key.
|
||||||
2. Decrypt your (encrypted) private key with your password.
|
2. Decrypt your (encrypted) private key with your password.
|
||||||
3. Get the project key for the project.
|
3. Get the project key for the project.
|
||||||
4. Decrypt the project key with your private key.
|
4. Decrypt the project key with your private key.
|
||||||
5. Encrypt your secrets with the project key.
|
5. Encrypt your secret(s) with the project key.
|
||||||
6. Send (encrypted) updated secrets to the Infical API
|
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"
|
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
|
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.
|
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.
|
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.
|
- 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.
|
- 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.
|
- 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>
|
||||||
|
@ -150,7 +150,8 @@
|
|||||||
"pages": [
|
"pages": [
|
||||||
"api-reference/overview/examples/create-secrets",
|
"api-reference/overview/examples/create-secrets",
|
||||||
"api-reference/overview/examples/retrieve-secrets",
|
"api-reference/overview/examples/retrieve-secrets",
|
||||||
"api-reference/overview/examples/update-secrets"
|
"api-reference/overview/examples/update-secrets",
|
||||||
|
"api-reference/overview/examples/delete-secrets"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -167,7 +168,13 @@
|
|||||||
{
|
{
|
||||||
"group": "Projects",
|
"group": "Projects",
|
||||||
"pages": [
|
"pages": [
|
||||||
"api-reference/endpoints/workspaces/workspace-key"
|
"api-reference/endpoints/workspaces/memberships",
|
||||||
|
"api-reference/endpoints/workspaces/update-membership",
|
||||||
|
"api-reference/endpoints/workspaces/delete-membership",
|
||||||
|
"api-reference/endpoints/workspaces/workspace-key",
|
||||||
|
"api-reference/endpoints/workspaces/logs",
|
||||||
|
"api-reference/endpoints/workspaces/secret-snapshots",
|
||||||
|
"api-reference/endpoints/workspaces/rollback-snapshot"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -176,7 +183,9 @@
|
|||||||
"api-reference/endpoints/secrets/create",
|
"api-reference/endpoints/secrets/create",
|
||||||
"api-reference/endpoints/secrets/read",
|
"api-reference/endpoints/secrets/read",
|
||||||
"api-reference/endpoints/secrets/update",
|
"api-reference/endpoints/secrets/update",
|
||||||
"api-reference/endpoints/secrets/delete"
|
"api-reference/endpoints/secrets/delete",
|
||||||
|
"api-reference/endpoints/secrets/versions",
|
||||||
|
"api-reference/endpoints/secrets/rollback-version"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
477
docs/spec.yaml
477
docs/spec.yaml
@ -11,48 +11,81 @@ servers:
|
|||||||
paths:
|
paths:
|
||||||
/api/v1/secret/{secretId}/secret-versions:
|
/api/v1/secret/{secretId}/secret-versions:
|
||||||
get:
|
get:
|
||||||
description: ''
|
summary: Return secret versions
|
||||||
|
description: Return secret versions
|
||||||
parameters:
|
parameters:
|
||||||
- name: secretId
|
- name: secretId
|
||||||
in: path
|
in: path
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
|
description: ID of secret
|
||||||
- name: offset
|
- name: offset
|
||||||
|
description: Number of versions to skip
|
||||||
|
required: false
|
||||||
in: query
|
in: query
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
- name: limit
|
- name: limit
|
||||||
|
description: Maximum number of versions to return
|
||||||
|
required: false
|
||||||
in: query
|
in: query
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: OK
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
secretVersions:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/SecretVersion'
|
||||||
|
description: Secret versions
|
||||||
'400':
|
'400':
|
||||||
description: Bad Request
|
description: Bad Request
|
||||||
|
security:
|
||||||
|
- apiKeyAuth: []
|
||||||
/api/v1/secret/{secretId}/secret-versions/rollback:
|
/api/v1/secret/{secretId}/secret-versions/rollback:
|
||||||
post:
|
post:
|
||||||
description: ''
|
summary: Roll back secret to a version.
|
||||||
|
description: Roll back secret to a version.
|
||||||
parameters:
|
parameters:
|
||||||
- name: secretId
|
- name: secretId
|
||||||
in: path
|
in: path
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
|
description: ID of secret
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: OK
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
secret:
|
||||||
|
type: object
|
||||||
|
$ref: '#/components/schemas/Secret'
|
||||||
|
description: Secret rolled back to
|
||||||
'400':
|
'400':
|
||||||
description: Bad Request
|
description: Bad Request
|
||||||
|
security:
|
||||||
|
- apiKeyAuth: []
|
||||||
requestBody:
|
requestBody:
|
||||||
|
required: true
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
version:
|
version:
|
||||||
example: any
|
type: integer
|
||||||
|
description: Version of secret to roll back to
|
||||||
/api/v1/secret-snapshot/{secretSnapshotId}:
|
/api/v1/secret-snapshot/{secretSnapshotId}:
|
||||||
get:
|
get:
|
||||||
description: ''
|
description: ''
|
||||||
@ -69,26 +102,44 @@ paths:
|
|||||||
description: Bad Request
|
description: Bad Request
|
||||||
/api/v1/workspace/{workspaceId}/secret-snapshots:
|
/api/v1/workspace/{workspaceId}/secret-snapshots:
|
||||||
get:
|
get:
|
||||||
description: ''
|
summary: Return project secret snapshot ids
|
||||||
|
description: Return project secret snapshots ids
|
||||||
parameters:
|
parameters:
|
||||||
- name: workspaceId
|
- name: workspaceId
|
||||||
in: path
|
in: path
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
|
description: ID of project
|
||||||
- name: offset
|
- name: offset
|
||||||
|
description: Number of secret snapshots to skip
|
||||||
|
required: false
|
||||||
in: query
|
in: query
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
- name: limit
|
- name: limit
|
||||||
|
description: Maximum number of secret snapshots to return
|
||||||
|
required: false
|
||||||
in: query
|
in: query
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: OK
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
secretSnapshots:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/SecretSnapshot'
|
||||||
|
description: Project secret snapshots
|
||||||
'400':
|
'400':
|
||||||
description: Bad Request
|
description: Bad Request
|
||||||
|
security:
|
||||||
|
- apiKeyAuth: []
|
||||||
/api/v1/workspace/{workspaceId}/secret-snapshots/count:
|
/api/v1/workspace/{workspaceId}/secret-snapshots/count:
|
||||||
get:
|
get:
|
||||||
description: ''
|
description: ''
|
||||||
@ -105,60 +156,107 @@ paths:
|
|||||||
description: Bad Request
|
description: Bad Request
|
||||||
/api/v1/workspace/{workspaceId}/secret-snapshots/rollback:
|
/api/v1/workspace/{workspaceId}/secret-snapshots/rollback:
|
||||||
post:
|
post:
|
||||||
description: ''
|
summary: >-
|
||||||
|
Roll back project secrets to those captured in a secret snapshot
|
||||||
|
version.
|
||||||
|
description: >-
|
||||||
|
Roll back project secrets to those captured in a secret snapshot
|
||||||
|
version.
|
||||||
parameters:
|
parameters:
|
||||||
- name: workspaceId
|
- name: workspaceId
|
||||||
in: path
|
in: path
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
|
description: ID of project
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: OK
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
secrets:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Secret'
|
||||||
|
description: Secrets rolled back to
|
||||||
'400':
|
'400':
|
||||||
description: Bad Request
|
description: Bad Request
|
||||||
|
security:
|
||||||
|
- apiKeyAuth: []
|
||||||
requestBody:
|
requestBody:
|
||||||
|
required: true
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
version:
|
version:
|
||||||
example: any
|
type: integer
|
||||||
|
description: Version of secret snapshot to roll back to
|
||||||
/api/v1/workspace/{workspaceId}/logs:
|
/api/v1/workspace/{workspaceId}/logs:
|
||||||
get:
|
get:
|
||||||
description: ''
|
summary: Return project (audit) logs
|
||||||
|
description: Return project (audit) logs
|
||||||
parameters:
|
parameters:
|
||||||
- name: workspaceId
|
- name: workspaceId
|
||||||
in: path
|
in: path
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
|
description: ID of project
|
||||||
|
- name: userId
|
||||||
|
description: ID of project member
|
||||||
|
required: false
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
- name: offset
|
- name: offset
|
||||||
|
description: Number of logs to skip
|
||||||
|
required: false
|
||||||
in: query
|
in: query
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
- name: limit
|
- name: limit
|
||||||
|
description: Maximum number of logs to return
|
||||||
|
required: false
|
||||||
in: query
|
in: query
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
- name: sortBy
|
- name: sortBy
|
||||||
in: query
|
description: Order to sort the logs by
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
- name: userId
|
enum:
|
||||||
|
- oldest
|
||||||
|
- recent
|
||||||
|
required: false
|
||||||
in: query
|
in: query
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
- name: actionNames
|
- name: actionNames
|
||||||
|
description: Names of log actions (comma-separated)
|
||||||
|
required: false
|
||||||
in: query
|
in: query
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: OK
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
logs:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Log'
|
||||||
|
description: Project logs
|
||||||
'400':
|
'400':
|
||||||
description: Bad Request
|
description: Bad Request
|
||||||
|
security:
|
||||||
|
- apiKeyAuth: []
|
||||||
/api/v1/action/{actionId}:
|
/api/v1/action/{actionId}:
|
||||||
get:
|
get:
|
||||||
description: ''
|
description: ''
|
||||||
@ -1285,8 +1383,11 @@ paths:
|
|||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
type: object
|
type: object
|
||||||
$ref: '#/components/schemas/CurrentUser'
|
properties:
|
||||||
description: Current user on request
|
user:
|
||||||
|
type: object
|
||||||
|
$ref: '#/components/schemas/CurrentUser'
|
||||||
|
description: Current user on request
|
||||||
'400':
|
'400':
|
||||||
description: Bad Request
|
description: Bad Request
|
||||||
security:
|
security:
|
||||||
@ -1379,6 +1480,107 @@ paths:
|
|||||||
description: OK
|
description: OK
|
||||||
'400':
|
'400':
|
||||||
description: Bad Request
|
description: Bad Request
|
||||||
|
/api/v2/workspace/{workspaceId}/memberships:
|
||||||
|
get:
|
||||||
|
summary: Return project memberships
|
||||||
|
description: Return project memberships
|
||||||
|
parameters:
|
||||||
|
- name: workspaceId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: ID of project
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
memberships:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Membership'
|
||||||
|
description: Memberships of project
|
||||||
|
'400':
|
||||||
|
description: Bad Request
|
||||||
|
security:
|
||||||
|
- apiKeyAuth: []
|
||||||
|
/api/v2/workspace/{workspaceId}/memberships/{membershipId}:
|
||||||
|
delete:
|
||||||
|
summary: Delete project membership
|
||||||
|
description: Delete project membership
|
||||||
|
parameters:
|
||||||
|
- name: workspaceId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: ID of project
|
||||||
|
- name: membershipId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: ID of membership
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
membership:
|
||||||
|
$ref: '#/components/schemas/Membership'
|
||||||
|
description: Deleted membership
|
||||||
|
'400':
|
||||||
|
description: Bad Request
|
||||||
|
security:
|
||||||
|
- apiKeyAuth: []
|
||||||
|
patch:
|
||||||
|
summary: Update project membership
|
||||||
|
description: Update project membership
|
||||||
|
parameters:
|
||||||
|
- name: workspaceId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: ID of project
|
||||||
|
- name: membershipId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: ID of membership
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
membership:
|
||||||
|
$ref: '#/components/schemas/Membership'
|
||||||
|
description: Updated membership
|
||||||
|
'400':
|
||||||
|
description: Bad Request
|
||||||
|
security:
|
||||||
|
- apiKeyAuth: []
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
role:
|
||||||
|
type: string
|
||||||
|
description: Role of membership - either admin or member
|
||||||
/api/v2/secret/batch-create/workspace/{workspaceId}/environment/{environment}:
|
/api/v2/secret/batch-create/workspace/{workspaceId}/environment/{environment}:
|
||||||
post:
|
post:
|
||||||
description: ''
|
description: ''
|
||||||
@ -1554,12 +1756,15 @@ paths:
|
|||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
type: array
|
type: object
|
||||||
items:
|
properties:
|
||||||
$ref: '#/components/schemas/Secret'
|
secrets:
|
||||||
description: >-
|
type: array
|
||||||
Array of newly-created secrets for the given project and
|
items:
|
||||||
environment
|
$ref: '#/components/schemas/Secret'
|
||||||
|
description: >-
|
||||||
|
Newly-created secrets for the given project and
|
||||||
|
environment
|
||||||
security:
|
security:
|
||||||
- apiKeyAuth: []
|
- apiKeyAuth: []
|
||||||
requestBody:
|
requestBody:
|
||||||
@ -1581,32 +1786,38 @@ paths:
|
|||||||
get:
|
get:
|
||||||
summary: Read secrets
|
summary: Read secrets
|
||||||
description: Read secrets from a project and environment
|
description: Read secrets from a project and environment
|
||||||
parameters: []
|
parameters:
|
||||||
|
- name: workspaceId
|
||||||
|
description: ID of project
|
||||||
|
required: true
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: environment
|
||||||
|
description: Environment within project
|
||||||
|
required: true
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: content
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: OK
|
description: OK
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
type: array
|
type: object
|
||||||
items:
|
properties:
|
||||||
$ref: '#/components/schemas/Secret'
|
secrets:
|
||||||
description: Array of secrets for the given project and environment
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Secret'
|
||||||
|
description: Secrets for the given project and environment
|
||||||
security:
|
security:
|
||||||
- apiKeyAuth: []
|
- 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:
|
patch:
|
||||||
summary: Update secret(s)
|
summary: Update secret(s)
|
||||||
description: Update secret(s)
|
description: Update secret(s)
|
||||||
@ -1617,12 +1828,13 @@ paths:
|
|||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
type: array
|
type: object
|
||||||
items:
|
properties:
|
||||||
$ref: '#/components/schemas/Secret'
|
secrets:
|
||||||
description: >-
|
type: array
|
||||||
Array of newly-updated secrets for the given project and
|
items:
|
||||||
environment
|
$ref: '#/components/schemas/Secret'
|
||||||
|
description: Updated secrets
|
||||||
security:
|
security:
|
||||||
- apiKeyAuth: []
|
- apiKeyAuth: []
|
||||||
requestBody:
|
requestBody:
|
||||||
@ -1645,10 +1857,13 @@ paths:
|
|||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
type: array
|
type: object
|
||||||
items:
|
properties:
|
||||||
$ref: '#/components/schemas/Secret'
|
secrets:
|
||||||
description: Array of deleted secrets
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Secret'
|
||||||
|
description: Deleted secrets
|
||||||
security:
|
security:
|
||||||
- apiKeyAuth: []
|
- apiKeyAuth: []
|
||||||
requestBody:
|
requestBody:
|
||||||
@ -1783,12 +1998,51 @@ components:
|
|||||||
encryptedPrivateKey:
|
encryptedPrivateKey:
|
||||||
type: string
|
type: string
|
||||||
example: ''
|
example: ''
|
||||||
|
iv:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
tag:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
updatedAt:
|
updatedAt:
|
||||||
type: string
|
type: string
|
||||||
example: ''
|
example: ''
|
||||||
createdAt:
|
createdAt:
|
||||||
type: string
|
type: string
|
||||||
example: ''
|
example: ''
|
||||||
|
Membership:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
user:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
_id:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
email:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
firstName:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
lastName:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
publicKey:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
updatedAt:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
createdAt:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
workspace:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
role:
|
||||||
|
type: string
|
||||||
|
example: admin
|
||||||
ProjectKey:
|
ProjectKey:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@ -1925,6 +2179,135 @@ components:
|
|||||||
createdAt:
|
createdAt:
|
||||||
type: string
|
type: string
|
||||||
example: ''
|
example: ''
|
||||||
|
Log:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
_id:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
user:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
_id:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
email:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
firstName:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
lastName:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
workspace:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
actionNames:
|
||||||
|
type: array
|
||||||
|
example:
|
||||||
|
- addSecrets
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
actions:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
example: addSecrets
|
||||||
|
user:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
workspace:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
payload:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
oldSecretVersion:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
newSecretVersion:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
channel:
|
||||||
|
type: string
|
||||||
|
example: cli
|
||||||
|
ipAddress:
|
||||||
|
type: string
|
||||||
|
example: 192.168.0.1
|
||||||
|
updatedAt:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
createdAt:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
SecretSnapshot:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
workspace:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
version:
|
||||||
|
type: number
|
||||||
|
example: 1
|
||||||
|
secretVersions:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
_id:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
SecretVersion:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
_id:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
secret:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
version:
|
||||||
|
type: number
|
||||||
|
example: 1
|
||||||
|
workspace:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
type:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
user:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
environment:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
isDeleted:
|
||||||
|
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: ''
|
||||||
securitySchemes:
|
securitySchemes:
|
||||||
bearerAuth:
|
bearerAuth:
|
||||||
type: http
|
type: http
|
||||||
|
Reference in New Issue
Block a user