Hashicorp Vault client best practise - security

I have an application using Hashicorp Vault to store a username and password secret. The application is deployed to a cloud hosting platform and passed a token as an environment variable. On application start the secret is read from vault using the token and used to open a session to a remote service. The application and session to the remote service are long lived. If all goes well the application rarely restarts and therefore rarely reads from vault. When the application does restart the token will likely have expired resulting in failure.
Is there any best practice guidance for how clients should use vault? The token lifetime could be extended but the longer the lifetime the more compromised the security. The application could reestablish the session with the remote service every time it is needed but this would be inefficient. Is there another alternative I’m not considering? Any thoughts would be appreciated.

You should use App Roles instead of passing in a plain token. In this, you bake a role id into your app, and then deploy a secret id for that role in your environment variable.
Your app can then combine these to get a real token from Vault on startup, and periodically renew that token as it is running.

Related

Why are there multiple client secrets for each azure client id?

As I understand it, the idea is that azure allows the registration of multiple applications (client ids) each with multiple secrets.
I (think that I) get the part of multiple applications registrations, since each app would get fine-grained access control.
The question then is why would it be possible to create multiple (client) secrets for the same application (client) id?
Don't all the secrets provide the exact same access (since they are all bound to the same application/client id)?
Why would someone need even a second (client) secret?
Correct, all secrets have the same access as they are similar to passwords for a user.
The point is that secrets expire, and having more than one allows you to rotate them.
Before secret 1 expires, create new secret 2
Update application with secret 2
Remove secret 1

What does the Google Client Secret in an OAuth2 application give access to?

I am implementing a login flow which uses the Google Client ID and Google Client Secret. I am considering the security implications of the Google Client Secret and who should be able to have access to it.
Currently the Client secret is stored in an environment variable, but I would like to know what someone with access to this secret could do with it to determine which developers should have access to this environment variable and if I should setup a different OAuth2 application in development vs production.
Client id and client secret are similar to a login and password. They give your application the ability to request consent of a user to access their data. If you are storing refresh tokens it would also give the user access to create access tokens from your refresh tokens.
Googles TOS states
Asking developers to make reasonable efforts to keep their private keys private and not embed them in open source projects.
You should not be sharing this with anyone. It should only be used by you and your developers.
Yes Ideally you should have a test and production client ids. Test client id can be used by your developers the only one who should be using your production verified project client ids is your production environment. I would store them in some for for secrete store personally.
It depends on which type of OAuth application you specified.
When creating an OAuth client ID in Google Cloud (and with that, a client secret), you are asked to specify the type of application you are creating:
If you choose Web App, your client secret should really be secret, as its treated as such by Google and is used to authenticate your own server. You should therefore hide it and especially not include it in open sourced code.
However, there is also the option of creating a Desktop app, which means you want to use OAuth without having your own server. For this case the documentation by Google says:
The process results in a client ID and, in some cases, a client
secret, which you embed in the source code of your application. (In
this context, the client secret is obviously not treated as a secret.)
So in this case it's fine (even required) to include the client secret in your app for your users.

How do we run automated testing when using OAuth2 and Azure AD

Our scenario is that we have an API which is currently only secured by a subscription key in APIM.
We plan to change this to also secure it with OAuth 2 following this guidance from Microsoft, we will then use the JWT validation policies within APIM to ensure that the user requesting access is a member of the appropriate groups to access given endpoints etc.
However as part of our release process we need to run some automated tests which call the API and check that certain data is returned.
Because these tests are run as part of an automated release pipeline we are struggling to understand how OAuth will fit into this process - as a user is required to enter credentials for a token to be issued...
We originally thought that we could just request a token manually once and then hard code it into the tests, but as tokens are only valid for a short time this isn't a good solution.
Other things we are considering are :
Creating a "test user" in AD and storing their credentials in the test project and then when the tests run we can request a token using the "Password" grant type and passing the username and password" however this doesn't seem like the best from a security point of view, even though the user would only have access to a very limited subset of the APIs functionality it still doesn't seem like a good practice.
Requesting a token using the client secret, however the downside to that is this is that the JWT does not contain the groups claim so this token will not pass JWT Validation.
This must be something that others have encountered? What is best practice in this scenario?
As you can see in the article you reference, you will be using Azure API Management to be the entry point to access your API. So, using the API Management you will have subscriptions with keys for your API. You just need to create a subscription for your automated testing, and save the key in the Azure Key Vault. And then during the deployment, you pull your subscription key from your Key Vault, and use it to call the API Management Endpoint, that consequently will call your API.
The solution that we went with in the end was to create a new App Registration for the Test project, then in APIM we added a rule so that the JWT policy is not applied to connections from that app.
Might not be the best solution but it works.

