Security questionnaires are very common today. When customers consider your product, especially if you’re a startup, they often ask for proof that using your service is safe. This can become a huge time-sink: you may spend hours answering questions that don’t always apply to you.
I won’t cover other strategies, like having a dedicated security page, getting a SOC 2 report, or using a standard security questionnaire. For that, I recommend reading Rami McCarthy’s post.
Instead, this post focuses on how to quickly answer security questionnaires using Amazon Bedrock, Aurora PostgreSQL with pgvector, AWS Lambda, and Amazon S3. With these services, you can create a serverless knowledge base that stores your security documentation and old questionnaire answers. You can query it to generate relevant answers with minimal cost (you only pay when you actually use it).
Searching for a solution
When I started looking for ways to build a security knowledge base in AWS, somewhere I could keep all my security documentation in one place and let others query it easily, I noticed most blogs recommended using Bedrock with Amazon OpenSearch Service’s vector database. However, many of them ended with a warning: “After testing, you should delete your OpenSearch domain, or else you’ll end up with a big bill.” Indeed, OpenSearch can become quite expensive.
I discovered Aurora PostgreSQL as another option for storing documents. After testing, Aurora’s cost was lower than OpenSearch, but it was still around $1 per day, so over $30/month. For something used only occasionally (like security questionnaires), I wanted an almost cost-free solution when not used.
Then I found that if I upgraded Aurora PostgreSQL to version 8.5, I could configure the minimum capacity to 0. This makes the cost $0 when not in use. If you try to use the recommended quick create way, you’ll end up with a PostgreSQL that does not scale to 0, so I built Terraform code to create the infrastructure for me.
Additionally, because my main goal was to handle security questionnaires, I wrote two Lambda functions:
- Sync Function: Whenever I upload new security documents to an S3 bucket, it ingests them into my Aurora-based knowledge base.
- Q&A Function: I can upload a text file of questions to another S3 bucket; the Lambda queries the knowledge base via Bedrock and then saves the answers as a CSV in that same bucket.
In my setup, I’ve been using Anthropic Claude to generate the responses. However, the Terraform variables in my repository allow you to customize which model ARN you want to use. Of course, these answers need a review, but having a first pass speeds things up. The more questionnaires you fill out and upload to your knowledge base, the better your system becomes over time.
How the Infrastructure Works
Aurora PostgreSQL v8.5
- Stores your documentation and security policies in a table that supports vector similarity search (pgvector).
- Uses a min capacity of 0, so you pay nothing when it’s idle.
Amazon Bedrock
- Handles both retrieving the right documents and generating text (a Retrieval-Augmented Generation approach).
- Links to your Aurora database via a “knowledge base” configuration.
- In the Terraform code, you can specify which LLM model ARN to use (Anthropic Claude, Amazon Titan, etc.).
AWS Lambda and S3
- Data Ingestion: One Lambda function watches for new files in an S3 bucket and loads them into Aurora.
- Q&A: Another Lambda function reads a file of questions from a different S3 bucket, calls Bedrock for answers, and saves the results as a CSV.
Try It Out
The complete Terraform code is here: adanalvarez/bedrock-secure-questionnaire-automation
In that repo, you’ll find all the terraform modules to set up Aurora Serverless, S3 buckets, Lambda functions, and the Bedrock knowledge base.
Wrap-Up
When security questionnaires can’t be avoided, automation with an LLM can save time. By storing key documents and previous answers in a secure, queryable knowledge base, you can quickly generate responses and cut down on repetitive work. This approach helps you keep costs near zero when you’re not actively using it, which is ideal for a task that hopefully doesn’t happen every day!
Top comments (0)