{"id":61,"date":"2016-09-30T16:15:10","date_gmt":"2016-09-30T12:15:10","guid":{"rendered":"http:\/\/www.dobryakov.net\/blog\/?p=61"},"modified":"2016-09-30T16:15:10","modified_gmt":"2016-09-30T12:15:10","slug":"hide-and-protect-your-aws-s3-endpoint-railsnginx-example","status":"publish","type":"post","link":"https:\/\/www.dobryakov.net\/blog\/61\/","title":{"rendered":"Hide and protect your AWS S3 endpoint (Rails+Nginx example)"},"content":{"rendered":"<p>It is very simple to use S3 as a storage for your static content in Rails application. Just add paperclip and aws-sdk gems. But what to do if you want to hide the direct links to S3 items, or even restrict access to some files by user&#8217;s roles and access rights? Here is a working example: <!--more--><\/p>\n<p>What we want to achieve:<br \/>\n<code>img src=\"\/p\/thumb\/123\/cat.jpg\"<\/code><\/p>\n<p>This example assumes that we have two nginx endpoints: one for frontend (SPA) application, and another for backend (API) application.<\/p>\n<p>At the first, let&#8217;s create a helper in your model:<br \/>\n<script src=\"https:\/\/gist.github.com\/dobryakov\/b5147dcaa2e26fd92e782d928b98980a.js?file=model.rb\"><\/script><\/p>\n<p>The requests will be pointed to host and catched in the nginx location:<br \/>\n<script src=\"https:\/\/gist.github.com\/dobryakov\/b5147dcaa2e26fd92e782d928b98980a.js?file=frontend-app.conf\"><\/script><\/p>\n<p>Then they will be served at your backend (Rails) application:<br \/>\n<script src=\"https:\/\/gist.github.com\/dobryakov\/b5147dcaa2e26fd92e782d928b98980a.js?file=backend-app.conf\"><\/script><\/p>\n<p>Note that we use secret &#8216;X-Project-Private&#8217; header to prevent direct calls to your secret location.<\/p>\n<p>The requests going to your Rails router:<br \/>\n<script src=\"https:\/\/gist.github.com\/dobryakov\/b5147dcaa2e26fd92e782d928b98980a.js?file=routes.rb\"><\/script><\/p>\n<p>And then to your controller:<br \/>\n<script src=\"https:\/\/gist.github.com\/dobryakov\/b5147dcaa2e26fd92e782d928b98980a.js?file=controller.rb\"><\/script><\/p>\n<p>How it works? The controller will parse request&#8217;s params, find @model, and prepare special &#8216;X-Accel-Redirect&#8217; header with path (not URL) to your S3 item <em>relatively to your bucket<\/em>. The nginx catches this header <em>internally<\/em>, and sends a subrequest to &#8220;secret_store&#8221; location. Note that your visitor will not see the redirection.<\/p>\n<p>In the &#8220;secret_store&#8221; location, we just rewrite it and make usual proxy request to S3 endpoint. We append a secret &#8216;S3_SECRET_UA&#8217; header to respect S3 policy (see below).<\/p>\n<p>Make sure it works at this step! Make sure you have all ENV values setted properly! You could broke your working website. Let&#8217;s go forward if all is OK:<\/p>\n<p>S3 policy:<br \/>\n<script src=\"https:\/\/gist.github.com\/dobryakov\/b5147dcaa2e26fd92e782d928b98980a.js?file=s3-policy.json\"><\/script><\/p>\n<p>Please do not copy-paste policy content. Use S3 policy generator instead (you can find it in your bucket propertis). To make sure the protection works, try to open any of your S3 item&#8217;s URL directly from the browser &#8211; you should see &#8216;Access denied&#8217;.<\/p>\n<p>If all works properly, now you can check your user&#8217;s roles and permissions in the controller to pass his requests or to block it.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>It is very simple to use S3 as a storage for your static content in Rails application. Just add paperclip and aws-sdk gems. But what to do if you want to hide the direct links to S3 items, or even restrict access to some files by user&#8217;s roles and access rights? Here is a working &hellip; <a href=\"https:\/\/www.dobryakov.net\/blog\/61\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Hide and protect your AWS S3 endpoint (Rails+Nginx example)&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[6,15,17,19],"class_list":["post-61","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-cdn","tag-nginx","tag-rails","tag-s3"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.10 - aioseo.com -->\n\t<meta name=\"description\" content=\"It is very simple to use S3 as a storage for your static content in Rails application. Just add paperclip and aws-sdk gems. But what to do if you want to hide the direct links to S3 items, or even restrict access to some files by user&#039;s roles and access rights? Here is a working\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"dobryakov\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.dobryakov.net\/blog\/61\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Grigoriy Dobryakov - IT+AI Blog - Grigoriy Dobryakov&#039;s blog: management, development and testing\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Hide and protect your AWS S3 endpoint (Rails+Nginx example) - Grigoriy Dobryakov - IT+AI Blog\" \/>\n\t\t<meta property=\"og:description\" content=\"It is very simple to use S3 as a storage for your static content in Rails application. Just add paperclip and aws-sdk gems. But what to do if you want to hide the direct links to S3 items, or even restrict access to some files by user&#039;s roles and access rights? Here is a working\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.dobryakov.net\/blog\/61\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2016-09-30T12:15:10+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2016-09-30T12:15:10+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Hide and protect your AWS S3 endpoint (Rails+Nginx example) - Grigoriy Dobryakov - IT+AI Blog\" \/>\n\t\t<meta name=\"twitter:description\" content=\"It is very simple to use S3 as a storage for your static content in Rails application. Just add paperclip and aws-sdk gems. But what to do if you want to hide the direct links to S3 items, or even restrict access to some files by user&#039;s roles and access rights? Here is a working\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"BlogPosting\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/61\\\/#blogposting\",\"name\":\"Hide and protect your AWS S3 endpoint (Rails+Nginx example) - Grigoriy Dobryakov - IT+AI Blog\",\"headline\":\"Hide and protect your AWS S3 endpoint (Rails+Nginx example)\",\"author\":{\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/author\\\/dobryakov\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/#organization\"},\"datePublished\":\"2016-09-30T16:15:10+00:00\",\"dateModified\":\"2016-09-30T16:15:10+00:00\",\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/61\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/61\\\/#webpage\"},\"articleSection\":\"Uncategorized, cdn, nginx, rails, s3\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/61\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/category\\\/uncategorized\\\/#listItem\",\"name\":\"Uncategorized\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/category\\\/uncategorized\\\/#listItem\",\"position\":2,\"name\":\"Uncategorized\",\"item\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/category\\\/uncategorized\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/61\\\/#listItem\",\"name\":\"Hide and protect your AWS S3 endpoint (Rails+Nginx example)\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/61\\\/#listItem\",\"position\":3,\"name\":\"Hide and protect your AWS S3 endpoint (Rails+Nginx example)\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/category\\\/uncategorized\\\/#listItem\",\"name\":\"Uncategorized\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/#organization\",\"name\":\"Grigoriy Dobryakov - IT+AI Blog\",\"description\":\"Grigoriy Dobryakov's blog: management, development and testing\",\"url\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/author\\\/dobryakov\\\/#author\",\"url\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/author\\\/dobryakov\\\/\",\"name\":\"dobryakov\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/61\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/40e48c39391f07d18b3013504096fdb82384a9aecb150c9df6497886ed2803fb?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"dobryakov\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/61\\\/#webpage\",\"url\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/61\\\/\",\"name\":\"Hide and protect your AWS S3 endpoint (Rails+Nginx example) - Grigoriy Dobryakov - IT+AI Blog\",\"description\":\"It is very simple to use S3 as a storage for your static content in Rails application. Just add paperclip and aws-sdk gems. But what to do if you want to hide the direct links to S3 items, or even restrict access to some files by user's roles and access rights? Here is a working\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/61\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/author\\\/dobryakov\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/author\\\/dobryakov\\\/#author\"},\"datePublished\":\"2016-09-30T16:15:10+00:00\",\"dateModified\":\"2016-09-30T16:15:10+00:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/\",\"name\":\"Grigoriy Dobryakov - IT+AI Blog\",\"description\":\"Grigoriy Dobryakov's blog: management, development and testing\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Hide and protect your AWS S3 endpoint (Rails+Nginx example) - Grigoriy Dobryakov - IT+AI Blog","description":"It is very simple to use S3 as a storage for your static content in Rails application. Just add paperclip and aws-sdk gems. But what to do if you want to hide the direct links to S3 items, or even restrict access to some files by user's roles and access rights? Here is a working","canonical_url":"https:\/\/www.dobryakov.net\/blog\/61\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"BlogPosting","@id":"https:\/\/www.dobryakov.net\/blog\/61\/#blogposting","name":"Hide and protect your AWS S3 endpoint (Rails+Nginx example) - Grigoriy Dobryakov - IT+AI Blog","headline":"Hide and protect your AWS S3 endpoint (Rails+Nginx example)","author":{"@id":"https:\/\/www.dobryakov.net\/blog\/author\/dobryakov\/#author"},"publisher":{"@id":"https:\/\/www.dobryakov.net\/blog\/#organization"},"datePublished":"2016-09-30T16:15:10+00:00","dateModified":"2016-09-30T16:15:10+00:00","inLanguage":"en-US","mainEntityOfPage":{"@id":"https:\/\/www.dobryakov.net\/blog\/61\/#webpage"},"isPartOf":{"@id":"https:\/\/www.dobryakov.net\/blog\/61\/#webpage"},"articleSection":"Uncategorized, cdn, nginx, rails, s3"},{"@type":"BreadcrumbList","@id":"https:\/\/www.dobryakov.net\/blog\/61\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/www.dobryakov.net\/blog#listItem","position":1,"name":"Home","item":"https:\/\/www.dobryakov.net\/blog","nextItem":{"@type":"ListItem","@id":"https:\/\/www.dobryakov.net\/blog\/category\/uncategorized\/#listItem","name":"Uncategorized"}},{"@type":"ListItem","@id":"https:\/\/www.dobryakov.net\/blog\/category\/uncategorized\/#listItem","position":2,"name":"Uncategorized","item":"https:\/\/www.dobryakov.net\/blog\/category\/uncategorized\/","nextItem":{"@type":"ListItem","@id":"https:\/\/www.dobryakov.net\/blog\/61\/#listItem","name":"Hide and protect your AWS S3 endpoint (Rails+Nginx example)"},"previousItem":{"@type":"ListItem","@id":"https:\/\/www.dobryakov.net\/blog#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/www.dobryakov.net\/blog\/61\/#listItem","position":3,"name":"Hide and protect your AWS S3 endpoint (Rails+Nginx example)","previousItem":{"@type":"ListItem","@id":"https:\/\/www.dobryakov.net\/blog\/category\/uncategorized\/#listItem","name":"Uncategorized"}}]},{"@type":"Organization","@id":"https:\/\/www.dobryakov.net\/blog\/#organization","name":"Grigoriy Dobryakov - IT+AI Blog","description":"Grigoriy Dobryakov's blog: management, development and testing","url":"https:\/\/www.dobryakov.net\/blog\/"},{"@type":"Person","@id":"https:\/\/www.dobryakov.net\/blog\/author\/dobryakov\/#author","url":"https:\/\/www.dobryakov.net\/blog\/author\/dobryakov\/","name":"dobryakov","image":{"@type":"ImageObject","@id":"https:\/\/www.dobryakov.net\/blog\/61\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/40e48c39391f07d18b3013504096fdb82384a9aecb150c9df6497886ed2803fb?s=96&d=mm&r=g","width":96,"height":96,"caption":"dobryakov"}},{"@type":"WebPage","@id":"https:\/\/www.dobryakov.net\/blog\/61\/#webpage","url":"https:\/\/www.dobryakov.net\/blog\/61\/","name":"Hide and protect your AWS S3 endpoint (Rails+Nginx example) - Grigoriy Dobryakov - IT+AI Blog","description":"It is very simple to use S3 as a storage for your static content in Rails application. Just add paperclip and aws-sdk gems. But what to do if you want to hide the direct links to S3 items, or even restrict access to some files by user's roles and access rights? Here is a working","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/www.dobryakov.net\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/www.dobryakov.net\/blog\/61\/#breadcrumblist"},"author":{"@id":"https:\/\/www.dobryakov.net\/blog\/author\/dobryakov\/#author"},"creator":{"@id":"https:\/\/www.dobryakov.net\/blog\/author\/dobryakov\/#author"},"datePublished":"2016-09-30T16:15:10+00:00","dateModified":"2016-09-30T16:15:10+00:00"},{"@type":"WebSite","@id":"https:\/\/www.dobryakov.net\/blog\/#website","url":"https:\/\/www.dobryakov.net\/blog\/","name":"Grigoriy Dobryakov - IT+AI Blog","description":"Grigoriy Dobryakov's blog: management, development and testing","inLanguage":"en-US","publisher":{"@id":"https:\/\/www.dobryakov.net\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"Grigoriy Dobryakov - IT+AI Blog - Grigoriy Dobryakov's blog: management, development and testing","og:type":"article","og:title":"Hide and protect your AWS S3 endpoint (Rails+Nginx example) - Grigoriy Dobryakov - IT+AI Blog","og:description":"It is very simple to use S3 as a storage for your static content in Rails application. Just add paperclip and aws-sdk gems. But what to do if you want to hide the direct links to S3 items, or even restrict access to some files by user's roles and access rights? Here is a working","og:url":"https:\/\/www.dobryakov.net\/blog\/61\/","article:published_time":"2016-09-30T12:15:10+00:00","article:modified_time":"2016-09-30T12:15:10+00:00","twitter:card":"summary_large_image","twitter:title":"Hide and protect your AWS S3 endpoint (Rails+Nginx example) - Grigoriy Dobryakov - IT+AI Blog","twitter:description":"It is very simple to use S3 as a storage for your static content in Rails application. Just add paperclip and aws-sdk gems. But what to do if you want to hide the direct links to S3 items, or even restrict access to some files by user's roles and access rights? Here is a working"},"aioseo_meta_data":{"post_id":"61","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_custom_url":null,"og_image_custom_fields":null,"og_image_url":null,"og_image_width":null,"og_image_height":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_image_url":null,"twitter_title":null,"twitter_description":null,"schema_type":"default","schema_type_options":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"limit_modified_date":false,"ai":null,"breadcrumb_settings":null,"seo_analyzer_scan_date":null,"created":"2026-07-26 15:21:42","updated":"2026-07-26 15:21:42"},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.dobryakov.net\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.dobryakov.net\/blog\/category\/uncategorized\/\" title=\"Uncategorized\">Uncategorized<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tHide and protect your AWS S3 endpoint (Rails+Nginx example)\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.dobryakov.net\/blog"},{"label":"Uncategorized","link":"https:\/\/www.dobryakov.net\/blog\/category\/uncategorized\/"},{"label":"Hide and protect your AWS S3 endpoint (Rails+Nginx example)","link":"https:\/\/www.dobryakov.net\/blog\/61\/"}],"_links":{"self":[{"href":"https:\/\/www.dobryakov.net\/blog\/wp-json\/wp\/v2\/posts\/61","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dobryakov.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dobryakov.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dobryakov.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dobryakov.net\/blog\/wp-json\/wp\/v2\/comments?post=61"}],"version-history":[{"count":0,"href":"https:\/\/www.dobryakov.net\/blog\/wp-json\/wp\/v2\/posts\/61\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.dobryakov.net\/blog\/wp-json\/wp\/v2\/media?parent=61"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dobryakov.net\/blog\/wp-json\/wp\/v2\/categories?post=61"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dobryakov.net\/blog\/wp-json\/wp\/v2\/tags?post=61"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}