3

Business Senario

There are multiple offices which have their own AWS S3 Buckets. No user from one office will have access to another office S3 Bucket.

Hence, for every office, there is a S3 Bucket and also an IAM user. Each IAM user has permission to only one bucket. As the offices don't grow often, IAM user creation and assigning permission is manually done through AWS Console.

Application Senario

Browser (Javascript) asks Server (PHP API) for temporary credentials to upload files to AWS S3. PHP API fetches Access key ID and Secret access key from database (based on office logged in). Then using AWS PHP SDK, calls StsClient and uses getSessionToken() method to get temporary credentials and pass it to Javascript.

PHP Code

use Aws\Sts\StsClient;
$credentials = new Aws\Credentials\Credentials($resultset['awssecret'], $resultset['awspass']);

$stsoptions = [
  'region'            => 'ap-south-1',
  'version'           => '2011-06-15',
  'signature_version' => 'v4',
  'credentials'       => $credentials,
];

$stsClient = new StsClient($stsoptions);
$response = $stsClient->getSessionToken();

Question

Currently, the IAM user has full access to the respective bucket. I want to restrict the temporary credentials access to only certain authorizations. Like only permission to upload, not delete files or list all files.

Can I pass an additional parameter to StsClient where I can restrict permissions to the bucket?

Edit 1

The user is assigned permissions through policy. Below is the permission added to the policy.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:ListBucketByTags",
                "s3:GetBucketTagging",
                "s3:DeleteObjectVersion",
                "s3:GetObjectVersionTagging",
                "s3:ListBucketVersions",
                "s3:GetBucketLogging",
                "s3:RestoreObject",
                "s3:ListBucket",
                "s3:GetAccelerateConfiguration",
                "s3:GetObjectAcl",
                "s3:AbortMultipartUpload",
                "s3:GetObjectVersionAcl",
                "s3:GetObjectTagging",
                "s3:GetMetricsConfiguration",
                "s3:PutObjectTagging",
                "s3:DeleteObject",
                "s3:PutBucketVersioning",
                "s3:GetIpConfiguration",
                "s3:DeleteObjectTagging",
                "s3:ListBucketMultipartUploads",
                "s3:GetBucketWebsite",
                "s3:PutObjectVersionTagging",
                "s3:DeleteObjectVersionTagging",
                "s3:GetBucketVersioning",
                "s3:GetBucketAcl",
                "s3:GetReplicationConfiguration",
                "s3:ListMultipartUploadParts",
                "s3:PutObject",
                "s3:GetObject",
                "s3:GetBucketCORS",
                "s3:GetAnalyticsConfiguration",
                "s3:GetObjectVersionForReplication",
                "s3:GetBucketLocation",
                "s3:ReplicateDelete",
                "s3:GetObjectVersion"
            ],
            "Resource": [
                "arn:aws:s3:::aws:s3:::mybucket",
                "arn:aws:s3:::*/*"
            ]
        }
    ]
}

My solution based on answer suggested by Accepted Answer.

Based on the suggestion in answer, added the permission

 {
        "Sid": "VisualEditor1",
        "Effect": "Allow",
        "Action": "sts:AssumeRole",
        "Resource": "*"
 }

Now my PHP Code is

$policy = '{
  "Id": "Policy1534086947311",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1534086676951",
      "Action": [
        "s3:PutObject",
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::mybucket"
      }
    }
  ]
}';

$awsrole = [
  'Policy' => $policy,
  'RoleArn' => 'arn:aws:s3:::mybucket',
  'RoleSessionName' => 'credApi' // just a random value
];
$response = $stsClient->assumeRole($awsrole);
Adarsh Madrecha
  • 6,364
  • 11
  • 69
  • 117

1 Answers1

3

Create an IAM role with more tightly-scoped permissions and then use your IAM user credentials to call AssumeRole to get temporary credentials. The IAM role would only allow s3:PutObject* to the relevant bucket. The IAM user would need permission to assume the role.

Or simply have your server generate a pre-signed URL for uploading to an object in the relevant S3 bucket. The client will not be able to use the URL for any other S3 operations.

jarmod
  • 71,565
  • 16
  • 115
  • 122
  • Thanks. Does using `AssumeRole` require any additional permisions? I am pasting the current permission in my question. – Adarsh Madrecha Aug 12 '18 at 15:53
  • The IAM user would need permission to assume the role (have edited answer). By the way, as a general rule, you would use IAM roles rather than IAM users to provide credentials to a server process in AWS - for example, you would run your PHP server on an EC2 instance which was launched with an appropriate IAM role. – jarmod Aug 12 '18 at 16:06
  • PHP server is on VPS, not hosted on AWS. – Adarsh Madrecha Aug 12 '18 at 16:17
  • Thanks for your help. Your answer works perfectly. It was exactly what I was looking for. – Adarsh Madrecha Aug 12 '18 at 18:15