managing jenkins credentials by users/roles - jenkins

I am currently trying to find a way to allow only certain users to use stored credentials in jenkins. I have not found a way to do this using the credential plugin. I am using the role based Access plugin as well.
is there a way to create credential domains that can only be accessed by allowed users?
how can a user use the credentials that they provide in their own "user profile" configuration area?
Is this possible ? or is there another plugin that can do this.

Not to miss an obvious answer - undocumented, but easy enough to figure out.
It only works for ssh/sftp access.
Edit a job.
Mark it "parameterized".
Add a parameter
type: credential
named my-ssh-private-key
Mark "SSH agent"
parameterized credential = ${my-ssh-private-key}
Enter ssh my_host "echo Hello world" as job's batch script action
Try to build the job. You would be asked to choose credentials, and here, lo and behold, you can pick also your private credentials amongst the global ones. But other users can only run this job if they have their own authorized ssh private key (with public part included in the remote authorized_keys).
If you have "host key verification" error, just go to jenkins shell to fix:
su - jenkins
ssh my_host # confirm the host key to be saved into your known_hosts
tail ~/.ssh/known_hosts

Related

Why is a Jenkins script job failing to use proper AWS credentials?

I have a simple jenkins job that just runs aws ssm send-command and it fails with:
"An error occurred (AccessDeniedException) when calling the SendCommand operation: User: arn:aws:sts::1234567890:assumed-role/jenkins-live/i-1234567890abc is not authorized to perform: ssm:SendCommand on resource: arn:aws:ssm:us-east-1:1234567890:document/my-document-name"
However, the IAM permissions are correct. To prove it, I directly SSH onto that instance and run the exact same ssm command, and it works. I verify it's using the instance role by running aws sts get-caller-identity and it returns arn:aws:sts::1234567890:assumed-role/jenkins-live/i-1234567890abc which is the same user mentioned in the error message.
So indeed, this assumed role can run the command.
I even modified the jenkins job to run aws sts get-caller-identity first, and it outputs the same user json.
Does jenkins do some caching that I am unaware of? Why would I get that AccessDeniedException if that jenkins-live user can run the command otherwise?
First, install the AWS Credentials and AWS Steps plugins and register your AWS key and secret access key in Jenkins credential store. Then, the next steps depends if you're using a freestyle or a declarative/scripted pipeline.
If you're using a freestyle pipeline: On "Build Environment", click on "Use secret text(s) or file(s)" and follow the next steps. After that, you're gonna have your credentials as variables in your pipeline;
If you're using a declarative/scripted pipeline: Enclose your aws calls with a withAWS block, something like this:
withAWS(region: 'us-east-1', credentials: 'my-pretty-credentials') {
// let's explode something
}
Best regards.

Accessing a Username with Password Credential Parameter from a Jenkins Execute Groovy build step using Groovy command?

Software levels:
Jenkins 2.121.2
Credentials Plugin 2.1.18
Credentials Binding Plugin 1.16
Plain Credentials Plugin 1.4
I am working with a Freestyle project (not a pipeline) and want to use a Groovy command build step for the job's main processing.
I am trying to obtain the userid and password from a user credential so the groovy script can use them for various CLI manipulations. I spent a lot of time searching for answers, but none of the ones I've found worked. Most were not clear, many were geared toward pipelines.
I would greatly appreciate a little guidance at this point.
Here are the gory details.
I created a new parameterized Freestyle project in which I added a Credentials Parameter for a "Username and password" credential. It defaults to one of the credentials that I defined to Jenkins via the Credentials Plugin. I'm not sure this is necessary if the binding selects the credential to use explicitly.
I checked "Use secret text(s) or file(s)" in the Build Environment section, although I'm not certain that is essential for a Username/password style binding.
I added a "Username and password (separated)" binding and set USERID and PASSWORD as the respective variables.
My groovy command window has this sole line:
println("${USERID} ${PASSWORD}")
When I build the job, I get this error:
The both ways will inject the credential into Environment Variable, thus you can access them from Environment Variable in Groovy Script as following for both ways.
def env = System.getenv()
println env['auth']
println env['USERNAME']
println env['PASSSWORD']
But the injected value of the both ways are different.
1) Adding a Credential job parameter for user to choose when run job
In this way, the credentialId is injected, so you not get the username and password.
credentialId example: 1dd4755a-9396-4819-9327-86f25650c7d7
2) Using Credential Bindings
In this way, the username and password are injected, I think this is what you wanted.
def env = System.getenv()
def username = env['USERNAME']
def password = env['PASSSWORD']
def cmd = "curl -u $username:$password ...."
Add a Jenkins Build Step supply by plugin Execute Groovy script
To summarize, the techniques identified by #yong's post will only work with System Groovy Script build steps. The latest plugin and Jenkins levels will obfuscate the credential parameters, so println cannot be used to verify their content by visual inspection.

How to configure jenkins slack plugin?

I tried to configure jenkins slack plugin to send a notification to slack channel. But it doesn't work. I followed below instruction:
1. Get a Slack account: https://slack.com/
2. Configure the Jenkins integration: https://my.slack.com/services/new/jenkins-ci
3. Install this plugin on your Jenkins server.
4. Configure it in your Jenkins job (and optionally as global configuration) and add it as a Post-build action.
After I install jenkins on slack app there is a instruction about how to configure jenkins. But the configuration fields mentioned on the instruction is a little different than my jenkins configuration.
Below is the configuration screenshot from the instruction:
the configuration for my jenkins server looks like below:
how can I fill in the Base URL in my configuration? I have tried to fill in my jenkins url but it doesn't work. The test connection failed.
I get below error in jenkins system log:
Slack post may have failed. Response: <html><head><meta http-equiv='refresh' content='1;url=/login?from=%2FOPRc9G4zB2JX289VOnTvfeey'/><script>window.location.replace('/login?from=%2FOPRc9G4zB2JX289VOnTvfeey');</script></head><body style='background-color:white; color:white;'>
Authentication required
<!--
You are authenticated as: anonymous
Groups that you are in:
Permission you need to have (but didn't): hudson.model.Hudson.Read
... which is implied by: hudson.security.Permission.GenericRead
... which is implied by: hudson.model.Hudson.Administer
-->
I have tried to leave base url empty but still doesn't work
After a lot of testing, I figured out the problem. The issue relates to the configuration panel for slack. When I change the slack configuration and hit the test button, it doesn't take the current configuration, instead, it takes the previously saved configuration. I have to save the configuration first then test the connection.
Base URL doesn't need to be filled. Try from Specific Project. Only supply Team SubDomain in Global setting.
You have to provide these info separately for every project:
Team Domain/Sub-Domain
Integration Token(Taken from the Browse Apps > Jenkins CI)
Channel Name
For each Project that you would like receive notifications for, choose Configure from the project's menu in Jenkins.
You'll also need to add Slack Notifications to the Post-build Actions for this project.
Provide the Channel name, Team Subdomain and Integration Token there.
Test the connection.
you can directly run a POST build shell script per project basis or per slack channel
#!/bin/bash
curl -X POST --data-urlencode 'payload={"text": "'"$SLACK_MSG"'"}' $SLACK_WEB_HOOK_URL
where $SLACK_WEB_HOOK_URL and $SLACK_MSG can be exported as env variables or hardcode it for each project
Hay,
you have to add you integration Token to your Jenkins(I would recommend to add a Credential ID but its not necessary), that should sole your Problem. Keep in mind that your Jenkins just can send Messages to channels, the Account which generated the token has access to.
As said previously, you dont have to add a Team-Domain and your Subdomain has to be the following part of your Slack link:
www.EXAMPLE.slack.com
Hopefully i was able to help

Jenkins: ansible host not reachable

I am trying Jenkins to execute an ansible playbook.
But I am getting the unreachable host error which I don't get otherwise.
fatal: [vogo-alpha.cloudapp.net]: UNREACHABLE! => {"changed": false, "msg": "Authentication failure.", "unreachable": true}
I have given this variable in ansible hosts file,
ansible_ssh_private_key_file=/home/luvpreet/.ssh/id_rsa
I think it is because the user jenkins is playing those playbooks and it cannot read this private key file. I tried to make jenkins' user home folder but it was not successful.
It can be done if I switch to the user luvpreet and then run these playbooks.
How do I switch to another user via jenkins shell ?
OR
Is there any other way this problem can be solved ?
There are a couple of possibilities why your solution is working. Most likely because Ansible is trying to ssh to your target machine as the jenkins user which isn't on said machine. I'd approach the problem from a different angle.
First, I'd install the Ansible plugin for Jenkins. This allows you to use the built in credentials located at "Manage Jenkins > Manage Credentials". There you can copy and paste your key in (or point to a key file located on the jenkins server) and set the username that will ssh to the target machine. In your job configuration choose "Invoke Ansible Playbook" for your build step rather than shell. There will be a "Credentials" parameter where you can specify the ssh key you added earlier. The rest should be pretty self explanatory.

Jenkins User's authorization to deploy

I wanted to have 2-factor authentication in Jenkins for all the users (even super admin) and wanted to know, if it's possible and if it is, what is the possible way or do we need a plugin for it.
Plus can we have authorization for scheduling the deployment in Jenkins and if it's possible, how can we do it.
Jenkins authorization is explained in detail here:
https://wiki.jenkins-ci.org/display/JENKINS/Standard+Security+Setup
The "Authorize Project plugin" is not for what you are asking.
You will not be prompted for password everytime you start a job. Instead, you should configure individual jobs to give access to individual people. Jenkins allows that granularity.
If you really want to prompt for password at every job execution, you will have to configure job to create a new password parameter, and then as one of your first build steps, validate the entered password against... against whatever it is that you want. But that means your validation script will probably reside on Jenkins itself.
Edit:
Configure Job
Select "This build is parameterized"
Add "String" parameter
Call it "password"
If on *nix environment, select "Execute Shell" for the first build step:
set +x
if ! [[ "$password" == "mysecret" ]]; then
echo "Bad password"
exit 1
fi
exit 0
If on Windows environment, select "Execute Windows batch command" for the first build step:
#echo off
if not "%password%" == "mysecret" (
echo "Bad password"
exit /b 1
)
exit /b 0
Add other build steps as normal.
Now, every time the job runs, it will prompt for "password", and if it doesn't match string "mysecret", the job will fail.
Important Notes:
This will run after SCM checkout. If you want to run it before SCM checkout, you'd need Pre-SCM build step plugin.
Anyone with "Configuration" access to the job permission or above will be able to see the "mysecret" in plain text. You can use EnvInject plugin to configure global (or job local) password and validate against that variable, instead of "mysecret"
Anyone with direct/remote login to the Jenkins machine will be able see the configuration file with "mysecret" in plain text (unless using EnvInject from above).
People with enough permissions could modify or copy the job, and remove this validation.
Once again, I implore you that the correct approach is to provide granular per-user permissions through default Jenkins security/authorization. Use "matrix" authorization to give permissions per user per job.

Resources