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

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

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

किसी फ़्लो में अनुमति देना

फ़्लो, अनुमति की जांच दो तरीकों से कर सकते हैं: अनुरोध बाइंडिंग (उदाहरण के लिए, Firebase के लिए Cloud Functions या express के लिए onCallGenkit) अनुमति लागू कर सकता है या वे फ़्रेमवर्क, अनुमति की नीतियों को फ़्लो में पास कर सकते हैं. फ़्लो में, फ़्लो में मैनेज की गई अनुमति की जानकारी का ऐक्सेस होता है.

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 (Firebase Authentication), context.app (Firebase App Check), और 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 डेवलपमेंट यूज़र इंटरफ़ेस (यूआई) के साथ चलाते समय, "Auth JSON" टैब में JSON डालकर Auth ऑब्जेक्ट को पास किया जा सकता है: {"uid": "abc-def"}.

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

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 डेवलपर टूल की मदद से फ़्लो की जांच करते समय, यूज़र इंटरफ़ेस (यूआई) में या --context फ़्लैग की मदद से कमांड लाइन पर, इस पुष्टि करने वाले ऑब्जेक्ट की जानकारी दी जा सकती है:

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

'Firebase के लिए Cloud Functions' का इस्तेमाल करने की अनुमति देना

Firebase के लिए Cloud Functions SDK टूल, Genkit के साथ काम करते हैं. इनमें Firebase Auth / Google Cloud Identity Platform के साथ इंटिग्रेशन के साथ-साथ, पहले से मौजूद Firebase ऐप्लिकेशन की जांच करने की सुविधा भी शामिल है.

उपयोगकर्ता की पुष्टि

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

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

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

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

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

पुष्टि करने की प्रोसेस से आपके ऐप्लिकेशन को सुरक्षित रखने में काफ़ी मदद मिलती है. हालांकि, यह पक्का करना भी ज़रूरी है कि सिर्फ़ आपके क्लाइंट ऐप्लिकेशन आपके फ़ंक्शन को कॉल कर रहे हों. Genkit के लिए Firebase प्लग इन में, 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);

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

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

auth जैसी कॉन्टेक्स्ट वैल्यू को पॉप्युलेट करने के लिए, ContextProvider का इस्तेमाल करें. साथ ही, एलान वाली नीति या नीति का कॉलबैक देने के लिए भी इसका इस्तेमाल करें. Genkit SDK टूल, apiKey जैसे ContextProvider उपलब्ध कराता है. साथ ही, प्लग इन भी उन्हें एक्सपोज़ कर सकते हैं. उदाहरण के लिए, @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}`);
})

ContextProviders वेब फ़्रेमवर्क को अलग रखता है, इसलिए ये टूल Next.js जैसे दूसरे फ़्रेमवर्क में भी काम करते हैं. यहां Next.js पर बनाए गए Firebase ऐप्लिकेशन का उदाहरण दिया गया है.

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

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

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