授权和完整性

在构建任何面向公众的应用时,务必要保护 存储在您系统中的数据对于 LLM,应格外注意 必须确保模型只访问应该访问的数据,工具会调用 已适当地限定为调用 LLM 的用户,并且该流程被调用 只有通过验证的客户端应用才能使用

Firebase Genkit 提供了用于管理授权政策和 上下文。对于在 Cloud Functions for Firebase 上运行的流,开发者 必须提供身份验证政策,或者明确承认缺少 一个。对于非 Functions 流程,您也可以管理和设置身份验证,但需要 手动集成

基本流程授权

所有流都可以在其配置中定义 authPolicy。身份验证政策是一个函数,用于测试是否满足特定条件(由您定义),并会在任何测试失败时抛出异常。 如果设置了此字段,则会在调用数据流之前执行此字段:

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 对象: 在“Auth JSON”中输入 JSON标签页:{"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 标头将自动添加为 只要您的应用客户端也使用 Firebase Auth SDK。 您可以使用 Firebase Authentication 来保护使用 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 之外的服务器上下文时, 您希望能够自行设置授权检查 与原生数据流结合使用您可以采用以下两种方法:

  1. 使用您喜欢的任何服务器框架,并通过 runFlow()

  2. 使用内置的 startFlowsServer() 并在 流配置:

    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),则 middleware 配置选项 会被 runFlow() 忽略。