{
  "synthetic": true,
  "execution": "Teaching record only; no live integration tested",
  "slug": "customer-portal-object-access",
  "group": "portal",
  "title": [
    "Approve a document access matrix before a customer portal",
    "客户资料门户，先验收对象权限矩阵"
  ],
  "intro": [
    "A property services business commissioning a records portal needs more than working logins. Decide which person can perform which action on which organisation’s document. Hiding a download button is not evidence that another tenant’s document is protected.",
    "物业服务企业委托制作资料门户，不能只验收登录成功；要确定谁能对哪家机构的哪份资料做什么。隐藏下载按钮，不证明另一组织的资料受到保护。"
  ],
  "facts": [
    [
      "OWASP recommends denying by default and checking authorisation on every request, including the specific object or function. Authentication alone is insufficient.",
      "OWASP建议默认拒绝，并在每个请求中核对具体对象或功能的授权；身份验证本身不够。",
      "https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html#validate-the-permissions-on-every-request"
    ]
  ],
  "columns": [
    [
      "Synthetic actor and object",
      "Requested action",
      "Expected policy result"
    ],
    [
      "合成操作者及对象",
      "请求动作",
      "预期策略结果"
    ]
  ],
  "example": [
    [
      [
        "Committee viewer / OC-A / documentA7",
        "Read approvedA7",
        "Allow only approved read"
      ],
      [
        "委员会只读成员／OC-A／A7",
        "读取已批准A7",
        "只允许已批准读取"
      ]
    ],
    [
      [
        "Same viewer / documentA7",
        "Delete",
        "Deny: viewer has no delete grant"
      ],
      [
        "同一只读成员／A7",
        "删除",
        "拒绝：没有删除授权"
      ]
    ],
    [
      [
        "Same viewer / OC-B documentB2",
        "Read by changing URL ID",
        "Deny: organisation mismatch"
      ],
      [
        "同一成员／OC-B的B2",
        "改网址ID后读取",
        "拒绝：组织不匹配"
      ]
    ],
    [
      [
        "Former member / OC-A / A7",
        "Read with old browser session",
        "Deny after membership revocation"
      ],
      [
        "已退出成员／OC-A／A7",
        "旧浏览器会话读取",
        "撤销成员资格后拒绝"
      ]
    ]
  ],
  "steps": [
    [
      "Agree actor, organisation membership, document classification and permitted actions with the data owner. Treat legal entitlement as an input requiring separate review, not a rule invented by the developer.",
      "与资料负责人确认角色、组织成员关系、资料分类及动作；法律查阅权应另行确认，不能由开发者编造。"
    ],
    [
      "Use synthetic tenants and records to exercise read, update, delete and export paths directly in an authorised test environment. Include background jobs and resource download endpoints.",
      "在获准测试环境用合成组织和资料直接演练读取、修改、删除及导出，包括后台任务及资源下载接口。"
    ],
    [
      "Revoke membership during the exercise and verify current policy is enforced. Keep a redacted decision log with actor role, object organisation, action and policy result.",
      "演练中撤销成员关系，核对当前策略是否生效；日志只保留脱敏角色、对象组织、动作及结果。"
    ]
  ],
  "result": [
    "The same person is allowed one read and denied three other requests. A single “logged in” test would miss the differences. The matrix becomes a supplier acceptance contract, while actual permissions must be implemented server-side and reviewed by the responsible security team.",
    "同一个人一次读取被允许，其余三种请求被拒绝；只测“已登录”会漏掉这些差异。矩阵可作为供应商验收合同，真实权限仍须在服务端实施并由安全负责人复核。"
  ],
  "accept": [
    "Require evidence that denied requests return no protected content, including exports and cached responses. A hidden control or an unguessable document ID cannot pass this gate.",
    "拒绝请求必须不返回受保护内容，导出及缓存响应也要核对；隐藏控件或难猜ID不能通过。"
  ],
  "limit": [
    "Synthetic defensive test plan only, not a penetration test or legal records-access decision. No real tenant record was accessed and no permissions were changed.",
    "仅为合成防御验收计划，不是渗透测试或法律查阅权判断；没有访问真实租户资料或修改权限。"
  ],
  "oldLinks": [
    {
      "language": "zh",
      "target": "/zh/scenarios/owners-corporation-handover/",
      "anchor": "物业资料交接还要确定记录与负责人",
      "reason": "Portal authorisation requires the handover record owner and document scope."
    }
  ]
}
