Saat mem-build aplikasi yang ditampilkan kepada publik, sangat penting untuk melindungi data yang disimpan di sistem Anda. Dalam hal LLM, ketelitian ekstra diperlukan untuk memastikan bahwa model hanya mengakses data yang seharusnya, panggilan alat diberi cakupan yang tepat untuk pengguna yang memanggil LLM, dan alur hanya dipanggil oleh aplikasi klien terverifikasi.
Firebase Genkit menyediakan mekanisme untuk mengelola kebijakan dan konteks otorisasi. Alur yang berjalan di Firebase dapat menggunakan callback (atau helper) kebijakan autentikasi. Atau, Firebase juga menyediakan konteks autentikasi ke dalam alur tempat Firebase dapat melakukan pemeriksaannya sendiri. Untuk alur non-Fungsi, autentikasi dapat dikelola dan ditetapkan melalui middleware.
Memberi otorisasi dalam Alur
Alur dapat memeriksa otorisasi dengan dua cara: binding permintaan (misalnya, onCallGenkit
untuk Cloud Functions for Firebase atau express
) dapat menerapkan otorisasi, atau framework tersebut dapat meneruskan kebijakan autentikasi ke alur itu sendiri, dengan alur memiliki akses ke informasi untuk autentikasi yang dikelola dalam alur.
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...
});
Dalam hal ini, pengikatan permintaan akan mengisi context.auth
. Misalnya, onCallGenkit
secara otomatis mengisi context.auth
(Firebase Authentication), context.app
(Firebase App Check), dan context.instanceIdToken
(Firebase Cloud Messaging). Saat memanggil alur
secara manual, Anda dapat menambahkan konteks autentikasi Anda sendiri secara manual.
// 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' } },
}
);
Saat berjalan dengan UI Pengembangan Genkit, Anda dapat meneruskan objek Auth dengan
memasukkan JSON di tab "Auth JSON": {"uid": "abc-def"}
.
Anda juga dapat mengambil konteks autentikasi untuk alur kapan saja dalam alur
dengan memanggil ai.currentContext()
, termasuk dalam fungsi yang dipanggil oleh alur:
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);
}
);
Saat menguji alur dengan alat developer Genkit, Anda dapat menentukan objek autentikasi
ini di UI, atau di command line dengan flag --context
:
genkit flow:run selfSummaryFlow '{"uid": "abc-def"}' --context '{"auth": {"email_verified": true}}'
Memberikan otorisasi menggunakan Cloud Functions for Firebase
Cloud Functions for Firebase SDK mendukung Genkit termasuk integrasi dengan Firebase Auth / Google Cloud Identity Platform, serta dukungan Firebase App Check bawaan.
Autentikasi pengguna
Wrapper onCallGenkit()
yang disediakan oleh library Firebase Functions memiliki dukungan bawaan untuk SDK klien Cloud Functions for Firebase.
Saat Anda menggunakan SDK ini, header Firebase Auth akan otomatis disertakan selama klien aplikasi Anda juga menggunakan Firebase Auth SDK.
Anda dapat menggunakan Firebase Auth untuk melindungi alur yang ditentukan dengan 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);
Saat Anda menggunakan onCallGenkit
, context.auth
akan ditampilkan sebagai objek dengan
uid
untuk ID pengguna, dan token
yang merupakan
DecodedIdToken.
Anda dapat mengambil objek ini kapan saja menggunakan ai.currentContext()
seperti
yang disebutkan sebelumnya. Saat menjalankan alur ini selama pengembangan, Anda akan meneruskan
objek pengguna dengan cara yang sama:
genkit flow:run selfSummaryFlow '{"uid": "abc-def"}' --context '{"auth": {"admin": true}}'
Setiap kali Anda mengekspos Cloud Function ke internet yang lebih luas, Anda harus menggunakan semacam mekanisme otorisasi untuk melindungi data Anda dan data pelanggan Anda. Dengan demikian, ada kalanya Anda perlu men-deploy Cloud Function tanpa pemeriksaan otorisasi berbasis kode (misalnya, Fungsi Anda tidak dapat dipanggil oleh semua orang, tetapi dilindungi oleh Cloud IAM).
Cloud Functions for Firebase memungkinkan Anda melakukannya menggunakan properti invoker
, yang mengontrol akses IAM. Nilai khusus 'private'
akan membuat fungsi tersebut menjadi setelan IAM default, yang berarti hanya pemanggil dengan peran Cloud Run Invoker yang dapat menjalankan fungsi tersebut. Sebagai gantinya, Anda dapat memberikan alamat email pengguna atau akun layanan yang harus diberi izin untuk memanggil fungsi yang tepat ini.
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);
Integritas klien
Autentikasi itu sendiri sangat membantu melindungi aplikasi Anda. Namun, penting juga untuk memastikan bahwa hanya aplikasi klien Anda yang memanggil fungsi Anda. Plugin Firebase untuk genkit menyertakan dukungan kelas satu untuk Firebase App Check. Lakukan hal ini dengan
menambahkan opsi konfigurasi berikut ke onCallGenkit()
Anda:
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);
Otorisasi HTTP non-Firebase
Saat men-deploy alur ke konteks server di luar Cloud Functions for Firebase, Anda harus memiliki cara untuk menyiapkan pemeriksaan otorisasi Anda sendiri bersama dengan alur bawaan.
Gunakan ContextProvider
untuk mengisi nilai konteks seperti auth
, dan untuk
memberikan kebijakan deklaratif atau callback kebijakan. Genkit SDK menyediakan ContextProvider
seperti apiKey
, dan plugin juga dapat mengeksposnya. Misalnya, plugin @genkit-ai/firebase/context
mengekspos penyedia konteks untuk memverifikasi kredensial Firebase Auth dan mengisinya ke dalam konteks.
Dengan kode seperti berikut, yang mungkin muncul di berbagai aplikasi:
// 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...
}
);
Anda dapat mengamankan aplikasi ekspres "server flow" sederhana dengan menulis:
import { apiKey } from "genkit";
import { startFlowServer, withContext } from "@genkit-ai/express";
startFlowServer({
flows: [
withContext(selfSummaryFlow, apiKey(process.env.REQUIRED_API_KEY))
],
});
Atau, Anda dapat mem-build aplikasi ekspres kustom menggunakan alat yang sama:
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
memisahkan framework web, sehingga alat ini juga berfungsi di framework lain seperti Next.js. Berikut adalah contoh aplikasi Firebase yang dibuat di Next.js.
import { appRoute } from "@genkit-ai/express";
import { firebaseContext } from "@genkit-ai/firebase";
export const POST = appRoute(selfSummaryFlow, { contextProvider: firebaseContext })
Untuk informasi selengkapnya tentang penggunaan Express, lihat petunjuk Cloud Run.