Secret Id and client token rotation in Hashicorp vault - spring

I am using approle authentication type which takes in role-id and secret-id along with root token in the header to generate a client token which can further be used as an auth token in the header to create and retrieve secrets. This is what happens internally when using spring cloud vault I guess. Correct me if I'm wrong.
Now, I need to rotate my secret-id for every 30 days and the client token for every 24 hours. How do I achieve this? Does spring cloud vault provides an inbuilt library to do this? If not where should I make the changes?

You need to do the equivalent of a vault write -f auth/approle/role/my-role/secret-id to get a new secret id. Where you do this is where it gets interesting...
I assume you already have a Vault policy that allows you to generate a new secret_id. Make sure that the role_name parameter is fixed to your application current role. Chances are you will want to limit the metadata, too.
I would suggest this pattern:
Something (a pipeline or scheduled job of some kind) creates the new secret-id. Bonus points if it is wrapped and single use, but let's save that for another question.
That something will store the secret-id in a secure place. Could be in the Vault KV version 2 store where the application can read.
After creating the new secret-id, that something lists the secrets and keeps the N most recent secret ids. Say the last 5. This makes the process asynchronous and allows running applications to keep going.
Now in your application, you must have a periodic task that looks up the latest secret id and reauthenticates to Vault with it.
If possible, I would suggest that you avoid the problem altogether and use the authentication method provided the platform your are on, it Vault supports it, like GCP, AWS or Kubernetes.

Related

How to distribute / Where to store keys that applications need to access HashiCorp Vault

We want to use HashiCorp Vault to save the passwords used by our applications.
What is not clear to me is, how to distribute/ where to store the keys our applications need to access the vault in a secure way.
I think this issue is not addressed by the vault documentation. At least,
I couldn't find it. But clearly, it should by a problem every vault user has to handle.
Can someone give me a hint or provide an external tutorial, please?
Thx in advance!
What you need to figure out is what Authentication method is available to you.
https://www.vaultproject.io/docs/auth/index.html
For example, if you are running your app in AWS, you could be using iam to authenticate. In this case, you dont need to provide anything to your application as its handled behind the scenes from Vault and AWS.
Another way would be tokens authentication where you'd need to provide your application a valid Vault token so that it can be used to get credentials.
This has more information about auth.

How to properly set up config files for sensitive credentials?

I am currently developing a backend application with spring-boot which has access to a database. The login credentials for the database are stored in a file called application.properties which is just an example for spring-boot but this has to be similar to other technologies I presume.
I was wondering whether this is the state of the art to store sensitive credentials or if there is another (better, safer) way to store this kind of information? What kind of techniques exist for such challenges?
Surely you do not want to push these config files to any versioning repositories and such but is it "safe" enough to store it this way?
One could argue that if someone has access to the code of your backend application you have other problems but I am still curious.
The argument that you use is correct. Let's say that one option is encryption. Even if you encrypt your credentials, the application will use the private key to decrypt, right? And if the server is compromised, the attacker could read the source code, find the private key and decrypt the credentials.
One way of making it more secure is using a request to collect the credentials. It could be done by an REST request (An API that could provide you the credentials to the application through a request).
And the most secure way is using a Password Vault. This post has good content about it.

Authentication using Using DIrectMail SDK?

I want to use the Direct Mail SDK(Java) directly within client application which is distributed across. The way to authenticate users within the application, I need to provide access keys as below,
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", "<your accessKey>", "<your accessSecret>");
How can I prevent user to know the Access Keys and still prevent the need of third-party API? Is it possible?
First, it is bad practice to code an application that requires secrets that runs on the client. You should manage everything on the server and provide an API that the client software interfaces with.
Second, there is no way to hide those credentials once passed to the client. You could encrypt the credentials but at some point the client application will need to decrypt them. Even amateur programmers can figure out how you are processing your credentials.
Ignoring the above advice, Alibaba Cloud supports STS which provides temporary access keys. Using your Alibaba credentials, you would call AssumeRole which creates temporary access keys giving the user permission call DirectMail. You can limit the time that the credentials are valid. The range is 900 to 3600 seconds. After that duration the keys become invalid.
Keep in mind that 900 seconds is a long time. A bad actor getting access to those keys could send thousands of emails using your account. Therefore implement strong user authentication, STS and temporary access keys.
If you think that just keeping your interface secret is enough, don't. There are millions of script kiddies on the Internet poking at every IP address. Launch a new ECS instance and you will see attacks within hours.
As you said since it is a Java Web Application(assuming), currently I think of something using similar to JBOSS Vault to store the access keys securely.
If it is some standalone client application still you can use some encryption methodologies to store the data. But this will only prevent easy access to the data/keys. But it is not impossible. The best bet would be creating another third-party API

Web API Application consumes endpoint, which needs periodic password changes - how to automate?

Our web application, WebAPI2, consumes an external endpoint. The external endpoint requires periodic password changes, so we would like to automate it, with the passwordChange endpoint it also has.
To prevent this being a manual job, we'd like to automate this. What would be the best way to accomplish this periodically from my own application web api?
So the 2 things I wonder about are:
How can I trigger it? (The requirement is every 90 days, but there's no reason why we couldn't do it more often.)
Where best to store it? config/Database/another
Thanks.
You could create a scheduled task on the server that runs ever 90 days, generates a new password and then simply encrypts that password and saves it to your database.
The WepApi then just needs a way of pulling the password from the database, decrypting it and using it when calling the external endpoint.
I wouldn't be modifying the web.config in this manner nor would i ever store passwords in a txt file.

What are the best ways to store a secret key in Parse cloud?

Normally I would add the secret key as an environment variable, but what is the best way to do it in Parse?
The Parse config functionality doesn't solve my problem because the secret key would be available on the client side. There are not security mechanisms to prevent access to specific config variables.
The only solution I can think of, is creating a class to store this really sensitive information and add security so it can not be accessed from a client application (or by certain users).
I don't love this solution because it adds extra requests each time the secret key is needed, which is bad in terms of response time and request usage limits/cost.
In AWS ..
You can use role based authentication using AWS SDK, where it get the role of you resource (ECS, EC2) and retrieve access and secret key from resource registry.
which is a similar implementation you mentioned in your post. That is quite helpful to provide security for your access key and secret, where you don't have to parse or get it from ENV as that can be compromise any time.
Also resource registry based key keep on changing over time so if anybody gets that also can't use it.
You can try to check the implementation how AWS resource / role based authentication works for AWS SDK.

Resources