Перейти к содержанию

Управление доступом

Страница описывает, как владелец бакета открывает и ограничивает доступ к бакету и объектам через S3 API: списки управления доступом, политику бакета, блокировку публичного доступа, заранее подписанные ссылки и правила CORS. Она нужна разработчику клиентского приложения. Раздел о правилах CORS тенанта по умолчанию предназначен администратору.

Решение о доступе складывается из трёх источников:

Разделы идут в порядке: кому разрешён доступ, как его ограничить, доступ без ключа, доступ из браузера. Каждый раздел содержит описание, пример и перечень особенностей и ограничений.

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

Список управления доступом (ACL) перечисляет, кому и что разрешено делать с бакетом или объектом. Поддерживаются предопределённые списки (private, public-read, public-read-write, authenticated-read, bucket-owner-read, bucket-owner-full-control) и явные разрешения.

aws s3api put-object-acl --bucket documents --key report.pdf --acl public-read
aws s3api get-object-acl --bucket documents --key report.pdf

# Явное разрешение отдельному пользователю
aws s3api put-object-acl --bucket documents --key report.pdf \
    --grant-read 'id=bob'

Особенности и ограничения

  • Идентификатором получателя разрешения служит имя пользователя Picodata.
  • Группы задаются идентификаторами URI http://acs.amazonaws.com/groups/global/AllUsers и http://acs.amazonaws.com/groups/global/AuthenticatedUsers.
  • Владелец объекта и доступ по умолчанию описаны в разделе Права доступа к объектам.

Права доступа к объектам

Владельцем объекта становится пользователь, который его создал. Владелец бакета прав на объект не получает; такое поведение определено спецификацией S3.

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

Доступ другим пользователям открывают списки управления доступом. Поддерживаются:

  • предопределённые списки: private, public-read, public-read-write, authenticated-read, bucket-owner-read, bucket-owner-full-control;
  • явные разрешения для отдельных пользователей;
  • явные разрешения для групп «все пользователи» и «все аутентифицированные пользователи».

Политика бакета

Политика служит вторым источником разрешений, независимым от списков управления доступом. Явный запрет действует всегда; если запрета нет, разрешение даёт либо политика, либо список управления доступом.

