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. When a flow is served over HTTP, a context provider populates this context from the request.
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: StatusCode.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: StatusCode.permissionDenied, ); } // 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
Section titled “Context providers”When serving flows over HTTP with GenkitRouter (from package:genkit/io.dart), pass a contextProvider to verify incoming requests and populate the context. The provider receives a framework-neutral RequestData (lowercased headers, method, and parsed input), so the same function works with the standalone server, Shelf, or any other adapter.
import 'dart:async';
import 'package:genkit/genkit.dart';import 'package:genkit/io.dart';
FutureOr<Map<String, dynamic>> apiKeyContextProvider(RequestData request) { final authHeader = request.headers['authorization']; if (authHeader == null || !authHeader.startsWith('Bearer ')) { // A thrown GenkitException is answered with its status (here 401). // Any other exception results in a 403. throw GenkitException('Missing API Key', status: StatusCode.unauthenticated); } final token = authHeader.substring(7); if (token != 'REQUIRED_API_KEY') { throw GenkitException('Invalid API Key', status: StatusCode.permissionDenied); } return { 'auth': {'uid': 'admin', 'key': token}, };}
void main() async { final ai = Genkit(); // ... define selfSummaryFlow ...
final genkit = GenkitRouter() ..addAction(selfSummaryFlow, contextProvider: apiKeyContextProvider);
await genkit.serve(port: 3400);}In a Shelf app, mount the same router with genkit.asShelfHandler() from genkit_shelf, or protect a single route with shelfHandler(selfSummaryFlow, contextProvider: apiKeyContextProvider).