GenKit Auth Issue using onCallGenkit and firebase
Related issues
[REQUIRED] Version info
node: 20.x
firebase-functions: 6.1.1
firebase-tools: 13.x
firebase-admin: 12.x
genkit: 0.9.x
[REQUIRED] Test case
Currently, onCallGenkit does not provide a way to pass Firebase Authentication context (user ID, email, custom claims, etc.) from the callable function to Genkit flows.
Current workaround - must use onCall instead of onCallGenkit:
export const generatePoem = onCall(
createGenKitOptions('generatePoem'),
async (request) => {
const flow = generatePoemFlow();
const authClaims = extractAuthClaims(request.auth);
const result = await flow.run(
{
subject: request.data.subject,
auth: authClaims, // Manually passing auth
},
{ context: { auth: authClaims } } // Also in context
);
return result.result;
}
);
[REQUIRED] Steps to reproduce
- Create a Firebase callable function using
onCallGenkit - Attempt to access Firebase Auth context (user ID, custom claims) within the Genkit flow
- Observe that auth context is not available in the flow
Minimal reproduction:
// genkit.ts - Using onCallGenkit (DESIRED)
export const generatePoem = onCallGenkit(
{ authPolicy: createAuthPolicy('generatePoem') },
generatePoemFlow()
);
// generatePoemFlow.ts
export const generatePoemFlow = () => {
const ai = genkit({
plugins: [googleAI()],
model: 'googleai/gemini-2.5-flash',
});
return ai.defineFlow(
{
name: 'generatePoem',
inputSchema: z.object({ subject: z.string() }),
outputSchema: z.object({ poem: z.string() }),
},
async ({ subject }) => {
// ❌ Cannot access auth.uid, auth.email, or custom claims here
// Auth context is validated by authPolicy but not passed to flow
const { text } = await ai.generate({
prompt: `Compose a poem about ${subject}.`
});
return { poem: text };
}
);
};
[REQUIRED] Expected behavior
Auth context should be automatically available in Genkit flows when using onCallGenkit, similar to how it's available in regular onCall functions:
Option 1: Automatic injection via flow context
async ({ subject }, context) => {
console.log('User:', context.auth.uid, context.auth.email);
console.log('Custom claims:', context.auth.token);
// Use auth context for user-scoped operations
}
Option 2: Extended CallableOptions
export const generatePoem = onCallGenkit(
{
authPolicy: createAuthPolicy('generatePoem'),
passAuthContext: true // Auto-inject auth
},
generatePoemFlow()
);
Option 3: Middleware/transform function
export const generatePoem = onCallGenkit(
{ authPolicy: createAuthPolicy('generatePoem') },
generatePoemFlow(),
{
transform: (request) => ({
...request.data,
auth: request.auth
})
}
);
[REQUIRED] Actual behavior
Auth context is NOT available in Genkit flows when using onCallGenkit. Developers must:
- Abandon
onCallGenkitand useonCallwith manual flow execution:
export const generatePoem = onCall(
createGenKitOptions('generatePoem'),
async (request) => {
const flow = generatePoemFlow();
const authClaims = extractAuthClaims(request.auth);
const result = await flow.run(
{
subject: request.data.subject,
auth: authClaims, // Manually passing auth
},
{ context: { auth: authClaims } } // Also in context
);
return result.result;
}
);
-
Or pass UIDs as input data (security risk - clients can spoof this)
-
Or fetch auth context separately in flows (inefficient, breaks traceability)
This defeats the purpose of onCallGenkit's streamlined integration.
Were you able to successfully deploy your functions?
Yes, functions deploy successfully. However, the limitation forces using onCall instead of onCallGenkit to access auth context in flows.
Additional Context
Why This Matters
- Security: Auth context is essential for user-scoped operations and access control within flows
- Observability: Audit trails require knowing which user triggered operations
- Personalization: AI responses need to be personalized based on user data
- Developer Experience: Abandoning
onCallGenkitfor basic auth needs is poor DX - Best Practices: Encourages proper auth-aware design vs. passing UIDs as input (spoofable)
Common Use Cases Blocked
- User-scoped AI generation: Personalize based on user preferences by UID
- Audit logging: Track which user triggered AI operations
- Custom claims logic: Different model configs for premium vs. free tier users
- Multi-tenant apps: Route to org-specific data using custom claims
- Rate limiting: Implement per-user quotas based on custom claims
Proposed Implementation
// Inside firebase-functions implementation
export function onCallGenkit<A extends GenkitAction>(
opts: CallableOptions<ActionInput<A>>,
flow: A
): CallableFunction<ActionInput<A>, Promise<ActionOutput<A>>, ActionStream<A>> {
return onCall(opts, async (request, response) => {
const context = {
auth: request.auth ? {
uid: request.auth.uid,
token: request.auth.token,
} : undefined,
};
return await flow.run(request.data, { context });
});
}
This would be non-breaking (auth context optional in flows) and consistent with Firebase's security model.
I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
Hi @codercatdev. Thanks for reporting this issue, it has been received and we'll review it as soon as possible!
I actually think I found the solution, I didn't realize there was an object passed and a helper function. I think this is more of a documentation issue in genkit repo on how to actually use it.
https://genkit.dev/docs/deployment/authorization/#user-authentication
When you use onCallGenkit, context.auth is returned as an object with a uid for the user ID, and a token that is a DecodedIdToken. You can always retrieve this object at any time using ai.currentContext() as noted earlier. When running this flow during development, you would pass the user object in the same way:
@codercatdev thanks for the update. I've moved this issue to the Genkit repo, since this is potentially a docs issue there.