Как получить учетные данные STS для мобильного приложения для доступа к защищенным объектам S3? - PullRequest
1 голос
/ 10 апреля 2020

Я развернул бэкэнд-сервис в AWS Fargate. Я хотел бы приобрести токены STS, чтобы получить набор защищенных объектов S3 из собственного мобильного приложения. Я использую Terraform для создания инфраструктуры. У меня уже есть роль задачи Fargate task-role. Поэтому для этого конкретного варианта использования я создал новую роль native-app-role и назначил task-role в качестве доверительного отношения с разрешением принять native-app-role.

Ниже приведен код Terraform:

# Fargate Role with trust relationship to ECS

data "aws_iam_policy_document" "fg_task_role_assume_role_policy_doc" {
  statement {
    actions = [
      "sts:AssumeRole"
    ]

    effect = "Allow"

    principals {
      type = "Service"
      identifiers = [
        "ecs-tasks.amazonaws.com"
      ]
    }
  }
}


resource "aws_iam_role" "task_role" {
  name = "${var.application}-${var.namespace}-fargate-task-role"
  assume_role_policy = data.aws_iam_policy_document.fg_task_role_assume_role_policy_doc.json

  tags = {
    Name = "${var.application}-${var.namespace}-fargate-task-role" # virtual-agent-alpha-fargate-task-role
  }
}


# Native app role with trust relationship to Fargate role
data "aws_iam_policy_document" "native_app_iam_policy_doc" {
  statement {
    actions = [
      "sts:AssumeRole"
    ]

    effect = "Allow"

    principals {
      type = "AWS"
      identifiers = [
        aws_iam_role.task_role.arn
      ]
    }
  }
}

resource "aws_iam_role" "virtual_agent_native_iam_role" {
  name = "${var.application}-${var.namespace}-native-application-role"
  assume_role_policy = data.aws_iam_policy_document.native_app_iam_policy_doc.json

  tags = {
    Name = "${var.application}-native-${var.namespace}-role"
  }
}

Затем я должен использовать следующий код Kotlin для получения учетных данных STS: Примечание: roleArn - это ARN virtual_agent_native_iam_role

