{
 "product": "APPROVAL",
 "slug": "approval",
 "base": "https://cainstudio.online",
 "page": "https://cainstudio.online/top25-approval.html",
 "claims": [
  {
   "id": "C01",
   "kind": "control",
   "claim": "Two different approvers say yes -> Quorum reached: the request becomes one single-use credential.",
   "requests": [
    {
     "method": "POST",
     "url": "/approval-keystone/request",
     "body": {
      "scenario_id": "delete-invoice"
     }
    },
    {
     "method": "POST",
     "url": "/approval-keystone/vote",
     "body": {
      "ballot": "${0.ballots.cfo}",
      "vote": "APPROVE"
     }
    },
    {
     "method": "POST",
     "url": "/approval-keystone/vote",
     "body": {
      "ballot": "${0.ballots.controller}",
      "vote": "APPROVE"
     }
    }
   ],
   "path": "status",
   "expect": [
    "APPROVED"
   ]
  },
  {
   "id": "C02",
   "kind": "attack",
   "claim": "One approver votes twice -> A ballot counts once.",
   "requests": [
    {
     "method": "POST",
     "url": "/approval-keystone/request",
     "body": {
      "scenario_id": "delete-invoice"
     }
    },
    {
     "method": "POST",
     "url": "/approval-keystone/vote",
     "body": {
      "ballot": "${0.ballots.cfo}",
      "vote": "APPROVE"
     }
    },
    {
     "method": "POST",
     "url": "/approval-keystone/vote",
     "body": {
      "ballot": "${0.ballots.cfo}",
      "vote": "APPROVE"
     }
    }
   ],
   "path": "",
   "expect": [],
   "expect_status": [
    400,
    409
   ]
  },
  {
   "id": "C03",
   "kind": "attack",
   "claim": "One yes is not enough -> 2 of 3 means 2.",
   "requests": [
    {
     "method": "POST",
     "url": "/approval-keystone/request",
     "body": {
      "scenario_id": "delete-invoice"
     }
    },
    {
     "method": "POST",
     "url": "/approval-keystone/vote",
     "body": {
      "ballot": "${0.ballots.cfo}",
      "vote": "APPROVE"
     }
    }
   ],
   "path": "status",
   "expect": [
    "PENDING",
    "OPEN"
   ]
  },
  {
   "id": "C04",
   "kind": "attack",
   "claim": "A no from anyone after one yes -> A denial is recorded and never counts toward approval.",
   "requests": [
    {
     "method": "POST",
     "url": "/approval-keystone/request",
     "body": {
      "scenario_id": "delete-invoice"
     }
    },
    {
     "method": "POST",
     "url": "/approval-keystone/vote",
     "body": {
      "ballot": "${0.ballots.cfo}",
      "vote": "APPROVE"
     }
    },
    {
     "method": "POST",
     "url": "/approval-keystone/vote",
     "body": {
      "ballot": "${0.ballots.security-lead}",
      "vote": "DENY"
     }
    }
   ],
   "path": "status",
   "expect": [
    "DENIED",
    "REJECTED",
    "PENDING",
    "OPEN"
   ]
  },
  {
   "id": "C05",
   "kind": "attack",
   "claim": "Forged ballot -> Ballots are signed; a made-up one is refused.",
   "requests": [
    {
     "method": "POST",
     "url": "/approval-keystone/vote",
     "body": {
      "ballot": "forged.ballot.value",
      "vote": "APPROVE"
     }
    }
   ],
   "path": "",
   "expect": [],
   "expect_status": [
    400,
    401,
    403,
    404
   ]
  },
  {
   "id": "C06",
   "kind": "attack",
   "claim": "Vote 'maybe' -> Only APPROVE or DENY.",
   "requests": [
    {
     "method": "POST",
     "url": "/approval-keystone/request",
     "body": {
      "scenario_id": "delete-invoice"
     }
    },
    {
     "method": "POST",
     "url": "/approval-keystone/vote",
     "body": {
      "ballot": "${0.ballots.cfo}",
      "vote": "MAYBE"
     }
    }
   ],
   "path": "",
   "expect": [],
   "expect_status": [
    400,
    422
   ]
  }
 ]
}