cat > policy.json <<'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {"AWS": "arn:aws:iam:::user/bob"},
      "Action": ["s3:GetObject"],
      "Resource": ["arn:aws:s3:::documents/public/*"]
     },
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": "arn:aws:s3:::documents/secret/*"
     }
  ]
 }
EOF

aws s3api put-bucket-policy --bucket documents --policy file://policy.json
aws s3api get-bucket-policy --bucket documents
aws s3api get-bucket-policy-status --bucket documents
aws s3api delete-bucket-policy --bucket documents

Поддерживаемые элементы политики:

Элемент Что поддерживается
Principal имя пользователя Picodata без ARN; ARN вида arn:aws:iam::<учётная-запись>:user/<имя>, в котором значима последняя составляющая; "*"
Action, NotAction с подстановочными знаками * и ?
Resource, NotResource с подстановочными знаками * и ?
Операторы условий StringEquals, StringNotEquals, StringLike, StringNotLike и суффикс IfExists
Ключи условий s3:prefix, s3:ExistingObjectTag/<ключ>, s3:RequestObjectTag/<ключ> и заголовки запроса, например s3:x-amz-acl, s3:x-amz-copy-source и s3:x-amz-metadata-directive

Особенности и ограничения

  • Субъект доступа задаётся именем пользователя Picodata.
  • Значение "Principal": "*" разрешает анонимное обращение.
  • Неизвестный администратор условия трактуется в пользу отказа: инструкция Allow с оператором, который плагин не реализует, доступа не даёт, а инструкция Deny с таким оператором запрещает доступ.

Блокировка публичного доступа

Блокировка публичного доступа состоит из четырёх флагов бакета, которые имеют приоритет над списками управления доступом и политикой.

aws s3api put-public-access-block --bucket documents \
    --public-access-block-configuration \
    'BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true'

aws s3api get-public-access-block --bucket documents
aws s3api delete-public-access-block --bucket documents
Флаг Действие
BlockPublicAcls отклоняет запись списка управления доступом, который даёт доступ группам «все пользователи» и «все аутентифицированные пользователи»
IgnorePublicAcls сохраняет такие разрешения, но не учитывает их при проверке
BlockPublicPolicy отклоняет запись политики с "Principal": "*" без условий
RestrictPublicBuckets не применяет публичную политику к запросам без подписи

Особенности и ограничения

  • PutPublicAccessBlock заменяет настройку целиком: опущенный флаг означает false, а не сохранение прежнего значения.
  • Запрос GetPublicAccessBlock для бакета, где настройка не задавалась, возвращает NoSuchPublicAccessBlockConfiguration (404). Настройка из четырёх значений false считается заданной и читается обратно.
  • Различие первых двух флагов существенно при разборе инцидента. BlockPublicAcls не даёт публичному разрешению появиться. IgnorePublicAcls оставляет разрешение в списке и перестаёт его учитывать, поэтому GetBucketAcl и GetObjectAcl по-прежнему его показывают, а снятие флага возвращает разрешение в силу.

Доступ к объекту без ключа доступа дают два способа: заранее подписанная ссылка и анонимное обращение.

Ссылка, подпись которой передаётся в параметрах запроса, даёт доступ к объекту тому, у кого нет ключа доступа:

aws s3 presign s3://documents/report.pdf --expires-in 3600

Анонимное обращение разрешает либо предопределённый список управления доступом public-read, либо политика бакета с "Principal": "*":

aws s3api put-object-acl --bucket documents --key public/logo.png --acl public-read
curl https://s3.example.net/documents/public/logo.png

Особенности и ограничения

Совместное использование ресурсов между источниками (CORS)

Правила Cross-Origin Resource Sharing (CORS) определяют, каким источникам браузер разрешит обращаться к бакету. Без правил браузер отклоняет ответ до того, как его получит приложение.

cat > cors.json <<'EOF'
{
  "CORSRules": [
    {
      "AllowedMethods": ["GET", "PUT"],
      "AllowedOrigins": ["https://app.example.com", "https://*.example.com"],
      "AllowedHeaders": ["x-amz-*"],
      "ExposeHeaders": ["ETag", "x-amz-request-id"],
      "MaxAgeSeconds": 3000
     }
  ]
 }
EOF

aws s3api put-bucket-cors --bucket documents --cors-configuration file://cors.json
aws s3api get-bucket-cors --bucket documents
aws s3api delete-bucket-cors --bucket documents

Особенности и ограничения

  • Допустимы методы GET, PUT, POST, DELETE и HEAD и не более 100 правил.
  • Документ проверяется при записи: неизвестный метод или образец с несколькими символами * отклоняются.
  • Заголовки Access-Control-* добавляются и к обычным ответам, в том числе к ответам с ошибкой: без них браузер не покажет приложению даже код ошибки.

Образец источника

Образец источника содержит не более одного символа * и сопоставляется со значением целиком. Примеры:

  • *suffix совпадает с foo.suffix, но не с foo.suffix.get;
  • start*end совпадает с startend и start12end, но не с 0start12end.

Одиночный * разрешает любой источник, и в ответе возвращается именно *, а не имя источника, поэтому браузер кэширует такой ответ для всех источников сразу.

Предварительный запрос

Предварительный запрос (OPTIONS) обслуживается без подписи, потому что браузер её не присылает, и не обращается к объекту. Применяется первое правило, у которого совпали источник, метод и все заголовки из Access-Control-Request-Headers. Правило, в котором запрошенный заголовок не перечислен, не считается совпавшим.

Предварительный запрос Ответ
Правило совпало, в том числе для несуществующего ключа 200
У бакета нет правил или ни одно правило не совпало 403 без заголовков Access-Control-*; браузер не отправляет основной запрос
Нет заголовка Origin или заголовка Access-Control-Request-Method 400