In our AWS environment we avoid using static AWS credentials (i.e. AWS Access Key ID and AWS Secret Access Key) - instead we use ephemeral credentials that are supplied using the Amazon IAM/STS system.

      i.e. The use of static AWS credentials is not possible in our environment - we need to dynamically acquire credentials on the master / slave to. These credentials are then used to switch roles per our IAM configuration.

      Once the credentials are acquired, we use those credentials (Access Key ID, Secret Access Key, Session Token) to perform AWS actions as normal.

      An example

      As a brief example (from a pipeline script)

        env.AWS_ACCESS_KEY_ID = ""
        env.AWS_SECRET_ACCESS_KEY = ""
        env.AWS_SESSION_TOKEN = ""
      
        roleArn = "arn:aws:iam::<13 character AWS ID>:role/my-custom-role"
        externalParam = "--external-id ABCDEFG" // security parameter - optional
      
        json = sh(returnStdout: true, 
                  script: "aws sts assume-role --duration-seconds 3600 --role-arn ${roleARN} --role-session-name rsn ${externalParam}"
      
        def jsonSlurper = new groovy.json.JsonSlurperClassic()
        def object = jsonSlurper.parseText(json)
      
        return object.Credentials
      

      Important points

      • external-id support required
      • credentials must be acquired on the correct instance (you can't always acquire on master as the security configuration is locked down per instance type)
      • credentials expire after an hour (maximum)
      • Access Key ID can be logged, but the other parameters should not be

          [JENKINS-38220] Support for EC2 instance profile credentials

          Dan Farrell added a comment -

          most (all?) modern AWS SDKs will provide some sort of credentials chain that should include, as a final step, checking the metadata service on 169.254.169.254.  That will in turn expose temporary credentials for the instance profile.  If you can set the profile to use the correct role when the instance boots, it can really simplify this logic, because all the SDKs will just use them by default.  

          Dan Farrell added a comment - most (all?) modern AWS SDKs will provide some sort of credentials chain that should include, as a final step, checking the metadata service on 169.254.169.254.  That will in turn expose temporary credentials for the instance profile.  If you can set the profile to use the correct role when the instance boots, it can really simplify this logic, because all the SDKs will just use them by default.  

          Kurt Madel added a comment -

          This should have been resolved with https://github.com/jenkinsci/aws-credentials-plugin/pull/20 - fixed since version 1.22

          Kurt Madel added a comment - This should have been resolved with https://github.com/jenkinsci/aws-credentials-plugin/pull/20  - fixed since version 1.22

          kmadel, that solution still requires IAM role to be specified in Jenkins AWS credentials. EC2 instance profile policy should allow to assume IAM role (Action: sts:AssumeRole). So the idea is to use temporary IAM instance profile credentials directly without assuming IAM role.

          Oleksandr Shmyrko added a comment - kmadel , that solution still requires IAM role to be specified in Jenkins AWS credentials. EC2 instance profile policy should allow to assume IAM role (Action: sts:AssumeRole). So the idea is to use temporary IAM instance profile credentials directly without assuming IAM role.

          John La Barge added a comment -

          Need this as well. 

          John La Barge added a comment - Need this as well. 

          John La Barge added a comment - - edited

          I'v noticed that there is a checkbox that is labeled as "Use EC2 instance profile to obtain credentials" but even if it's checked, if no private key is supplied it throws a NPE.  This seems incorrect or at least confusing to me.  Instead I'd propose that if that box is checked, no private key is required.  

          There are essentially two steps to getting the agent: 1) provisioning the ec2 instance - for which the instance credentials can be used and 2) connecting to the agent.

          If this is required to connect to the agent, that can be internalized instead with a temporary ssh key.  So in that case I would remove the logic that seeks to use the supplied private key and instead generate a key and use it silently. 

          Thoughts (before I start implementing the PR) ? 

          John La Barge added a comment - - edited I'v noticed that there is a checkbox that is labeled as "Use EC2 instance profile to obtain credentials" but even if it's checked, if no private key is supplied it throws a NPE.  This seems incorrect or at least confusing to me.  Instead I'd propose that if that box is checked, no private key is required.   There are essentially two steps to getting the agent: 1) provisioning the ec2 instance - for which the instance credentials can be used and 2) connecting to the agent. If this is required to connect to the agent, that can be internalized instead with a temporary ssh key.  So in that case I would remove the logic that seeks to use the supplied private key and instead generate a key and use it silently.  Thoughts (before I start implementing the PR) ? 

          Ellery added a comment -

          Also please make sure all EC2 metadata calls use the V2 of the IMDS (IMDSV2).  Our security posture does not let us use the less secure older model.

          Ellery added a comment - Also please make sure all EC2 metadata calls use the V2 of the IMDS (IMDSV2).  Our security posture does not let us use the less secure older model.

            Unassigned Unassigned
            bwalding Ben Walding
            Votes:
            5 Vote for this issue
            Watchers:
            11 Start watching this issue

              Created:
              Updated: