The Private Vault: AlloyDB Satır Düzeyinde Güvenlik ile "Sıfır Güven Zekası" Oluşturma

1. Genel Bakış

Üretken yapay zeka uygulamaları geliştirme telaşında genellikle en kritik bileşeni, yani güvenliği unutuyoruz.

Bir İK Chatbot'u oluşturduğunuzu düşünün. "Maaşım ne kadar?" veya "Ekibimin performansı nasıl?" gibi soruları yanıtlamasını istiyorsanız

  • Ayşe (normal bir çalışan) sorarsa yalnızca kendi verilerini görmelidir.
  • Bob (bir yönetici) isterse ekibinin verilerini görmelidir.

Sorun

Çoğu RAG (Retrieval Augmented Generation) mimarisi bunu Uygulama Katmanı'nda işlemeye çalışır. Parçaları aldıktan sonra filtreler veya LLM'nin "uygun şekilde davranmasını" bekler. Bu ürün kırılgandır. Uygulama mantığı başarısız olursa veriler sızar.

Çözüm

Güvenliği Veritabanı Katmanı'na kadar indirin. AlloyDB'de PostgreSQL Satır Düzeyinde Güvenlik (RLS)'yi kullanarak, yapay zeka ne isterse istesin veritabanının kullanıcının görmesine izin verilmeyen verileri döndürmeyi fiziksel olarak reddetmesini sağlıyoruz.

Bu kılavuzda, "The Private Vault" adlı bir uygulama oluşturacağız: Oturum açan kullanıcıya göre yanıtlarını dinamik olarak değiştiren güvenli bir İK asistanı.

1e095ac5fe069bb6.png

Mimari

Python'da karmaşık izin mantığı oluşturmuyoruz. Veritabanı motorunun kendisini kullanıyoruz.

  1. Arayüz: Giriş işlemini simüle eden basit bir Streamlit uygulaması.
  2. The Brain: AlloyDB AI (PostgreSQL uyumlu).
  3. Mekanizma: Her işlemin başında bir oturum değişkeni (app.active_user) ayarlarız. Veritabanı politikaları, satırları filtrelemek için otomatik olarak bir user_roles tablosunu (kimlik sağlayıcımız olarak hareket eden) kontrol eder.

Ne oluşturacaksınız?

Güvenli bir İK Asistanı uygulaması. Hassas verileri filtrelemek için uygulama mantığına güvenmek yerine, satır düzeyinde güvenliği (RLS) doğrudan AlloyDB veritabanı motorunda uygulayacaksınız. Bu sayede, yapay zeka modeliniz "halüsinasyon" görse veya yetkisiz verilere erişmeye çalışsa bile veritabanı bu verileri döndürmeyi fiziksel olarak reddeder.

Neler öğreneceksiniz?

Öğrenecekleriniz:

  • RLS için şema tasarlama (Verileri kimlikten ayırma).
  • PostgreSQL politikaları yazma (CREATE POLICY).
  • FORCE ROW LEVEL SECURITY kullanarak "Tablo Sahibi" muafiyetini atlama
  • Kullanıcılar için "Bağlam Değiştirme" işlemi gerçekleştiren bir Python uygulaması oluşturma

Şartlar

  • Chrome veya Firefox gibi bir tarayıcı
  • Faturalandırmanın etkin olduğu bir Google Cloud projesi.
  • Cloud Shell'e veya gcloud ve psql'nin yüklü olduğu bir terminale erişim.

2. Başlamadan önce

Proje oluşturma

  1. Google Cloud Console'daki proje seçici sayfasında bir Google Cloud projesi seçin veya oluşturun.
  2. Cloud projeniz için faturalandırmanın etkinleştirildiğinden emin olun. Bir projede faturalandırmanın etkin olup olmadığını nasıl kontrol edeceğiniziöğrenin.
  1. Google Cloud'da çalışan bir komut satırı ortamı olan Cloud Shell'i kullanacaksınız. Google Cloud Console'un üst kısmından Cloud Shell'i etkinleştir'i tıklayın.

Cloud Shell'i etkinleştir düğmesinin resmi

  1. Cloud Shell'e bağlandıktan sonra aşağıdaki komutu kullanarak kimliğinizin doğrulanmış olduğunu ve projenin proje kimliğinize ayarlandığını kontrol edin:
gcloud auth list
  1. gcloud komutunun projeniz hakkında bilgi sahibi olduğunu doğrulamak için Cloud Shell'de aşağıdaki komutu çalıştırın.
gcloud config list project
  1. Projeniz ayarlanmamışsa ayarlamak için aşağıdaki komutu kullanın:
gcloud config set project <YOUR_PROJECT_ID>
  1. Gerekli API'leri etkinleştirin: Bağlantıyı takip ederek API'leri etkinleştirin.

Alternatif olarak, bu işlem için gcloud komutunu kullanabilirsiniz. gcloud komutları ve kullanımı için belgelere bakın.

gcloud services enable \
  alloydb.googleapis.com \
  compute.googleapis.com \
  cloudresourcemanager.googleapis.com \
  servicenetworking.googleapis.com \
  aiplatform.googleapis.com

Dikkat Edilmesi Gerekenler ve Sorun Giderme

"Hayalet Proje" Sendromu

gcloud config set project komutunu çalıştırdınız ancak Console kullanıcı arayüzünde aslında farklı bir projeye bakıyorsunuz. Sol üstteki açılır listede proje kimliğini kontrol edin.

Faturalandırma Barikatı

Projeyi etkinleştirdiniz ancak faturalandırma hesabını unuttunuz. AlloyDB yüksek performanslı bir motordur. "Yakıt deposu" (faturalandırma) boşsa çalışmaz.

API Yayma Gecikmesi

"API'leri etkinleştir"i tıkladınız ancak komut satırında hâlâ Service Not Enabled yazıyor. 60 saniye bekleyin. Bulutun nöronlarını uyandırması biraz zaman alabilir.

Kota Quags

Yeni bir deneme hesabı kullanıyorsanız AlloyDB örnekleri için bölgesel kotaya ulaşabilirsiniz. us-central1 başarısız olursa us-east1'ı deneyin.

3. Veritabanı kurulumu

Bu laboratuvarda, test verileri için veritabanı olarak AlloyDB'yi kullanacağız. Veritabanları ve günlükler gibi tüm kaynakları tutmak için kümeler kullanılır. Her kümede, verilere erişim noktası sağlayan bir birincil örnek bulunur. Tablolar gerçek verileri içerir.

Test veri kümesinin yükleneceği bir AlloyDB kümesi, örneği ve tablosu oluşturalım.

  1. Google Cloud Console kullanıcısının oturumunun açık olduğu tarayıcıda düğmeyi tıklayın veya aşağıdaki bağlantıyı tarayıcınıza kopyalayın.

  1. Bu adım tamamlandıktan sonra depo yerel Cloud Shell düzenleyicinize klonlanır ve aşağıdaki komutu proje klasöründen çalıştırabilirsiniz (proje dizininde olduğunuzdan emin olmanız önemlidir):
sh run.sh
  1. Şimdi kullanıcı arayüzünü kullanın (terminaldeki bağlantıyı veya terminaldeki "web'de önizleme" bağlantısını tıklayarak).
  2. Başlamak için proje kimliği, küme ve örnek adlarıyla ilgili ayrıntılarınızı girin.
  3. Günlükler kayarken kahve almaya gidebilirsiniz. Bu işlemin arka planda nasıl yapıldığı hakkında bilgi edinmek için burayı ziyaret edebilirsiniz. Bu işlem yaklaşık 10-15 dakika sürebilir.

Dikkat Edilmesi Gerekenler ve Sorun Giderme

"Sabır" Sorunu

Veritabanı kümeleri ağır altyapılardır. Sayfayı yenilerseniz veya "takılmış gibi göründüğü" için Cloud Shell oturumunu sonlandırırsanız kısmen sağlanan ve manuel müdahale olmadan silinmesi mümkün olmayan bir "hayalet" örneğiniz olabilir.

Bölge Uyuşmazlığı

API'lerinizi us-central1 içinde etkinleştirdiyseniz ancak kümeyi asia-south1 içinde sağlamaya çalışırsanız kota sorunları veya hizmet hesabı izinleriyle ilgili gecikmelerle karşılaşabilirsiniz. Tüm laboratuvar için tek bir bölgeye bağlı kalın.

Zombi Kümeleri

