The logout flow allows users to terminate their sessions and sign out of the application. Kratos supports both browser-based logout with cookies and API-based logout with session tokens.
Flow types
Logout is handled differently for browser and API clients.
Browser logout
For browser applications using session cookies:
Create logout flow
Initialize a logout flow to get the logout URL and token: curl -X GET \
'https://{project}.projects.oryapis.com/self-service/logout/browser' \
-H 'Cookie: ory_kratos_session=...'
Response: {
"logout_url" : "https://{project}.projects.oryapis.com/self-service/logout?token=abc123..." ,
"logout_token" : "abc123..."
}
Visit logout URL
Redirect the user’s browser to the logout_url or submit the token: curl -X GET \
'https://{project}.projects.oryapis.com/self-service/logout?token=abc123...' \
-H 'Cookie: ory_kratos_session=...'
The session cookie is invalidated and the user is redirected to the configured return URL.
Query parameters:
return_to - URL to redirect to after logout
API logout
For native applications using session tokens:
curl -X DELETE \
'https://{project}.projects.oryapis.com/self-service/logout/api' \
-H 'Content-Type: application/json' \
-d '{
"session_token": "your_session_token"
}'
Response: 204 No Content
The session token is immediately revoked.
A 204 response is returned even if the token was already revoked. This prevents leaking information about token validity.
Flow initialization
Browser flow initialization
Create a logout URL:
curl -X GET \
'https://{project}.projects.oryapis.com/self-service/logout/browser?return_to=https://your-app.com' \
-H 'Cookie: ory_kratos_session=...'
Error cases:
401 Unauthorized: No active session exists
400 Bad Request: Invalid return_to URL
Direct logout (browser)
Skip flow initialization by using a logout token from the session:
curl -X GET \
'https://{project}.projects.oryapis.com/self-service/logout?token=<logout_token>' \
-H 'Cookie: ory_kratos_session=...'
The logout token is included in the session response from /sessions/whoami.
Configuration
Configure logout behavior:
selfservice :
flows :
logout :
after :
default_browser_return_url : https://your-app.com/login
allowed_return_urls :
- https://your-app.com
- https://app.example.com
Security considerations
Logout token validation: The logout token in the URL must match the logout token in the session cookie. This prevents CSRF attacks where an attacker tricks a user into logging out.
Token validation
When processing a logout request, Kratos:
Extracts the logout token from the query parameter
Fetches the session from the cookie
Compares the tokens
Only proceeds if they match
Return URL validation
Return URLs are validated against configured allowed domains to prevent open redirects:
selfservice :
allowed_return_urls :
- https://your-app.com
- https://subdomain.your-app.com
AJAX logout
For single-page applications, use AJAX with JSON responses:
fetch ( 'https://{project}.projects.oryapis.com/self-service/logout/browser' , {
credentials: 'include' ,
headers: { 'Accept' : 'application/json' }
})
. then ( res => res . json ())
. then (({ logout_url }) => {
// Option 1: Redirect to logout URL
window . location . href = logout_url
// Option 2: Call logout URL with fetch
fetch ( logout_url , {
credentials: 'include' ,
headers: { 'Accept' : 'application/json' }
})
. then (() => {
// Logout successful - 204 response
window . location . href = '/login'
})
})
Complete examples
Browser logout
API logout
Browser with SDK
API with SDK
# 1. Get logout URL
curl -X GET \
'https://{project}.projects.oryapis.com/self-service/logout/browser?return_to=https://your-app.com' \
-H 'Cookie: ory_kratos_session=...'
# Response:
# {
# "logout_url": "https://{project}.projects.oryapis.com/self-service/logout?token=abc123&return_to=https://your-app.com",
# "logout_token": "abc123"
# }
# 2. Visit logout URL
curl -X GET \
'https://{project}.projects.oryapis.com/self-service/logout?token=abc123&return_to=https://your-app.com' \
-H 'Cookie: ory_kratos_session=...'
# Browser is redirected to https://your-app.com
# Session cookie is cleared
Error handling
401 Unauthorized
403 Forbidden
400 Bad Request
Cause: No active session exists.Solution: User is already logged out. Redirect to login or home page.
Cause: Logout token doesn’t match session token.Solution: Initialize a new logout flow to get a valid token.
Cause: Missing or invalid logout token in URL.Solution: Ensure the token parameter is included and valid.
Session revocation
When a logout completes:
The session is marked as revoked in the database
Session cookies are cleared (browser flows)
The session token becomes invalid immediately
A SessionRevoked event is emitted (available in event streams)
CSRF protection
Browser logout flows are protected against CSRF:
The logout token acts as a CSRF token
The token must be present in both the URL and session cookie
Failed validation returns a 403 Forbidden error
API logout doesn’t require CSRF protection as it uses bearer token authentication.
Logout all sessions
To revoke all sessions for an identity, use the Admin API:
curl -X DELETE \
'https://{project}.projects.oryapis.com/admin/identities/{identity_id}/sessions' \
-H 'Authorization: Bearer ory_pat_...'
This immediately invalidates all sessions for the specified identity.
API reference
Endpoint Method Description /self-service/logout/browserGET Create logout flow for browsers /self-service/logout/apiDELETE Revoke session token for native apps /self-service/logoutGET Complete logout with token
All endpoints are defined in selfservice/flow/logout/handler.go:33-36