Vault login token expiring unexpectedly - spring

We operate a containerized Spring Boot application. In order to access third party APIs, secrets to those APIs are kept in a Vault instance. Our application connects to Vault via Spring Vault Core using token authentication:
spring:
cloud:
vault:
fail-fast: true
...
authentication: token
session:
lifecycle:
refresh-before-expiry: 15s
expiry-threshold: 25s
The token is handed over to our application on startup via an environment variable spring.cloud.vault.token.
The token itself is created as a periodic service token using vault token create -policy=<some policy> -period 4h. It shows renewable=true and has no explicit max TTL. As such, it should never expire if properly renewed during application lifetime. This is handled automatically by Spring Vault's LifecycleAwareSessionManager.
Now in testing as well as in production environments, the generated token in fact expires from time to time even though being renewed before expiry. The remaining TTL that is returned to Spring Vault's renewal attempt shows the TTL is not reset but continues to decrease until the token expires.
Does anyone have a clue why this might happen? Or else: what might cause a periodic service token to expire even though it is properly renewed?

Two different notes:
First, child token cannot outlive it's parent. If the parent token expires, the child token regardless of it's TTL left, will also expire. If you need the token to outlive its parent you need to provide -orphan param when creating the token.
Second, renewable does not mean, you can renew forever, you can keep extending the life of a token UP TO the "max ttl". But that's it. The token will expire. "Renew" does not get you a now token, it simply extends the life of the current TTL. You still cannot get past the max-ttl age limit. My suggestion is not to use service tokens, switch to batch tokens (still will run into maxttl issues) or even better an auth system (approle for example) to get your apps access.
If you're in secure environment (kub pods, or locked VM for example) consider using the Vault Agent. It'll help you to keep your session alive.

Related

How to authenticate google cloud function for HTTP trigger?

I have a function app which is hosted in my GCP project with authentication turned on.
This app will be triggered from Jfrog container registry webhook based on events.
The issue I face here is to authenticate/authorize the HTTP request. I tried using "Authorization: bearer " header, which works good. But that token seems to expire after 60 minutes.
Q: Is there a permanent way(with no expiration) to authorize/authenticate cloud function HTTP requests ? Jfrog webhooks cannot programmatically create tokens since it's a simple HTTP POST trigger which can accept additional headers.
I am finding it hard to get a solution from GCP documentation. I do have the service account created with "roles/cloudfunctions.invoker" role.
Reference about Jfrog artifactory webhooks: https://www.jfrog.com/confluence/display/JFROG/Webhooks
It's for that reason I wrote that article. It's based on ESPv2 and Cloud Run, but API Gateway is the managed version of that technical stack. The principle and the OpenAPI spec is the same.
The solution downgrade the security level from a short lived token (1h) to long lived token (no limit). But you can use API Gateway to ensure the API Key check and query forward.
A much more simpler pattern is to remove the authentication check on Cloud Functions (and make it public) and to perform that API key (in fact a random string comparison) in your functions itself.
In both case, the API is publicly accessible (API Gateway, or Cloud Functions) and, in case of DDoS attack, nothing will protect your service (and your money). Set the correct Cloud Functions Max instance to prevent any bad surprise.

How to get new Client Secret once the old one expires in Azure App?

My Azure App's client secret expiry was set to 3 months which has expired and the application has stopped. My questions are:
How can I get the new client secret to the same Azure App to
replace the new client secret in my NodeJS application?
Also is there a way to get a warning or message/mail before the client secret expire?
How to check the expiry of client credentials without using the Azure portal( that is by using REST requests if any)?
Screen Shot showing expiry in Azure portal. Can we get this expiry somehow by REST requests?
How to check the expiry of client credentials without using the Azure
portal( that is by using REST requests if any)?
You should be able to use Graph API to get this information. The operation you would want to invoke is List applications which will give you a list of application objects. The property you would want to check is passwordCredential for credential expiry.
Also is there a way to get a warning or message/mail before the client secret expire?
AFAIK, there is not an automated way to do this. I believe I read somewhere that Graph API team is working on it but there was no ETA provided for this by them. For now you have to roll out your own solution. You may write a timer-triggered Azure Function which runs daily. This Function can get the list of applications and filter out the applications credentials for which are expiring soon and take action on that.
How can I get the new client secret to the same Azure App to replace the new client secret in my NodeJS application?
Based on your comment, considering you are currently doing this process manually so I would assume you can continue to do so. Once you know that the secret is expiring soon, you can create a new application secret and at appropriate time replace the old secret with the new secret.

