title: How to set Open/Download permissions on a file created in S3 with Amazon Lambda?
body: <p>I have an Amazon Lambda function that successfully writes files to an Amazon S3 bucket. However, by default these files are not publicly accessible. How do I make them automatically accessible when they are written?</p>
  
  <p>Is there a way to change the bucket itself so that all items are publicly readable (open/download)?</p>
  
  <p>Alternatively, I've gleaned that this can be done with the IAM role policy. This is what I have:</p>
  
  <pre><code>{
  "Version": "2012-10-17",
  "Statement": [
  {
    "Effect": "Allow",
    "Action": [
      "logs:CreateLogGroup",
      "logs:CreateLogStream",
      "logs:PutLogEvents"
    ],
    "Resource": "arn:aws:logs:*:*:*"
  },
  {
    "Effect": "Allow",
    "Action": [
      "s3:GetObject",
      "s3:PutObject"
    ],
    "Resource": [
      "arn:aws:s3:::*"
    ]
  }
  ]
  }
  </code></pre>
  
  <p>I think it's the "Resource" that needs to be changed, but I'm not sure how.</p>
  
  <p>For completeness (in case anyone else needs to do something similar and is wading into the morass that is the Lambda documentation), here's my ajax call on the clientside (I'm writing an image to S3 and need the filename back):</p>
  
  <pre><code>$.ajax({
  url: 'https://mylambdafunctionurl/',
  type: 'POST',
  crossDomain: true,
  contentType: 'application/json',
  data: JSON.stringify(data),
  dataType: 'json',
  success: function(data) {
      var path = "https://myregion.amazonaws.com/mybucket/";
      var filename = JSON.parse(data).filename;
      document.getElementById('finalimage').innerHTML = "&lt;a href='"+path+filename+"'&gt;Your image&lt;/a&gt;";
  },
  error: function(xhr, ajaxOptions, thrownError) {
      if (xhr.status == 200) {
          console.log(ajaxOptions);
      } else {
          console.log("Error: ");
          console.log(xhr.status);
          console.log(thrownError);
      }
  }
  });
  </code></pre>
  
  <p>And here is the Lambda POST function (nodejs):</p>
  
  <pre><code>var AWS = require('aws-sdk');
  var s3 = new AWS.S3();
  
  exports.handler = function(event,context) {
      var s3 = new AWS.S3();
      var nowtime = new Date();
      var bodycontent = event.image;
  
      mykey = nowtime.getTime() + '.png';
      var param = {Bucket: 'mybucket', Key: mykey, Body: bodycontent};
      var successdata = {filename:mykey};
      s3.upload(param, function(e,data) {
          if (e) {
              console.log(e,e.stack);
          } else {
              console.log(event);
          }
          context.done(null,JSON.stringify(successdata));
      });
  }
  </code></pre>
  
  <p>Caveat: using the current time for the filename is not production ready. It was just a quick way to produce a reasonably unique filename.</p>