AWS Builder Center
Using Kiro to Implement the AWS Well-Architected Agentic AI Lens

Using Kiro to Implement the AWS Well-Architected Agentic AI Lens

How to make best practices the default, not a separate review step, by encoding the Agentic AI Lens into your development workflow with Kiro.

Series: Operating at Hyperscale (7 articles)

  1. …
  2. 4
    Using Kiro to Implement the AWS Well-Architected Agentic AI Lens This article

The gap between best practices and implementation

The AWS Well-Architected Agentic AI Lens  is one of the most comprehensive guides available for building production-grade autonomous AI systems. It covers six pillars, Operational Excellence, Security, Reliability, Performance Efficiency, Cost Optimization, and Sustainability, each adapted specifically for agentic workloads.
Teams read it. They agree with the recommendations. And then they struggle to operationalize them consistently.
The problem is familiar: best-practice documents describe what good looks like, but they don't embed themselves into the development workflow. A security recommendation like "implement tool authorization with least-privilege scoping" is unambiguous, but without enforcement at authoring time, it depends on every developer remembering to apply it to every agent feature, in every sprint, forever.
This is the gap Kiro closes.
Kiro  is AWS's spec-driven agentic development tool, available as both an IDE and a CLI. Its control surface, steering files, agent hooks, structured specifications, and MCP integrations, maps directly to the control mechanisms the Agentic AI Lens recommends. When you encode lens recommendations into Kiro's configuration, compliance becomes a side effect of normal development rather than a separate review step.
This post shows how to do it, pillar by pillar.
A note on versions: The Kiro configuration examples in this post (hook file format, trigger names, and the permissions model) target Kiro CLI 3.0. Earlier CLI versions used a different hook format (hooks embedded in the agent config, with trigger names like postToolUse), and Kiro is evolving quickly. If you are on a different version, check the Kiro documentation  and the CLI 3.0 migration guide  for the current syntax. The pillar-to-feature mapping and the overall approach hold regardless of version; only the exact configuration syntax changes.

The Agentic AI Lens in 60 seconds

The Agentic AI Lens is organized around six pillars, each addressing a unique characteristic of autonomous AI systems:
  • Operational Excellence: prompt lifecycle management, behavioral monitoring, human-in-the-loop governance.
  • Security: agent identity, tool access authorization, data flow protection, prompt injection defense, privilege escalation prevention.
  • Reliability: predictable task execution, automatic failure recovery, graceful degradation under adverse conditions.
  • Performance Efficiency: cognitive pipeline optimization, model selection, memory access patterns, multi-agent coordination.
  • Cost Optimization: cost as a primary design consideration, right-sizing model and memory capabilities, full cost visibility.
  • Sustainability: modular, reusable architectures and resource efficiency.
The key insight: agentic systems need controls at authoring time, not just at runtime. Runtime guardrails (Amazon Bedrock Guardrails, IAM policies, CloudWatch alarms) catch problems after they are built. Author-time controls help prevent them from being built in the first place.

Kiro's control surface, a quick primer

Kiro provides four mechanisms that map directly to lens control requirements.

1. Steering files (.kiro/steering/)

Steering files  are Markdown files that give Kiro persistent knowledge about your project, patterns, standards, constraints. They support optional YAML frontmatter with an inclusion field:
  • always (or no frontmatter): loaded into every session.
  • fileMatch: loaded only when files matching a pattern are in context.
  • manual: loaded only when explicitly referenced (it runs as a /<filename> slash command).
One thing worth knowing: the built-in default agent loads steering files automatically. A custom agent loads them only if you add the steering path to the agent's resources (for example, file://.kiro/steering/**/*.md).

2. Spec-driven development

A three-phase workflow : requirements.md (what, in EARS format) → design.md (how, with architecture) → tasks.md (sequenced implementation steps). Each phase has a review checkpoint. This forces explicit thinking about acceptance criteria, failure modes, and security boundaries before any code is written.

3. Agent hooks