Daha önce bir küme için aynı adı kullandıysanız ve bu adı silmediyseniz komut dosyası, küme adının zaten mevcut olduğunu söyleyebilir. Küme adları, proje içinde benzersiz olmalıdır.

Cloud Shell Zaman Aşımı

Kahve molanız 30 dakika sürerse Cloud Shell uyku moduna geçebilir ve sh run.sh işleminin bağlantısını kesebilir. Sekmeyi etkin tutun.

4. Şema Sağlama

Bu adımda şu konuları ele alacağız:

d05d7d2706c689dc.png

Ayrıntılı adım adım işlemler aşağıda verilmiştir:

AlloyDB kümeniz ve örneğiniz çalıştıktan sonra yapay zeka uzantılarını etkinleştirmek ve şemayı sağlamak için AlloyDB Studio SQL düzenleyicisine gidin.

1e3ac974b18a8113.png

Örneğinizin oluşturulma işleminin tamamlanmasını beklemeniz gerekebilir. Bu işlem tamamlandıktan sonra, kümeyi oluştururken oluşturduğunuz kimlik bilgilerini kullanarak AlloyDB'de oturum açın. PostgreSQL'de kimlik doğrulaması yapmak için aşağıdaki verileri kullanın:

  • Kullanıcı adı : "postgres"
  • Veritabanı : "postgres"
  • Şifre : "alloydb" (veya oluşturma sırasında ayarladığınız şifre)

AlloyDB Studio'da kimliğinizi başarıyla doğruladıktan sonra SQL komutları Düzenleyici'ye girilir. Son pencerenin sağındaki artı işaretini kullanarak birden fazla Editor penceresi ekleyebilirsiniz.

28cb9a8b6aa0789f.png

Gerekli durumlarda Çalıştır, Biçimlendir ve Temizle seçeneklerini kullanarak AlloyDB için komutları düzenleyici pencerelerine gireceksiniz.

Tablo oluşturma

İki tabloya ihtiyacımız var: biri hassas veriler (çalışanlar), diğeri ise kimlik kuralları (user_roles) için. Politikalarda "Sonsuz Özyineleme" hatalarını önlemek için bunları ayırmak çok önemlidir.

AlloyDB Studio'da aşağıdaki DDL ifadesini kullanarak bir tablo oluşturabilirsiniz:

-- 1. Create User Roles (The Identity Provider)
CREATE TABLE user_roles (
    username TEXT PRIMARY KEY,
    role TEXT -- 'employee', 'manager', 'admin'
);

INSERT INTO user_roles (username, role) VALUES
('Alice', 'employee'),
('Bob', 'manager'),
('Charlie', 'employee');

-- 2. Create the Data Table
CREATE TABLE employees (
    id SERIAL PRIMARY KEY,
    name TEXT,
    salary INTEGER,
    performance_review TEXT
);

INSERT INTO employees (name, salary, performance_review) VALUES
('Alice', 80000, 'Alice meets expectations but needs to improve punctuality.'),
('Bob', 120000, 'Bob is a strong leader. Team morale is high.'),
('Charlie', 85000, 'Charlie exceeds expectations. Ready for promotion.');

Dikkat Edilmesi Gerekenler ve Sorun Giderme

Çalışan tablosunda roller tanımlanırken sonsuz yineleme algılandı

Neden başarısız olur? Politikanızda "Yönetici olup olmadığımı görmek için çalışan tablosunu kontrol et" ifadesi yer alıyorsa veritabanının politikayı kontrol etmek için tabloyu sorgulaması gerekir. Bu da politikayı tekrar tetikler.Sonuç: Sonsuz özyineleme algılandı.Düzeltme: Her zaman ayrı bir arama tablosu (user_roles) tutun veya roller için gerçek veritabanı kullanıcılarını kullanın.

Verileri doğrulayın:

SELECT count(*) FROM employees;
-- Output: 3

5. Güvenliği Etkinleştirme ve Uygulama

Şimdi kalkanları açıyoruz. Ayrıca, Python kodumuzun bağlanmak için kullanacağı genel bir "Uygulama Kullanıcısı" oluşturacağız.

AlloyDB Sorgu Düzenleyici'den aşağıdaki SQL ifadesini çalıştırın:

-- 1. Activate RLS
ALTER TABLE employees ENABLE ROW LEVEL SECURITY;


