Answers.Body: <p>I like the table.</p>
  
  <p>It would be really cool if that information were available inline as part of the "API Explorer" -- eg when you inspect the <code>Activity.create</code> API, you'd be able to further review the required permissions.</p>
  
  <p>The permissions in the table you describe are generally <em>coarse-grained</em>, <em>entity-oriented</em> permissions. Quintessential examples are "edit all contacts" or "delete mailings". These depend only on the entity name and action name.</p>
  
  <p>The other items that you're asking about could be categorized as <em>fine-grained</em> authorizations. These depend on the specific data involved. However, they slice-and-dice differently (applying different rules to different data in different use-cases).</p>
  
  <ul>
  <li><code>DynamicFKAuthorization</code> is applied to <code>Attachment</code> API. Every attachment is subordinate to another record (like <code>Mailing #123</code> or <code>Contact #456</code> or <code>Activity #789</code>). Your permission to CRUD an <code>Attachment</code> depends on your permission to CRUD the targeted record. The basic idea is <em>delegation</em>. For example, the permissions for <code>Attachment.create(entity_type=mailing,entity_id=123)</code> are determined by delegating to the authorization logic of <code>Mailing.create(id=123)</code>.</li>
  <li><code>_civicrm_api3_check_edit_permissions()</code> is nominally applied to many API entities, but in reality only applies to <code>Phone</code>, <code>Email</code>, <code>Address</code>, <code>IM</code>, <code>OpenID</code>, and <code>Website</code> records. All of these are subordinate to <code>Contact</code>. Your permission to CRUD a <code>Phone</code> depends on your permission to CRUD the contact record.</li>
  <li><code>BAO::addSelectWhereClause</code> is nominally applied to most API entities. On its own, it doesn't do much, but it can be adapted via subclass or hook. It allows to limit visibility into entities based on their data. For example, a listener might define a rule that "the current user can only query activities of type <code>Meeting</code>".</li>
  </ul>
  
  <p>These three examples have some similarities (e.g. they're all <em>fine-grained</em>), and they have some arbitrary differences (e.g. procedural style vs OOP style), but they also address qualitatively different scenarios. I don't think their original authors intended/expected them to be compared in this way, so it wouldn't be accurate to describe them with an "over-arching strategic architecture". However, if someone finds an elegant way to make these more-similar, that would be great.</p>
  
  <p>(<strong>Edit</strong>) Returning to your original question -- "Why is the matrix sparse?" The matrix only addresses cases where we expect coarse-grained/entity-oriented access-control to serve the business-needs of typical organizations. In cases where we expect the business needs to be more fine-grained/data-oriented, you need to reference more nuanced logic.</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-03-24T04:30:24.243Z
Answers.LastActivityDate: 2017-03-24T04:38:43.170Z
Answers.LastEditDate: 2017-03-24T04:38:43.170Z
Answers.UserDisplayName: Tim Otten
Body: <p>I've recently been exploring the <code>$permissions</code> array that drives API actions and <a href="https://github.com/civicrm/civicrm-core/pull/10016/files" rel="nofollow noreferrer">extracted the metadata from the logic</a> to allow <a href="https://github.com/ErichBSchulz/api4/blob/c091dfaa37562e618ca3e3630840f548a2ccd695/autodocs/permissions.md" rel="nofollow noreferrer">displaying as a nice table</a>.</p>
  
  <p>The <code>CRM_Utils_Hook::alterAPIPermissions($entity, $action, $params, $permissions)</code> hook further modifies this permission matrix before it gets passed to <a href="https://github.com/civicrm/civicrm-core/blob/master/CRM/Core/Permission.php#L120" rel="nofollow noreferrer">function check($permissions)</a> </p>
  
  <p>The grid is sparse in some places and references:</p>
  
  <ul>
  <li><a href="https://github.com/civicrm/civicrm-core/blob/master/Civi/API/Subscriber/DynamicFKAuthorization.php#L48" rel="nofollow noreferrer">DynamicFKAuthorization</a></li>
  <li><a href="https://github.com/civicrm/civicrm-core/blob/master/api/v3/utils.php#L2473" rel="nofollow noreferrer">_civicrm_api3_check_edit_permissions($bao_name, $params)</a></li>
  <li><a href="https://github.com/civicrm/civicrm-core/blob/master/CRM/Core/DAO.php#L2442" rel="nofollow noreferrer">addSelectWhereClause()</a></li>
  <li>CRM_Case_BAO_Case::addSelectWhereClause</li>
  </ul>
  
  <p>What is the over-arching strategic architecture behind this? (to the extent that one exists at least)</p>
  
  <p>Or what should it be?</p>
  
Tags: <permissions><coding-standards>
Title: Why is the entity.action permission sparse?
ThreadText: # Why is the entity.action permission sparse?
  
  (Asked by: username_0 on 2017-03-24)
  
  I've recently been exploring the `$permissions` array that drives API actions and [extracted the metadata from the logic](https://github.com/civicrm/civicrm-core/pull/10016/files) to allow [displaying as a nice table](https://github.com/username_0/api4/blob/c091dfaa37562e618ca3e3630840f548a2ccd695/autodocs/permissions.md).
  
  The `CRM_Utils_Hook::alterAPIPermissions($entity, $action, $params, $permissions)` hook further modifies this permission matrix before it gets passed to [function check($permissions)](https://github.com/civicrm/civicrm-core/blob/master/CRM/Core/Permission.php#L120)
  
  The grid is sparse in some places and references:
  
  * [DynamicFKAuthorization](https://github.com/civicrm/civicrm-core/blob/master/Civi/API/Subscriber/DynamicFKAuthorization.php#L48)
  * [\_civicrm\_api3\_check\_edit\_permissions($bao\_name, $params)](https://github.com/civicrm/civicrm-core/blob/master/api/v3/utils.php#L2473)
  * [addSelectWhereClause()](https://github.com/civicrm/civicrm-core/blob/master/CRM/Core/DAO.php#L2442)
  * CRM\_Case\_BAO\_Case::addSelectWhereClause
  
  What is the over-arching strategic architecture behind this? (to the extent that one exists at least)
  
  Or what should it be?
  
  **Tags:** permissions, coding-standards
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2017-03-24. Score: 1 | Accepted answer
  
  I like the table.
  
  It would be really cool if that information were available inline as part of the "API Explorer" -- eg when you inspect the `Activity.create` API, you'd be able to further review the required permissions.
  
  The permissions in the table you describe are generally *coarse-grained*, *entity-oriented* permissions. Quintessential examples are "edit all contacts" or "delete mailings". These depend only on the entity name and action name.
  
  The other items that you're asking about could be categorized as *fine-grained* authorizations. These depend on the specific data involved. However, they slice-and-dice differently (applying different rules to different data in different use-cases).
  
  * `DynamicFKAuthorization` is applied to `Attachment` API. Every attachment is subordinate to another record (like `Mailing #123` or `Contact #456` or `Activity #789`). Your permission to CRUD an `Attachment` depends on your permission to CRUD the targeted record. The basic idea is *delegation*. For example, the permissions for `Attachment.create(entity_type=mailing,entity_id=123)` are determined by delegating to the authorization logic of `Mailing.create(id=123)`.
  * `_civicrm_api3_check_edit_permissions()` is nominally applied to many API entities, but in reality only applies to `Phone`, `Email`, `Address`, `IM`, `OpenID`, and `Website` records. All of these are subordinate to `Contact`. Your permission to CRUD a `Phone` depends on your permission to CRUD the contact record.
  * `BAO::addSelectWhereClause` is nominally applied to most API entities. On its own, it doesn't do much, but it can be adapted via subclass or hook. It allows to limit visibility into entities based on their data. For example, a listener might define a rule that "the current user can only query activities of type `Meeting`".
  
  These three examples have some similarities (e.g. they're all *fine-grained*), and they have some arbitrary differences (e.g. procedural style vs OOP style), but they also address qualitatively different scenarios. I don't think their original authors intended/expected them to be compared in this way, so it wouldn't be accurate to describe them with an "over-arching strategic architecture". However, if someone finds an elegant way to make these more-similar, that would be great.
  
  (**Edit**) Returning to your original question -- "Why is the matrix sparse?" The matrix only addresses cases where we expect coarse-grained/entity-oriented access-control to serve the business-needs of typical organizations. In cases where we expect the business needs to be more fine-grained/data-oriented, you need to reference more nuanced logic.
  
  
  ---
  
  