maintaining session key with backup services

How is the session key/token is maintained for Resful web service, when the main microservice is crashed and the backup service has to run? in otherwords, how the backup service (all) will get the session details?
Best practice for microservices is, to be stateless.
That means, the service should not cache the session key or token. Session details should be maintained in a caching service like Redis.
And each instance of the microservice is equal. There should be no distinction like "main" and "backup" instance. All instances will have access to the redis cache.
A service request should include the token. BTW, the browser can do this for you.
The servicing instance, which could be any, first query the cache for the session details and then proceed accordingly - redirect to login if none found; validate session validity, access rights etc, if a valid token is found.

Why sharing session to implement SSO is not good?

Why sharing session to implement SSO is not good? I'm learning SSO system.
Thinking about this scenes:
Assume that all http requests to business services is required Login, the business services need verify the requests is login or not by asking SSO service in CAS or SAML. If there are 10 business services, and each service's request is 1k req/s, so the SSO service's request is 10k req/s. It's hard to image the SSO service can hold on.
SO, may be there is a cache mechanism in the business services to verify login token. But when user logout, the SSO service need remove the verify info, and the business services need remove the cache verify info also. I think that's too complicated. The SSO service need tell the business services some people was logout. So why don't all service sharing the login token verify info? Let SSO service write, and other business read. It remind me the sharing the session to implement SSO. And I thought if I can sharing the login token verify info by redis distributed cluster. But I have hear sharing session is not good? So why?
Whether the SSO server can handle that many requests depends on your deployment of it. There are very large deployments of CAS that handle hundreds of thousands of requests. It varies.
In general, the SSO session is entirely separate from your application session. Once you have logged onto the application via SSO, you have established a session for that application that will last for as long as you configure it to last. When it expires, your application may decide to authenticate against your SSO server again. If the SSO server has still an SSO session, it will simply re-issue the appropriate data and your app will recreate the session. If not, it will challenge the user for credentials, whatever they may, and redo the same.
Session concerns of the application are entirely yours and application's concerns. The SSO server should never get involved. If your application has a requirement to share sessions because it's clustered, then you should share sessions. Nobody said it's a bad idea. However, you generally want to make sure your application is as stateless as possible since that will make clustered deployments easier.
When you log out from your application, your app session is gone, but the SSO session may still exist. As a result, you will get right back into the app because there is no need to provide credentials. If you wish, you could log out of the app AND your SSO server.
If you have all other applications logged in via SSO, and you wish to log out of all by logging out of one, this is called SLO. Your SSO server will need to reach out to every app that it has created a ticket for and contact them to logout. Or, you could destroy the shared sessions for all apps assuming they are all part of the same suite.

Why do I need sticky sessions with a Spring OAuth2 JbdcTokenStore?

I would like to use Spring OAuth2 with a load balancer.
I was thinking that if I use
authorized-grant-types="password,authorization_code,refresh_token"
I will just need a JdbcTokenStore and am good to go because each spring server has access to the same DB.
But now I am reading in this github link
Even with these (Jbc) services ... needs to be fronted by a load balancer with sticky
sessions
Why do I need Sticky Sessions with a JbdcTokenStore?
Any session-based interaction would need sticky sessions, since the session data is not shared between servers. For example, when you authenticate the user during the authorization code flow, they are authenticated and a session is created. If you weren't using sticky sessions then the authentication information might be lost between browser interactions with the authorization server. The session will be used to cache their initial request while they are logging in, and will also retain the authentication information while the user checks and authorizes the scope requested by the client.

Resources