Authorization and integrity
Authorize within a Flow
Section titled “Authorize within a Flow”Flows can check authorization by inspecting the context property passed to the flow function. It is up to the framework integration (like genkit_shelf) to populate this context.
import 'package:genkit/genkit.dart';
import 'package:schemantic/schemantic.dart';
part 'self_summary.g.dart'; // Generated by build_runner
// Define the input schema@Schema()abstract class $SelfSummaryInput { String get uid;}
// Define the output schema@Schema()abstract class $SelfSummaryOutput { String get profileSummary;}
final selfSummaryFlow = ai.defineFlow( name: 'selfSummaryFlow', inputSchema: SelfSummaryInput.$schema, outputSchema: SelfSummaryOutput.$schema, fn: (input, context) async { final auth = context.context?['auth']; if (auth == null) { throw GenkitException('Unauthenticated', status: StatusCodes.UNAUTHENTICATED); } // Access typed properties on the generated concrete class if (input.uid != auth['uid']) { throw GenkitException('You may only summarize your own profile data.', status: StatusCodes.PERMISSION_DENIED); } // Flow logic here... return SelfSummaryOutput(profileSummary: 'User profile summary would go here'); },);You can verify this logic by manually passing context during execution:
// Error: Unauthenticatedawait selfSummaryFlow(SelfSummaryInput(uid: 'abc-def'));
// Error: Permission deniedawait selfSummaryFlow( SelfSummaryInput(uid: 'abc-def'), context: {'auth': {'uid': 'hij-klm'}},);
// Successawait selfSummaryFlow( SelfSummaryInput(uid: 'abc-def'), context: {'auth': {'uid': 'abc-def'}},);Context Providers (Shelf)
Section titled “Context Providers (Shelf)”When deploying with genkit_shelf (running as a server), you can use a ContextProvider to verify incoming requests and populate the context.
import 'dart:async';import 'package:genkit/genkit.dart';import 'package:genkit_shelf/genkit_shelf.dart';import 'package:shelf/shelf.dart';import 'package:shelf/shelf_io.dart' as io;
FutureOr<Map<String, dynamic>> apiKeyContextProvider(Request request) { final authHeader = request.headers['Authorization']; if (authHeader == null || !authHeader.startsWith('Bearer ')) { // Throwing here will result in a 403 Forbidden response throw GenkitException('Missing API Key', status: StatusCodes.UNAUTHENTICATED); } final token = authHeader.substring(7); if (token != 'REQUIRED_API_KEY') { throw GenkitException('Invalid API Key', status: StatusCodes.PERMISSION_DENIED); } return { 'auth': {'uid': 'admin', 'key': token} };}
void main() async { final ai = Genkit(plugins: []); // ... define flow ...
final handler = const Pipeline() .addMiddleware(logRequests()) .addHandler(shelfHandler(selfSummaryFlow, contextProvider: apiKeyContextProvider));
await io.serve(handler, 'localhost', 3400);}