مجوز و صداقت

هنگام ساخت هر برنامه عمومی، محافظت از داده های ذخیره شده در سیستم شما بسیار مهم است. وقتی نوبت به LLM ها می رسد، دقت بیشتری لازم است تا اطمینان حاصل شود که مدل فقط به داده هایی که باید دسترسی داشته باشد، فراخوانی ابزار به درستی برای کاربر که LLM را فراخوانی می کند، فراخوانی می شود، و جریان فقط توسط برنامه های کاربردی کلاینت تایید شده فراخوانی می شود.

Firebase Genkit مکانیسم هایی را برای مدیریت سیاست ها و زمینه های مجوز ارائه می دهد. برای جریان‌هایی که روی توابع ابری برای Firebase اجرا می‌شوند، توسعه‌دهندگان ملزم به ارائه خط‌مشی احراز هویت هستند یا به صراحت فقدان آن را تأیید کنند. برای جریان های غیر توابع، auth را می توان مدیریت و تنظیم کرد، اما به یکپارچه سازی دستی کمی بیشتر نیاز دارد.

مجوز جریان اصلی

همه جریان ها می توانند یک 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) => { ... });

هنگام اجرای این جریان، باید یک شی auth با استفاده از withLocalAuthContext ارائه دهید، در غیر این صورت یک خطا دریافت خواهید کرد:

// 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 Development UI، می توانید با وارد کردن JSON در برگه "Auth JSON"، شی Auth را ارسال کنید: {"uid": "abc-def"} .

همچنین می‌توانید با فراخوانی getFlowAuth() ، از جمله در توابعی که توسط جریان فراخوانی می‌شوند، زمینه auth را برای جریان در هر زمانی در جریان بازیابی کنید:

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 را در UI یا در خط فرمان با پرچم --auth مشخص کنید:

genkit flow:run selfSummaryFlow '{"uid": "abc-def"}' --auth '{"uid": "abc-def"}'

توابع ابری برای ادغام Firebase

افزونه Firebase ادغام راحت با Firebase Auth / Google Cloud Identity Platform و همچنین پشتیبانی داخلی Firebase App Check را فراهم می کند.

مجوز

بسته بندی onFlow() ارائه شده توسط افزونه Firebase به طور بومی با توابع Cloud برای SDK های مشتری Firebase کار می کند. وقتی از 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 Auth، user به عنوان DecodedIdToken بازگردانده می شود. همانطور که در بالا ذکر شد، همیشه می توانید این شی را در هر زمان از طریق 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 Function را در معرض اینترنت گسترده تر قرار می دهید، بسیار مهم است که از نوعی مکانیسم مجوز برای محافظت از داده های خود و داده های مشتریان خود استفاده کنید. با این اوصاف، مواقعی وجود دارد که نیاز دارید یک Cloud Function را بدون بررسی مجوز مبتنی بر کد اجرا کنید (به عنوان مثال، عملکرد شما قابل فراخوانی جهانی نیست اما در عوض توسط Cloud IAM محافظت می شود). فیلد authPolicy همیشه هنگام استفاده از onFlow() مورد نیاز است، اما می‌توانید با استفاده از تابع 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) => {...})

یکپارچگی مشتری

احراز هویت به تنهایی به محافظت از برنامه شما کمک زیادی می کند. اما این نیز مهم است که اطمینان حاصل کنید که فقط برنامه های مشتری شما با توابع شما تماس می گیرند. افزونه Firebase برای genkit شامل پشتیبانی درجه یک از 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) => {...})

مجوز HTTP غیر Firebase

هنگام استقرار جریان ها در زمینه سرور خارج از Cloud Functions برای Firebase، باید راهی برای تنظیم بررسی های مجوز خود در کنار جریان های بومی داشته باشید. شما دو گزینه دارید:

  1. از هر فریم ورک سروری که دوست دارید استفاده کنید، و همانطور که در بالا ذکر شد، زمینه auth را از طریق runFlow() عبور دهید.

  2. از 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) پیش بروید، گزینه پیکربندی middleware توسط runFlow() نادیده گرفته می‌شود.