مجوز و صداقت

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

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

مجوز در یک جریان

جریان‌ها می‌توانند مجوز را از دو طریق بررسی کنند: یا الزام‌آوری درخواست (مثلاً onCallGenkit برای توابع ابری برای Firebase یا express ) می‌تواند مجوز را اعمال کند، یا آن چارچوب‌ها می‌توانند خط‌مشی‌های تأیید اعتبار را به خود جریان منتقل کنند، جایی که جریان به اطلاعات مربوط به احراز هویت مدیریت شده در جریان دسترسی دارد.

import { genkit, z, UserFacingError } from 'genkit';

const ai = genkit({ ... });

export const selfSummaryFlow = ai.defineFlow( {
  name: 'selfSummaryFlow',
  inputSchema: z.object({ uid: z.string() }),
  outputSchema: z.string(),
}, async (input, { context }) => {
  if (!context.auth) {
    throw new UserFacingErrorError('UNAUTHENTICATED', 'Unauthenticated');
  }
  if (input.uid !== context.auth.uid) {
    throw new UserFacingError('PERMISSION_DENIED', 'You may only summarize your own profile data.');
  }
  // Flow logic here...
});

در این مورد به درخواست الزام آور برای پر کردن context.auth بستگی دارد. به عنوان مثال، onCallGenkit به طور خودکار context.auth (Authentication Firebase)، context.app (بررسی برنامه Firebase) و context.instanceIdToken (Firebase Cloud Messaging) را پر می کند. هنگام فراخوانی یک جریان به صورت دستی، می توانید زمینه تأیید اعتبار خود را به صورت دستی اضافه کنید.

// Error: Authorization required.
await selfSummaryFlow({ uid: 'abc-def' });

// Error: You may only summarize your own profile data.
await selfSummaryFlow.run(
  { uid: 'abc-def' },
  {
    context: { auth: { uid: 'hij-klm' } },
  }
);

// Success
await selfSummaryFlow(
  { uid: 'abc-def' },
  {
    context: { auth: { uid: 'abc-def' } },
  }
);

هنگام اجرا با Genkit Development UI، می توانید با وارد کردن JSON در برگه "Auth JSON"، شی Auth را ارسال کنید: {"uid": "abc-def"} .

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

import { genkit, z } from 'genkit';

const ai = genkit({ ... });;

async function readDatabase(uid: string) {
  const auth = ai.currentContext()?.auth;
  // Note: the shape of context.auth depends on the provider. onCallGenkit puts
  // claims information in auth.token
  if (auth?.token?.admin) {
    // Do something special if the user is an admin
  } else {
    // Otherwise, use the `uid` variable to retrieve the relevant document
  }
}

export const selfSummaryFlow = ai.defineFlow(
  {
    name: 'selfSummaryFlow',
    inputSchema: z.object({ uid: z.string() }),
    outputSchema: z.string(),
    authPolicy: ...
  },
  async (input) => {
    await readDatabase(input.uid);
  }
);

هنگام آزمایش جریان ها با ابزارهای توسعه دهنده Genkit، می توانید این شی auth را در UI یا در خط فرمان با پرچم --context مشخص کنید:

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

مجوز استفاده از توابع ابری برای Firebase

توابع Cloud برای Firebase SDK از Genkit از جمله ادغام با Firebase Auth / Google Cloud Identity Platform، و همچنین پشتیبانی داخلی Firebase App Check پشتیبانی می‌کند.

احراز هویت کاربر

پوشش onCallGenkit() ارائه شده توسط کتابخانه Firebase Functions دارای پشتیبانی داخلی از توابع Cloud برای SDK های مشتری Firebase است. وقتی از این SDK ها استفاده می کنید، تا زمانی که کلاینت برنامه شما از Firebase Auth SDK نیز استفاده می کند، سرصفحه Firebase Auth به طور خودکار گنجانده می شود. می توانید از Firebase Auth برای محافظت از جریان های تعریف شده با onCallGenkit() استفاده کنید:

import { genkit } from 'genkit';
import { onCallGenkit } from 'firebase-functions/https';

const ai = genkit({ ... });;

const selfSummaryFlow = ai.defineFlow({
  name: 'selfSummaryFlow',
  inputSchema: z.string(),
  outputSchema: z.string(),
}, async (input) => {
  // Flow logic here...
});

export const selfSummary = onCallGenkit({
  authPolicy: (auth) => auth?.token?.['email_verified'] && auth?.token?.['admin'],
}, selfSummaryFlow);

هنگامی که از onCallGenkit استفاده می کنید، context.auth به عنوان یک شی با یک uid برای شناسه کاربر، و یک token که یک DecodedIdToken است، برگردانده می شود. همانطور که قبلا ذکر شد، همیشه می توانید این شی را در هر زمان با استفاده از ai.currentContext() بازیابی کنید. هنگام اجرای این جریان در حین توسعه، شی کاربر را به همین ترتیب ارسال می کنید:

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

هر زمان که یک Cloud Function را در معرض اینترنت گسترده تر قرار می دهید، بسیار مهم است که از نوعی مکانیسم مجوز برای محافظت از داده های خود و داده های مشتریان خود استفاده کنید. با این اوصاف، مواقعی وجود دارد که نیاز دارید یک Cloud Function را بدون بررسی مجوز مبتنی بر کد اجرا کنید (به عنوان مثال، عملکرد شما قابل فراخوانی جهانی نیست اما در عوض توسط Cloud IAM محافظت می شود). Cloud Functions for Firebase به شما امکان می دهد این کار را با استفاده از ویژگی invoker انجام دهید که دسترسی IAM را کنترل می کند. مقدار ویژه 'private' تابع را به عنوان تنظیمات پیش فرض IAM می گذارد، به این معنی که فقط تماس گیرندگان با نقش Cloud Run Invoker می توانند این تابع را اجرا کنند. درعوض می‌توانید آدرس ایمیل یک حساب کاربری یا سرویسی را که باید مجوز فراخوانی دقیق این عملکرد را داشته باشد، ارائه دهید.

import { onCallGenkit } from 'firebase-functions/https'

const selfSummaryFlow = ai.defineFlow({
  name: 'selfSummaryFlow',
  inputSchema: z.string(),
  outputSchema: z.string(),
}, async (input) => {
  // Flow logic here...
});

export const selfSummary = onCallGenkit({
  invoker: 'private',
}, selfSummaryFlow);

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

احراز هویت به تنهایی به محافظت از برنامه شما کمک زیادی می کند. اما این نیز مهم است که اطمینان حاصل کنید که فقط برنامه های مشتری شما با توابع شما تماس می گیرند. افزونه Firebase برای genkit شامل پشتیبانی درجه یک از Firebase App Check است. این کار را با افزودن گزینه های پیکربندی زیر به onCallGenkit() خود انجام دهید:

import { onCallGenkit } from 'firebase-functions/https';

const selfSummaryFlow = ai.defineFlow({
  name: 'selfSummaryFlow',
  inputSchema: z.string(),
  outputSchema: z.string(),
}, async (input) => {
  // Flow logic here...
});

export const selfSummary = onCallGenkit({
  // 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: ...,
}, selfSummaryFlow);

مجوز HTTP غیر Firebase

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

از یک ContextProvider برای پر کردن مقادیر متنی مانند auth و برای ارائه یک خط‌مشی اعلامی یا یک فراخوان خط مشی استفاده کنید. Genkit SDK ContextProvider هایی مانند apiKey را ارائه می دهد و افزونه ها نیز ممکن است آنها را در معرض دید قرار دهند. به عنوان مثال، پلاگین @genkit-ai/firebase/context یک ارائه‌دهنده زمینه را برای تأیید اعتبار Firebase Auth و پر کردن آنها در متن نشان می‌دهد.

با کدی مانند زیر که ممکن است در برنامه های مختلف ظاهر شود:

// Express app with a simple API key
import { genkit, z } from 'genkit';

const ai = genkit({ ... });;

export const selfSummaryFlow = ai.defineFlow(
  {
    name: 'selfSummaryFlow',
    inputSchema: z.object({ uid: z.string() }),
    outputSchema: z.string(),
  },
  async (input) => {
    // Flow logic here...
  }
);

شما می‌توانید یک برنامه اکسپرس ساده «سرور جریان» را با نوشتن:

import { apiKey } from "genkit";
import { startFlowServer, withContext } from "@genkit-ai/express";

startFlowServer({
  flows: [
    withContext(selfSummaryFlow, apiKey(process.env.REQUIRED_API_KEY))
  ],
});

یا می توانید یک برنامه اکسپرس سفارشی با استفاده از ابزارهای مشابه بسازید:

import { apiKey } from "genkit";
import * as express from "express";
import { expressHandler } from "@genkit-ai/express;

const app = express();
// Capture but don't validate the API key (or its absence)
app.post('/summary', expressHandler(selfSummaryFlow, { contextProvider: apiKey()}))

app.listen(process.env.PORT, () => {
  console.log(`Listening on port ${process.env.PORT}`);
})

ContextProvider چارچوب وب را انتزاعی می کند، بنابراین این ابزارها در چارچوب های دیگری مانند Next.js نیز کار می کنند. در اینجا نمونه ای از یک برنامه Firebase ساخته شده بر روی Next.js است.

import { appRoute } from "@genkit-ai/express";
import { firebaseContext } from "@genkit-ai/firebase";

export const POST = appRoute(selfSummaryFlow, { contextProvider: firebaseContext })

برای اطلاعات بیشتر در مورد استفاده از Express، دستورالعمل‌های Cloud Run را ببینید.