Hey! We're on the Essentials plan, with cache enab...
# ory-network
a
Hey! We're on the Essentials plan, with cache enabled, and I recently noticed that the whoami call will hit cache for a while after the user account is deleted. Based on some cookies, I guess that your cache lifetime is ~260,000 seconds, so it is definitely forcefully expired by something on your side. It just seems like this expiration can take a few minutes. Is that correct? Is there something we can do to expire this cache faster? Long story short, we have a use-case where (for specific users), we grant them access to our application temporarily and then their access is revoked and accounts deleted. Think about it as a short "demo". We would like them to lose access as soon as their account is deleted - for that, we periodically check whether user's credential is still valid. Due to the nature of our system, it's important that access is revoked pretty quickly. It looks like the whoami call will return cache-HIT success for a while after the account was deleted. This could be a 1 minute delay but we also got reports of it going above 5 minutes. 1 minute is probably fine. 5+ minutes is a bit much. Do you have any advice how this could be improved?
p
Hi @acoustic-insurance-23566 I would need to verify with the rest of the team, but maybe you could try invalidate the session through the admin endpoint before deleting the account? https://www.ory.sh/docs/kratos/session-management/list-revoke-get-sessions#revoking-a-session
a
Thanks @proud-plumber-24205 for getting back to me. I tried to deactivate all of the user sessions or the individual session before deleting the account and the behaviour is similar, although perhaps a bit better and the cache invalidation triggers a bit quicker. I have also observed some inconsistent behaviour - after the account has been deleted or session deactivated some requests would fail authentication and others would pass. Example requests log attached for a case where I deleted the user account.
list
is a request to our backend where our backend will authenticate the user, it's issued every 10 seconds (think of it as a heartbeat).
whoami
is direct call to Kratos. In this example, I have deleted the user account after the second
list
request after the first
whoami
request. After that, you can see a few successful
list
requests, a failed
list
request, a successful
whoami
request, successful
list
request and further failed
list
requests.
Similar example here for deleting the specific session. Similarly as above, I deleted the session after the second
list
request after the first
whoami
call. Here you can observe that
list
requests started to fail immediately (good) but subsequent
whoami
call succeeds along with a few
list
requests further down.
I'll also add that the user is in EU, whereas our backend is in the US
For comparison, this is the behaviour with edge caching disabled. Same as above, the account was deleted after the second
list
call after the first
whoami
call. This is pretty much what I'd expect. I understand there might be some eventual consistency mechanism to invalidate the cache, but it looks like it takes you more than 2 minutes to reach consistency, which feels a bit much...
s
in our cache we basically serve the cache, but start a background call on every request to update the cache it depends however what worker you hit
so the best way to "force" an update is doing more whoami calls
alternatively, you can also disable the cache, or force not using the cache in some cases (demo only) by setting the cache control header
h
I need to correct that - the best way to force fresh cache is to set the max-age header:
Copy code
ory.toSession(undefined, undefined, {
  headers: {
    "Cache-Control": "max-age=10",
  },
})
Flooding the whoami endpoint with additional calls is NOT the best way to invalidate the cache! In fact, it might lead to issues.
a
This seems reasonable, thank you @steep-lamp-91158 and @high-optician-2097!
I'm actually struggling to get this working. Here's more or less what I'm doing (if it matters, in a Vue.js frontend app)
Copy code
import { Configuration, FrontendApi } from "<@U010S8T03NG>/client";
const kratos = new FrontendApi(
    new Configuration({
        basePath: KRATOS_HOSTNAME,
        baseOptions: {
            // Ensures we send cookies in the CORS requests.
            withCredentials: true,
        },
    })
);
const test = await kratos.toSession(undefined, undefined, {
    headers: {
        "Cache-Control": "max-age=60",
    },
});
but this throws a build error
Copy code
(...).ts:36:54 - error TS2554: Expected 0-2 arguments, but got 3.

 36         await kratos.toSession(undefined, undefined, {
                                                         ~
 37             headers: {
    ~~~~~~~~~~~~~~~~~~~~~~
... 
 39             },
    ~~~~~~~~~~~~~~
 40         });
    ~~~~~~~~~


Found 1 error in (...).ts:36
TS hints that the method signature is
FrontendApi.toSession(requestParameters?: FrontendApiToSessionRequest | undefined, options?: AxiosRequestConfig | undefined): Promise<AxiosResponse<Session>>
If I try like
Copy code
await kratos.toSession(undefined, {
    headers: {
        "Cache-Control": "max-age=60",
    },
});
it builds and makes the request, but it is stripped of some other headers so it causes a CORS error. It looks like I have version
1.2.11
of the SDK, which is the latest 🤔 attached screenshot of how this
/whoami
request looks like, we're using the Ory Tunnel for local dev here. The request works fine if I call it without arguments, like
kratos.toSession()
or even
kratos.toSession(undefined)
@steep-lamp-91158, would you perhaps have any suggestion for the above? Thanks in advance 🙂
s
I guess
transformRequest
would be a way to extend the already set headers, instead of replacing all
a
Thanks @steep-lamp-91158 for the suggestion. It looks like my analysis was wrong, the headers are fine - the request fails the CORS check I attach a screenshot showing basic consecutive
fetch
requests, one with the extra header and one without. A plain
fetch
request works fine - returns a 401 as expected. But if I add the
Cache-Control
header to the request, the request is blocked by CORS policy. The result is the same if I am logged in and set the
credentials: "include"
option. Then I get a correct 200 without the extra header and a CORS error if I set the
Cache-Control
header