-- 2. CRITICAL: Force RLS for Table Owners
ALTER TABLE employees FORCE ROW LEVEL SECURITY;


-- 3. Create the Application User
DO
$do$
BEGIN
   IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'app_user') THEN
      CREATE ROLE app_user LOGIN PASSWORD 'password';
   END IF;
END
$do$;


-- 4. Grant Access
GRANT SELECT ON employees TO app_user;
GRANT SELECT ON user_roles TO app_user;

Gotchas & Troubleshooting

postgres (Superuser) olarak test yapıyorum ve tüm verileri görüyorum.

Neden başarısız olur? RLS, varsayılan olarak tablo sahibi veya süper kullanıcılar için geçerli değildir. Tüm politikaları atlar.Sorun giderme: Politikalarınız "bozuk" görünüyorsa (her şeye izin veriyorsa) postgres olarak giriş yapıp yapmadığınızı kontrol edin.Düzeltme: FORCE ROW LEVEL SECURITY komutu, sahibin bile kurallara tabi olmasını sağlar. Bu, test için çok önemlidir.

6. Erişim politikalarını oluşturma

Uygulama kodumuzdan daha sonra ayarlayacağımız bir oturum değişkeni (app.active_user) kullanarak iki kural tanımlayacağız.

AlloyDB Sorgu Düzenleyici'den aşağıdaki SQL ifadesini çalıştırın:

-- Policy 1: Self-View
-- Users can see rows where their name matches the session variable
CREATE POLICY "view_own_data" ON employees
FOR SELECT
USING (name = current_setting('app.active_user', true));

-- Policy 2: Manager-View
-- Managers can see ALL rows.
CREATE POLICY "manager_view_all" ON employees
FOR SELECT
USING (
    EXISTS (
        SELECT 1 FROM user_roles
        WHERE username = current_setting('app.active_user', true)
        AND role = 'manager'
    )
);

Dikkat Edilmesi Gerekenler ve Sorun Giderme

app.active_user yerine current_user kullanılıyor.

Sorun: Current_user, veritabanı rolünü (ör. app_user) döndüren ayrılmış bir SQL anahtar kelimesidir. Uygulama kullanıcısının (ör. Alice).Düzeltme: Her zaman app.variable_name gibi özel bir ad alanı kullanın.

current_setting içinde true parametresinin unutulması.

Sorun: Değişken ayarlanmamışsa sorgu hata vererek kilitleniyor.Düzeltme: current_setting('...', true) kilitlenmek yerine NULL döndürüyor. Bu da güvenli bir şekilde 0 satır döndürülmesine neden oluyor.

7. "Chameleon" uygulamasını oluşturma

Uygulama mantığını simüle etmek için Python ve Streamlit'i kullanacağız.

296a980887b5c700.png

Cloud Shell Terminal'i Düzenleyici modunda açın, kök klasörünüze veya bu uygulamayı oluşturmak istediğiniz dizine gidin. Yeni bir klasör oluşturun.

1. Bağımlılıkları Yükle:

Cloud Shell terminalinde yeni proje dizininizden aşağıdaki komutu çalıştırın:

pip install streamlit psycopg2-binary

2. app.py dosyasını oluşturun:

app.py adlı yeni bir dosya oluşturun ve repo dosyasındaki içeriği kopyalayın.

import streamlit as st
import psycopg2

# CONFIGURATION (Replace with your IP)
DB_HOST = "10.x.x.x"
DB_NAME = "postgres"
DB_USER = "postgres"
DB_PASS = "alloydb"

def get_db_connection():
    return psycopg2.connect(
        host=DB_HOST, database=DB_NAME, user=DB_USER, password=DB_PASS
    )

def query_database(user_name):
    conn = get_db_connection()
    try:
        with conn.cursor() as cur:
            # THE SECURITY HANDSHAKE
            # We tell the database: "For this transaction, I am acting as..."
            cur.execute(f"SET app.active_user = '{user_name}';")
            
            # THE BLIND QUERY
            # We ask for EVERYTHING. The database silently filters it.
            cur.execute("SELECT name, role, salary, performance_review FROM employees;")
            return cur.fetchall()
    finally:
        conn.close()

# UI
st.title("🛡️ The Private Vault")
user = st.sidebar.radio("Act as User:", ["Alice", "Bob", "Charlie", "Eve"])

