Списки управления доступом (ACL)

Hotbox предоставляет возможность управлять доступом к контейнерам и объектам с помощью списка управления доступа - ACL. У каждого контейнера и объекта есть свой список доступа. Этот список определяет каким проектам или глобальным группам предоставляются права доступа и соответствующие права доступа.При получении запроса на ресурс сервис проверяет соответствующий ACL на наличие прав доступа у запрашивающего.

При создании контейнера или объекта сервис создает стандартный ACL, который предоставляет владельцу ресурса право полного контроля над этим ресурсом, и запрещает доступ остальным проектам и глобальным группам. Это показано в следующем примере ACL бакета (стандартный ACL объекта имеет ту же структуру).


<?xml version="1.0" encoding="UTF-8"?>
<AccessControlPolicy xmlns="http://BucketName.hb.bizmrg.com/doc/2006-03-01/">
  <Owner>
    <ID>*** Owner-Canonical-User-ID ***</ID>
    <DisplayName>owner-display-name</DisplayName>
  </Owner>
  <AccessControlList>
    <Grant>
      <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="Canonical User">
        <ID>*** Owner-Canonical-User-ID ***</ID>
        <DisplayName>owner-display-name</DisplayName>
      </Grantee>
      <Permission>FULL_CONTROL</Permission>
    </Grant>
  </AccessControlList>
</AccessControlPolicy>
  • Блок Owner определяет владельца по каноническому идентификатору пользователя проекта и по домену.
  • Блок Grant определяет получателя прав (проект сервиса или глобальную группу) и предоставляемое право доступа.

Базовый ACL содержит один элемент Grant для владельца. Вы можете предоставлять права с помощью добавления элементов Grant, где каждый из них определяет получателя прав и соответствующее право доступа.

Получатель прав

Получателем прав может являться проект сервиса или одна из глобальных групп сервиса. Вы можете предоставлять права проекту сервиса при помощи адреса электронной почты (домена) или канонического идентификатора проекта. При этом если вы указываете адрес электронной почты (домен) в вашем запросе на права доступа, то сервис определяет канонический идентификатор пользователя для соответствующего проекта и добавляет его в ACL. В результате ACL всегда будут содержать канонический идентификатор пользователя для проекта сервиса, а не адрес электронной почты проекта (домен).

Глобальные группы сервиса

У сервиса существует набор предопределенных групп. При предоставлении группе прав доступа к проекту вы указываете один из наших URI вместо канонического идентификатора пользователя. Сервисом предоставляются нижеуказанные глобальные группы.


  • Группа Authenticated Users — группа авторизованных пользователей.

Данная группа представляет собой все проекты сервиса. Наличие права доступа к этой группе позволяет любому проекту сервиса получать доступ к ресурсу. Но в то же время все запросы должны быть подписаны (авторизованы).

  • Группа All Users — группа всех пользователей. 

Наличие права доступа к этой группе позволяет всем получать доступ к ресурсу. Запросы могут быть подписанными (авторизованными) или неподписанными (анонимными). В неподписанных запросах отсутствует заголовок аутентификации Authentication в запросе.

При использовании ACL, получателем прав может являться проект сервиса или одна из предопределенных групп сервиса.

Предоставляемые разрешения

Следующая таблица содержит набор разрешений, поддерживаемых сервисом в ACL. Необходимо отметить, что набор разрешений ACL один и тот же для объекта и контейнера (за исключением запрета права WRITE на объекте).Нижеследующие таблицы содержат разрешения и описывают их в контексте разрешений объекта и контейнера.


Разрешение
При предоставлении на контейнере
При предоставлении на объекте
READ
Позволяет получателю прав получить список объектов в контейнере.
Позволяет получателю прав прочитать данные объекта и его метаданные.
WRITE
Позволяет получателю прав создавать, переписывать и удалять любой объект в контейнере.
Неприменимо.
READ_ACP
Позволяет получателю прав прочитать ACL контейнера.
Позволяет получателю прав прочитать ACL объекта.
WRITE_ACP
Позволяет получателю прав записывать ACL для соответствующего контейнера.
Позволяет получателю прав записывать ACL для соответствующего объекта.
FULL_CONTROL
Дает получателю прав следующие разрешения на контейнер: READ, WRITE, READ_ACP и WRITE_ACP.
Дает получателю прав следующие разрешения на объект: READ, READ_ACP и WRITE_ACP.

