Zero standing permissions for your cloud.
Agent Zero is a continuous, just-in-time access broker for AWS. Humans and AI agents get the access they need, when they need it, for only as long as they need it, and nothing more. No standing IAM users. No thousands of static policies. No multi-day waits on legal, security, or IT to approve a one-off task.
Cloud identity is broken in two directions at once:
- Humans sit on permanent, over-broad IAM roles because nobody has time to scope them per task. So every laptop is a blast radius.
- AI agents are about to make this 100x worse. Every new agent today gets handed a static API key or a long-lived role, and it keeps that access forever, regardless of what it is actually doing in any given moment.
Meanwhile, the access request process is stuck in a ticketing queue. An engineer needs read access to one table to debug one ticket and waits two days for an approval chain that nobody actually reads.
Every request, from a human or an agent, flows through a broker that asks four questions in plain English:
- Who are you?
- What do you want to do?
- Which resource do you need?
- Why do you need it?
The broker pulls the principal's free-text policy from DynamoDB, hands the
request to an LLM reviewer with the resource catalog as context, runs the LLM's
structured decision through a deterministic validator, and if the request is
approved, calls sts:AssumeRole with a tightly scoped inline session policy.
The result is one short-lived AWS session, scoped to one action on one resource, that auto-expires. CloudTrail logs the whole thing.
- Humans get a one-click AWS console sign-in URL backed by those temporary credentials when the request is staff-facing.
- AI agents get raw STS credentials returned to the calling Lambda.
The trick that makes this work at scale: a small set of broad target roles gets narrowed at request time by an inline session policy. AWS evaluates the intersection, so you do not have to mint a new IAM policy per task.
Cloud agents are hard to permission safely. The organization wants them to have enough access to help end users and complete real work, but nobody wants to hand an agent a huge policy up front. Prompt injection, bad tool calls, or a confused conversation can turn broad standing access into a serious security incident.
Static credentials are the wrong primitive for autonomous agents. An agent that is allowed to read customer profiles to answer a support question should not also be able to read that customer's payment history, dump the whole table, or touch an unrelated table, even though the underlying IAM role might technically permit all of it.
Agent Zero gives teams a safer way to deploy agents in the cloud. There are zero standing policies for the agent to abuse. When access is needed, the broker makes a just-in-time decision and returns short-lived credentials scoped to the exact approved job. Prompt injection that tries to widen the agent's access gets denied at the broker, not at the application layer.
There are four core objects:
- Principals: humans and AI agents, stored in
users-tableand backed by Cognito for signed-in human users. - Policies: free-text business rules stored in
policy-table, keyed byuser_id. - Resources: known AWS resources from the live resource catalog, including bank customer profiles, balances, transactions, support requests, operational metrics, the user directory, the policy table, and the Cognito user pool.
- Access requests: short-lived requests with a trusted
user_id, a reason, and staff/customer context.
The current repo flow works like this:
- A user logs in through Cognito in the Nuxt app.
- The frontend opens the Agent API WebSocket with the Cognito access token in
the
tokenquery string. - The WebSocket authorizer validates the Cognito access token and passes the
trusted
user_id, username, client id, and groups into the route context. - The frontend sends a
requestAccessWebSocket message with the user's prompt. - The WebSocket route Lambda validates the route and asynchronously invokes the
UserAgentWorkerLambda. - The worker runs the OpenAI agent with trusted Cognito context. The agent can
call tools such as
request_aws_access,run_dynamodb_operation,write_user_policy, andcreate_cognito_user. - When the agent needs AWS access, it calls the Broker API
GET /credentialsendpoint withuser_id,reason, andis_staff. - The Agent worker signs that broker request with AWS SigV4. API Gateway
protects
/credentialswith IAM auth, so callers cannot hit it anonymously. - The Broker Lambda rejects caller-selected resources. The caller supplies the identity and reason, but the broker chooses the resource grants.
- The Broker Lambda loads the principal profile from
users-tableand the free-text policy frompolicy-table. - The Broker Lambda builds the live resource catalog from environment-backed table names, table ARNs, and the Cognito user pool ARN.
- The LLM reviewer decides whether the reason fits the policy and returns a structured access decision with approved grants, AWS actions, resource keys, and duration.
- The deterministic validator checks that decision against hard rules, allowed actions, allowed resources, duration limits, and sensitive resource constraints.
- If the request is denied, the broker logs the denial and returns the reason.
- If the request is approved, the broker builds an inline STS session policy
from the approved grants. Customer-owned tables such as balances,
transactions, and support requests are scoped with
dynamodb:LeadingKeysfor the signed-inuser_id. - The broker calls
sts:AssumeRoleinto the reusable broker credentials role with that inline session policy and the approved duration. - The broker writes the decision, policy snapshot, grants, session policy, target role, and credential expiration to the request log table.
- The broker returns temporary credentials to the Agent worker. For staff requests, it can also return a console login URL.
- The Agent worker retries the approved tool call with the temporary credentials, streams tool results and answer deltas back over the WebSocket, and then the credentials expire naturally.
The important boundary is that the chat agent does not decide authorization. The Agent worker can ask for access, but Agent Zero, the Broker API, decides what access is allowed and mints the short-lived credentials.
infra/ CDK app, single IamAgentStack with all AWS resources
services/broker-api/ Broker Lambda, LLM reviewer, validator, STS AssumeRole
services/agent-api/ Agent Lambda, WebSocket API for the customer support agent
app/ Nuxt frontend, login, chat, and WebSocket client
scripts/ Bootstrap and teardown helpers for demo data
Target AWS account: 338375260114
Target AWS region: ap-southeast-2
AWS profile: openai-hackathon
First-time only, bootstrap CDK in the target account:
cd infra
cdk bootstrap --profile openai-hackathonThen deploy the stack:
cd infra
cdk deploy IamAgentStack --profile openai-hackathonThis provisions the DynamoDB tables, Cognito user pool and groups, Broker API, Agent API WebSocket, broad reusable IAM role, request logs, and Amplify hosting app for the frontend.
After the CDK deploy finishes, seed Cognito and DynamoDB from the repo root:
python3 scripts/bootstrap_demo_users.py bootstrap --profile openai-hackathonThis creates demo Cognito users, adds them to groups, writes their records into
users-table, seeds the bank demo data, and writes free-text policies into
policy-table.
Seeded users:
Email or id Role Type
admin@example.com admin human
employee1@example.com employee human
customer_support_agent employee agent
To tear it back down:
python3 scripts/bootstrap_demo_users.py teardown --execute --profile openai-hackathonThe Nuxt app in app/ is wired to AWS Amplify Hosting via the CDK stack.
- Push this repo to GitHub.
- Open the Amplify app created by
IamAgentStackin the AWS console and connect it to the GitHub repo if CDK did not attach it automatically. - Confirm Amplify builds from the monorepo root with
app/as the app directory. - Visit the Amplify default domain once the build finishes.
Local dev alternative:
cd app
npm install
npm run devOpen the hosted Amplify URL, or http://localhost:3000 for local dev. The
login screen is wired to Cognito.
- As
admin@example.com, manage users, write free-text policies, and view the access request log. - As
employee1@example.com, request temporary AWS access by saying what you need and why. - As any signed-in user, use
/chatto talk to the customer support AI agent. Try a normal customer support request, then try a prompt injection asking it to read another customer's record. The overbroad request should be denied at the broker.