GPG keys vs ssh keys vs personal access tokens - security

What are the scenarios where you would use GPG keys vs ssh keys vs personal access tokens.
They seem to achieve the same objective (secure, authorized access to repos); why have three different ways to do the same?
Are there any situations where using one is better than the other?

GPG keys are for signing commits, in the sense that they become part of the Git repository. SSH keys only allow you to temporarily access the repo (push, pull). You can use SSH keys for commit signings, but it's not what it's used for and not recommended [0]
Personal access tokens and SSH keys are also similar but personal access tokens have more restrictions, and one use case for that would be to allow IDE's or third party software to access your repos with restrictions [1].
[0] Some previous related post: GPG vs SSH keys
[1] In what ways is an SSH Key different from tokens?

Related

Is it possible to auth user in third party app with their ssh key used to login?

I'm writing CLI application secured with strong password. The users supposed to run it on a server inside of secured perimeter over ssh. My users complain it's too annoying to enter the password every time.
I'm trying to figure out if it's possible to use user's ssh keys to authenticate them in my app instead of inputting application password. I can't rely on $USER because I want bind authentication to user's ssh keys.
I considered ssh-agent but it runs on user's machine afaik. I'm considering PAM now, but not sure if it's possible to check the keys the user used to authenticate.
Could anyone suggest if it's possible and where to research?
As Martin Prikryl commented, there is no robust solution other then install custom OpenSSH server. More over, there is probably no way to prove cryptographically that the user utilized certain key to log into the system.
Setting up environment variable (in any way) is not sufficient to prove the user actually owns it.

Unable to authenitcate TFS from git command

I use TFS for source control and when I use git command line from new machine, I need to save credentials manager manually. Otherwise, I receive "Authentication Failed"
Is there alternative than pre-defining credentials in credential manager?
Current case from CentOS 7:
The Git Credential Manager which is just used to provide security Git credential storage. It's ok to pre-defining credentials in credential manager.
However for macOS and Linux, instead of using credential manager,
We recommend using SSH keys to authenticate to Azure DevOps,
not a credential manager.
SSH public key authentication works with a pair of generated encryption keys. The public key is shared and used to encrypt messages. The private key is kept safe and secure on your system and is used to read messages encrypted with the public key.
More details please take a look at our official tutorial--Use SSH key authentication
Update
Besides, you could also use PAT token to access git repositories.
To authenticate with the PAT while using Git, you can use it as the password. The username can be anything, since your identity is identified with the PAT. For example:
Username: anything
Password:
Or:
git clone https://anything:<PAT>#dev.azure.com/yourOrgName/yourProjectName/_git/yourRepoName
More details please take a look at this link.
As for how to use PAT, you could refer this -- Authenticate access with personal access tokens
Note: This is only available with TFS2017 version and above. Besides, recommend you keep IIS Basic Authentication turned off when using Azure DevOps Server. When IIS Basic Authentication is enabled on your windows machine, it prevents you from using personal access tokens (PATs) as an authentication mechanism.

Verify ability to login to server via jumpbox for application support (ssh multiple hops)

I am due to go on application support shortly and one of the steps in order to do that is to verify that I can login to all of our application nodes.
In order to login to an application node, you first need to login to a jumpbox, then from here you need to login to the application node.
All login is done via ssh.
ssh user#jumpbox
ssh user#applicationnode
uname -a - > Verified login
This is going to be a neanderthal task that will occur on roughly 1000 nodes.
Consequently I am trying to automate the process.
I have tried using Fabric library in Python, setting up a gateway to point at the jumpbox, but I still get prompted for password, which would take away from the automation.
Is this automated in the industry by any devops tools?
this has two answers: one for the future, and one for now.
Doing automated remote login correctly
In the future you should generate a public/private key pair, and list the public key in your remote user's .ssh/authorized keys. That will make access password-less, if your local SSH uses the right private key to authenticate:
rsa-keygen -t rsa -f deploykey
cp deploykey .ssh/id_rsa
#and insert the content of deploykey.pub into the remote user's .ssh/authorized keys
Doing mass access using password
Now, I don't know which OS you're using, but just assuming you're using a linux or *BSD
http://sourceforge.net/projects/sshpass/ will allow you to non-interactively supply your password.

Automated Code Signing - Protecting the private key

