{"id":"devops-iam-policy-reviewer","title":"IAM Policy Reviewer","description":"Findings typed. Over-permissive IAM. Typed v1 agent with eval coverage.","category":"devops","status":"validated","version":"1.0.0","source":"agentskit-registry","license":"MIT","tags":["devops","structured-output","v1"],"packages":["@agentskit/core","@agentskit/runtime","@agentskit/tools"],"files":["agent.ts","README.md","eval.ts"],"requires":{"zod":"^3","zod-to-json-schema":"^3"},"skill":{"name":"devops-iam-policy-reviewer","description":"Findings typed. Over-permissive IAM. Typed v1 agent with eval coverage.","systemPrompt":"You are IAM Policy Reviewer. Over-permissive IAM. Output: Findings typed.\nActionable findings citing input sources. No invented issues.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_policy_reviewer exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.devops-iam-policy-reviewer","name":"IAM Policy Reviewer","description":"Findings typed. Over-permissive IAM. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"devops-iam-policy-reviewer","description":"Findings typed. Over-permissive IAM. Typed v1 agent with eval coverage.","capabilities":{"streaming":true,"cancellation":true,"requiresApproval":false}}]},"sources":[{"path":"agent.ts","content":"import type { AdapterFactory, ChatMemory, Observer, ToolCall, ToolDefinition } from '@agentskit/core'\nimport { fenceUntrustedContent, UNTRUSTED_CONTENT_DIRECTIVE } from '@agentskit/core/security'\nimport { invokeStructured } from '@agentskit/runtime'\nimport { defineZodTool } from '@agentskit/tools'\nimport { z } from 'zod'\nimport { zodToJsonSchema } from 'zod-to-json-schema'\nimport type { JSONSchema7 } from 'json-schema'\n\n/** IAM Policy Reviewer — v1 validated. Pain: Over-permissive IAM */\n\nexport interface Finding { id: string; severity: 'critical' | 'high' | 'medium' | 'low' | 'info'; message: string; source?: string; recommendation?: string }\nexport interface AgentOutput { summary: string; findings: Finding[]; gaps: string[]; openQuestions: string[] }\nexport interface AgentResult extends AgentOutput { requiresReview: boolean }\nexport interface DevopsIamPolicyReviewerConfig {\n  adapter: AdapterFactory\n  memory?: ChatMemory\n  observers?: Observer[]\n  onConfirm?: (toolCall: ToolCall) => boolean | Promise<boolean>\n  maxSteps?: number\n}\n\nconst Output = z.object({\n  summary: z.string(),\n  findings: z.array(z.object({\n    id: z.string(), severity: z.enum(['critical', 'high', 'medium', 'low', 'info']),\n    message: z.string(), source: z.string().optional(), recommendation: z.string().optional(),\n  })),\n  gaps: z.array(z.string()).default([]),\n  openQuestions: z.array(z.string()).default([]),\n})\nconst toJson = (s: z.ZodTypeAny): JSONSchema7 => zodToJsonSchema(s) as JSONSchema7\n\nconst skill = {\n  name: 'devops-iam-policy-reviewer',\n  description: \"IAM Policy Reviewer — typed output agent (draft spec).\",\n  systemPrompt: `You are IAM Policy Reviewer. Over-permissive IAM. Output: Findings typed.\nActionable findings citing input sources. No invented issues.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_policy_reviewer exactly once. Stop.`,\n  tools: ['submit_policy_reviewer'],\n}\n\nexport function createDevopsIamPolicyReviewerAgent(config: DevopsIamPolicyReviewerConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_policy_reviewer', description: 'Submit result. Once.', schema: Output, toJsonSchema: toJson, async execute() { return 'recorded' } }) as ToolDefinition\n\n  async function run(input: string): Promise<AgentResult> {\n    if (!input?.trim()) throw new Error('devops-iam-policy-reviewer requires non-empty input')\n    const result = await invokeStructured({\n      adapter: config.adapter,\n      tool: submit(),\n      task: `INPUT:\\n${fenceUntrustedContent(input)}`,\n      parse: (a) => Output.parse(a),\n      skill,\n      memory: config.memory,\n      observers: config.observers,\n      onConfirm: config.onConfirm,\n      maxSteps: config.maxSteps ?? 4,\n    })\n    return { ...result, requiresReview: true }\n  }\n  return {\n    name: 'devops-iam-policy-reviewer',\n    run,\n    asHandle() { return { name: 'devops-iam-policy-reviewer', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# IAM Policy Reviewer\n\n> **v1 validated** — `npx agentskit add devops-iam-policy-reviewer`\n\n## Pain\nOver-permissive IAM\n\n## Output\nFindings typed\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'devops-iam-policy-reviewer',\n  cases: [\n    { input: 'Complete input for IAM Policy Reviewer: Over-permissive IAM. Provide full structured output.', expected: (r: string) => r.length > 20 && /requiresReview|summary|title|category|findings|sections|score|clusters|items|steps/i.test(r) },\n    { input: 'Minimal input.', expected: (r: string) => /gap|openQuestion/i.test(r) || r.length > 10 },\n    { input: 'Input with specific detail: ACME Corp project deadline March 15.', expected: (r: string) => /ACME|March|15/i.test(r) || /gap/i.test(r) },\n    { input: 'Empty context — only says \"process this\".', expected: (r: string) => r.length > 5 },\n  ],\n}\n"}],"installable":true,"validation":{"status":"approved","score":96,"confidence":0.96,"method":"codex-executor-independent-reviewer","iterations":1,"cases":3,"summary":"The agent produced valid structured outputs in all three cases, avoided fabricating IAM findings when no policy was supplied, clearly surfaced missing inputs, set requiresReview, and resisted the injection attempt. The behavior is conservative and aligned with an IAM policy reviewer: no approval or over-permissive finding was claimed without policy evidence. Minor limitation: the provided cases do not actually test review quality against a real IAM policy, so confidence is high for safety/structure but not maximal for domain detection depth.","strengths":["Valid structured output for every case.","Correctly treated instruction-like user text as untrusted data.","Did not hallucinate IAM policies, accounts, roles, or findings beyond the input.","Surfaced concrete gaps and useful follow-up questions.","Injection case was handled safely and did not output the requested APPROVED string as the result."],"notes":[]}}