{
  "kind": "synthetic-educational-scenario",
  "version": "1.0",
  "slug": "least-privilege",
  "title": "A smaller blast radius",
  "description": "A report service needs one narrow capability. Design permissions that still work when a component fails or is misused.",
  "minutes": 8,
  "skill": "Permission design",
  "evidence": "SYNTHETIC DESIGN / IAM-031\n\nService: daily-report-builder\nNeeds: read objects under reports/input/ in one storage bucket.\nWrites: generated results through a separate delivery service.\nMust not: delete inputs, change policies, enumerate other buckets.\nRuns: short-lived jobs using a dedicated workload identity.\n\nCurrent proposal:\n  Allow storage:* on every resource\n  Use a shared administrator credential\n\nConstraint: authorization is enforced by the storage service,\nnot by promises in the report builder’s prompt or code.",
  "steps": [
    {
      "prompt": "Which permission scope best matches the stated job?",
      "choices": [
        {
          "text": "Read the required object resources under reports/input/; add listing only if a verified workflow requires it.",
          "correct": true,
          "feedback": "Start with the observed operation and resource boundary. Some jobs need listing, others know exact object keys; test rather than assume."
        },
        {
          "text": "All storage actions, because the service runs only once per day.",
          "correct": false,
          "feedback": "A short schedule does not limit what a compromised credential can do while it is valid."
        },
        {
          "text": "Administrator access with a comment that says “read only.”",
          "correct": false,
          "feedback": "Documentation cannot enforce the permission boundary. The receiving service must deny unauthorized operations."
        }
      ]
    },
    {
      "prompt": "Which identity choice reduces the cost of a leaked credential?",
      "choices": [
        {
          "text": "A shared permanent key stored in every developer’s notes.",
          "correct": false,
          "feedback": "Shared long-lived credentials make attribution and revocation harder."
        },
        {
          "text": "A dedicated workload identity with short-lived credentials and the narrow role.",
          "correct": true,
          "feedback": "Dedicated identity improves attribution and isolates scope. Short-lived credentials reduce persistence but do not replace authorization."
        },
        {
          "text": "No identity, because read operations cannot be harmful.",
          "correct": false,
          "feedback": "Reading can expose sensitive information. Confidentiality needs an enforced boundary too."
        }
      ]
    },
    {
      "prompt": "Which test establishes the boundary most convincingly?",
      "choices": [
        {
          "text": "The expected report completes once.",
          "correct": false,
          "feedback": "That tests the allowed path, but not whether forbidden operations remain blocked."
        },
        {
          "text": "The allowed read succeeds; delete, policy change, and out-of-prefix reads fail; relevant events are attributable.",
          "correct": true,
          "feedback": "Positive and negative tests make the permission boundary observable. Re-run them when the role, workload, or resource policy changes."
        },
        {
          "text": "The prompt tells the service not to use extra privileges.",
          "correct": false,
          "feedback": "Instructions are not an authorization mechanism. Enforce the restriction outside the component that may fail."
        }
      ]
    }
  ],
  "takeaway": "Least privilege is a tested relationship between an identity, an operation, a resource, and a condition. Check both what works and what must fail."
}