Skip to content

Least privilege, measured not guessed

Know who breaks before you trim the role.

Nobody trims a role they cannot prove is safe, so nothing gets trimmed. Kyro measures what each identity actually uses, so you cut it knowing exactly what depends on it.

kyro-bot wants to merge 1 commit into main

right-size payments-copilot-irsa

iam/payments.tf
9 actions = [
10 "s3:GetObject",
11 "s3:ListBucket",
12 "s3:DeleteObject", not observed · 90d
13 "dynamodb:*", not observed · 90d
14 "ec2:TerminateInstances", not observed · 90d
15 ]

s3:ListBucket kept: reconciler-job shares this role and calls it nightly

Self-hosted and managed agents, on the stack you already run.

Azure soon Vertex soon LiteLLM soon

A role lists what was granted, never what was used.

Every agent needs credentials, and nobody writes a fresh permission model for each one. Agents inherit whatever already exists, and nobody goes back to check what actually got used.

150,000

"by 2028, an average global Fortune 500 enterprise will have over 150,000 agents in use, up from less than 15 in 2025"

Gartner® Press Release, "Gartner Identifies Six Steps to Manage AI Agent Sprawl," 28 April 2026.

"Manage the agent identity, permission model and access controls, review, and retire redundant agents to prevent uncontrolled sprawl."

Gartner Press Release, "Gartner Identifies Six Steps to Manage AI Agent Sprawl," 28 April 2026.

One agent identity, and everywhere it went last night.

One night of traffic for a single payments copilot: 41 permissions granted, 6 exercised, and 9,295 connections to destinations no cloud audit log recorded.

Nothing merges without you.

prod-payments / sa-payments-copilot
IRSA 90d window

granted

41

used in window

6

unused 90+ days

35

Destinations reached in the last 24 hours, with CloudTrail visibility
visibility destination connections
visible s3://prod-ledger-exports AWS S3 1,204
visible sqs prod-payment-events AWS SQS 318
visible bedrock-runtime.us-east-1 AWS Bedrock 892
blind mongo.prod.svc.cluster.local:27017 MongoDB 6,441
blind ledger-api.prod.svc.cluster.local unmapped 2,110
blind mcp-gateway.internal:8931 unmapped 744

who depends on this role

  • sa-payments-copilot (prod-payments) → 4 pods
  • reconciler-job (prod-payments) → shares this role → would lose s3:ListBucket would break
  • gcp:ledger-sync → via Workload Identity Federation

proposal

  • removed 3 unused services entirely
  • collapsed s3:* to 4 observed actions
  • KEEP s3:GetObject, dynamodb:GetItem
  • KEEP iam:*, sts:*, kms:*

The chain runs both ways.

Forward, it shows what an identity can reach; backward, it shows who breaks when you take something away.

Diagram: Kyro observes what each identity reaches, compares granted permissions against used ones, and traces which workloads depend on a permission before proposing its removal. A second workload then appears sharing one of those identities.

A call to your own database leaves no cloud audit record.

Cloud audit logs cover the calls that go to cloud APIs. The Kyro sensor adds the rest of the wire. One bar holds everything one identity touched, and every permission is judged on all of it.

In cloud audit logs

Seen on the wire

See which permissions you can cut.

One cluster is enough to start. Tell us where your workload identities run, and the next thing you see is what the first pull request would say.