Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions apps/docs/components/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4502,6 +4502,24 @@ export function DynamoDBIcon(props: SVGProps<SVGSVGElement>) {
)
}

export function SecretsManagerIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg {...props} viewBox='0 0 80 80' xmlns='http://www.w3.org/2000/svg'>
<defs>
<linearGradient x1='0%' y1='100%' x2='100%' y2='0%' id='secretsManagerGradient'>
<stop stopColor='#BD0816' offset='0%' />
<stop stopColor='#FF5252' offset='100%' />
</linearGradient>
</defs>
<rect fill='url(#secretsManagerGradient)' width='80' height='80' />
<path
d='M38.76,43.36 C38.76,44.044 39.317,44.6 40,44.6 C40.684,44.6 41.24,44.044 41.24,43.36 C41.24,42.676 40.684,42.12 40,42.12 C39.317,42.12 38.76,42.676 38.76,43.36 L38.76,43.36 Z M36.76,43.36 C36.76,41.573 38.213,40.12 40,40.12 C41.787,40.12 43.24,41.573 43.24,43.36 C43.24,44.796 42.296,46.002 41,46.426 L41,49 L39,49 L39,46.426 C37.704,46.002 36.76,44.796 36.76,43.36 L36.76,43.36 Z M49,38 L31,38 L31,51 L49,51 L49,48 L46,48 L46,46 L49,46 L49,43 L46,43 L46,41 L49,41 L49,38 Z M34,36 L45.999,36 L46,31 C46.001,28.384 43.143,26.002 40.004,26 L40.001,26 C38.472,26 36.928,26.574 35.763,27.575 C34.643,28.537 34,29.786 34,31.001 L34,36 Z M48,31.001 L47.999,36 L50,36 C50.553,36 51,36.448 51,37 L51,52 C51,52.552 50.553,53 50,53 L30,53 C29.447,53 29,52.552 29,52 L29,37 C29,36.448 29.447,36 30,36 L32,36 L32,31 C32.001,29.202 32.897,27.401 34.459,26.058 C35.982,24.75 38.001,24 40.001,24 L40.004,24 C44.265,24.002 48.001,27.273 48,31.001 L48,31.001 Z M19.207,55.049 L20.828,53.877 C18.093,50.097 16.581,45.662 16.396,41 L19,41 L19,39 L16.399,39 C16.598,34.366 18.108,29.957 20.828,26.198 L19.207,25.025 C16.239,29.128 14.599,33.942 14.399,39 L12,39 L12,41 L14.396,41 C14.582,46.086 16.224,50.926 19.207,55.049 L19.207,55.049 Z M53.838,59.208 C50.069,61.936 45.648,63.446 41,63.639 L41,61 L39,61 L39,63.639 C34.352,63.447 29.93,61.937 26.159,59.208 L24.988,60.828 C29.1,63.805 33.928,65.445 39,65.639 L39,68 L41,68 L41,65.639 C46.072,65.445 50.898,63.805 55.01,60.828 L53.838,59.208 Z M26.159,20.866 C29.93,18.138 34.352,16.628 39,16.436 L39,19 L41,19 L41,16.436 C45.648,16.628 50.069,18.138 53.838,20.866 L55.01,19.246 C50.898,16.27 46.072,14.63 41,14.436 L41,12 L39,12 L39,14.436 C33.928,14.629 29.1,16.269 24.988,19.246 L26.159,20.866 Z M65.599,39 C65.399,33.942 63.759,29.128 60.79,25.025 L59.169,26.198 C61.89,29.957 63.4,34.366 63.599,39 L61,39 L61,41 L63.602,41 C63.416,45.662 61.905,50.097 59.169,53.877 L60.79,55.049 C63.774,50.926 65.415,46.086 65.602,41 L68,41 L68,39 L65.599,39 Z M56.386,25.064 L64.226,17.224 L62.812,15.81 L54.972,23.65 L56.386,25.064 Z M23.612,55.01 L15.772,62.85 L17.186,64.264 L25.026,56.424 L23.612,55.01 Z M28.666,27.253 L13.825,12.413 L12.411,13.827 L27.252,28.667 L28.666,27.253 Z M54.193,52.78 L67.586,66.173 L66.172,67.587 L52.779,54.194 L54.193,52.78 Z'
fill='#FFFFFF'
/>
</svg>
)
}

