session-auth
workflowv1.0.0Session management with persistent SQLite storage for authentication
Install
Then run locally:
Configure LLM provider in ~/.kdeps/config.yaml (created automatically on first run).
README
Session Management Example
This example demonstrates session management with persistent SQLite storage in KDeps v2.
Features
- SQLite-backed persistent session storage
- Session TTL (time-to-live) configuration
- Python-based credential validation
- Session data storage and retrieval
- Automatic cleanup of expired sessions
Session Configuration
Sessions are configured in workflow.yaml:
settings:
session:
type: "sqlite" # Storage type: "sqlite" or "memory"
path: ".kdeps/sessions.db" # Database path (relative or absolute)
ttl: "30m" # Session expiration time
cleanupInterval: "5m" # Cleanup interval for expired sessions
Configuration Options
- type:
"sqlite"(persistent) or"memory"(in-memory, lost on restart) - path: Path to SQLite database file (default:
~/.kdeps/sessions.db) - ttl: Session expiration time in Go duration format (e.g.,
"30m","1h","24h") - cleanupInterval: How often to clean up expired sessions (e.g.,
"5m","1h")
Run Locally
# From examples/session-auth directory
kdeps run workflow.yaml --dev
# Or from root
kdeps run examples/session-auth/workflow.yaml --dev
Test
1. Login (Validate Credentials)
# Save cookie for session persistence
curl -X POST http://localhost:16395/api/v1/login \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": "secret"}' \
-c cookies.txt
Response (success):
{
"success": true,
"data": {
"endpoint": "/api/v1/login",
"login": {"data": {"message": "Login successful", "user_id": "admin"}, "success": true},
"session": {"logged_in": "true", "login_time": "2026-01-30T08:14:56Z", "user_id": "admin"},
"user_id": "admin",
"logged_in": "true",
"login_time": "2026-01-30T08:14:56Z"
}
}
Response (invalid credentials):
curl -X POST http://localhost:16395/api/v1/login \
-H "Content-Type: application/json" \
-d '{"username": "wrong", "password": "wrong"}'
{
"success": false,
"error": {"code": 500, "message": "Invalid credentials"}
}
2. Access Session Data (with cookie)
# Use the saved cookie to access session
curl http://localhost:16395/api/v1/session -b cookies.txt
Response:
{
"success": true,
"data": {
"endpoint": "/api/v1/session",
"session": {"logged_in": "true", "login_time": "2026-01-30T08:14:56Z", "user_id": "admin"},
"user_id": "admin",
"logged_in": "true",
"login_time": "2026-01-30T08:14:56Z"
}
}
3. Access Session Without Login (401 Unauthorized)
# Without cookie - returns 401
curl http://localhost:16395/api/v1/session
Response:
{
"success": false,
"error": {"code": 401, "message": "Not logged in. Please login first."}
}
Structure
session-auth/
├── workflow.yaml # Workflow with session configuration
└── resources/
├── login-handler.yaml # Python validates, sets session on success
├── session-handler.yaml # Returns session data (requires login)
└── session-response.yaml # API response (target)
Resources
loginHandler (login-handler.yaml)
Python validates credentials. If valid, exits with 0 and expr blocks set session data. If invalid, exits with error code 1 to prevent session from being set.
run:
validations:
routes: [/api/v1/login]
required: [username, password]
python:
script: |
import json
import sys
username = "{{ get('username') }}"
password = "{{ get('password') }}"
if username == "admin" and password == "secret":
print(json.dumps({"success": True, "user": username}))
else:
print(json.dumps({"error": "Invalid credentials"}), file=sys.stderr)
sys.exit(1)
# These only run if Python succeeds (exit 0)
expr:
- "{{ set('user_id', get('username'), 'session') }}"
- "{{ set('logged_in', 'true', 'session') }}"
- "{{ set('login_time', info('current_time'), 'session') }}"
sessionHandler (session-handler.yaml)
Returns session data. Requires user to be logged in:
run:
validations:
routes: [/api/v1/session]
check:
- "{{ get('logged_in', 'session') == 'true' }}"
error:
code: 401
message: "Not logged in. Please login first."
python:
script: |
import json
session_data = {{ session() }}
print(json.dumps({"session": session_data}))
sessionResponse (session-response.yaml)
Target resource that combines outputs:
run:
apiResponse:
success: true
response:
endpoint: "{{ get('path') }}"
login: "{{ output('loginHandler') }}"
session: "{{ output('sessionHandler') }}"
Key Concepts
Expression Positioning (exprBefore, expr, exprAfter)
Control when expression blocks execute relative to the primary execution type:
run:
# Runs BEFORE the primary execution type
exprBefore:
- "{{ set('start_time', info('current_time')) }}"
python:
script: |
# Your Python code here
# Runs AFTER the primary execution type (default)
expr:
- "{{ set('user_id', get('username'), 'session') }}"
# Also runs AFTER (alias for expr)
exprAfter:
- "{{ set('completed', 'true') }}"
Combining apiResponse with Primary Types
You can combine apiResponse with primary execution types (python, chat, sql, etc.):
run:
python:
script: |
import json
print(json.dumps({"result": "success"}))
# apiResponse runs after the primary type and uses its output
apiResponse:
success: true
response:
message: "Operation completed"
python_output: "{{ output('currentResource') }}"
Python Credential Validation
Use Python scripts to validate credentials against any backend:
python:
script: |
import json
# Validate against database, LDAP, etc.
if validate_user(username, password):
print(json.dumps({"success": True}))
else:
print(json.dumps({"success": False, "error": "Invalid"}))
Session Function
Access all session data using the session() function:
python:
script: |
session_data = {{ session() }}
Checking Current Session
There are multiple ways to check the current user's session:
# 1. Get all session data as a map
session_data: "{{ session() }}"
# Returns: {"user_id": "admin", "logged_in": "true", "login_time": "..."}
# 2. Get specific session values
user_id: "{{ get('user_id', 'session') }}"
logged_in: "{{ get('logged_in', 'session') }}"
# 3. Use validations.check to require login
run:
validations:
check:
- "{{ get('logged_in', 'session') == 'true' }}"
error:
code: 401
message: "Not logged in"
# 4. Use in Python scripts
python:
script: |
import json
session = {{ session() }}
user_id = session.get('user_id')
if user_id:
print(json.dumps({"user": user_id, "authenticated": True}))
# 5. Skip resource if not logged in
run:
validations:
skip:
- "{{ get('logged_in', 'session') != 'true' }}"
Route Restrictions
Resources only execute when their route matches:
run:
validations:
routes: [/api/v1/login] # Only runs for this route
Output Function
Access output from other resources:
response:
login: "{{ output('loginHandler') }}"
Demo Credentials
- Username:
admin - Password:
secret
Session Storage Details
SQLite Schema
Sessions are stored in SQLite with the following schema:
CREATE TABLE sessions (
session_id TEXT NOT NULL,
key TEXT NOT NULL,
value TEXT NOT NULL,
created_at INTEGER NOT NULL,
accessed_at INTEGER NOT NULL,
expires_at INTEGER,
PRIMARY KEY (session_id, key)
);
Persistent vs In-Memory
- SQLite (
type: "sqlite"): Persists across restarts, stored on disk - Memory (
type: "memory"): Lost on restart, faster for development
Use Cases
- User Authentication: Validate credentials with Python
- Session Management: Store and retrieve session data
- Multi-Step Forms: Store form data across requests
- User Preferences: Store user settings temporarily
- API Rate Limiting: Track API usage per session
Versions
| Version | Published | Status |
|---|---|---|
| 1.0.0 | 4/11/2026 | active |
Details
- Author
- kdeps
- License
- Apache-2.0
- Latest Version
- 1.0.0
- Published
- 4/11/2026