if st.button("Access Data"):
    results = query_database(user)
    if not results:
        st.error("🚫 Access Denied.")
    else:
        st.success(f"Viewing data as {user}")
        for row in results:
            st.write(row)

3. Uygulamayı çalıştırın:

Cloud Shell terminalinde yeni proje dizininizden aşağıdaki komutu çalıştırın:

streamlit run app.py --server.port 8080 --server.enableCORS false

Dikkat Edilmesi Gerekenler ve Sorun Giderme

Bağlantı havuzu.

Risk: Bağlantı havuzu kullanıyorsanız SET app.active_user oturum değişkeni bağlantıda kalıcı olabilir ve bu bağlantıyı alan bir sonraki kullanıcıya "sızabilir". Düzeltme: Üretim ortamında, bağlantıyı havuza döndürürken her zaman RESET app.active_user veya DISCARD ALL kullanın.

Cloud Shell'de boş ekran.

Düzeltme: 8080 numaralı bağlantı noktasında "Web Önizlemesi" düğmesini kullanın. Terminaldeki localhost bağlantısını tıklamayın.

8. Sıfır güveni doğrulama

Sıfır güven uygulamasının doğru şekilde yapıldığından emin olmak için uygulamayı deneyin:

"Alice" seçeneğini belirleyin: 1 satır (kendisi) görmelidir.

b3b7e374fa66ac87.png

"Bob"'u seçin: 3 satır (Herkes) görmelidir.

fdc65cb1acdee8a4.png

Bu, yapay zeka temsilcileri için neden önemli?

Modelinizi bu veritabanına bağladığınızı düşünün. Bir kullanıcı modelinize "Tüm performans değerlendirmelerini özetle" diye sorarsa SELECT performance_review FROM employees ifadesi oluşturulur.

  1. RLS olmadan: Modeliniz herkesin özel yorumlarını alır ve bunları Ayşe'ye sızdırır.
  2. RLS ile: Modeliniz tam olarak aynı sorguyu çalıştırır ancak veritabanı yalnızca Ayşe'nin yorumunu döndürür.

Bu, sıfır güven temelli yapay zekadır. Verileri filtrelemek için modele güvenmiyorsunuz. Veritabanını verileri gizlemeye zorluyorsunuz.

Üretime alma

Burada gösterilen mimari, üretim düzeyindedir ancak belirli uygulama, öğrenme amacıyla basitleştirilmiştir. Bunu gerçek dünyadaki bir kurumsal ortamda güvenli bir şekilde dağıtmak için aşağıdaki geliştirmeleri uygulamanız gerekir:

  1. Gerçek kimlik doğrulama: "Kimlik Değiştirici" açılır listesini Google Identity Platform, Okta veya Auth0 gibi güçlü bir kimlik sağlayıcıyla (IDP) değiştirin. Uygulamanız, veritabanı oturumu değişkenini ayarlamadan önce kullanıcının jetonunu doğrulamalı ve kimliğini güvenli bir şekilde çıkarmalıdır. Böylece kullanıcıların kimliklerini taklit etmesi önlenir.
  2. Bağlantı havuzu güvenliği: Bağlantı havuzları kullanılırken oturum değişkenleri doğru şekilde işlenmezse bazen farklı kullanıcı isteklerinde kalıcı olabilir. Uygulamanızın oturum değişkenini (ör. RESET app.active_user) veya kullanıcılar arasında veri sızıntısını önlemek için bağlantıyı havuza döndürürken bağlantı durumunu temizler.
  3. Gizli Yönetimi: Veritabanı kimlik bilgilerinin sabit kodlanması güvenlik riski oluşturur. Veritabanı şifrelerinizi ve bağlantı dizelerinizi çalışma zamanında güvenli bir şekilde depolamak ve almak için Google Secret Manager gibi özel bir gizli anahtar yönetimi hizmeti kullanın.

9. Temizleme

Bu laboratuvar tamamlandıktan sonra AlloyDB kümesini ve örneğini silmeyi unutmayın.

Küme, örnekleriyle birlikte temizlenmelidir.

10. Tebrikler

Tebrikler! Güvenliği başarıyla veri katmanına taşıdınız. Python kodunuzda print(all_salaries) denemeye çalışan bir hata olsa bile veritabanı Alice'e hiçbir şey döndürmez.

Sonraki Adımlar