Соответствие разрешений ACL и разрешений политики доступа

Каждое из прав доступа позволяет провести в сервисе одну или несколько операций. Следующая таблица показывает соответствие прав доступа и операций.


Разрешение ACL
Соответствующее разрешение политики доступа при предоставлении разрешения ACL на бакете
Соответствующее разрешение политики доступа при предоставлении разрешения ACL на объекте
READ
  • HeadBucket
  • ListMultiparts
  • ListObjects
  • ListParts
  • GetObject
  • HeadObject

WRITE

  • AbortMultipartUpload
  • CompliteMultipartUpload
  • InitiateMultipartUpload
  • UploadPart
  • PutObject
  • DeleteObject
Неприменимо
READ_ACP
  • GetBucketAcl
  • GetObjectAcl
WRITE_ACP
  • PutBucketAcl
  • PutObjectAcl
FULL_CONTROL
Эквивалентно предоставлению следующих разрешений ACL: READ, WRITE, READ_ACP и WRITE_ACP.
Эквивалентно предоставлению следующих разрешений ACL: READ, READ_ACP и WRITE_ACP.



Связанный ACL

Сервис поддерживает набор предопределенных предоставлений разрешений — так называемых «готовых ACL». Каждый готовый ACL содержит предопределенный набор получателей прав и разрешений. Следующая таблица содержит набор готовых ACL и связанных с ними предопределенных предоставлений разрешений.


Связанный ACL
Область применения
Добавленные в ACL разрешения
private
Контейнер и объект
Владелец получает полные права (FULL_CONTROL). Остальные пользователи не получают прав доступа (по умолчанию).
public-read
Контейнер и объект
Владелец получает полные права (FULL_CONTROL). Группа всех пользователей Allusers получает право доступа на чтение (READ).
public-read-write
Контейнер и объект
Владелец получает полные права (FULL_CONTROL). Группа всех пользователей AllUsers получает права доступа на чтение (READ) и запись (WRITE). Как правило, не рекомендуется предоставлять данные разрешений на контейнер.
authenticated-read
Контейнер и объект
Владелец получает полные права (FULL_CONTROL). Группа авторизованных пользователей (AuthenticatedUsers) получает права доступа на чтение (READ).
bucket-owner-read
Объект
Владелец объекта получает полные права (FULL_CONTROL). Владелец бакета получает права на чтение (READ).
bucket-owner-full-control
Объект
Владелец объекта и владелец бакета получают полные права (FULL_CONTROL) на объект.

Можно указывать только один из этих связанных ACL в своем запросе  — только при установлении ACL через заголовки

Установка ACL

API-сервис позволяет вам установить ACL при создании бакета или объекта. Сервис также предоставляет API для возможности установки ACL на существующем бакете или объекте. Эти API дают возможность устанавливать ACL с помощью нижеуказанных способов.

  • Установка ACL с помощью заголовков запроса — при отправке запроса по созданию ресурса (бакета или объекта) вы устанавливаете ACL при помощи заголовков запроса. Данные заголовки позволяют вам указать или готовый ACL, или установить предоставления разрешений явным образом (однозначно определить получателя прав и разрешения).
  • Установка ACL с помощью тела запроса — при отправке запроса по установке ACL на существующем ресурсе вы можете установить ACL или в заголовке запроса, или в теле.

Обзор особых случаев при установке ACL

Будьте внимательны когда устанавливаете новое право доступа. Политика назначения прав  доступа такова, что установлении прав доступа в некоторых случаях может видоизменяться ваш  ACL.  Например при установлении прав любой глобальной группе будут потеряны все права доступа для отдельных проектов. Чтобы этого не происходило вам нужно устанавливать все права доступа одновременно - только в этом случае утери прав доступа отдельными проектами не происходит

Рассмотрим пример. Вы завели проект client@bizmrg.ru и создали контейнер bucketname. Изначально контейнер частный — только вы имеете к нему доступ.


<?xml version="1.0" encoding="UTF-8"?>
<AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Owner>
<ID>client_canonical_id</ID>
<DisplayName>client@bizmrg.ru</DisplayName>
</Owner>
<AccessControlList>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="Canonical User">
<ID>client_canonical_id</ID>
<DisplayName>client@bizmrg.ru</DisplayName>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
</AccessControlList>
</AccessControlPolicy>