authenticating a python script to be able to use a signing key from Key Vault

HTTP/Rest - need to authenticate a code/token/etc in order to pass data to keyvault so that keyvault will sign data with a key in the Key Vault.
Azure has quite a few docs on how to register my app, create credentials for it in the key vault, but then for it to authenticate via OATH2 (first step is getting a code, (then later, a token?) via REST) I keep getting redirected to log in.
Am I missing something? I want my python script to run unattended. I have created its ID and wrote down the plaintext password it gave me that it warned would never be displayed again. Not sure how to use REST in this case as I really cannot auth to any application, I dont really even have any application - the Azure people told me to just put ANY url in the box when I registered the APP in AAD.
You need to use client credentials flow. In this flow you send your credentials to AAD and it'll send you back a token. Then you can call Key Vault with that.
V1: https://learn.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-client-creds-grant-flow
V2: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow

Using JWT with Active Directory authentication in NodeJS backend

I am building an intranet web application consisting of an Angular frontend and a Node.JS backend. The application needs to use the corporate Active Directory for authentication and authorization.
I'm considering how to best implement this in a secure way. I am planning to use the Active Directory node module for actually communicating with the AD to authenticate when the user logs in, and to check security group membership for certain restricted actions, etc.
However, I am not quite sure what is the best way to authorize my backend endpoints. The AD module does not offer any token/ticket, even though I suppose Kerberos is used for the actual authentication process. In other authenticated apps I've developed I've generated a jsonwebtoken when the user logs in, and then passed and verified that token in each backend route, is that a good idea also when authenticating against AD?
EDIT: Second part of question spawned to separate thread: Best practices for server-side handling of JWT tokens
Also, I have a more general concern, regarding what the best practice is for actually verifying tokens. Suppose that the "secret" used for JWT generation is compromised (in my scenario many people may have access to the source code of the system, but not to the system itself). Am I right in believing that a malicious user could then, with only this information, generate a token on behalf of any given user, and without ever authenticating with AD use that token in my API requests? A token is typically generated using jwt.sign(payload, secretOrPrivateKey, options).
Alternatively, suppose a malicious user could get hold of an actual token (before it has expired). To me it seems like instead of having to know a user's username and password, the security is now reduced to having to know the username and the JWT secret. Is this a valid concern and what should I do to prevent this?
My best hope so far is using a server side session to store information about the current user after logging in, so that even if a token is maliciously generated and used when accessing backend endpoints, it would fail unless the user has actually gone through the login route, authenticated with AD and stored some information in the session as a result of this.
I also considered actually authenticating with AD in each API endpoint, but that would require the AD username/password to be sent in every request, which in turn would require that sensitive information would have to be stored in the client's sessionstorage or localstorage, which is most likely a bad idea.
So, questions:
1) Is it reasonable to combine AD authorization with JWT as bearer token or what is the preferred way to build a secure backend + frontend utilizing AD for authentication?
2) If JWT is a good idea, what is the best practice for securing endpoints using JWT? Is using a server side session reasonable?
Interestingly enough I have found tons of examples on how to best implement token based authentication (in general, or with NodeJS specifically), but many of them seem flawed in one way or another.
1) Is it reasonable to combine AD authorization with JWT as bearer
token or what is the preferred way to build a secure backend +
frontend utilizing AD for authentication?
It is reasonable, but if you are already using Kerberos and AD to initially authenticate the user, you might consider using s4u2proxy constrained delegation which allows the service to present the user's service ticket to the KDC and acquire (subject to authorisation checks) a ticket for a backend service (and repeat for as many services are necessary).
If you have a lot of backend services that need to be contacted, a single JWT bearing all the authorization claims needed for all the services to enforce authorization policy may be a better option.
2) If JWT is a good idea, what is the best practice for securing
endpoints using JWT? Is using a server side session reasonable?
General key security practices apply:
Never store keys in the clear in non-volatile storage, anywhere.
Ideally do not store encrypted keys in attached storage on the server where, if the server is compromised, they would be subject to offline attack. Make them available to the host only at server startup.
Ensure key material resides in secure memory so that it cannot be swapped to disk (and/or use encrypted swap).
Use public key algorithms so that no secret key need exist on multiple hosts.
Consider using a hardware security module (HSM).

Resources