본문 바로가기

AWS IoT/안드로이드 앱

[AWS LED Button] 어플리케이션 (2) : 정책 & 신뢰 관계

먼저 Cognito에서 ID Pool을 생성한 후 IAM에서 "인증된 역할"과 "인증되지 않은 역할"(ID Pool 생성시 IAM에 자동 생성)에 대한 권한을 설정(원하는 정책을 만들어서 해당 역할에 붙이거나 해당 역할에서 인라인 정책을 생성)해 주어야 합니다. 

 

또한 역할은 IAM에 정의되어 있지만, 이 역할에 의해 생성된 "임시 자격 증명"이 Security Token Service(STS)에 있기 때문에, 역할 맡는 동작(AssumeRole)은 STS가 담당합니다. AssumeRole에 대한 동작은 따로 해당 정책의 신뢰 관계 정책에서 설정해야 합니다. 다음은 제가 IAM에서 "인증된 역할"에 설정한 정책과 신뢰 관계입니다.

 

정책

* 는 와일드 카드를 의미합니다. 그리고 사물(Thing)의 정책과 비교해 보세요. 대칭되는게 있을겁니다.

[AWS/LED Button - ESP32] - AWS LED Button 1단계 - ESP32 (2) : MQTT 프로토콜과 정책, JSON 포맷

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:Connect",
      "Resource": "arn:aws:iot:us-east-1:<account id>:client/LEDButton*"
    },
    {
      "Effect": "Allow",
      "Action": "iot:Receive",
      "Resource": [
        "arn:aws:iot:us-east-1:<account id>:topic/LEDButton*/result",
        "arn:aws:iot:us-east-1:<account id>:topic/$aws/things/LEDButton*/shadow/get/accepted",
        "arn:aws:iot:us-east-1:<account id>:topic/$aws/things/LEDButton*/shadow/get/rejected"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "iot:Subscribe",
      "Resource": [
        "arn:aws:iot:us-east-1:<account id>:topicfilter/LEDButton*/result",
        "arn:aws:iot:us-east-1:<account id>:topicfilter/$aws/things/LEDButton*/shadow/get/accepted",
        "arn:aws:iot:us-east-1:<account id>:topicfilter/$aws/things/LEDButton*/shadow/get/rejected"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "iot:Publish",
      "Resource": [
        "arn:aws:iot:us-east-1:<account id>:topic/LEDButton*/command",
        "arn:aws:iot:us-east-1:<account id>:topic/$aws/things/LEDButton*/shadow/get"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "iot:GetThingShadow",
      "Resource": "arn:aws:iot:us-east-1:<account id>:thing/LEDButton*"
    },
    {
       "Effect": "Allow",
       "Action": [
           "iot:AttachPrincipalPolicy",
           "iot:DetachPrincipalPolicy"
       ],
       "Resource": "*"
     }
  ]
}

 

신뢰 관계

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "cognito-identity.amazonaws.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "cognito-identity.amazonaws.com:aud": "us-east-1:<user pool id>"
        },
        "ForAnyValue:StringLike": {
          "cognito-identity.amazonaws.com:amr": "authenticated"
        }
      }
    },
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "iot.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

하지만 IAM에서 AWS IoT 서비스에 대한 접근 권한을 설정했다고 해서 바로 IoT 서비스에 접근할 수 있는 것은 아닙니다. AWS IoT 내에서 또다시 정책을 생성하고, 이 정책을 AWS IoT에 접근하기 위해 사용된 STS의 임시 자격 증명에 붙여야 합니다. 즉, AWS IoT에서 생성되지 않은 인증(임시 자격 증명)을 통해 IoT 서비스에 접근할 경우엔 그 인증에 대한 IoT 접근 권한 뿐만 아니라 AWS IoT 내의 접근 권한이 추가되어야 합니다. 이때 추가로 부착되는 AWS IoT 내의 IoT에 대한 접근 권한 범위가 IAM에서 임시 자격 증명에 부착된 AWS IoT에 접근 권한 범위보다 커야합니다. 

 

하지만 IAM에서 AWS IoT 서비스에 대한 접근 권한을 설정했다고 해서 바로 IoT 서비스에 접근할 수 있는 것은 아닙니다. AWS IoT 내에서 또다시 정책을 생성하고, 이 정책을 AWS IoT에 접근하기 위해 사용된 STS의 임시 자격 증명에 붙여야 합니다. AWS IoT에서 생성되지 않은 인증(임시 자격 증명)을 통해 IoT 서비스에 접근할 경우엔 그 인증에 대한 IoT 접근 권한 뿐만 아니라 AWS IoT 내의 접근 권한이 또다시 추가되어야 하기 때문입니다. 이때 추가로 부착되는 AWS IoT 내의 IoT에 대한 접근 권한 범위가 IAM에서 임시 자격 증명에 부착된 AWS IoT에 접근 권한 범위보다 커야합니다. 

 

AWS IoT 내 안드로이드 앱 클라이언트를 위한 정책(AttachPolicyPrincipal, DetacchPolicyPrincipal을 제외하고 IAM 정책과 동일)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:Connect",
      "Resource": "arn:aws:iot:us-east-1:<account id>:client/LEDButton*"
    },
    {
      "Effect": "Allow",
      "Action": "iot:Receive",
      "Resource": [
        "arn:aws:iot:us-east-1:<account id>:topic/LEDButton*/result",
        "arn:aws:iot:us-east-1:<account id>:topic/$aws/things/LEDButton*/shadow/get/accepted",
        "arn:aws:iot:us-east-1:<account id>:topic/$aws/things/LEDButton*/shadow/get/rejected"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "iot:Subscribe",
      "Resource": [
        "arn:aws:iot:us-east-1:<account id>:topicfilter/LEDButton*/result",
        "arn:aws:iot:us-east-1:<account id>:topicfilter/$aws/things/LEDButton*/shadow/get/accepted",
        "arn:aws:iot:us-east-1:<account id>:topicfilter/$aws/things/LEDButton*/shadow/get/rejected"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "iot:Publish",
      "Resource": [
        "arn:aws:iot:us-east-1:<account id>:topic/LEDButton*/command",
        "arn:aws:iot:us-east-1:<account id>:topic/$aws/things/LEDButton*/shadow/get"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "iot:GetThingShadow",
      "Resource": "arn:aws:iot:us-east-1:<account id>:thing/LEDButton*"
    }
  ]
}

먼저 AWS IoT 서비스 내에서 설정할 수 있는 IoT 접근 권한은 Publish, Subscribe, Connect, Receive, UpdateThingShadow, GetThingShadow, DeleteThingShadow 입니다. AttachPolicyPrincipal 등 IoT에 없는 나머지 권한은 IAM에서만 설정하면 됩니다.

 

기본적으로 IAM의 IoT 접근 권한과 IoT의 IoT 접근 권한을 같게 하는 것을 추천드립니다.