Skip to main content
Glama
JSR-codes

ai-ops-agent-zero-standing-creds

by JSR-codes

AI Ops Agent with Zero Standing AWS Credentials

An AI SRE agent (Amazon Bedrock + Claude) that investigates operational incidents by querying a DynamoDB table — without ever holding a long-lived AWS access key.

Instead of a static credential, the agent assumes a short-lived IAM role via STS, scoped to read-only access on exactly one table, with every call auditable in CloudTrail.

This project is inspired by a similar "no static credential" security pattern I came across, adapted here to AWS-native tooling: IAM roles + STS instead of a third-party identity provider.


The big idea

The "wrong way" ❌

This project's way ✅

App holds a static AWS access key

App holds no key — assumes a role via STS

Credential never expires

Session expires in 15 minutes, auto-renewed

Often over-permissioned

Least privilege: read-only, one table, nothing else

No record of what ran

Every call auditable in CloudTrail

Two things you can watch happen live in the UI:

  1. No static credential — the agent process never has an AWS_ACCESS_KEY_ID for itself; it calls sts:AssumeRole and gets a token that expires on its own.

  2. Least privilege enforced — clicking "Try write" attempts a PutItem with the agent's credentials and is denied by IAM before it ever reaches DynamoDB.


Related MCP server: ghost-dev-mcp

How it works (request flow)

You ask a question in the chat UI (app.py / Streamlit)
       │
       ▼
agent_core.py ──► Amazon Bedrock (Claude)        "run this query" (tool_use)
       │   ◄──────────────────────────────────
       ▼
mcp_server.py   (MCP server, one tool: query_incidents_readonly)
       │
       ▼
aws_client.py ──► sts:AssumeRole ──► short-lived creds (15 min, auto-refreshed)
       │                                    │
       │                          IAM policy: read-only, one table
       │                          write attempt → DENIED
       ▼                                    ▼
DynamoDB (Query/Scan only) ──► results ──► rendered in the chat UI
       │
       ▼
CloudTrail logs the AssumeRole call and every DynamoDB read

What's in the box

File

What it does

app.py

Streamlit chat UI + live security panel (session countdown, "Try write → DENIED").

agent_core.py

The agent loop: Bedrock Converse API + MCP client over stdio.

mcp_server.py

MCP server exposing the single tool query_incidents_readonly — the only seam into AWS.

aws_client.py

STS AssumeRole logic — the core of the "zero standing credentials" story.

seed.py

One-time: creates the table and loads sample incident data (run with your own admin credentials).

iam/readonly-incidents-policy.json

The least-privilege policy: read-only, one table.

iam/role-trust-policy.json

Who is allowed to assume the role.

terraform/

Provisions the DynamoDB table + IAM role + policy as code.


Prerequisites

  • Python 3.11+

  • An AWS account with:

    • Amazon Bedrock access to a Claude model (request access here if you haven't already)

    • Permission to create IAM roles and DynamoDB tables (for initial setup)

  • AWS credentials configured locally (aws configure)


Setup

git clone https://github.com/JSR-codes/ai-ops-agent-zero-standing-creds.git
cd ai-ops-agent-zero-standing-creds

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

1. Provision the AWS infrastructure with Terraform

cd terraform
terraform init
terraform apply -var="assuming_principal_arn=arn:aws:iam::<your-account-id>:user/<your-iam-username>"

Copy the readonly_role_arn output — you'll need it next.

2. Configure the app

cd ..
cp .env.example .env
# edit .env: paste in READONLY_ROLE_ARN from the terraform output

3. Seed sample data

python seed.py

(This runs with your own admin credentials, not the agent's read-only role — the agent's role isn't allowed to write, by design.)

4. Run the app

streamlit run app.py

Try it

  • Ask "what open incidents do we have?" and watch the agent query DynamoDB through the read-only role.

  • Watch the session countdown in the security panel — it's counting down a real STS session, not a fake timer.

  • Click "Try write (should be denied)" to see the IAM policy block a write attempt live.

  • Check CloudTrail in the AWS console afterward — you'll see the AssumeRole call and the Query/Scan calls, all attributable to the short-lived session.


Security notes for anyone reusing this

  • This is a teaching demo, not production-hardened — review IAM policies and network setup before adapting it further.

  • .env and all Terraform state/var files are git-ignored — never commit real values.

  • The whole point is that the agent runs with short-lived, least-privilege, audited credentials — keep it that way if you extend this.

Possible extensions

  • Add a second MCP tool with its own narrower role, to show per-tool credential scoping

  • Add an EventBridge rule that alerts if AccessDenied shows up in CloudTrail unexpectedly

  • Swap DynamoDB for RDS and compare the IAM-auth flow to this table-scoped one

License

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Connects AI assistants to AWS infrastructure through AWS IAM Identity Center for secure, natural language management of cloud resources across multiple accounts. It enables users to execute AWS CLI commands, monitor resources, and run remote shell commands on EC2 instances via Systems Manager.
    377 npm
    15
    ISC
  • F
    license
    Not graded
    quality
    D
    maintenance
    An MCP server on AWS Lambda that gives AI assistants read-only access to SQS dead-letter queues and CloudWatch logs for fast incident triage.
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables autonomous SRE incident investigation by allowing users to describe incidents in natural language. The agent follows a governed state machine to gather read-only evidence and produce grounded conclusions.
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to diagnose and analyze AWS serverless infrastructure through Model Context Protocol, providing access to CloudWatch logs, Lambda functions, DynamoDB tables, IAM policies, and Bedrock-powered incident root-cause analysis.
    -