I want to automate the code signing of some ClickOnce deployment artifacts - application exe's and manifests. I am using signtool to accomplish this. In an attempt to make the private key available for signing and yet protect the certificate file containing the private key (.pfx file), my plan is to install the certificate into the local machine certificate store with a non-exportable key. (I am aware that there are ways of exporting the key even if it is marked non-exportable.) The machine is a continuous integration server that will be accessible to a select few. My hope was to set it up in such a way that any time the private key needed to be used, it would require the private key password to be entered. I would then set up an automated job (using Jenkins) which would require a build parameter that would collect the private key password. The Mask Passwords plugin would be used to mask the password while being entered and in the console output.
However, I've run into a couple of roadblocks. First of all, even though there is the "Enable strong private key protection. You will be prompted every time the private key is used by an application if you enable this option." when importing a certificate, it appears to be only available when importing it into the current user store, not the local machine store. Secondly, even if this option were available, the signtool tool doesn't provide an option for setting the password when signing using a certificate in a store. The password parameter, '/p', is only applicable when using a pfx file as the source of the private key ('/f' option). Given that, this doesn't appear to be a viable option. Note: Even if "Enable strong private key protection." is available for certificates in the machine store, my testing shows that attempting to use a certificate with this option enabled just pops up a dialog asking for permission to use it, which obviously wouldn't work for an automated job. I originally thought "prompting" meant it would ask for the password.
One other option I've considered is to create ACLs to secure the private key within a certificate store. This can be done by right clicking on the certificate and selecting All Tasks... | Manage Private Keys... dialog. This would restrict the private key usage to only those authorized. (Note: When a user without permissions on the private key attempts to use it for signing, they get the message "SignTool Error: No certificates were found that met all the given criteria.") However, I don't want to give access to the credentials being used by the Jenkins build service because then any build job would be able to sign code. I could create a job that would execute a script to run the signing command as a specific user. This would require taking the domain user name and password in as build parameters. I could do this using the Jenkins Mask Passwords plugin. I don't really like that, though, because I'm not comfortable that Mask Passwords is sufficient protection against exposing the domain credentials, which, if compromised, would give access to a lot more than just the private key.
If I abandon my original idea of storing the certificate in the machine store, there is the option of placing the certificate pfx file in an ACL secured folder on the build machine that only the build process and signing users have permissions on. Doing that would allow me to create a build job to use the contained private key while not exposing the file to others that have access to the machine. To use the private key, the build parameters would need to collect the private key password.
Finally, there is the option of using a smart card for storing the certificate but we've decided against that.
So, my question is, are there any other ways to do this that 1) protects the private key from being copied, 2) prevents the private key from being used by unauthorized users to sign code and 3), given the private key password is provided by an authorized user, makes the private key for signing by build service?
First of all I will try to answer your questions separately:
Protects the private key from being copied:Only the cryptographic hardware (smartcard or hsm) can really protect the key from being copied. Windows certificate store (even with non-exportable option as you correctly noted) or PKCS#12 (PFX) file provide only the false sense of protection.
Prevents the private key from being used by unauthorized users to sign code:IMO this requires user interaction such as entering password or PIN. If you pass the password as a parameter there is always a possibility that other processes would be able to gain it i.e. from process info, logs etc.
Given the private key password is provided by an authorized user, makes the private key for signing by build service:Cryptographic hardware (smartcard or hsm) accessible via CSP (windows certificate store) with interactively entered PIN should work with signtool without any problems.
I agree that the requirement of user interaction may not be exactly convenient for an automatic build service but you will probably have to choose between secure solution with user interaction and less secure solution without user interaction.
Convenient but less secure solution no. 1: It seems to me that you have already found an acceptable solution because you did not provide any of its disadvantages.
If I abandon my original idea of storing the certificate in the machine store, there is the option of placing the certificate pfx file in an ACL secured folder on the build machine that only the build process and signing users have permissions on. Doing that would allow me to create a build job to use the contained private key while not exposing the file to others that have access to the machine. To use the private key, the build parameters would need to collect the private key password.
However please note that PFX file can be copied undetectably not only from the live system but also from the backups.
Convenient but less secure solution no. 2: Store private key on a smartcard that does not require PIN to be entered and allow system access only to the trusted users. This would ensure that your private key cannot be copied while it would remain easily accessible for signtool. However it would probably require you to have two separate build servers - one without the smartcard accessible to all users and one with the smartcard accessible only to the trusted users.
Inconvenient secure solution: Store private key on a smartcard that requires PIN to be entered and require user interaction (entering of the PIN) during the build process.
You could also consider signing development builds with self-signed codesigning certificate in an automatic mode and signing public release builds with trusted codesigning certificate in manual mode.
The only option left that I see is to use HSM.
You could generate private key protected by operator card/cardset (for example Thales has this sort of HSMs). Operator cardset can be set with a quorum that specifies how many operators have to insert the card before the private key can be usable by application that requested use of this private key. Thales also has a CSP that supports this feature.
The problem might be that the CSP will invoke window to show user that a card has to be inserted (and optionaly password to that card entered). This problem might be solved when you run you build server under some user account with desktop that can be logged into. When you log in as this user and start the build server it has to request the use of private key (for example by signing some dummy file or something). Windows will pop up and operators (as many as required by the quorum) will one by one insert their cards and optionally enter their passwords. After all required cards have been inserted the key will be usable by your build server. Any other application (possibly started by other user) will go through same procedure to use that key. If your build server crashes (do build servers crash? ) you will go through the same procedure.
HSM have also tamper protection so the private key is IMHO safe in there. Sorry for talking about Thales HSMs only but I personally do not have experience with any other HSM.
It seems that relying on a password-protected PFX file, rather than the certificate store, is secure. Even without ACL protection on the hard drive folder where the PFX resides, no-one who takes the PFX file could use it to sign anything, unless they also had the password.
Then, set up a parameterized Jenkins "signing" job on that computer that fully encapsulates the PFX-password so that no-one can see it. (I am contemplating a script of some sort, Powershell maybe, converted to a black-box EXE.) Authorized Jenkins jobs could chain to the signing job to accomplish the signature. The EXE would log every time it was used, as an auditing feature. Just need to figure out how to prevent unauthorized use of the signing job...there must be a way to do that?

Website access based on ssh keys?

Is there a way to restrict access to a website based on ssh keys? Exactly the same way ssh works:
If you have a key, access granted -- no password
If you don't have a key, access denied
If not, what is the best alternative that would satisfy the above conditions? Would I be better off using htuser? I can't restrict access based on IP addresses because the people accessing the site will most likely not always have the same IP.
Sure, using Mutual-SSL-Authentication you can secure your website using SSL certificates.
I don't know your environment, but here's a pretty detailed writeup on how to perform mutual authentication on Tomcat.

Resources