
Kiro CLI Now Supports Claude Opus 4.8: Checking the Differences Between Opus Models
This page has been translated by machine translation. View original
Introduction
On May 29, 2026, Anthropic's latest model, Claude Opus 4.8, became available in Kiro CLI (Kiro CLI 2.5.0 or later, treated as an experimental preview).
Opus 4.8 became available on Amazon Bedrock and Claude Platform on AWS on May 28, 2026, and support in Kiro (IDE / CLI / Web) was announced the next day, May 29.
In this article, I confirmed that Opus 4.8 can actually be selected and run in Kiro CLI 2.5.0, and measured the differences when changing the model generation (4.8 / 4.7 / 4.6) and the effort level (low to max) on the same CloudFormation template analysis task.
Model list on Kiro and credit multipliers
This is an excerpt of the model list shown by the /model command. The credit multiplier for all Opus 4.x models is the same at 2.20x.
| Model | Credit multiplier | Notes |
|---|---|---|
| claude-opus-4.8 | 2.20x | Experimental preview / 1M context |
| claude-opus-4.7 | 2.20x | Experimental preview / 1M context |
| claude-opus-4.6 | 2.20x | Claude Opus 4.6 |
| claude-sonnet-4.6 | 1.30x | Latest Sonnet / 1M context |
According to the official Kiro blog, the supported plans are Kiro Pro / Pro+ / Power, the context is 1M tokens, and the maximum output is 128K tokens. The available regions are AWS US-East-1 (N. Virginia) and Europe (Frankfurt), with cross-region inference supported.
Verification details
Task and scoring method
I had Kiro CLI read a CloudFormation template (eval_template.yaml) with 10 intentionally planted problems, and asked it to point out the architecture overview and the security / best-practice issues.
eval_template.yaml (CFn template with planted issues)
AWSTemplateFormatVersion: '2010-09-09'
Description: Sample stack for analysis (intentionally contains ~10 planted issues)
Resources:
DataBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: my-app-data-bucket
AccessControl: PublicRead
AppSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: app sg
VpcId: vpc-0abc1234
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 3306
ToPort: 3306
CidrIp: 0.0.0.0/0
AppRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal: { Service: ec2.amazonaws.com }
Action: sts:AssumeRole
Policies:
- PolicyName: full-access
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action: '*'
Resource: '*'
AppInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Roles: [ !Ref AppRole ]
AppServer:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-0123456789abcdef0
InstanceType: t3.large
IamInstanceProfile: !Ref AppInstanceProfile
SecurityGroupIds: [ !Ref AppSecurityGroup ]
AppDatabase:
Type: AWS::RDS::DBInstance
Properties:
Engine: mysql
DBInstanceClass: db.t3.medium
AllocatedStorage: '20'
MasterUsername: admin
MasterUserPassword: Password123!
PubliclyAccessible: true
StorageEncrypted: false
VPCSecurityGroups: [ !Ref AppSecurityGroup ]
Outputs:
DBEndpoint:
Value: !GetAtt AppDatabase.Endpoint.Address
The 10 items that were scored are as follows.
- S3 public access (PublicRead)
- S3 without encryption
- S3 PublicAccessBlock not configured
- SSH (port 22) open to everyone
- DB port (3306) open to everyone
- IAM full permissions (Action / Resource =
*) - DB password hardcoded in plain text
- RDS PubliclyAccessible
- RDS storage without encryption
- Data protection (deletion protection / automated backups / snapshots, etc.) not configured
Scoring was based on keyword matching, but I corrected misjudgments caused by variations in wording by visually checking the body text. For item 10, it is an OR condition: it counts as detected if any of deletion protection, backups, snapshots, etc. is mentioned.
How it was run
Each condition was run in headless mode.
kiro-cli chat --no-interactive --trust-tools=read --model <model> "<prompt>"
Effort switching was configured as follows.
# 明示指定
kiro-cli settings chat.modelDefaults '{"claude-opus-4.8":{"output_config":{"effort":"high"}}}'
# デフォルトに戻す(設定削除)
kiro-cli settings --delete chat.modelDefaults
The times in the results tables are the Time shown by Kiro, and Credits are also the values displayed by Kiro as they are. Each condition was measured 5 times and the averages are shown.
bench.sh (repeated measurement script)
#!/usr/bin/env bash
# 同一プロンプトを条件ごとにREPS回くり返し実行し、生出力とインデックスを残す。
# 使い方: ./bench.sh [REPS] [MODE]
# REPS : 各条件のくり返し回数 (default 5)
# MODE : effort | models | both (default effort)
set -uo pipefail
DIR="$(cd "$(dirname "$0")" && pwd)"
REPS="${1:-5}"
MODE="${2:-effort}"
MODEL="claude-opus-4.8"
EFFORTS=(low medium high xhigh max default)
MODELS=(claude-opus-4.8 claude-opus-4.7 claude-opus-4.6)
OUT="$DIR/bench/out"; ERR="$DIR/bench/err"; IDX="$DIR/bench/runs.tsv"
mkdir -p "$OUT" "$ERR"
[ -f "$IDX" ] || printf "cond\trun\twall_sec\toutfile\terrfile\n" > "$IDX"
TPL=$(cat "$DIR/eval_template.yaml")
PROMPT="次のCloudFormationテンプレートを逆解析し、(1)アーキテクチャ概要 と (2)セキュリティ/ベストプラクティス上の問題点 を箇条書きで漏れなく指摘してください。
\`\`\`yaml
$TPL
\`\`\`"
set_effort() {
if [ "$1" = "default" ]; then kiro-cli settings --delete chat.modelDefaults >/dev/null 2>&1
else kiro-cli settings chat.modelDefaults "{\"$MODEL\":{\"output_config\":{\"effort\":\"$1\"}}}" >/dev/null; fi
}
one_run() {
local cond="$1" model="$2" r o e s en wall
for r in $(seq 1 "$REPS"); do
o="$OUT/${cond}_${r}.txt"; e="$ERR/${cond}_${r}.txt"
s=$(date +%s.%N)
timeout 600 kiro-cli chat --no-interactive --trust-tools=read --model "$model" "$PROMPT" > "$o" 2> "$e"
en=$(date +%s.%N); wall=$(echo "$en - $s" | bc)
printf "%s\t%s\t%s\t%s\t%s\n" "$cond" "$r" "$wall" "$o" "$e" >> "$IDX"
echo "[$(date +%T)] $cond run $r/$REPS wall=${wall}s"
done
}
if [ "$MODE" = "effort" ] || [ "$MODE" = "both" ]; then
for ef in "${EFFORTS[@]}"; do set_effort "$ef"; one_run "effort_${ef}" "$MODEL"; done
fi
if [ "$MODE" = "models" ] || [ "$MODE" = "both" ]; then
kiro-cli settings --delete chat.modelDefaults >/dev/null 2>&1
for m in "${MODELS[@]}"; do one_run "model_${m}" "$m"; done
fi
kiro-cli settings --delete chat.modelDefaults >/dev/null 2>&1
echo "[$(date +%T)] DONE. 解析: python3 analyze.py"
analyze.py (statistics aggregation script)
#!/usr/bin/env python3
"""bench.sh の出力を解析。条件ごとに平均・中央値・外れ値を出力。"""
import re, os, statistics as st
DIR = os.path.dirname(os.path.abspath(__file__))
IDX = os.path.join(DIR, "bench", "runs.tsv")
ANSI = re.compile(r'\x1b\[[0-9;?]*[a-zA-Z]')
CHECKS = {
"S3公開": ["publicread", "パブリック", "公開"],
"S3無暗号": ["bucketencryption", "暗号化されていない", "暗号化されない",
"暗号化未設定", "暗号化が未", "暗号化が無", "暗号化無",
"暗号化なし", "sse-", "暗号化を有効", "保存データが平文"],
"S3ブロック無": ["publicaccessblock", "パブリックアクセスブロック"],
"22全開放": ["22", "ssh"],
"3306全開放": ["3306"],
"IAM全権限": ["action: '*'", "ワイルドカード", "全権限", "'*'", "管理者", "フルアクセス"],
"DBパス平文": ["平文", "ハードコード", "password123", "secrets manager", "直書き"],
"RDS公開": ["publiclyaccessible", "インターネット", "公開され", "パブリックip"],
"RDS無暗号": ["storageencrypted", "保管時", "ストレージ暗号", "保存データが暗号化"],
"削除/バックアップ無": ["deletionpolicy", "削除保護", "スナップショット",
"バックアップ", "multiaz", "multi-az"],
}
def strip(p):
return ANSI.sub("", open(p, encoding="utf-8", errors="replace").read())
def parse_run(outf, errf):
body = strip(outf); lo = body.lower()
detect = sum(any(w in lo for w in ks) for ks in CHECKS.values())
chars = len(re.sub(r"\s", "", body))
err = strip(errf) if os.path.exists(errf) else ""
m = re.search(r'Credits:\s*([\d.]+).*?Time:\s*(\d+)\s*([hms])', err)
credits = float(m.group(1)) if m else None
app_t = None
if m:
v = int(m.group(2))
app_t = v*60 if m.group(3) == "m" else (v*3600 if m.group(3) == "h" else v)
return credits, app_t, detect, chars
def iqr_outliers(vals):
xs = sorted(v for v in vals if v is not None)
if len(xs) < 4:
return set()
q1 = st.quantiles(xs, n=4)[0]; q3 = st.quantiles(xs, n=4)[2]; iqr = q3 - q1
lo, hi = q1 - 1.5*iqr, q3 + 1.5*iqr
return {v for v in xs if v < lo or v > hi}
def stats(vals):
xs = [v for v in vals if v is not None]
if not xs:
return None
return dict(n=len(xs), mean=st.mean(xs), median=st.median(xs),
stdev=(st.pstdev(xs) if len(xs) > 1 else 0.0),
min=min(xs), max=max(xs))
runs = {}
if not os.path.exists(IDX):
raise SystemExit(f"not found: {IDX} (先に ./bench.sh を実行)")
for line in open(IDX):
if line.startswith("cond\t"):
continue
cond, r, wall, outf, errf = line.rstrip("\n").split("\t")
cr, at, det, ch = parse_run(outf, errf)
runs.setdefault(cond, []).append(
dict(run=int(r), wall=float(wall), credits=cr, app_t=at, detect=det, chars=ch))
metrics = [("credits", "cr"), ("app_t", "s"), ("wall", "s"), ("detect", "/10"), ("chars", "")]
for cond in sorted(runs):
rs = runs[cond]; n = len(rs)
print(f"\n===== {cond} (n={n}) =====")
print(f"{'metric':9}{'mean':>9}{'median':>9}{'stdev':>9}{'min':>8}{'max':>8}{' 外れ値(run#)'}")
for key, unit in metrics:
s = stats([x[key] for x in rs])
if not s:
print(f"{key:9}{'n/a':>9}"); continue
outs = iqr_outliers([x[key] for x in rs])
orun = [f"#{x['run']}({x[key]})" for x in rs
if x[key] in outs and x[key] is not None]
print(f"{key:9}{s['mean']:>9.2f}{s['median']:>9.2f}{s['stdev']:>9.2f}"
f"{s['min']:>8.2f}{s['max']:>8.2f} {', '.join(orun) if orun else '-'}")
Results
Comparison by model (no effort specified = each model's default, n=5 average)
| Model | Detection (avg.) | Credits (avg.) | Kiro-displayed Time (avg.) | Output characters (avg.) |
|---|---|---|---|---|
| claude-opus-4.8 | 10/10 | 0.65cr | 36.6s | approx. 1,940 |
| claude-opus-4.7 | 10/10 | 0.98cr | 50.0s | approx. 3,000 |
| claude-opus-4.6 | 9.2/10 | 0.32cr | 20.8s | approx. 1,260 |
The clearest difference was by model generation. 4.7 had the largest Credits and time, and its answers were also longer. In this 5-run average, 4.8 showed smaller Credits and time than 4.7 (0.65 vs 0.98cr, 36.6 vs 50.0s). Detection was 10/10 for both. 4.6 had the smallest Credits and time (0.32cr / 20.8s), with detection of 9.2/10.
The difference with 4.6 was mainly in mentioning "S3 PublicAccessBlock not configured". Since it is recommended to enable PublicAccessBlock for S3 and, even when public exposure is needed, to avoid direct exposure by using something like CloudFront OAC, I included it as a scoring item from a best-practice perspective this time. 4.7 / 4.8 pointed this out as well, whereas 4.6 mentioned this aspect less often.
On the other hand, 4.6 also detected critical risks such as SSH / DB ports open to everyone, IAM full permissions, plain-text DB password, public RDS, and RDS without encryption. It can be a sufficient choice for use cases where you want to keep things concise, fast, and low in Credits.
Comparison by effort (claude-opus-4.8, n=5 average)
| effort | Detection (avg.) | Credits (avg.) | Kiro-displayed Time (avg.) |
|---|---|---|---|
| low | 10/10 | 0.67cr | 35.4s |
| medium | 10/10 | 0.66cr | 35.6s |
| high | 10/10 | 0.67cr | 34.6s |
| xhigh | 9.6/10 | 0.61cr | 36.6s |
| max | 10/10 | 0.62cr | 33.6s |
| Not specified (default) | 10/10 | 0.64cr | 34.8s |
No clear trend was seen in detection, Credits, or time from low to max. At least for this CloudFormation analysis task, changing the effort did not make a large difference in the final output.
Summary
Claude Opus 4.8 can now be selected in Kiro CLI 2.5.0, although it is treated as a preview. In this task, 4.8 had detection ability equal to 4.7 while being smaller in both Credits and time, and in a comparison of default settings it appeared to be a strict upgrade. Meanwhile, 4.6 is concise, fast, and low in Credits, and it detected the critical risks, so it still looks like a strong option when prioritizing speed or Credits.
Reference links
