अनुमति देना और रखरखाव करना

सार्वजनिक ऐप्लिकेशन बनाते समय, अपने सिस्टम में सेव किए गए डेटा को सुरक्षित रखना बहुत ज़रूरी है. एलएलएम के मामले में, इस बात का ज़्यादा ध्यान रखना ज़रूरी है कि मॉडल सिर्फ़ उस डेटा को ऐक्सेस कर रहा हो जिसे उसे ऐक्सेस करना चाहिए. टूल कॉल, एलएलएम के लिए उपयोगकर्ता के डेटा को ऐक्सेस करने के दायरे में आते हैं. साथ ही, फ़्लो को सिर्फ़ पुष्टि किए गए क्लाइंट ऐप्लिकेशन से ही शुरू किया जाता है.

Firebase Genkit आपको अनुमति देने से जुड़ी नीतियों और कॉन्टेक्स्ट को मैनेज करने के तरीके उपलब्ध कराता है. 'Firebase के लिए Cloud 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 का इस्तेमाल करके, पुष्टि करने वाला एक ऑब्जेक्ट देना ज़रूरी है. ऐसा न करने पर, आपको यह गड़बड़ी मिलेगी:

// 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 डालकर, OAuth ऑब्जेक्ट को पास किया जा सकता है: {"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"}'

'Firebase के लिए Cloud Functions' का इंटिग्रेशन

Firebase प्लगिन, Firebase पुष्टि / Google Cloud Identity Platform के साथ-साथ, पहले से मौजूद Firebase ऐप्लिकेशन की जांच के साथ दी गई सहायता को आसानी से इंटिग्रेट करने की सुविधा देता है.

अनुमति देना

Firebase प्लगिन से मिला onFlow() रैपर, Firebase के लिए Cloud Functions क्लाइंट SDK टूल के साथ काम करता है. SDK टूल इस्तेमाल करते समय, Firebase ऑथराइज़ेशन हेडर अपने-आप शामिल हो जाएगा, बशर्ते आपका ऐप्लिकेशन क्लाइंट Firebase ऑथराइज़ेशन SDK टूल का इस्तेमाल कर रहा हो. onFlow() में बताए गए अपने फ़्लो को सुरक्षित रखने के लिए, Firebase पुष्टि का इस्तेमाल किया जा सकता है:

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 को DeCodeIdToken के तौर पर दिखाया जाएगा. जैसा कि ऊपर बताया गया है, getFlowAuth() की मदद से आप जब चाहें, इस ऑब्जेक्ट को वापस पा सकते हैं. डेवलपमेंट के दौरान इस फ़्लो को चलाते समय, आप उपयोगकर्ता ऑब्जेक्ट को इसी तरह पास करेंगे:

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

डिफ़ॉल्ट रूप से Firebase पुष्टि प्लगिन के लिए, क्लाइंट से पुष्टि करने वाला हेडर भेजना ज़रूरी होता है. हालांकि, जिन मामलों में आपको पुष्टि किए गए उपयोगकर्ताओं को खास हैंडलिंग की मदद से, बिना पुष्टि वाले ऐक्सेस की अनुमति देनी है (जैसे कि अपसेल करने की सुविधाएं), उन मामलों में नीति को इस तरह से कॉन्फ़िगर किया जा सकता है:

authPolicy: firebaseAuth((user) => {
  if (user && !user.email_verified) {
    throw new Error("Logged in users must have verified emails");
  }
}, {required: false}),

जब भी किसी क्लाउड फ़ंक्शन को पूरे इंटरनेट पर सार्वजनिक किया जाता है, तो यह बेहद ज़रूरी होता है कि अपने डेटा और ग्राहकों के डेटा को सुरक्षित रखने के लिए, अनुमति देने का कोई तरीका इस्तेमाल किया जाए. हालांकि, कई बार आपको ऐसा Cloud फ़ंक्शन डिप्लॉय करने की ज़रूरत होती है जिसमें कोड की मदद से पुष्टि न की गई हो. उदाहरण के लिए, आपके फ़ंक्शन को पूरी दुनिया में कॉल नहीं किया जा सकता. इसके बजाय, यह 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 वाले एचटीटीपी की अनुमति

Firebase के लिए Cloud Functions के बाहर किसी सर्वर कॉन्टेक्स्ट में फ़्लो डिप्लॉय करते समय, आपको नेटिव फ़्लो के साथ-साथ, अपनी अनुमति से जुड़ी जांच सेट अप करने का भी तरीका चाहिए. आपके पास दो विकल्प हैं:

  1. अपनी पसंद के सर्वर फ़्रेमवर्क का इस्तेमाल करें और जैसा कि ऊपर बताया गया है, 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() नज़रअंदाज़ कर देगा.