{"id":115,"date":"2019-03-10T22:35:38","date_gmt":"2019-03-10T22:35:38","guid":{"rendered":"https:\/\/blog.adonlon.org\/?p=115"},"modified":"2019-03-20T13:02:39","modified_gmt":"2019-03-20T13:02:39","slug":"jenkins-and-aws-ecr","status":"publish","type":"post","link":"https:\/\/blog.adonlon.org\/index.php\/2019\/03\/10\/jenkins-and-aws-ecr\/","title":{"rendered":"Jenkins, Docker and AWS ECR"},"content":{"rendered":"\n<p>There&#8217;s a difficulty using Jenkins to access ECR in a security conscious environment, such as an environment requiring HIPAA or PCI compliance. Even if Jenkins is on an EC2 instance, using the standard docker login command documented by AWS utilising IAM roles and the STS to get short-lived AWS credentials, the docker login command generated by the command line puts the STS token into a command parameter, visible by tools such as <code>ps<\/code>, but it also ends up causing the default docker engine to store the short term credential in plain-text in a file on disk (<code>~\/.docker\/credentials.json<\/code>).  The docker community have &#8216;helpfully&#8217; created warnings about these things, which auditors &#8216;helpfully&#8217; pick up on and then ask questions about your approach to security.<\/p>\n\n\n\n<p>So, let&#8217;s go through the issues, why the auditors care about them and what might be the best solution to them.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Issue 1 &#8211; The Documented Method Leaks Via Command Line<\/h2>\n\n\n\n<p>According to the standard <a href=\"https:\/\/docs.aws.amazon.com\/AmazonECR\/latest\/userguide\/ECR_GetStarted.html\">AWS documentation<\/a> on using AWS ECR, the best way to log into an ECR repository is via the AWS CLI &#8211; <code>$(aws ecr get-login --no-include-email)<\/code>. The documentation is quite clear that this results in a docker login command which includes the short lived token as a command line parameter.<\/p>\n\n\n\n<p>Just to be clear, <code>aws ecr get-login --no-include-email<\/code>generates a docker login command which looks like this&#8230;.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">docker login -u AWS -p eyJwYXlsb2FkIjoiaWV0ekhtdEVWblFTTXovV3NlT2w5aWE4VlMwNGxhZm40eWd6OE9mL0VpbjNURjJrZE8wc1hWeUM5SFY2aEhYSmVmb3k5VFVZT20xU2hTS1I4RFcrdzhCY0xWOTE0TndDbi9WT1IydnhQZ2VtcEtMbzRnZW1HclIvU2pSNnNlV0tlbVZURGUyaUVJMlZoSGtuZDJXY3p1V1R0bVJ0SzA5NEMweStmTVlSV0hiMklDd3hSWXJBVkdiNmdKWFJVYjZxL2pmc2RSVkdqS2JLTjNyT094djY4N3ExUm0rTll4dFIvdHQ4OHZhOWpzWnBFQjZHbGhzekJ1TVhDMHplb0lGMVdIdXB3RGtnU0hkVm5tU3hyUU96ckRRZW1iWXBNYmxqWGFqTzF2YkhsZVlNdFBSWnVXelhzbVlKbWkvd3VhVThFNS9nZmtQVll3Q1BsWG0zcXpRY2daTjQ5WjhZZXVTT3grczFZcTdydk4rdU93cWZpQ0doTVJJTVVYdERCMCtWT2U4SGl6elpuNGhpTmdva05adXpMMGNuRXRDa1BFc0VMak5acE00UzZ4QUpxcDZjM01wdW9IMmNsMEFadHlyMmN0NmY4aHM4Yjk3cGM5MGhnSGhTL3hkR0h1RnRnZFVWZ3Y4c3QxYXJJTXYwYkhuRm9xeFgzQkFIZUFzZWVDSjhjZG5Ca2JmYUYyZkxZYzRpejJuNXdOK0lTTFNWN0NjenkyeFBobUN1VG93STNqdWVYOCtFY203aXFHY3g4ZEpYbzFQbmFaQkVXZnFwTTVGMDQ1RzhkdTlBb0F5TzFGbFRCbUcxUUhHcGViNWVSVzhoa3MzTXdYTU5zNnJ2Y0tZd01uWlAvY241aklmMWpmWWVFZXVPeHdFTVFJTDVrYzhFYkVROE0vSVlBMGUyNVVvcTVVcXhaUDBjR29xL1RRRXVpRERYWDJKYW9YNGI4NFpCZlhFa3o2djFHNThHL0xyeGp2UXJNMHFmVmt0ZXRoQ2VkdXJkWUErNmhGRnhoTVFVQ0ZselArTUZOdStvMXR3YXEvekRwRjErY1RLck1DTjJtNEdCM2xESUpnNHNob2lQVEMzMkRIS21pcXdrY1N1YmdvNlAvSzc1SVcxZjBJTUYyNEZTWDZrbkh5RWpiZlNRbE1kRit2SVNHZi9YVC9sOVAxM1JkQjNJWlNQanZlVlpBdDhXbGJ2NENlWUVsM0ZiUVdhRUlNcEl1MFJweTNWNzhORldpQmZUb1oyVGl4Y3BYSmYxT3hXZkJveE84ajFPV2xDQkRLWjdRMHJwMi9ncThSTGR4dk5IdjNaVTBUWEd1YVdMemhONHlEdnNyZm5vTlMyNmRrL3RRZ1ZmUENabTRGZER1MWE5a3k0MW0zSHoydVE0cFFJSllQWnJibEdGQ3BrSER3bW5Nbk5vNnhIay9NeTFzemtmYlkrQk9wNUk2a0hWN3ZWbmRQM0dKQnpVM3FDV3dqbUs3S01SWStBdHFpM0syUkE4cDNmWVlnPT0iLCJkYXRha2V5IjoiQVFFQkFIaCtkUytCbE51ME54blh3b3diSUxzMTE1eWpkK0xOQVpoQkxac3VuT3hrM0FBQUFINHdmQVlKS29aSWh2Y05BUWNHb0c4d2JRSUJBREJvQmdrcWhraUc5dzBCQndFd0hnWUpZSVpJQVdVREJBRXVNQkVFREVRTzNzY25XQ1U1aDVNRytBSUJFSUE3MXhiRlJpWUlvRzJpQjE2aE9Sa0NjbnJtRVZ6NnE5aWNiTzlOWXpaK3d5MDRQTzd3bGc0WnNVTURtdjdncVFmVmFRMk9RRWV1Zyt1WHRjOD0iLCJ2ZXJzaW9uIjoiMiIsInR5cGUiOiJEQVRBX0tFWSIsImV4cGlyYXRpb24iOjE1NTEwODgwMTV9 -e none https:\/\/xxxxxxxxxxxxx.dkr.ecr.xxxxxxxxx.amazonaws.com<\/pre>\n\n\n\n<p>Now, I&#8217;m pretty sure nobody&#8217;s going to be using this to shoulder surf any passwords. What they *can* do, however, is to use automated tools to snaffle the token via commands like <code>ps -ef <\/code> or its lower-level programmatic equivalents. The thing about this is that the token is no longer tied to the EC2 instance which it was generated for &#8211; anyone can use it from anywhere and act like they were the original IAM role.<\/p>\n\n\n\n<p>That&#8217;s possibly not the worst thing in the world if you&#8217;re working with a system where people log in with their own IAM roles from their own laptops \/ desktops. An individual users workstation or laptop isn&#8217;t *supposed* to be used by multiple people so it&#8217;s quite likely only to have the credential owner actively using the system. For the credentials to leak the system must first be compromised by some kind of malware.<\/p>\n\n\n\n<p>On a Jenkins CI server, however, this isn&#8217;t quite the case. The server itself is generally accessed by multiple groups of people with varying levels of ability to affect what happens on the system. Some, for sure, will have limited ability to cause things to happen but others will have more intimate access, up to and including shell access. So now you&#8217;ve got *2* mechanisms by which credentials could leak &#8211; either a malicious intruder *or* a malicious insider.<\/p>\n\n\n\n<p>It&#8217;s worth remembering that Jenkins exists to allow people with a significant amount of access to the machine just to do their job. A malicious developer could craft a job which runs once a minute search for &#8216;docker login&#8217; commands and mails the tokens to their secret lair. A malicious operator could install a script doing similar. The Jenkins UI could be configured to lock things down but ultimately the really determined malicious developer would just write a script which does the same thing.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Issue 2: The Documented Method Stores Credentials In Plain Text<\/h2>\n\n\n\n<p>So, the AWS default mechanism for logging into a remote registry has the potential to leak credentials but that&#8217;s not the only issue. The default docker installation actually stores the credentials it gets for logging into registries in a file in <code>~\/.docker\/configuration.json<\/code>. The file is readable only by the <code>jenkins<\/code> user bu basically, anyone with access to this file has access to all the credentials which that user has used to access any repository (or at least any one which they have required credentials for).<\/p>\n\n\n\n<p>The issue here is similar to the previous one &#8211; on a single machine used by a single developer (e.g. workstation or laptop) it may not be such a big deal for credentials to be available but when that machine is shared then those credentials are potentially available to anybody with access to the machine.<\/p>\n\n\n\n<p>It doesn&#8217;t really matter that the credentials are only valid for 12 hours. The reality is that they&#8217;re only really usable by automated processes anyway (given their length) so the most likely attack vector involves *some* kind of automation somewhere, even if only copy-paste.<\/p>\n\n\n\n<p>The other thing is, Jenkins runs jobs as jobs as the jenkins user. So the credentials which, on a single laptop, are stored in file which a directly accessible only to the logged-in user are now available to a group of users on a shared instance. Now anyone with Jenkins access can acquire the permissions associated with the Jenkins user \/ role. Typically, this is quite a lot of power given that Jenkins is often given CI \/ CD responsibilities and so can have the power to push \/ pull docker images into ECR.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Clue Is In The Error Message<\/h2>\n\n\n\n<p>When you run AWS&#8217;s version of the <code>docker login<\/code> with a password on the command line it says this to you<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">WARNING! Using --password via the CLI is insecure. Use --password-stdin.<br> WARNING! Your password will be stored unencrypted in \/xxxxxxxxxxxxxx\/.docker\/config.json.<br> Configure a credential helper to remove this warning. See<br> https:\/\/docs.docker.com\/engine\/reference\/commandline\/login\/#credentials-store<br><br>Login Succeeded<br><\/pre>\n\n\n\n<p>There&#8217;s a mini-wall of text there but basically it&#8217;s got two lines which are telling you that the AWS token giving you access to the ECR will be<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>visible on the command line<\/li><li>stored in plain- text<\/li><\/ul>\n\n\n\n<p>If you start with the first warning and fix them one at a time you might be tempted to start by looking into how to use docker&#8217;s alternative mechanism for specifying a password &#8211; the <code>--password<\/code>option. That can get you to doing something like <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">echo $(aws ecr get-authorization-token --region eu-central-1 --output text --query 'authorizationData[].authorizationToken' | base64 -d | cut -d: -f2) | docker login -u AWS https:\/\/123456.dkr.ecr.eu-central-1.amazonaws.com --password-stdin<\/pre>\n\n\n\n<p>Having done that you get onto the second issue, about the token being stored in a file in plain text. The trick is not to get sucked down that rabbit hole &#8211; the *real* clue is in the second error message which says to <code>Configure a credential helper to remove this warning.<\/code><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Solution<\/h2>\n\n\n\n<p>What we did was to install the <a href=\"https:\/\/github.com\/awslabs\/amazon-ecr-credential-helper\">AWS Labs ECR Credential Helper<\/a>. It sounds simple, and to a large extent it is, but there are *some* twists to be aware of and its worth understanding what&#8217;s happening under the covers just to avoid bumping into any further security issues in an audit of a compliance environment.<\/p>\n\n\n\n<p>So, the helper itself is basically a plugin to docker. The core idea is to install a program on the machine which handles docker&#8217;s requests to deal with remote registries. Docker can then be configured to use the helper whenever it needs credentials to use the registry.<\/p>\n\n\n\n<p>The first step is to install the AWS credential helper, which itself is a go application, distributed via git and built with make. So, once you have <code>make, go<\/code>and <code>git<\/code>installed you should be able to tell the go runtime to download and build the command&#8230;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">go get -u github.com\/awslabs\/amazon-ecr-credential-helper\/ecr-login\/cli\/docker-credential-ecr-login<\/pre>\n\n\n\n<p>That will build a binary which can be installed somewhere accessible (e.g. \/usr\/local\/bin\/).<\/p>\n\n\n\n<p>Then you need to configure docker to use it. Docker uses a configuration file to store credentials it knows about and, since Docker v1.11, about credentials providers it knows about. It lives in $HOME\/.docker\/config.json. To use the <code>docker-credential-ecr-login<\/code>helper you just add it as a credential store in that config.json file&#8230;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">{<br>    \"credsStore\": \"ecr-login\"<br>}<\/pre>\n\n\n\n<p>Note that the name of the store matches the suffix on the binary name.<\/p>\n\n\n\n<p>After that there&#8217;s one final thing to do &#8211; ensure that the credential helper itself doesn&#8217;t store credentials. Unfortunately, by default it does. The behaviour can be disabled by ensuring that jenkins is run with the environment variable <code>AWS_ECR_DISABLE_CACHE<\/code>set to 1 (or anything other than an empty string).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Results<\/h2>\n\n\n\n<p>Having done all that, the docker command should be able to run against an ECR repository without every having to be explicitly logged into first. So the first result is that every <code>docker login<\/code>command can be removed from Jenkinsfile and related build scripts.<\/p>\n\n\n\n<p>Every time that docker needs credentials for a docker command it will use the helper to retrieve a temporary token from STS. Because the credentials are never stored on disk a new set will be retrieved for every docker interaction. <\/p>\n\n\n\n<p>At the end of the day, the security requirements are satisfied. Credentials are not stored on disk or visible via any simple system tooling. Meanwhile, the credentials which *are* used are short-lived STS tokens based on an IAM role, fulfilling AWS security best practice. At the same time, build \/ deployment configuration is actually simplified by removing the need to log into ECR repos explicitly.<\/p>\n\n\n\n<p>In short &#8211; everyone&#8217;s a winner.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There&#8217;s a difficulty using Jenkins to access ECR in a security conscious environment, such as an environment requiring HIPAA or PCI compliance. Even if Jenkins is on an EC2 instance, using the standard docker login command documented by AWS utilising IAM roles and the STS to get short-lived AWS credentials, the docker login command generated [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[3,5],"class_list":["post-115","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-aws","tag-ci"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Jenkins, Docker and AWS ECR - Pragmatic Software Engineering<\/title>\n<meta name=\"description\" content=\"Integrating Jenkins with ECR in a PCI compliant environment\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.adonlon.org\/index.php\/2019\/03\/10\/jenkins-and-aws-ecr\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Jenkins, Docker and AWS ECR - Pragmatic Software Engineering\" \/>\n<meta property=\"og:description\" content=\"Integrating Jenkins with ECR in a PCI compliant environment\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.adonlon.org\/index.php\/2019\/03\/10\/jenkins-and-aws-ecr\/\" \/>\n<meta property=\"og:site_name\" content=\"Pragmatic Software Engineering\" \/>\n<meta property=\"article:published_time\" content=\"2019-03-10T22:35:38+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-03-20T13:02:39+00:00\" \/>\n<meta name=\"author\" content=\"alastair\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"alastair\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/blog.adonlon.org\/index.php\/2019\/03\/10\/jenkins-and-aws-ecr\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/blog.adonlon.org\/index.php\/2019\/03\/10\/jenkins-and-aws-ecr\/\"},\"author\":{\"name\":\"alastair\",\"@id\":\"https:\/\/blog.adonlon.org\/#\/schema\/person\/4c5a1b2463425db9814bf8540f8954c1\"},\"headline\":\"Jenkins, Docker and AWS ECR\",\"datePublished\":\"2019-03-10T22:35:38+00:00\",\"dateModified\":\"2019-03-20T13:02:39+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/blog.adonlon.org\/index.php\/2019\/03\/10\/jenkins-and-aws-ecr\/\"},\"wordCount\":1416,\"publisher\":{\"@id\":\"https:\/\/blog.adonlon.org\/#\/schema\/person\/4c5a1b2463425db9814bf8540f8954c1\"},\"keywords\":[\"aws\",\"ci\"],\"articleSection\":[\"Uncategorized\"],\"inLanguage\":\"en-GB\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.adonlon.org\/index.php\/2019\/03\/10\/jenkins-and-aws-ecr\/\",\"url\":\"https:\/\/blog.adonlon.org\/index.php\/2019\/03\/10\/jenkins-and-aws-ecr\/\",\"name\":\"Jenkins, Docker and AWS ECR - Pragmatic Software Engineering\",\"isPartOf\":{\"@id\":\"https:\/\/blog.adonlon.org\/#website\"},\"datePublished\":\"2019-03-10T22:35:38+00:00\",\"dateModified\":\"2019-03-20T13:02:39+00:00\",\"description\":\"Integrating Jenkins with ECR in a PCI compliant environment\",\"breadcrumb\":{\"@id\":\"https:\/\/blog.adonlon.org\/index.php\/2019\/03\/10\/jenkins-and-aws-ecr\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.adonlon.org\/index.php\/2019\/03\/10\/jenkins-and-aws-ecr\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.adonlon.org\/index.php\/2019\/03\/10\/jenkins-and-aws-ecr\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blog.adonlon.org\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Jenkins, Docker and AWS ECR\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.adonlon.org\/#website\",\"url\":\"https:\/\/blog.adonlon.org\/\",\"name\":\"Pragmatic Software Engineering\",\"description\":\"Random thoughts and insights on software engineering\",\"publisher\":{\"@id\":\"https:\/\/blog.adonlon.org\/#\/schema\/person\/4c5a1b2463425db9814bf8540f8954c1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.adonlon.org\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/blog.adonlon.org\/#\/schema\/person\/4c5a1b2463425db9814bf8540f8954c1\",\"name\":\"alastair\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\/\/blog.adonlon.org\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/cf9abf1220f449fccd0f6795d12b05cb?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/cf9abf1220f449fccd0f6795d12b05cb?s=96&d=mm&r=g\",\"caption\":\"alastair\"},\"logo\":{\"@id\":\"https:\/\/blog.adonlon.org\/#\/schema\/person\/image\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Jenkins, Docker and AWS ECR - Pragmatic Software Engineering","description":"Integrating Jenkins with ECR in a PCI compliant environment","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.adonlon.org\/index.php\/2019\/03\/10\/jenkins-and-aws-ecr\/","og_locale":"en_GB","og_type":"article","og_title":"Jenkins, Docker and AWS ECR - Pragmatic Software Engineering","og_description":"Integrating Jenkins with ECR in a PCI compliant environment","og_url":"https:\/\/blog.adonlon.org\/index.php\/2019\/03\/10\/jenkins-and-aws-ecr\/","og_site_name":"Pragmatic Software Engineering","article_published_time":"2019-03-10T22:35:38+00:00","article_modified_time":"2019-03-20T13:02:39+00:00","author":"alastair","twitter_card":"summary_large_image","twitter_misc":{"Written by":"alastair","Estimated reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blog.adonlon.org\/index.php\/2019\/03\/10\/jenkins-and-aws-ecr\/#article","isPartOf":{"@id":"https:\/\/blog.adonlon.org\/index.php\/2019\/03\/10\/jenkins-and-aws-ecr\/"},"author":{"name":"alastair","@id":"https:\/\/blog.adonlon.org\/#\/schema\/person\/4c5a1b2463425db9814bf8540f8954c1"},"headline":"Jenkins, Docker and AWS ECR","datePublished":"2019-03-10T22:35:38+00:00","dateModified":"2019-03-20T13:02:39+00:00","mainEntityOfPage":{"@id":"https:\/\/blog.adonlon.org\/index.php\/2019\/03\/10\/jenkins-and-aws-ecr\/"},"wordCount":1416,"publisher":{"@id":"https:\/\/blog.adonlon.org\/#\/schema\/person\/4c5a1b2463425db9814bf8540f8954c1"},"keywords":["aws","ci"],"articleSection":["Uncategorized"],"inLanguage":"en-GB"},{"@type":"WebPage","@id":"https:\/\/blog.adonlon.org\/index.php\/2019\/03\/10\/jenkins-and-aws-ecr\/","url":"https:\/\/blog.adonlon.org\/index.php\/2019\/03\/10\/jenkins-and-aws-ecr\/","name":"Jenkins, Docker and AWS ECR - Pragmatic Software Engineering","isPartOf":{"@id":"https:\/\/blog.adonlon.org\/#website"},"datePublished":"2019-03-10T22:35:38+00:00","dateModified":"2019-03-20T13:02:39+00:00","description":"Integrating Jenkins with ECR in a PCI compliant environment","breadcrumb":{"@id":"https:\/\/blog.adonlon.org\/index.php\/2019\/03\/10\/jenkins-and-aws-ecr\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.adonlon.org\/index.php\/2019\/03\/10\/jenkins-and-aws-ecr\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog.adonlon.org\/index.php\/2019\/03\/10\/jenkins-and-aws-ecr\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blog.adonlon.org\/"},{"@type":"ListItem","position":2,"name":"Jenkins, Docker and AWS ECR"}]},{"@type":"WebSite","@id":"https:\/\/blog.adonlon.org\/#website","url":"https:\/\/blog.adonlon.org\/","name":"Pragmatic Software Engineering","description":"Random thoughts and insights on software engineering","publisher":{"@id":"https:\/\/blog.adonlon.org\/#\/schema\/person\/4c5a1b2463425db9814bf8540f8954c1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.adonlon.org\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":["Person","Organization"],"@id":"https:\/\/blog.adonlon.org\/#\/schema\/person\/4c5a1b2463425db9814bf8540f8954c1","name":"alastair","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/blog.adonlon.org\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/cf9abf1220f449fccd0f6795d12b05cb?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/cf9abf1220f449fccd0f6795d12b05cb?s=96&d=mm&r=g","caption":"alastair"},"logo":{"@id":"https:\/\/blog.adonlon.org\/#\/schema\/person\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/blog.adonlon.org\/index.php\/wp-json\/wp\/v2\/posts\/115","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.adonlon.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.adonlon.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.adonlon.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.adonlon.org\/index.php\/wp-json\/wp\/v2\/comments?post=115"}],"version-history":[{"count":0,"href":"https:\/\/blog.adonlon.org\/index.php\/wp-json\/wp\/v2\/posts\/115\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.adonlon.org\/index.php\/wp-json\/wp\/v2\/media?parent=115"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.adonlon.org\/index.php\/wp-json\/wp\/v2\/categories?post=115"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.adonlon.org\/index.php\/wp-json\/wp\/v2\/tags?post=115"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}