Authentication
Identify the caller of your function. When a signed-in user invokes a function from the Koolbase SDK, the runtime injects their identity into ctx.auth.
The ctx.auth object
Every function receives an auth field on its context. Two properties:
{
"user_id": "bf061caa-b43e-4e18-975a-a4b61f1d030e",
"is_authenticated": true
}When no signed-in user is invoking — or when the function is fired by a DB trigger — user_id is null and is_authenticated is false.
Reading the caller
Inside the function, read ctx.auth.user_id to identify who's calling. Reject if absent.
export async function handler(ctx) {
const userId = ctx.auth?.user_id;
if (!userId) {
return {
error: { code: 'AUTH_REQUIRED', message: 'Sign in required.' },
status: 401,
};
}
const result = await ctx.db.find('profiles', { user_id: userId }, 1);
return { profile: result.records?.[0] ?? null };
}Future<Map<String, dynamic>> handler(Map<String, dynamic> ctx) async {
final auth = ctx['auth'] as Map<String, dynamic>?;
final userId = auth?['user_id'] as String?;
if (userId == null) {
return {
'error': {'code': 'AUTH_REQUIRED', 'message': 'Sign in required.'},
'status': 401,
};
}
final db = ctx['db'] as Map<String, dynamic>;
final result = await (db['find'] as Function)('profiles', {'user_id': userId}, 1);
final records = (result['records'] as List?) ?? [];
return {'profile': records.isEmpty ? null : records.first};
}Public functions
Some functions are designed to be called without a signed-in user — sign-up flows, password reset, anonymous reads. Skip the auth check and proceed:
export async function handler(ctx) {
// No auth check — anyone can call this.
await ctx.db.insert('events', {
name: ctx.request.body.event,
timestamp: new Date().toISOString(),
});
return { ok: true };
}A function can also do both — branch on ctx.auth.is_authenticated when authenticated callers get a richer response than anonymous ones.
Invoking from the SDK
When a user is signed in via Koolbase.auth, the SDK forwards their access token on every Koolbase.functions.invoke() call. No extra arguments needed.
await Koolbase.auth.signInWithEmail(email, password);
final result = await Koolbase.functions.invoke('get-profile');
// ctx.auth.user_id is populated inside the function.await Koolbase.auth.signIn(email, password);
const result = await Koolbase.functions.invoke('get-profile');
// ctx.auth.user_id is populated inside the function.Token refresh is transparent
Direct REST invoke
When calling the REST endpoint directly, attach the user's access token as a Bearer header alongside the project's API key:
curl -X POST https://api.koolbase.com/v1/sdk/functions/get-profile \
-H "Content-Type: application/json" \
-H "x-api-key: pk_live_your_key" \
-H "Authorization: Bearer <user_access_token>" \
-d '{"body": {}}'Without the Authorization header, the request is treated as unauthenticated and ctx.auth.is_authenticated resolves to false.
SDK compatibility
ctx.auth is populated automatically when calling from these SDK versions or later:
koolbase_flutter2.8.0+@techfinityedge/koolbase-react-native1.8.0+Older SDK versions
ctx.auth.is_authenticated as false even when the user is signed in. Upgrade the SDK to enable authenticated invocations.