fun getS3ReadOnlyTempCredentials(roleArn: String, bucket: String, objectKey: String, expiry: Expiry = Expiry(15, ChronoUnit.MINUTES)): AwsStsCredentials {
        val duration = Duration.of(expiry.duration, expiry.unit).toSeconds().toInt()
        val request = AssumeRoleRequest().apply {
            this.roleArn = roleArn
            roleSessionName = UUID.randomUUID().toString()
            durationSeconds = duration
            policy = """
                {
                  "Id": "${UUID.randomUUID()}",
                  "Version": "2012-10-17",
                  "Statement": [
                    {
                      "Action": [
                        "s3:GetObject"
                      ],
                      "Effect": "Allow",
                      "Resource": "arn:aws:s3:::$bucket/$objectKey",
                      "Principal": {
                        "AWS": [ $roleArn ]
                      }
                    }
                  ]
                }
            """.trimIndent()
        }

        return stsClient.assumeRole(request).credentials.let {
            AwsStsCredentials(it.accessKeyId, it.secretAccessKey, it.sessionToken, ZonedDateTime.now().plusSeconds(duration.toLong()) )
        }

Когда я выполняю это, я получаю следующую ошибку : com.amazonaws.services.securitytoken.model.AWSSecurityTokenServiceException: User: arn:aws:sts::913597729265:assumed-role/virtual-agent-alpha-fargate-task-role/c082fba5-3d13-4030-a457-9a18fb105efd is not authorized to perform: sts:AssumeRole on resource: "arn:aws:iam::913597729265:role/virtual-agent-alpha-native-application-role" (Service: AWSSecurityTokenService; Status Code: 403; Error Code: AccessDenied; Request ID: 573630b6-b02a-4185-ae5b-9360d05b4225)

Приведенная выше ошибка говорит о том, что virtual-agent-alpha-fargate-task-role не имеет разрешения на принятие virtual-native-role, но я добавил доверительные отношения через атрибут aussumeRole aws_iam_resource Terraform.

Может кто-нибудь указать, что я делаю не так?

Ответы [ 3 ]

0 голосов
/ 13 апреля 2020

Я могу попытаться помочь вам с двумя альтернативами, но для этого мне нужно подтвердить ваш вариант использования. Как я понял, вам необходимо предоставить доступ конкретному c пользователю для чтения (в течение определенного промежутка времени) указанного c s3 объекта. Если это так, вот мои предложения:

Первая альтернатива - попытаться заставить ваше решение работать. Но вам нужно протестировать его, потому что у меня нет этого сценария: сначала я бы удалил virtual_agent_native_iam_role и оставил только task_role. Мне по-прежнему нужно вызывать AssumeRole, используя task_role и спецификацию c $bucket/$objectKey. Но в конфигурации вашей роли чего-то не хватает. Согласно документации по API предположительной роли :

Полученные разрешения сеанса являются пересечением политики, основанной на идентификации роли, и политик сеанса.

Таким образом, чтобы это работало, ваши политики task_role должны иметь разрешения, обеспечивающие более широкий доступ к s3, и ваш вызов метода только ограничит уже существующие политики. В этом случае я бы прикрепил новую политику к вашему task_role в вашем шаблоне terraform, чтобы разрешить действие s3:GetObject для всех объектов в корзине (или, если необходимо, для всех корзин в вашей учетной записи, в зависимости от вашего варианта использования).

Вызов AssumeRole будет использоваться для ограничения доступа временных учетных данных к конкретным c bucket/objectkey.

Но есть и вторая альтернатива, которая, как мне кажется, будет гораздо более простой. Но вам нужно оценить, применимо ли это к вашему варианту использования:

S3 позволяет вам создать временный URL для указанного объекта c, который позволит пользователю, у которого есть URL, получить объект в течение определенного c интервала времени. Для этого решения вам также необходимо добавить политику с разрешениями на s3:GetObject для task_role. Но в этом случае вам не нужно будет вызывать метод AssumeRole в вашем коде. Вы можете просто вызвать метод, чтобы создать предварительно подписанный URL-адрес и отправить его обратно вашему пользователю. Вы можете найти более подробную информацию об этой альтернативной реализации, используя java -sdk здесь .

При таком сценарии пользователь будет иметь доступ только к выбранному объекту. Не все ведро.

0 голосов
/ 14 апреля 2020

Я исправил проблему. Ошибка, которую я сделал, не предоставила разрешение task_role на AssumeRole разрешения. Все остальное, изложенное в вопросе, сделано правильно. Поэтому в моем terraform для task_role мне пришлось прикрепить пользовательскую политику с правильными разрешениями.

Код Terraform:

data "aws_iam_policy_document" "virtual_agent_native_assume_role_policy_doc" {
  statement {
    effect = "Allow"
    actions = ["sts:AssumeRole"]
    resources = ["*"]
  }
}

resource "aws_iam_policy" "virtual_agent_native_assume_role_policy" {
  name = "${var.application}-${var.namespace}-native-role-assume-role-policy"
  policy = data.aws_iam_policy_document.virtual_agent_native_assume_role_policy_doc.json
}

resource "aws_iam_role_policy_attachment" "task_role_virtual_agent_native_assume_role_policy_att" {
  role = aws_iam_role.task_role.name
  policy_arn = aws_iam_policy.virtual_agent_native_assume_role_policy.arn
}
0 голосов
/ 10 апреля 2020

Я верю, что твоя роль в создании неверна. Политика, которую вы создали внутри своего кода, должна быть частью вашего virtual_agent_native_iam_role внутри вашего шаблона terraform.

Вам также не нужно предполагать роль внутри вашего кода, вы можете настроить свою задачу на использование роли выполнения что вы создали в своем шаблоне terraform. Проверьте здесь для получения дополнительной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...