Yetkilendirme ve bütünlük

Herkese açık bir uygulama geliştirirken sisteminizde saklanan verileri korumak son derece önemlidir. LLM'ler söz konusu olduğunda, modelin yalnızca gerekli verilere eriştiğinden, araç çağrılarının LLM'yi çağıran kullanıcıya uygun şekilde kapsamlandırıldığından ve akışın yalnızca doğrulanmış istemci uygulamaları tarafından çağrıldığından emin olmak için daha fazla özen gösterilmesi gerekir.

Firebase Genkit, yetkilendirme politikalarını ve bağlamlarını yönetmek için mekanizmalar sağlar. Cloud Functions for Firebase'de çalışan akışlar için geliştiricilerin bir kimlik doğrulama politikası sağlaması veya politikanın bulunmadığını açıkça kabul etmesi gerekir. Functions dışı akışlar için kimlik doğrulama da yönetilebilir ve ayarlanabilir ancak biraz daha manuel entegrasyon gerektirir.

Temel akış yetkilendirmesi

Tüm akışlar yapılandırmalarında bir authPolicy tanımlayabilir. Kimlik doğrulama politikası, belirli ölçütlerin (sizin tarafınızdan tanımlanan) karşılanıp karşılanmadığını test eden ve herhangi bir test başarısız olursa istisna atan bir işlevdir. Bu alan ayarlanırsa akış çağrılmadan önce yürütülür:

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...
  }
);

Bu akışı yürüttüğünüzde withLocalAuthContext kullanarak bir kimlik doğrulama nesnesi sağlamanız gerekir. Aksi takdirde hata alırsınız:

// 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 Geliştirme kullanıcı arayüzüyle çalışırken "Auth JSON" sekmesine JSON girerek Auth nesnesini iletebilirsiniz: {"uid": "abc-def"}.

Ayrıca akış tarafından çağrılan işlevler dahil olmak üzere akış içinde dilediğiniz zaman getFlowAuth()'yi çağırarak akış için kimlik doğrulama bağlamını alabilirsiniz:

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 geliştirici araçlarıyla akışları test ederken bu kimlik doğrulama nesnesini kullanıcı arayüzünde veya komut satırında --auth işaretiyle belirtebilirsiniz:

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

Cloud Functions for Firebase entegrasyonu

Firebase eklentisi, Firebase Auth / Google Cloud Identity Platform ile kolay entegrasyon ve yerleşik Firebase App Check desteği sunar.

Yetkilendirme

Firebase eklentisi tarafından sağlanan onFlow() sarmalayıcı, Firebase için Cloud Functions istemci SDK'larıyla yerel olarak çalışır. SDK kullanılırken, uygulama istemciniz de Firebase Auth SDK'sını kullandığı sürece Firebase Auth başlığı otomatik olarak eklenir. onFlow() ile tanımlanan akışlarınızı korumak için Firebase Auth'i kullanabilirsiniz:

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 eklentisi kullanılırken user, DecodedIdToken olarak döndürülür. Bu nesneyi dilediğiniz zaman yukarıda belirtildiği gibi getFlowAuth() aracılığıyla alabilirsiniz. Geliştirme sırasında bu akışı çalıştırırken kullanıcı nesnesini aynı şekilde iletirsiniz:

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

Firebase Auth eklentisi varsayılan olarak kimlik doğrulama üstbilgisinin istemci tarafından gönderilmesini gerektirir. Ancak kimliği doğrulanmış kullanıcılar için özel işlemlerle kimliği doğrulanmamış erişime izin vermek istediğiniz durumlarda (ör. upsell özellikleri) politikayı aşağıdaki gibi yapılandırabilirsiniz:

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

Bir Cloud işlevini daha geniş bir internet kullanıcı kitlesine sunduğunuzda verilerinizi ve müşterilerinizin verilerini korumak için bir tür yetkilendirme mekanizması kullanmanız son derece önemlidir. Bununla birlikte, kod tabanlı yetkilendirme kontrolleri içermeyen bir Cloud Functions işlevi dağıtmanız gereken durumlar olabilir (örneğin, işleviniz herkes tarafından çağrılabilir değil, Cloud IAM tarafından korunuyor olabilir). onFlow() kullanırken authPolicy alanı her zaman gereklidir ancak noAuth() işlevini kullanarak kitaplığa yetkilendirme kontrollerinden vazgeçtiğinizi belirtebilirsiniz:

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...
  }
);

Müşteri bütünlüğü

Kimlik doğrulama, uygulamanızı korumak için tek başına çok önemli bir adımdır. Ancak işlevlerinizin yalnızca istemci uygulamalarınızın çağırdığından emin olmak da önemlidir. Genkit için Firebase eklentisi, Firebase Uygulama Kontrolü için birinci sınıf destek içerir. onFlow() dosyanıza aşağıdaki yapılandırma seçeneklerini eklemeniz yeterlidir:

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 dışı HTTP yetkilendirmesi

Firebase için Cloud Functions dışındaki bir sunucu bağlamına akış dağıtırken, yerel akışlarla birlikte kendi yetkilendirme kontrollerinizi ayarlamanızı sağlayacak bir yönteme sahip olmanız gerekir. İki seçeneğiniz vardır:

  1. İstediğiniz sunucu çerçevesini kullanın ve yukarıda belirtildiği gibi akış çağrısı üzerinden kimlik doğrulama bağlamını iletin.

  2. Dahili startFlowsServer()'ü kullanın ve akış yapılandırmasında Express aracısı sağlayın:

    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'i kullanma hakkında daha fazla bilgi için Cloud Run talimatlarına bakın.

(1) seçeneğini belirlerseniz middleware yapılandırma seçeneğinin, akış doğrudan çağrıldığında yoksayıldığını lütfen unutmayın.