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

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

Firebase Genkit, अनुमति की नीतियों और कॉन्टेक्स्ट को मैनेज करने के लिए, तरीके उपलब्ध कराता है. 'Firebase के लिए Cloud Functions' पर चल रहे फ़्लो के लिए, डेवलपर को पुष्टि करने की नीति देनी होगी. इसके अलावा, अगर कोई नीति नहीं है, तो इसकी जानकारी साफ़ तौर पर देनी होगी. Functions फ़्लो के अलावा, अन्य फ़्लो के लिए भी पुष्टि करने की सुविधा को मैनेज और सेट किया जा सकता है. हालांकि, इसके लिए मैन्युअल तरीके से थोड़ा ज़्यादा इंटिग्रेशन करना पड़ता है.

बुनियादी फ़्लो के लिए अनुमति

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

import { genkit, z } from 'genkit';

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

export const selfSummaryFlow = ai.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) => {
    // Flow logic here...
  }
);

इस फ़्लो को लागू करते समय, आपको withLocalAuthContext का इस्तेमाल करके पुष्टि करने वाला ऑब्जेक्ट देना ज़रूरी है. ऐसा न करने पर, आपको गड़बड़ी का मैसेज दिखेगा:

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

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

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

Genkit डेवलपमेंट यूज़र इंटरफ़ेस (यूआई) के साथ चलाते समय, "Auth JSON" टैब में JSON डालकर Auth ऑब्जेक्ट को पास किया जा सकता है: {"uid": "abc-def"}.

getFlowAuth() को कॉल करके, फ़्लो में किसी भी समय फ़्लो के लिए पुष्टि का कॉन्टेक्स्ट भी वापस पाया जा सकता है. इसमें, फ़्लो से शुरू किए गए फ़ंक्शन भी शामिल हैं:

import { genkit, z } from 'genkit';

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

async function readDatabase(uid: string) {
  const auth = ai.getAuthContext();
  if (auth?.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 फ़्लैग की मदद से, इस पुष्टि करने वाले ऑब्जेक्ट की जानकारी दी जा सकती है:

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

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

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

अनुमति देना

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

import { genkit } from 'genkit';
import { firebaseAuth } from '@genkit-ai/firebase';
import { onFlow } from '@genkit-ai/firebase/functions';

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

export const selfSummaryFlow = onFlow(
  ai,
  {
    name: 'selfSummaryFlow',
    inputSchema: z.string(),
    outputSchema: z.string(),
    authPolicy: firebaseAuth((user) => {
      if (!user.email_verified && !user.admin) {
        throw new Error('Email not verified');
      }
    }),
  },
  async (input) => {
        // Flow logic here...
  }
);

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

import { onFlow, noAuth } from "@genkit-ai/firebase/functions";

export const selfSummaryFlow = onFlow(
  ai,
  {
    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(),
  },
  async (input) => {
        // Flow logic here...
  }
);

क्लाइंट इंटिग्रिटी

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

import { onFlow } from "@genkit-ai/firebase/functions";

export const selfSummaryFlow = onFlow(
  ai,
  {
    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: ...,
  },
  async (input) => {
        // Flow logic here...
  }
);

Firebase के अलावा किसी अन्य एचटीटीपी से पुष्टि करना

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

  1. अपनी पसंद का कोई भी सर्वर फ़्रेमवर्क इस्तेमाल करें और ऊपर बताए गए फ़्लो कॉल के ज़रिए पुष्टि करने के लिए कॉन्टेक्स्ट पास करें.

  2. पहले से मौजूद startFlowsServer() का इस्तेमाल करें और फ़्लो कॉन्फ़िगरेशन में एक्सप्रेस मिडलवेयर दें:

    import { genkit, z } from 'genkit';
    
    const ai = genkit({ ... });;
    
    export const selfSummaryFlow = ai.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);
    
            // Pass auth information to the flow
            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) => {
        // Flow logic here...
      }
    );
    
    ai.startFlowServer({
      flows: [selfSummaryFlow],
    });  // Registers the middleware
    

    Express का इस्तेमाल करने के बारे में ज़्यादा जानने के लिए, Cloud Run के निर्देश देखें.

कृपया ध्यान दें कि अगर आपने (1) विकल्प चुना है, तो फ़्लो को सीधे तौर पर शुरू करने पर, middleware कॉन्फ़िगरेशन विकल्प को अनदेखा कर दिया जाएगा.