title: How to get Django to make some files public and media files private on AWS S3 (no 403 errors)?
body: <p>I'm using <strong>boto3</strong> and <strong>django-storages</strong> in my Django app to serve files from AWS S3. I'd like my static files to be public but other files to be private. I've got it kinda sorta working but not quite. My static files are being served as if they're private, with a pre-signed key. In my template file when I use:</p>
  <pre><code>&lt;img src=&quot;{% static 'images/3d-house-nav-gray.png' %}&quot;&gt;
  </code></pre>
  <p>instead of what I want</p>
  <pre><code>&lt;img src=&quot;https://mybucket.s3.amazonaws.com/static/images/3d-house-nav-gray.png&quot;&gt;
  </code></pre>
  <p>I'm getting</p>
  <pre><code>&lt;img id=&quot;home-img&quot; src=&quot;https://mybucket.s3.amazonaws.com/static/images/3d-house-nav-gray.png?AWSAccessKeyId=AKIA1234564LQ7X4EGHK&amp;amp;Signature=123456gIBTFlTQKCexLo3UJmoPs%3D&amp;amp;Expires=1621693552&quot;&gt;
  </code></pre>
  <p>This actually works when the templates are rendered from the server as part of an HTTPResponse, but not when an image like this is simply included as part of, say, a .css file. In that case I'll get:</p>
  <pre><code>Failed to load resource: the server responded with a status of 403 (Forbidden)
  </code></pre>
  <p>(I find that if I copy and paste the problematic image link and replace the <code>&amp;amp;</code> with an <code>&amp;</code> then I have access, a further mystery.)</p>
  <p>Here is how I have AWS configured:</p>
  <pre><code>AWS_ACCESS_KEY_ID = os.environ['AWS_ACCESS_KEY_ID']
  AWS_SECRET_ACCESS_KEY = os.environ['AWS_SECRET_ACCESS_KEY']
  AWS_STORAGE_BUCKET_NAME = 'mybucket'
  AWS_S3_OBJECT_PARAMETERS = {
      'CacheControl': 'max-age=86400',
  }
  AWS_DEFAULT_ACL = None
  AWS_LOCATION = 'static'
  STATICFILES_STORAGE = 'myapp.storage_backends.StaticStorage'
  DEFAULT_FILE_STORAGE = 'myapp.storage_backends.MediaStorage'
  AWS_S3_URL = 'https://%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME
  STATIC_DIRECTORY = '/static/'
  MEDIA_DIRECTORY = '/media/'
  STATIC_URL = AWS_S3_URL + STATIC_DIRECTORY
  MEDIA_URL = AWS_S3_URL + MEDIA_DIRECTORY
  </code></pre>
  <p>Where <code>myapp.storage_backends.py</code> contains:</p>
  <pre><code>from storages.backends.s3boto3 import S3Boto3Storage
  
  class MediaStorage(S3Boto3Storage):
      location = 'media'
      file_overwrite = False
  
  class StaticStorage(S3Boto3Storage):
      location = 'static'
      file_overwrite = True
  </code></pre>
  <p>And on AWS S3, my bucket policy is set up like so:</p>
  <pre><code>{
      &quot;Version&quot;: &quot;2012-10-17&quot;,
      &quot;Id&quot;: &quot;Policy1621539673651&quot;,
      &quot;Statement&quot;: [
          {
              &quot;Sid&quot;: &quot;Stmt1621539665305&quot;,
              &quot;Effect&quot;: &quot;Allow&quot;,
              &quot;Principal&quot;: {
                  &quot;AWS&quot;: &quot;arn:aws:iam::063896663644:user/mylogin&quot;
              },
              &quot;Action&quot;: [
                  &quot;s3:GetObject&quot;,
                  &quot;s3:GetObjectAcl&quot;,
                  &quot;s3:PutObject&quot;,
                  &quot;s3:PutObjectAcl&quot;
              ],
              &quot;Resource&quot;: &quot;arn:aws:s3:::mybucket/*&quot;
          },
          {
              &quot;Sid&quot;: &quot;Stmt1621539600741&quot;,
              &quot;Effect&quot;: &quot;Allow&quot;,
              &quot;Principal&quot;: {
                  &quot;AWS&quot;: &quot;*&quot;
              },
              &quot;Action&quot;: &quot;s3:GetObject&quot;,
              &quot;Resource&quot;: &quot;arn:aws:s3:::mybucket/static/*&quot;
          }
      ]
  }
  </code></pre>
  <p>How can I fix this to make certain files (like everything in static/) unsigned and public, but other files signed and private?</p>