title: How to lockdown S3 bucket to specific users and IAM role(s)
body: <p>In our environment, all IAM user accounts are assigned a customer-managed policy that grants read-only access to a lot of AWS services. Here's what I want to do:</p>
  
  <ul>
  <li>Migrate a sql server 2012 express database from on-prem to a RDS instance</li>
  <li>Limit access to the S3 bucket containing the database files</li>
  </ul>
  
  <p>Here's the requirements according to AWS:</p>
  
  <ul>
  <li>A S3 bucket to store the .bak database file</li>
  <li>A role with access to the bucket</li>
  <li>SQLSERVER_BACKUP_RESTORE option attached to RDS instance</li>
  </ul>
  
  <p>So far, I've done the following:</p>
  
  <ul>
  <li>Created a bucket under the name "test-bucket" (and uploaded the .bak file here)</li>
  <li>Created a role under the name "rds-s3-role"</li>
  <li><p>Created a policy under the name "rds-s3-policy" with these settings:</p>
  
  <pre><code>{
      "Version": "2012-10-17",
      "Statement": [
       {
          "Effect": "Allow",
          "Action": [
              "s3:ListBucket",
              "s3:GetBucketLocation"
          ],
          "Resource": "arn:aws:s3:::test-bucket/"
       },
       {
          "Effect": "Allow",
          "Action": [
              "s3:GetObjectMetaData",
              "s3:GetObject",
              "s3:PutObject",
              "s3:ListMultipartUploadParts",
              "s3:AbortMultipartUpload"
          ],
          "Resource": "arn:aws:s3:::test-bucket/*"
       }
      ]
  }
  </code></pre></li>
  <li><p>Assigned the policy to the role</p></li>
  <li>Gave the AssumeRole permissions to the RDS service to assume the role created above</li>
  <li>Created a new option group in RDS with the SQLSERVER_BACKUP_RESTORE option and linked it to my RDS instance</li>
  </ul>
  
  <p>With no restrictions on my S3 bucket, I can perform the restore just fine; however, I can't find a solid way of restricting access to the bucket without hindering the RDS service from doing the restore.</p>
  
  <p>In terms of my attempts to restrict access to the S3 bucket, I found a few posts online recommending using an explicit Deny statement to deny access to all types of principals and grant access based on some conditional statements.</p>
  
  <p>Here's the contents of my bucket policy:</p>
  
  <pre><code>    {
          "Version": "2012-10-17",
          "Id": "Policy1486769843194",
          "Statement": [
              {
                   "Sid": "Stmt1486769841856",
                   "Effect": "Deny",
                   "Principal": "*",
                   "Action": "s3:*",
                   "Resource": [
                       "arn:aws:s3:::test-bucket",
                       "arn:aws:s3:::test-bucket/*"
                   ],
                   "Condition": {
                       "StringNotLike": {
                           "aws:userid": [
                               "&lt;root_id&gt;",
                               "&lt;user1_userid&gt;",
                               "&lt;user2_userid&gt;",
                               "&lt;user3_userid&gt;",
                               "&lt;role_roleid&gt;:*"
                           ]
                       }
                   }
               }
           ]
       }
  </code></pre>
  
  <p>I can confirm the bucket policy does restrict access to only the IAM users that I specified, but I am not sure how it treats IAM roles. I used the :* syntax above per a document I found on the aws forums where the author stated the ":*" is a catch-all for every principal that assumes the specified role.</p>
  
  <p>The only thing I'm having a problem with is, with this bucket policy in place, when I attempt to do the database restore, I get an access denied error. Has anyone ever done something like this? I've been going at it all day and haven't been able to find a working solution.</p>