export function SQSIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg
Expand Down
2 changes: 2 additions & 0 deletions apps/docs/components/ui/icon-mapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ import {
S3Icon,
SalesforceIcon,
SearchIcon,
SecretsManagerIcon,
SendgridIcon,
SentryIcon,
SerperIcon,
Expand Down Expand Up @@ -317,6 +318,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
s3: S3Icon,
salesforce: SalesforceIcon,
search: SearchIcon,
secrets_manager: SecretsManagerIcon,
sendgrid: SendgridIcon,
sentry: SentryIcon,
serper: SerperIcon,
Expand Down
1 change: 1 addition & 0 deletions apps/docs/content/docs/en/tools/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@
"s3",
"salesforce",
"search",
"secrets_manager",
"sendgrid",
"sentry",
"serper",
Expand Down
157 changes: 157 additions & 0 deletions apps/docs/content/docs/en/tools/secrets_manager.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
---
title: AWS Secrets Manager
description: Connect to AWS Secrets Manager
---

import { BlockInfoCard } from "@/components/ui/block-info-card"

<BlockInfoCard
type="secrets_manager"
color="linear-gradient(45deg, #BD0816 0%, #FF5252 100%)"
/>

{/* MANUAL-CONTENT-START:intro */}
[AWS Secrets Manager](https://aws.amazon.com/secrets-manager/) is a secrets management service that helps you protect access to your applications, services, and IT resources. It enables you to rotate, manage, and retrieve database credentials, API keys, and other secrets throughout their lifecycle.

With AWS Secrets Manager, you can:

- **Securely store secrets**: Encrypt secrets at rest using AWS KMS encryption keys
- **Retrieve secrets programmatically**: Access secrets from your applications and workflows without hardcoding credentials
- **Rotate secrets automatically**: Configure automatic rotation for supported services like RDS, Redshift, and DocumentDB
- **Audit access**: Track secret access and changes through AWS CloudTrail integration
- **Control access with IAM**: Use fine-grained IAM policies to manage who can access which secrets
- **Replicate across regions**: Automatically replicate secrets to multiple AWS regions for disaster recovery

In Sim, the AWS Secrets Manager integration allows your workflows to securely retrieve credentials and configuration values at runtime, create and manage secrets as part of automation pipelines, and maintain a centralized secrets store that your agents can access. This is particularly useful for workflows that need to authenticate with external services, rotate credentials, or manage sensitive configuration across environments — all without exposing secrets in your workflow definitions.
{/* MANUAL-CONTENT-END */}


## Usage Instructions

Integrate AWS Secrets Manager into the workflow. Can retrieve, create, update, list, and delete secrets.



## Tools

### `secrets_manager_get_secret`

Retrieve a secret value from AWS Secrets Manager

#### Input

| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `region` | string | Yes | AWS region \(e.g., us-east-1\) |
| `accessKeyId` | string | Yes | AWS access key ID |
| `secretAccessKey` | string | Yes | AWS secret access key |
| `secretId` | string | Yes | The name or ARN of the secret to retrieve |
| `versionId` | string | No | The unique identifier of the version to retrieve |
| `versionStage` | string | No | The staging label of the version to retrieve \(e.g., AWSCURRENT, AWSPREVIOUS\) |

#### Output

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `name` | string | Name of the secret |
| `secretValue` | string | The decrypted secret value |
| `arn` | string | ARN of the secret |
| `versionId` | string | Version ID of the secret |
| `versionStages` | array | Staging labels attached to this version |
| `createdDate` | string | Date the secret was created |

### `secrets_manager_list_secrets`

List secrets stored in AWS Secrets Manager

#### Input

| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `region` | string | Yes | AWS region \(e.g., us-east-1\) |
| `accessKeyId` | string | Yes | AWS access key ID |
| `secretAccessKey` | string | Yes | AWS secret access key |
| `maxResults` | number | No | Maximum number of secrets to return \(1-100, default 100\) |
| `nextToken` | string | No | Pagination token from a previous request |

#### Output

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `secrets` | json | List of secrets with name, ARN, description, and dates |
| `nextToken` | string | Pagination token for the next page of results |
| `count` | number | Number of secrets returned |

### `secrets_manager_create_secret`

Create a new secret in AWS Secrets Manager

#### Input

| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `region` | string | Yes | AWS region \(e.g., us-east-1\) |
| `accessKeyId` | string | Yes | AWS access key ID |
| `secretAccessKey` | string | Yes | AWS secret access key |
| `name` | string | Yes | Name of the secret to create |
| `secretValue` | string | Yes | The secret value \(plain text or JSON string\) |
| `description` | string | No | Description of the secret |

#### Output

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `message` | string | Operation status message |
| `name` | string | Name of the created secret |
| `arn` | string | ARN of the created secret |
| `versionId` | string | Version ID of the created secret |

### `secrets_manager_update_secret`

Update the value of an existing secret in AWS Secrets Manager

#### Input

| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `region` | string | Yes | AWS region \(e.g., us-east-1\) |
| `accessKeyId` | string | Yes | AWS access key ID |
| `secretAccessKey` | string | Yes | AWS secret access key |
| `secretId` | string | Yes | The name or ARN of the secret to update |
| `secretValue` | string | Yes | The new secret value \(plain text or JSON string\) |
| `description` | string | No | Updated description of the secret |

#### Output

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `message` | string | Operation status message |
| `name` | string | Name of the updated secret |
| `arn` | string | ARN of the updated secret |
| `versionId` | string | Version ID of the updated secret |

### `secrets_manager_delete_secret`

Delete a secret from AWS Secrets Manager

#### Input

| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `region` | string | Yes | AWS region \(e.g., us-east-1\) |
| `accessKeyId` | string | Yes | AWS access key ID |
| `secretAccessKey` | string | Yes | AWS secret access key |
| `secretId` | string | Yes | The name or ARN of the secret to delete |
| `recoveryWindowInDays` | number | No | Number of days before permanent deletion \(7-30, default 30\) |
| `forceDelete` | boolean | No | If true, immediately delete without recovery window |

#### Output

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `message` | string | Operation status message |
| `name` | string | Name of the deleted secret |
| `arn` | string | ARN of the deleted secret |
| `deletionDate` | string | Scheduled deletion date |


2 changes: 2 additions & 0 deletions apps/sim/app/(landing)/integrations/data/icon-mapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ import {
S3Icon,
SalesforceIcon,
SearchIcon,
SecretsManagerIcon,
SendgridIcon,
SentryIcon,
SerperIcon,
Expand Down Expand Up @@ -317,6 +318,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
s3: S3Icon,
salesforce: SalesforceIcon,
search: SearchIcon,
secrets_manager: SecretsManagerIcon,
sendgrid: SendgridIcon,
sentry: SentryIcon,
serper: SerperIcon,
Expand Down
39 changes: 39 additions & 0 deletions apps/sim/app/(landing)/integrations/data/integrations.json
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,45 @@
"integrationType": "crm",
"tags": ["sales-engagement", "enrichment"]
},
{
"type": "secrets_manager",
"slug": "aws-secrets-manager",
"name": "AWS Secrets Manager",
"description": "Connect to AWS Secrets Manager",
"longDescription": "Integrate AWS Secrets Manager into the workflow. Can retrieve, create, update, list, and delete secrets.",
"bgColor": "linear-gradient(45deg, #BD0816 0%, #FF5252 100%)",
"iconName": "SecretsManagerIcon",
"docsUrl": "https://docs.sim.ai/tools/secrets-manager",
"operations": [
{
"name": "Get Secret",
"description": "Retrieve a secret value from AWS Secrets Manager"
},
{
"name": "List Secrets",
"description": "List secrets stored in AWS Secrets Manager"
},
{
"name": "Create Secret",
"description": "Create a new secret in AWS Secrets Manager"
},
{
"name": "Update Secret",
"description": "Update the value of an existing secret in AWS Secrets Manager"
},
{
"name": "Delete Secret",
"description": "Delete a secret from AWS Secrets Manager"
}
],
"operationCount": 5,
"triggers": [],
"triggerCount": 0,
"authType": "none",
"category": "tools",
"integrationType": "developer-tools",
"tags": ["cloud", "secrets-management"]
},
{
"type": "textract_v2",
"slug": "aws-textract",
Expand Down
65 changes: 65 additions & 0 deletions apps/sim/app/api/tools/secrets_manager/create-secret/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { createSecret, createSecretsManagerClient } from '../utils'

const logger = createLogger('SecretsManagerCreateSecretAPI')

const CreateSecretSchema = z.object({
region: z.string().min(1, 'AWS region is required'),
accessKeyId: z.string().min(1, 'AWS access key ID is required'),
secretAccessKey: z.string().min(1, 'AWS secret access key is required'),
name: z.string().min(1, 'Secret name is required'),
secretValue: z.string().min(1, 'Secret value is required'),
description: z.string().nullish(),
})

export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)

const auth = await checkInternalAuth(request)
if (!auth.success || !auth.userId) {
return NextResponse.json({ error: auth.error || 'Unauthorized' }, { status: 401 })
}

try {
const body = await request.json()
const params = CreateSecretSchema.parse(body)

logger.info(`[${requestId}] Creating secret ${params.name}`)

const client = createSecretsManagerClient({
region: params.region,
accessKeyId: params.accessKeyId,
secretAccessKey: params.secretAccessKey,
})

try {
const result = await createSecret(client, params.name, params.secretValue, params.description)

logger.info(`[${requestId}] Secret created: ${result.name}`)

return NextResponse.json({
message: `Secret "${result.name}" created successfully`,
...result,
})
} finally {
client.destroy()
}
} catch (error) {
if (error instanceof z.ZodError) {
logger.warn(`[${requestId}] Invalid request data`, { errors: error.errors })
return NextResponse.json(
{ error: 'Invalid request data', details: error.errors },
{ status: 400 }
)
}

const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'
logger.error(`[${requestId}] Failed to create secret:`, error)

return NextResponse.json({ error: `Failed to create secret: ${errorMessage}` }, { status: 500 })
}
}
Loading
Loading