In Kiro 3.0, hooks  live in standalone JSON files under .kiro/hooks/*.json (in earlier CLI versions they were embedded in the agent config; 3.0 moved them out). Each hook has a trigger, an optional matcher, and an action that runs a shell command or an agent prompt.
The CLI trigger types  include:
  • SessionStart: when a new session begins (the CLI surfaces this as "Agent Spawn").
  • UserPromptSubmit: when you submit a message.
  • PreToolUse: before a tool runs (this one can block the tool).
  • PostToolUse: after a tool runs.
  • Stop: when the agent finishes responding.
(Note: File Create / File Save / File Delete triggers are IDE-only. In the CLI, wire "run a check on every change" as a PostToolUse hook matching the write tool, or PreToolUse if you want it to block.)
A hook file looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
{
"version": "v1",
"hooks": [
{
"name": "observability-check",
"trigger": "PostToolUse",
"matcher": "write",
"action": { "type": "command", "command": "bash .kiro/scripts/check-observability.sh" },
"timeout": 30,
"enabled": true
}
]
}
The matcher accepts built-in tool categories: read, write, shell, web, spec, or * for all tools.

4. MCP integrations

Connect Kiro to private package registries, internal documentation, issue trackers, and infrastructure tooling via the Model Context Protocol (MCP) , configured under mcpServers. This is how you give an agent controlled, explicit tool access instead of blanket capabilities.

A note on least-privilege in 3.0

Kiro 3.0 expresses tool access through a permissions model : you declare capability tags in tools (like read, write, shell) and constrain them with a permissions.rules array (or a permissions.yaml file) using capability, match, and effect. This replaces the older toolsSettings / allowedCommands approach. It is the cleanest way to scope an agent to least privilege.

Mapping the six pillars to Kiro features

Lens pillarKiro featureWhat I use it for
Operational ExcellenceSteering + Specs + HooksObservability standards, deployment/rollback expectations, prompt versioning
SecuritySteering + Permissions + Hooks + MCPLeast-privilege tool access, credential scanning, prompt-injection defenses, scoped MCP tooling
ReliabilitySpecs + HooksGraceful-degradation acceptance criteria, edge-case tests, error-handling enforcement
Performance EfficiencySteering + Specs + HooksModel-selection guidance, latency budgets in design docs, perf checks
Cost OptimizationSteering + Specs + HooksToken budgets, explicit max_tokens, cost estimation in design
SustainabilitySpecs + SteeringModular architecture via specs, component-reuse patterns
Let's walk through each pillar.

Operational Excellence → Steering + Specs + Hooks

The lens recommends prompt lifecycle management, agent deployment processes, observability and monitoring, and testing and evaluation frameworks.
Steering file: .kiro/steering/operational-excellence.md
1
2
3
4
5
6
7
8
9
10
11
12
# Operational Excellence Standards

## Observability Requirements
- Every agent action MUST emit a structured log with: timestamp, action_type,
model_id, input_token_count, output_token_count, latency_ms, success/failure.
- All agent interactions MUST be traceable via X-Ray trace IDs.
- Prompts MUST be versioned. Use a prompt_version field in all invocations.

## Deployment Standards
- Agent deployments MUST include rollback procedures in the design doc.
- All prompt changes MUST go through the spec workflow (not direct edits).
- Canary deployments required for any agent handling >1000 requests/day.
To back this up at authoring time, wire a PostToolUse hook that runs an observability check after file writes. In 3.0 that hook is a standalone file:
.kiro/hooks/observability.json
1
2
3
4
5
6
7
8
9
10
11
12
13
{
"version": "v1",
"hooks": [
{
"name": "observability-check",
"trigger": "PostToolUse",
"matcher": "write",
"action": { "type": "command", "command": "bash .kiro/scripts/check-observability.sh" },
"timeout": 30,
"enabled": true
}
]
}
And the script it calls (.kiro/scripts/check-observability.sh) stays deliberately simple:
1
2
3
4
5
6
#!/usr/bin/env bash
# Flags agent source files that are missing a structured logging pattern.
for f in $(git diff --name-only --diff-filter=AM -- 'src/agents/*'); do
grep -Lq "structured_log\|emit_metric" "$f" \
&& echo "WARNING: $f missing structured logging pattern"
done
The hook lives in .kiro/hooks/; the script is just what the hook runs.

Security → Steering + Permissions + Hooks + MCP

The lens recommends tool authorization with least-privilege, prompt injection defense, identity propagation, and human-in-the-loop for mutating operations.
Steering file: .kiro/steering/security-guardrails.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Security Guardrails

## Tool Authorization
- Agents MUST NOT be granted blanket access to all tools.
- Each agent MUST have an explicit tool allowlist in its configuration.
- Mutating operations (write, delete, update) MUST require human approval.
- Tool invocations MUST propagate user identity context.

## Prompt Injection Defense
- All user inputs MUST be delimited with unique nonce tokens.
- System prompts MUST include injection-detection instructions.
- Never embed raw user input directly into tool invocation parameters.

## Credential Handling
- NEVER hardcode credentials, API keys, or secrets in agent code.
- Use AWS Secrets Manager or SSM Parameter Store for all secrets.
- Rotate webhook secrets per organizational security policy.
Beyond the steering guidance, enforce least-privilege directly in the agent config using the 3.0 permissions model , scoping capabilities to what the agent actually needs:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"name": "customer-service-agent",
"model": "claude-sonnet-4",
"tools": ["read", "write", "shell"],
"permissions": {
"rules": [
{ "capability": "fs_read", "match": ["src/**"], "effect": "allow" },
{ "capability": "fs_read", "match": [".env", "secrets/**"], "effect": "deny" },
{ "capability": "fs_write", "match": ["src/**"], "effect": "allow" },
{ "capability": "shell", "match": ["git status", "npm test*"], "effect": "allow" },
{ "capability": "shell", "match": ["rm -rf*"], "effect": "deny" }
]
}
}
For credential scanning, add a PreToolUse hook that can block a write if it detects a hardcoded secret:
.kiro/hooks/scan-credentials.json
1
2
3
4
5
6
7
8
9
10
11
12
13
{
"version": "v1",
"hooks": [
{
"name": "scan-credentials",
"trigger": "PreToolUse",
"matcher": "write",
"action": { "type": "command", "command": "bash .kiro/scripts/scan-credentials.sh" },
"timeout": 15,
"enabled": true
}
]
}
.kiro/scripts/scan-credentials.sh
1
2
3
4
5
6
7
8
#!/usr/bin/env bash
# Non-zero exit signals the hook to block the pending tool call.
for f in $(git diff --name-only --diff-filter=AM); do
if grep -nE "(AKIA|aws_secret|password\s*=)" "$f"; then
echo "BLOCKED: Potential hardcoded credential detected in $f"
exit 1
fi
done
A note on AI-assisted security review: in the Kiro IDE you can also use the hooks UI to trigger a natural-language review step ("check these changes for blanket tool access, missing identity propagation, or unsanitized input in tool parameters"). In the CLI, the deterministic script-based hooks above are what I rely on as gates, and I run an AI review by prompting Kiro directly at the end of a task rather than treating it as a guaranteed automated gate.

Reliability → Specs + Hooks

The lens recommends predictable task execution, automatic failure recovery, graceful degradation, and partial functionality under adverse conditions.
Spec: requirements.md with reliability criteria in EARS format
1
2
3
4
5
6
7
8
9
10
11
# Requirements: Customer Service Agent - Order Lookup

## Acceptance Criteria (Reliability)
- WHEN the downstream order API is unavailable,
THE AGENT SHALL inform the user and offer to retry in 30 seconds.
- WHEN the model returns a timeout,
THE AGENT SHALL fall back to a smaller model for the response.
- WHEN token count exceeds 80% of context window,
THE AGENT SHALL summarize conversation history before proceeding.
- THE AGENT SHALL implement a circuit-breaker pattern for all external calls
with max 3 retries and exponential backoff.
From these criteria, you can prompt Kiro to generate property-based tests exercising randomized inputs:
1
2
3
4
5
6
# Prompted from the reliability acceptance criteria above
@given(st.text(min_size=1, max_size=200000))
def test_agent_handles_any_input_length(user_input):
response = agent.process(user_input)
assert response.status in ("success", "graceful_degradation")
assert response.latency_ms < 30000
To be precise: Kiro does not magically guarantee these tests exist. You prompt for them as part of the tasks.md breakdown and review what it produces. The value is that the spec makes the reliability expectations explicit enough that generating meaningful tests becomes straightforward.

Performance Efficiency → Steering + Specs + Hooks

The lens recommends optimizing cognitive pipelines, model selection, memory access, and multi-agent coordination.
Steering file: .kiro/steering/performance.md
1
2
3
4
5
6
7
8
9
10
11
12
13
# Performance Efficiency Standards

## Model Selection
- Use a small/fast model for classification, routing, and simple extraction.
- Use a mid-tier model for complex reasoning, code generation, multi-step planning.
- Reserve the largest model for tasks that genuinely need long context or
expert-level reasoning - and justify it in design.md.
- Default max_tokens to the expected output size + 20% buffer (NEVER leave unset).

## Latency Budgets
- Time-to-first-token for user-facing agents: < 2 seconds.
- End-to-end for tool-calling agents: < 15 seconds per action.
- Pre-inference pipeline (context assembly): < 500ms.
I keep model names generic on purpose. The specific tiers change over time, so the steering file describes the selection principle rather than pinning a model that will be stale in six months.
A PostToolUse hook can run the perf suite after changes to agent code:
.kiro/hooks/perf.json
1
2
3
4
5
6
7
8
9
10
11
12
13
{
"version": "v1",
"hooks": [
{
"name": "perf-suite",
"trigger": "PostToolUse",
"matcher": "write",
"action": { "type": "command", "command": "python -m pytest tests/perf/ --timeout=30 -q" },
"timeout": 60,
"enabled": true
}
]
}

Cost Optimization → Steering + Specs + Hooks

The lens recommends treating cost as a primary consideration, right-sizing model and memory capabilities, and full cost visibility.
Steering file: .kiro/steering/cost-constraints.md
1
2
3
4
5
6
7
8
9
10
11
# Cost Constraints

## Token Budgets
- Input prompts MUST NOT exceed 4000 tokens for routing agents.
- Summarization prompts MUST use truncation before hitting 50K input tokens.
- Always set max_tokens explicitly. NEVER rely on model defaults.

## Model Cost Awareness
- Larger models cost materially more per token - justify their use in design.md.
- Batch non-urgent requests where batch inference is available.
- Cache repeated context (e.g., stable system prompts) where supported.
Require every design.md to include a cost estimation section:
1
2
3
4
5
## Cost Estimation (Required)
- Estimated requests/day
- Model tier | approx input tokens | approx output tokens
- Estimated daily cost and cost per request
- Optimization opportunities (prompt caching, batching for offline tasks)
Forcing even a rough estimate at design time has caught more than one "why is this using the biggest model for a routing decision?" before it ever shipped.

Sustainability → Specs + Steering

The lens recommends modular, reusable architectures. Kiro's spec workflow naturally pushes toward this: each spec defines a discrete, testable feature with explicit boundaries, which counters the monolithic-agent anti-pattern where one agent slowly accumulates every responsibility.
Steering file: .kiro/steering/sustainability.md
1
2
3
4
5
6
7
8
9
10
11
# Sustainability Patterns

## Component Reuse
- Extract reusable tool-calling patterns into shared libraries.
- Use a common agent base class with standard logging, error handling, metrics.
- Share prompt templates via a central registry.

## Resource Efficiency
- Prefer streaming responses over buffered for user-facing agents.
- Implement conversation pruning for long-running sessions.
- Reuse cached system prompts where supported.

Building a lens-compliant agent from scratch

Here is how the pieces come together for an agentic customer service bot, using Kiro end-to-end.
Step 1: Set up steering files. Drop the templates above into .kiro/steering/. On your next session they load into context automatically for the default agent, or for a custom agent once you add file://.kiro/steering/**/*.md to its resources. Every code suggestion Kiro makes now respects your lens-aligned guardrails.
Step 2: Create the spec. Prompt Kiro with your feature request. It generates requirements.md (EARS-format acceptance criteria covering reliability, security, and observability), design.md (architecture with model-selection rationale, latency budgets, cost estimation, and rollback procedures, all shaped by the steering files), and tasks.md (sequenced steps with test tasks interleaved, not deferred to the end).
Step 3: Implement with hooks active. As Kiro generates code from the tasks, the credential-scanner PreToolUse hook runs before writes and blocks on a detected secret, and the observability PostToolUse hook flags any agent file missing structured logging.
Step 4: Property-based testing. Prompt Kiro to generate property-based tests from the reliability requirements, exercising edge cases (oversized inputs, timeout scenarios, malformed responses) that a hand-written suite would miss.
Result: by the time the feature is complete, it is lens-aligned by construction, observability instrumented, tool access scoped and credentials secured, graceful degradation tested, model selection justified and latency budgeted, cost estimated, and architecture kept modular. The controls were applied during development, not bolted on in a separate review.

