在构建任何面向公众的应用时,保护存储在您系统中的数据极为重要。对于 LLM,需要采取额外的措施,以确保模型只访问它应该访问的数据,将工具调用的范围适当地限定为调用 LLM 的用户,并且只有经过验证的客户端应用可以调用该流程。
Firebase Genkit 提供用于管理授权政策和上下文的机制。对于在 Cloud Functions for Firebase 上运行的流,开发者需要提供身份验证政策,或明确确认缺���身份验证政策。对于非函数流程,您也可以管理和设置身份验证,但需要更多手动集成。
基本流授权
所有流都可以在其配置中定义 authPolicy
。身份验证政策是一个函数,用于测试是否满足特定条件(由您定义),如果任何测试失败,则会抛出异常。如果设置了此字段,则会在调用 flow 之前执行:
import { defineFlow, runFlow } from '@genkit-ai/flow';
export const selfSummaryFlow = defineFlow(
{
name: 'selfSummaryFlow',
inputSchema: z.object({uid: z.string()}),
outputSchema: z.string(),
authPolicy: (auth, input) => {
if (!auth) {
throw new Error('Authorization required.');
}
if (input.uid !== auth.uid) {
throw new Error('You may only summarize your own profile data.');
}
}
},
async (input) => { ... });
执行此流程时,您必须使用 withLocalAuthContext
提供 auth 对象,否则将会收到错误消息:
// Error: Authorization required.
await runFlow(selfSummaryFlow, { uid: 'abc-def' });
// Error: You may only summarize your own profile data.
await runFlow(
selfSummaryFlow,
{ uid: 'abc-def' },
{
withLocalAuthContext: { uid: 'hij-klm' },
}
);
// Success
await runFlow(
selfSummaryFlow,
{ uid: 'abc-def' },
{
withLocalAuthContext: { uid: 'abc-def' },
}
);
使用 Genkit 开发界面运行时,您可以通过在“Auth JSON”标签页中输入 JSON 来传递 Auth 对象:{"uid": "abc-def"}
。
您还可以随时调用 getFlowAuth()
(包括在数据流调用的函数中)检索该流的身份验证上下文:
import { getFlowAuth, defineFlow } from '@genkit-ai/flow';
async function readDatabase(uid: string) {
if (getFlowAuth().admin) {
// Do something special if the user is an admin:
...
} else {
// Otherwise, use the `uid` variable to retrieve the relevant document
...
}
}
export const selfSummaryFlow = defineFlow(
{
name: 'selfSummaryFlow',
inputSchema: z.object({uid: z.string()}),
outputSchema: z.string(),
authPolicy: ...
},
async (input) => {
...
await readDatabase(input.uid);
});
使用 Genkit 开发者工具测试流时,您可以在界面中或在命令行中使用 --auth
标志指定此身份验证对象:
genkit flow:run selfSummaryFlow '{"uid": "abc-def"}' --auth '{"uid": "abc-def"}'
Cloud Functions for Firebase 集成
Firebase 插件可让您方便地与 Firebase Auth / Google Cloud Identity Platform 集成,还内置��� Firebase App Check 支持。
授权
Firebase 插件提供的 onFlow()
封装容器可与 Cloud Functions for Firebase 客户端 SDK 原生搭配使用。使用该 SDK 时,只要您的应用客户端也使用 Firebase Auth SDK,Firebase Auth 标头就会自动包含。您可以使用 Firebase Auth 来保护使用 onFlow()
定义的流:
import {firebaseAuth} from "@genkit-ai/firebase/auth";
import {onFlow} from "@genkit-ai/firebase/functions";
export const selfSummaryFlow = onFlow({
name: "selfSummaryFlow",
inputSchema: z.string(),
outputSchema: z.string(),
authPolicy: firebaseAuth((user) => {
if (!user.email_verified && !user.admin) {
throw new Error("Email not verified");
}
}),
}, (subject) => {...})
使用 Firebase 身份验证插件时,user
将以 DecodingIdToken 的形式返回。如上所述,您随时可以通过 getFlowAuth()
检索此对象。在开发期间运行此流程时,您应以相同的方式传递用户对象:
genkit flow:run selfSummaryFlow '{"uid": "abc-def"}' --auth '{"admin": true}'
默认情况下,Firebase Auth 插件要求客户端发送身份验证标头,但如果您希望通过对经过身份验证的用户(例如,追加销售功能)的特殊处理来允许未经身份验证的访问,则可以按如下方式配置该政策:
authPolicy: firebaseAuth((user) => {
if (user && !user.email_verified) {
throw new Error("Logged in users must have verified emails");
}
}, {required: false}),
每当您将 Cloud Functions 函数公开给更广泛的互联网时,使用某种授权机制来保护您的数据和客户数据至关重要。不过,有时您需要在不进行基于代码的授权检查的情况下部署 Cloud Functions 函数(例如,您的函数不是全局调用的,而是受 Cloud IAM 的保护)。使用 onFlow()
时,authPolicy
字段始终为必填字段,但您可以使用 noAuth()
函数向库指明您正在忘记进行授权检查:
import {onFlow, noAuth} from "@genkit-ai/firebase/functions";
export const selfSummaryFlow = onFlow({
name: "selfSummaryFlow",
inputSchema: z.string(),
outputSchema: z.string(),
// WARNING: Only do this if you have some other gatekeeping in place, like
// Cloud IAM!
authPolicy: noAuth(),
}, (subject) => {...})
客户端完整性
身份验证本身就大大地保护了您的应用。不过,确保只有客户端应用调用您的函数也很重要。适用于 genkit 的 Firebase 插件包含对 Firebase App Check 的一流支持。只需将以下配置选项添加到 onFlow()
即可:
import {onFlow} from "@genkit-ai/firebase/functions";
export const selfSummaryFlow = onFlow({
name: "selfSummaryFlow",
inputSchema: z.string(),
outputSchema: z.string(),
// These two fields for app check. The consumeAppCheckToken option is for
// replay protection, and requires additional client configuration. See the
// App Check docs.
enforceAppCheck: true,
consumeAppCheckToken: true,
authPolicy: ...,
}, (subject) => {...})
非 Firebase HTTP 授权
在将流部署到 Cloud Functions for Firebase 之外的服务器上下文时,您需要一种方法来设置自己的授权检查以及原生流。您可以采用以下两种方法:
使用您喜欢的任何服务器框架,并通过
runFlow()
传递身份验证上下文(如上所述)。使用内置
startFlowsServer()
并在流配置中提供 Express 中间件:export const selfSummaryFlow = defineFlow( { name: 'selfSummaryFlow', inputSchema: z.object({uid: z.string()}), outputSchema: z.string(), middleware: [ (req, res, next) => { const token = req.headers['authorization']; const user = yourVerificationLibrary(token); // This is what will get passed to your authPolicy req.auth = user; next(); } ], authPolicy: (auth, input) => { if (!auth) { throw new Error('Authorization required.'); } if (input.uid !== auth.uid) { throw new Error('You may only summarize your own profile data.'); } } }, async (input) => { ... }); startFlowsServer(); // This will register the middleware
如需详细了解如何使用 Express,请参阅 Cloud Run 说明。
请注意,如果您选择 (1),runFlow()
会忽略 middleware
配置选项。