Допустим, вы захотели дать доступ на запись, удаление или перезапись объектов для вашего контейнера bucketname другому проекту friend_project@bizmrg.ru.


<?xml version="1.0" encoding="UTF-8"?>
<AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Owner>
<ID>*** Owner-Canonical-User-ID ***</ID>
<DisplayName>owner-display-name</DisplayName>
</Owner>
<AccessControlList>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="Canonical User">
<ID>friend_project_canonical_id</ID>
<DisplayName>friend_project@bizmrg.ru</DisplayName>
</Grantee>
<Permission>WRITE</Permission>
</Grant>
</AccessControlList>
</AccessControlPolicy>

Как вы видите, блок, содержащий ваши данные и предоставляемое право FULL_CONTROL (AccessControlPolicy.AccessControlList.Grant.Grantee, пропал. Однако это не значит что вы как владелец больше не обладаете правом FULL_CONTROL. Вы всегда владеете  этим правом и вас невозможно его лишить.

Данное поведение объясняется лишь синтаксисом ответа ACL, который требует наличие секций (AccessControlPolicy.AccessControlList.Grant.Grantee). Как вы можете заметить, при частном доступе на объекте никаким проектам или глобальным группам права не предоставляются.

 Теперь, допустим, вы захотели сделать ваш контейнер публичным для чтения. Для этого есть два пути:

1. Добавить public ACL через заголовки x-amz-acl или x-amz-grant-read или через тело запроса:

 PUT /?acl HTTP/1.1
 Authorization: authorization string
 Connection: close
 Date: Wed, 02 Aug 2017 09:53:13 GMT
 Host: bucketname.hb.bizmrg.com
 X-amz-content-sha256: UNSIGNED-PAYLOAD
 X-amz-acl: public-read


 HTTP/1.1 200 OK
 Server: nginx/1.12.1
 Date: Wed, 02 Aug 2017 09:53:14 GMT
 Content-Type: text/html; charset=utf-8
 Content-Length: 0
 Connection: close
 X-req-id: iySm3Cph

И тогда запросив ACL на вашем контейнере снова вы увидите:


<?xml version="1.0" encoding="utf-8"?>
<AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <Owner>
        <ID>client_canonical_id</ID>
        <DisplayName>client@bizmrg.ru</DisplayName>
    </Owner>
    <AccessControlList>
        <Grant>
            <Permission>FULL_CONTROL</Permission>
            <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
                <ID>client_canonical_id</ID>
                <DisplayName>client@bizmrg.ru</DisplayName>
            </Grantee>
        </Grant>
        <Grant>
            <Permission>READ</Permission>
            <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
                <URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
            </Grantee>
        </Grant>
    </AccessControlList>
</AccessControlPolicy>

Право WRITE для проекта friend_project@bizmrg.ru исчезло и теперь данный проект не может записывать, удалять, перезаписывать объекты в вашем контейнере. В блоках AccessControlPolicy.AccessControlList.Grant вы увидите информацию о пользователя который установил публичный ACL и сам публичный ACL.

 2. Для сохранения прав доступа у проекта friend_project@bizmrg.ru  вам необходимо за один запрос установить права доступа и глобальной группе и вашему пользователю:

 PUT /?acl HTTP/1.1
 Authorization: authorization string
 Connection: close
 Content-Length: 417
 Date: Wed, 02 Aug 2017 09:53:13 GMT
 Host: bucketname.hb.bizmrg.com
 X-amz-content-sha256: UNSIGNED-PAYLOAD
<?xml version="1.0" encoding="utf-8"?>
<AccessControlPolicy>
    <Owner>
        <ID>client_canonical_id1</ID>
        <DisplayName>client@bizmrg.ru</DisplayName>
    </Owner>
    <AccessControlList>
        <Grant>
            <Permission>READ</Permission>
            <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
                <URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
            </Grantee>
        </Grant>
        <Grant>
            <Permission>WRITE</Permission>
            <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
                <ID>friend_project_canonical_id</ID>
                <DisplayName>friend_project@bizmrg.ru</DisplayName>
            </Grantee>
        </Grant>
    </AccessControlList>
</AccessControlPolicy>