# Secrets

Soda Cloud API Secret Endpoints

## List secrets

> This endpoint allows you to list secrets in your organization.\
> \
> This GET is a paginated API that uses the following parameters to request specific details:\
> \
> \- \`size\`: Supply an integer value between 10 and 1000, inclusive. The default value is 10.\
> \
> \- \`page\`: Supply an integer value. The default value is 0.\
> \
> \- \`search\`: Supply a string value to filter secrets by name (case-insensitive partial match).\
> \
> \## Authentication\
> \
> User authentication required: \`true\`\
> \
> This endpoint accepts authentication via API keys in the \`Basic\` authentication header, or a pre-authenticated token in HTTP cookie \`token\`. Cookie sessions extend automatically on each request.\
> \
> \## Authorization\
> \
> Users must have global role permission MANAGE\_DATASOURCES\_AND\_AGENTS to execute this call.\
> \
> \## Tags\
> \
> \`Secrets\`\
> \
> \## Rate limiting\
> \
> 60 requests/60 seconds

```json
{"openapi":"3.1.0","info":{"title":"Soda Cloud API v4","version":"v1"},"tags":[{"description":"Soda Cloud API Secret Endpoints","name":"Secrets"}],"servers":[{"description":"Cloud EU","url":"https://cloud.soda.io"},{"description":"Cloud US","url":"https://cloud.us.soda.io"}],"security":[{"basicAuthApiKey":[]},{"cookieToken":[]}],"components":{"securitySchemes":{"basicAuthApiKey":{"scheme":"basic","type":"http"},"cookieToken":{"in":"cookie","name":"token","type":"apiKey"}},"schemas":{"PublicApiListSecretsResponse":{"type":"object","properties":{"content":{"type":"array","items":{"type":"object","$ref":"#/components/schemas/PublicApiSecretDTO"}},"first":{"type":"boolean"},"last":{"type":"boolean"},"number":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int32"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","first","last","number","size","totalElements","totalPages"]},"PublicApiSecretDTO":{"type":"object","properties":{"created":{"type":"string","format":"date-time"},"id":{"type":"string"},"lastUpdated":{"type":"string","format":"date-time"},"name":{"type":"string"}}},"ErrorResponse":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}},"paths":{"/api/v1/secrets":{"get":{"description":"This endpoint allows you to list secrets in your organization.\n\nThis GET is a paginated API that uses the following parameters to request specific details:\n\n- `size`: Supply an integer value between 10 and 1000, inclusive. The default value is 10.\n\n- `page`: Supply an integer value. The default value is 0.\n\n- `search`: Supply a string value to filter secrets by name (case-insensitive partial match).\n\n## Authentication\n\nUser authentication required: `true`\n\nThis endpoint accepts authentication via API keys in the `Basic` authentication header, or a pre-authenticated token in HTTP cookie `token`. Cookie sessions extend automatically on each request.\n\n## Authorization\n\nUsers must have global role permission MANAGE_DATASOURCES_AND_AGENTS to execute this call.\n\n## Tags\n\n`Secrets`\n\n## Rate limiting\n\n60 requests/60 seconds","operationId":"GET/api/v1/secrets","parameters":[{"in":"query","name":"page","schema":{"type":"integer","format":"int32"}},{"in":"query","name":"search","schema":{"type":"string"}},{"in":"query","name":"size","schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/PublicApiListSecretsResponse"}}},"description":"Successful response"},"400":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad request"},"401":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"429":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too many requests"},"500":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal server error"}},"summary":"List secrets","tags":["Secrets"]}}}}
```

## Create a secret

> Creates a new secret in your organization. Secrets store encrypted credentials that can be referenced in datasource configurations using \`${secret.NAME}\` placeholders, keeping sensitive values out of plain text.\
> \
> \## Encryption\
> \
> Secret values must be encrypted \*\*client-side\*\* before sending them to this endpoint. This enables a zero-trust design, where Soda never decrypts the secret. Decryption happens only during scan execution, within the runner.\
> \
> Use the \`GET /api/v1/secretsPublicKey\` endpoint to obtain the server's RSA public key. The encryption uses a two-layer scheme:\
> \
> 1\. Fetch the RSA public key from \`GET /api/v1/secretsPublicKey\`.\
> \
> 2\. Generate a random AES-256-GCM key (32 bytes) and initialization vector (IV, 12 bytes).\
> \
> 3\. Encrypt the secret value using AES-256-GCM with the generated key and IV. Base64-encode the ciphertext and prefix it with \`encrypted\_\`. This becomes the \`encryptedValue\` field.\
> \
> 4\. Export the raw AES key and IV as base64 strings and concatenate them as \`{base64\_key}:::{base64\_iv}\`. Encrypt this string using RSA-OAEP (SHA-256) with the public key from step 1. Base64-encode the result. This becomes the \`encryptionKey\` field.\
> \
> \## Constraints\
> \
> \- The secret \`name\` must not contain whitespace and must be unique within the organization.\
> \
> \- Both \`encryptionKey\` and \`encryptedValue\` are required.\
> \
> \- The organization must have the contracts feature enabled and the secure store must not be disabled.\
> \
> \## Authentication\
> \
> User authentication required: \`true\`\
> \
> This endpoint accepts authentication via API keys in the \`Basic\` authentication header, or a pre-authenticated token in HTTP cookie \`token\`. Cookie sessions extend automatically on each request.\
> \
> \## Authorization\
> \
> Users must have global role permission MANAGE\_DATASOURCES\_AND\_AGENTS to execute this call.\
> \
> \## Tags\
> \
> \`Secrets\`\
> \
> \## Rate limiting\
> \
> 10 requests/60 seconds

```json
{"openapi":"3.1.0","info":{"title":"Soda Cloud API v4","version":"v1"},"tags":[{"description":"Soda Cloud API Secret Endpoints","name":"Secrets"}],"servers":[{"description":"Cloud EU","url":"https://cloud.soda.io"},{"description":"Cloud US","url":"https://cloud.us.soda.io"}],"security":[{"basicAuthApiKey":[]},{"cookieToken":[]}],"components":{"securitySchemes":{"basicAuthApiKey":{"scheme":"basic","type":"http"},"cookieToken":{"in":"cookie","name":"token","type":"apiKey"}},"schemas":{"PublicApiCreateSecretRequestDTO":{"type":"object","properties":{"encryptedValue":{"type":"string"},"encryptionKey":{"type":"string"},"name":{"type":"string"}},"required":["encryptedValue","encryptionKey","name"]},"PublicApiCreateSecretResponse":{"type":"object","properties":{"secret":{"type":"object","$ref":"#/components/schemas/PublicApiSecretDTO"}}},"PublicApiSecretDTO":{"type":"object","properties":{"created":{"type":"string","format":"date-time"},"id":{"type":"string"},"lastUpdated":{"type":"string","format":"date-time"},"name":{"type":"string"}}},"ErrorResponse":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}},"paths":{"/api/v1/secrets":{"post":{"description":"Creates a new secret in your organization. Secrets store encrypted credentials that can be referenced in datasource configurations using `${secret.NAME}` placeholders, keeping sensitive values out of plain text.\n\n## Encryption\n\nSecret values must be encrypted **client-side** before sending them to this endpoint. This enables a zero-trust design, where Soda never decrypts the secret. Decryption happens only during scan execution, within the runner.\n\nUse the `GET /api/v1/secretsPublicKey` endpoint to obtain the server's RSA public key. The encryption uses a two-layer scheme:\n\n1. Fetch the RSA public key from `GET /api/v1/secretsPublicKey`.\n\n2. Generate a random AES-256-GCM key (32 bytes) and initialization vector (IV, 12 bytes).\n\n3. Encrypt the secret value using AES-256-GCM with the generated key and IV. Base64-encode the ciphertext and prefix it with `encrypted_`. This becomes the `encryptedValue` field.\n\n4. Export the raw AES key and IV as base64 strings and concatenate them as `{base64_key}:::{base64_iv}`. Encrypt this string using RSA-OAEP (SHA-256) with the public key from step 1. Base64-encode the result. This becomes the `encryptionKey` field.\n\n## Constraints\n\n- The secret `name` must not contain whitespace and must be unique within the organization.\n\n- Both `encryptionKey` and `encryptedValue` are required.\n\n- The organization must have the contracts feature enabled and the secure store must not be disabled.\n\n## Authentication\n\nUser authentication required: `true`\n\nThis endpoint accepts authentication via API keys in the `Basic` authentication header, or a pre-authenticated token in HTTP cookie `token`. Cookie sessions extend automatically on each request.\n\n## Authorization\n\nUsers must have global role permission MANAGE_DATASOURCES_AND_AGENTS to execute this call.\n\n## Tags\n\n`Secrets`\n\n## Rate limiting\n\n10 requests/60 seconds","operationId":"POST/api/v1/secrets","requestBody":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/PublicApiCreateSecretRequestDTO"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/PublicApiCreateSecretResponse"}}},"description":"Successful response"},"400":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad request"},"401":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"429":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too many requests"},"500":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal server error"}},"summary":"Create a secret","tags":["Secrets"]}}}}
```

## Update a secret

> Updates the encrypted value of an existing secret. The secret name cannot be changed.\
> \
> Both \`encryptionKey\` and \`encryptedValue\` must be provided together — you cannot update one without the other.\
> \
> \## Encryption\
> \
> The new secret value must be encrypted \*\*client-side\*\* using the same two-layer encryption scheme as creation. See the \`POST /api/v1/secrets\` (Create a secret) endpoint for the full encryption workflow.\
> \
> \## Authentication\
> \
> User authentication required: \`true\`\
> \
> This endpoint accepts authentication via API keys in the \`Basic\` authentication header, or a pre-authenticated token in HTTP cookie \`token\`. Cookie sessions extend automatically on each request.\
> \
> \## Authorization\
> \
> Users must have global role permission MANAGE\_DATASOURCES\_AND\_AGENTS to execute this call.\
> \
> \## Tags\
> \
> \`Secrets\`\
> \
> \## Rate limiting\
> \
> 100 requests/60 seconds

```json
{"openapi":"3.1.0","info":{"title":"Soda Cloud API v4","version":"v1"},"tags":[{"description":"Soda Cloud API Secret Endpoints","name":"Secrets"}],"servers":[{"description":"Cloud EU","url":"https://cloud.soda.io"},{"description":"Cloud US","url":"https://cloud.us.soda.io"}],"security":[{"basicAuthApiKey":[]},{"cookieToken":[]}],"components":{"securitySchemes":{"basicAuthApiKey":{"scheme":"basic","type":"http"},"cookieToken":{"in":"cookie","name":"token","type":"apiKey"}},"schemas":{"PublicApiUpdateSecretRequestDTO":{"type":"object","properties":{"encryptedValue":{"type":"string"},"encryptionKey":{"type":"string"}},"required":["encryptedValue","encryptionKey"]},"PublicApiUpdateSecretResponse":{"type":"object","properties":{"secret":{"type":"object","$ref":"#/components/schemas/PublicApiSecretDTO"}}},"PublicApiSecretDTO":{"type":"object","properties":{"created":{"type":"string","format":"date-time"},"id":{"type":"string"},"lastUpdated":{"type":"string","format":"date-time"},"name":{"type":"string"}}},"ErrorResponse":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}},"paths":{"/api/v1/secrets/{secretId}":{"post":{"description":"Updates the encrypted value of an existing secret. The secret name cannot be changed.\n\nBoth `encryptionKey` and `encryptedValue` must be provided together — you cannot update one without the other.\n\n## Encryption\n\nThe new secret value must be encrypted **client-side** using the same two-layer encryption scheme as creation. See the `POST /api/v1/secrets` (Create a secret) endpoint for the full encryption workflow.\n\n## Authentication\n\nUser authentication required: `true`\n\nThis endpoint accepts authentication via API keys in the `Basic` authentication header, or a pre-authenticated token in HTTP cookie `token`. Cookie sessions extend automatically on each request.\n\n## Authorization\n\nUsers must have global role permission MANAGE_DATASOURCES_AND_AGENTS to execute this call.\n\n## Tags\n\n`Secrets`\n\n## Rate limiting\n\n100 requests/60 seconds","operationId":"POST/api/v1/secrets/{secretId}","parameters":[{"in":"path","name":"secretId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/PublicApiUpdateSecretRequestDTO"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/PublicApiUpdateSecretResponse"}}},"description":"Successful response"},"400":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad request"},"401":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"429":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too many requests"},"500":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal server error"}},"summary":"Update a secret","tags":["Secrets"]}}}}
```

## Delete a secret

> Deletes an existing secret.\
> \
> The secret cannot be deleted if it is referenced by a datasource configuration.\
> \
> \## Authentication\
> \
> User authentication required: \`true\`\
> \
> This endpoint accepts authentication via API keys in the \`Basic\` authentication header, or a pre-authenticated token in HTTP cookie \`token\`. Cookie sessions extend automatically on each request.\
> \
> \## Authorization\
> \
> Users must have global role permission MANAGE\_DATASOURCES\_AND\_AGENTS to execute this call.\
> \
> \## Tags\
> \
> \`Secrets\`\
> \
> \## Rate limiting\
> \
> 10 requests/60 seconds

```json
{"openapi":"3.1.0","info":{"title":"Soda Cloud API v4","version":"v1"},"tags":[{"description":"Soda Cloud API Secret Endpoints","name":"Secrets"}],"servers":[{"description":"Cloud EU","url":"https://cloud.soda.io"},{"description":"Cloud US","url":"https://cloud.us.soda.io"}],"security":[{"basicAuthApiKey":[]},{"cookieToken":[]}],"components":{"securitySchemes":{"basicAuthApiKey":{"scheme":"basic","type":"http"},"cookieToken":{"in":"cookie","name":"token","type":"apiKey"}},"schemas":{"PublicApiDeleteSecretResponse":{"type":"object","properties":{"message":{"type":"string"}}},"ErrorResponse":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}},"paths":{"/api/v1/secrets/{secretId}":{"delete":{"description":"Deletes an existing secret.\n\nThe secret cannot be deleted if it is referenced by a datasource configuration.\n\n## Authentication\n\nUser authentication required: `true`\n\nThis endpoint accepts authentication via API keys in the `Basic` authentication header, or a pre-authenticated token in HTTP cookie `token`. Cookie sessions extend automatically on each request.\n\n## Authorization\n\nUsers must have global role permission MANAGE_DATASOURCES_AND_AGENTS to execute this call.\n\n## Tags\n\n`Secrets`\n\n## Rate limiting\n\n10 requests/60 seconds","operationId":"DELETE/api/v1/secrets/{secretId}","parameters":[{"in":"path","name":"secretId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/PublicApiDeleteSecretResponse"}}},"description":"Successful response"},"400":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad request"},"401":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not found"},"429":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too many requests"},"500":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal server error"}},"summary":"Delete a secret","tags":["Secrets"]}}}}
```

## Get the encryption public key

> Returns the RSA public key in JWK (JSON Web Key) format, used for client-side encryption of secret values.\
> \
> \## Usage\
> \
> When creating or updating a secret, the secret value must be encrypted client-side before sending it to the API. This endpoint provides the RSA public key needed for that encryption.\
> \
> \## Encryption workflow\
> \
> 1\. Fetch this public key.\
> \
> 2\. Generate a random AES-256-GCM key (32 bytes) and initialization vector (IV, 12 bytes).\
> \
> 3\. Encrypt the secret value using AES-256-GCM with the generated key and IV. Base64-encode the ciphertext and prefix it with \`encrypted\_\`. This becomes the \`encryptedValue\` field.\
> \
> 4\. Export the raw AES key and IV as base64 strings and concatenate them as \`{base64\_key}:::{base64\_iv}\`. Encrypt this string using RSA-OAEP (SHA-256) with this public key. Base64-encode the result. This becomes the \`encryptionKey\` field.\
> \
> 5\. Use the \`encryptedValue\` and \`encryptionKey\` in the create or update secret request.\
> \
> \## Authentication\
> \
> User authentication required: \`true\`\
> \
> This endpoint accepts authentication via API keys in the \`Basic\` authentication header, or a pre-authenticated token in HTTP cookie \`token\`. Cookie sessions extend automatically on each request.\
> \
> \## Authorization\
> \
> Users must have global role permission MANAGE\_DATASOURCES\_AND\_AGENTS to execute this call.\
> \
> \## Tags\
> \
> \`Secrets\`\
> \
> \## Rate limiting\
> \
> 60 requests/60 seconds

```json
{"openapi":"3.1.0","info":{"title":"Soda Cloud API v4","version":"v1"},"tags":[{"description":"Soda Cloud API Secret Endpoints","name":"Secrets"}],"servers":[{"description":"Cloud EU","url":"https://cloud.soda.io"},{"description":"Cloud US","url":"https://cloud.us.soda.io"}],"security":[{"basicAuthApiKey":[]},{"cookieToken":[]}],"components":{"securitySchemes":{"basicAuthApiKey":{"scheme":"basic","type":"http"},"cookieToken":{"in":"cookie","name":"token","type":"apiKey"}},"schemas":{"PublicApiGetEncryptionKeyResponse":{"type":"object","properties":{"encryptionKey":{"type":"object","$ref":"#/components/schemas/MapOfStringTo_object"}}},"MapOfStringTo_object":{"type":"object","additionalProperties":true},"ErrorResponse":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}},"paths":{"/api/v1/secretsPublicKey":{"get":{"description":"Returns the RSA public key in JWK (JSON Web Key) format, used for client-side encryption of secret values.\n\n## Usage\n\nWhen creating or updating a secret, the secret value must be encrypted client-side before sending it to the API. This endpoint provides the RSA public key needed for that encryption.\n\n## Encryption workflow\n\n1. Fetch this public key.\n\n2. Generate a random AES-256-GCM key (32 bytes) and initialization vector (IV, 12 bytes).\n\n3. Encrypt the secret value using AES-256-GCM with the generated key and IV. Base64-encode the ciphertext and prefix it with `encrypted_`. This becomes the `encryptedValue` field.\n\n4. Export the raw AES key and IV as base64 strings and concatenate them as `{base64_key}:::{base64_iv}`. Encrypt this string using RSA-OAEP (SHA-256) with this public key. Base64-encode the result. This becomes the `encryptionKey` field.\n\n5. Use the `encryptedValue` and `encryptionKey` in the create or update secret request.\n\n## Authentication\n\nUser authentication required: `true`\n\nThis endpoint accepts authentication via API keys in the `Basic` authentication header, or a pre-authenticated token in HTTP cookie `token`. Cookie sessions extend automatically on each request.\n\n## Authorization\n\nUsers must have global role permission MANAGE_DATASOURCES_AND_AGENTS to execute this call.\n\n## Tags\n\n`Secrets`\n\n## Rate limiting\n\n60 requests/60 seconds","operationId":"GET/api/v1/secretsPublicKey","responses":{"200":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/PublicApiGetEncryptionKeyResponse"}}},"description":"Successful response"},"401":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"429":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too many requests"},"500":{"content":{"application/json":{"schema":{"type":"object","$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal server error"}},"summary":"Get the encryption public key","tags":["Secrets"]}}}}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.soda.io/reference/rest-api/secrets.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
