Skip to main content

Govern Kiro (AWS) GA

Surfaces used: coding assistant hooks Modes supported: Local Hosted Hybrid Tiers: Free (individual) Teams (org-wide enrollment) SDK: Python (pip install controlzero)

Kiro is AWS's agentic IDE, paired with kiro-cli. It runs shell commands, file reads and writes, and AWS API calls on your behalf. Control Zero hooks into Kiro's hook system so a deny rule blocks the tool call before it executes -- and every call is logged to your audit trail.

Maturity
  • Kiro CLI (kiro-cli chat): GA. Full pre-tool-use policy enforcement, including argument-level deny rules. Validate any install with controlzero kiro verify.
  • Kiro IDE: Limited preview. The Prompt Submit and File Save hooks are active; the Pre Tool Use hook ships disabled because of an upstream Kiro bug (see IDE limitation below).

Kiro support ships in the Python SDK. (Node.js Kiro support is code-complete but not yet published to npm -- use the Python controlzero CLI for Kiro today.) requires_approval (HITL) policies are enforced on the CLI as a hard block (stop-and-review), because Kiro CLI has no native interactive approval state.

Install

Install the Control Zero CLI (requires Python 3.10+):

pip install controlzero

Wire Kiro with the dedicated installer. Pick the surface you use:

# Kiro CLI only
controlzero kiro init --surface cli

# Kiro IDE only
controlzero kiro init --surface ide

# Both surfaces
controlzero kiro init --surface both

The installer writes a default policy to ~/.controlzero/policy.yaml (ALLOW ALL by default, so Kiro keeps working out of the box) and registers the hook. Add deny rules to start blocking.

How it works

Kiro has two surfaces, both wired by controlzero kiro init:

  • Kiro CLI passes the event JSON on stdin in snake_case, byte-compatible with what controlzero hook-check already consumes. The hook command is controlzero hook-check directly.
  • Kiro IDE delivers the payload via the USER_PROMPT environment variable. The cz-kiro-adapter shim (installed with the SDK) normalises it to stdin and tags the audit source as the IDE surface.

Every Kiro tool call is logged to ~/.controlzero/audit.log with agent="kiro" so the dashboard attributes the action to Kiro.

Policy

Policies live at ~/.controlzero/policy.yaml. Rules are evaluated top to bottom, first match wins. A per-project controlzero.yaml overrides the global file.

version: '1'

rules:
# Block destructive shell on the CLI surface
- id: deny-shell
deny: 'execute_bash'
reason: 'Kiro runs in read-only mode in this workspace'

# Block AWS mutations from the agent
- id: deny-aws-writes
deny: 'use_aws'
reason: 'AWS mutations go through CI, not the agent'

# Allow everything else (remove for deny-by-default)
- id: allow-everything-else
allow: '*'
reason: 'Default allow. Tighten by adding deny rules above this one.'

Common Kiro tool names

Tool (CLI aliases)What it does
fs_read / readFile read
fs_write / writeFile write (also fires the File Save hook)
execute_bash / shellShell execution
use_aws / awsAWS API call
@<server>/<tool>MCP tools, namespaced

Test a decision without running Kiro

echo '{"hook_event_name":"preToolUse","tool_name":"execute_bash","tool_input":{"command":"rm -rf /"}}' \
| controlzero hook-check

Kiro IDE limitation

On the Kiro IDE surface, the Pre Tool Use hook ships disabled. An upstream Kiro bug delivers an empty payload to IDE preToolUse hooks, so enabling the hook would fail closed and block every tool call. The Prompt Submit and File Save hooks carry data and are active, so you still get prompt-level governance and file-write auditing in the IDE.

The Kiro CLI surface (kiro-cli chat) has full pre-tool-use policy enforcement today. For argument-level policy in the IDE, use the Python SDK directly until the upstream issue is resolved.

Verify

# Confirm the CLI hook is wired AND blocks a synthetic deny (exit 0 = enforcing):
controlzero kiro verify

# CLI: reload your shell, then run kiro-cli chat -- every tool call shows
# "[Control Zero] Allowed: <tool>" or a branded deny reason.
kiro-cli chat

# IDE: reload the workspace so Kiro picks up .kiro/hooks/

# Tail the audit log
tail -f ~/.controlzero/audit.log

See also