Starter kit: steering file templates

Drop these into any .kiro/steering/ folder to encode lens recommendations:
  • security-guardrails.md: tool authorization, prompt injection defense, credential handling.
  • operational-excellence.md: observability standards, deployment processes, prompt versioning.
  • reliability-patterns.md: circuit breakers, graceful degradation, fallback model chains.
  • performance.md: model selection guidance, latency budgets, TTFT targets.
  • cost-constraints.md: token budgets, batch inference guidance, cost estimation requirements.
  • sustainability.md: component reuse patterns, prompt caching, conversation pruning.
Use fileMatch inclusion so each file loads only when relevant. Start with security-guardrails.md (highest-risk pillar) and expand from there.

Where this fits in the full lifecycle

Kiro handles the author-time layer. The Agentic AI Lens spans the whole lifecycle, and the layers connect like this:
  • Author-time (Kiro): steering files, specs, hooks, property-based tests. Helps prevent bad patterns from being written.
  • Build-time (CI/CD): the same scripts your Kiro hooks call can run in CI as merge gates.
  • Inference-time (Amazon Bedrock Guardrails): content filters, topic denial, and contextual grounding applied at inference. Catches runtime violations.
  • Operations-time: monitoring and incident investigation on deployed agents, feeding lessons back into the steering files and specs.
This creates a closed loop: build lens-aligned agents in Kiro, enforce at inference with Bedrock Guardrails, detect runtime issues in operations, and feed fixes back into Kiro. Each tool handles its layer; the lens provides the unified framework.

Getting started

You do not need to implement all six pillars at once. Start small:
  1. Install Kiro and open your agent project.
  2. Generate baseline steering docs (product.md, tech.md, structure.md) for context.
  3. Add one lens-aligned steering file, starting with security-guardrails.md.
  4. Create a spec for your next agent feature. Notice how the steering file influences the generated requirements and design.
  5. Add one hook. The credential scanner is the highest value-to-effort.
  6. Iterate, adding a pillar per sprint until all six are encoded.
Within a few sprints, your agent development workflow will enforce lens alignment by default, and new team members inherit the guardrails automatically.

Making compliance the default

The Agentic AI Lens tells you what good looks like. Kiro helps make it the default.
When best practices are encoded in steering files and enforced by hooks and permissions, compliance becomes a side effect of normal development, not a separate review step, not a checklist someone forgets, not a gate that slows down delivery.
The pattern is simple: read the lens, distill each recommendation into a constraint or standard, write it as a steering file, hook, or permissions rule, and let Kiro apply it every time code is written. The lens provides the knowledge. Kiro provides the enforcement mechanism.
If you are building agents on AWS and want to compare approaches on encoding the lens into your workflow, I would genuinely like to hear what is working for you.

References

Series: Operating at Hyperscale (7 articles)

  1. …
  2. 4
    Using Kiro to Implement the AWS Well-Architected Agentic AI Lens This article
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article