2026-03-22
SaaS Yetkilendirme için AWS Cognito + Verified Permissions
AWS Cognito ve Verified Permissions ile SaaS yetkilendirme mimarisi. Cedar politika dili, çok kiracılı desenler, JWT token akışı, maliyet analizi ve TypeScript örnekleriyle yaygın hatalar.
Abstract
AWS Cognito kimlik doğrulamayı yönetir. AWS Verified Permissions (AVP) yetkilendirmeyi yönetir. Birlikte AWS’nin yerel SaaS yetkilendirme altyapısını oluşturur. Bu yazıda iki servisin nasıl entegre edildiğini, Cedar politikalarının kiracı izolasyonunu nasıl sağladığını ve B2B SaaS ürünleri için çok kiracılı yetkilendirmenin nasıl yapılandırılacağını inceliyoruz. TypeScript entegrasyon kodu, Cedar politika örnekleri, maliyet analizi ve Microsoft Entra ID yaklaşımıyla bir karşılaştırma içerir.
Note: Bu yazı Harici Yetkilendirme Sistemleri serisinin 2. bölümüdür. 1. bölüm, daha geniş yetkilendirme platformu haritasını ve karar çerçevesini kapsar.
Cognito’nun Yetkilendirmedeki Rolü
Cognito bir kimlik doğrulama servisidir, yetkilendirme motoru değildir. Ancak kimlik doğrulama ve yetkilendirme SaaS sistemlerinde sıkı sıkıya bağlıdır. Cognito’nun çıktısı — claim’ler içeren JWT token’lar — yetkilendirme kararlarının girdisi olur.
JWT Token’lar ve Claim’ler
Kullanıcı kimliğini doğruladıktan sonra Cognito üç token verir:
- ID Token: Kullanıcı kimlik claim’lerini içerir (e-posta, ad, özel nitelikler). Kullanıcı profil bilgileri için kullanılır.
- Access Token: Scope’lar ve yetkilendirmeyle ilgili claim’leri içerir. API yetkilendirmesi için kullanılır.
- Refresh Token: Yeniden kimlik doğrulama olmadan yeni ID ve access token almak için kullanılır.
Yetkilendirme açısından access token en önemlisidir. AVP Cedar politikalarının değerlendirdiği claim’leri taşır.
Özel Claim’ler ve Kiracı Bağlamı
Cognito, kullanıcı profillerinde özel nitelikler destekler (custom: ön ekiyle). SaaS için kritik özel nitelikler, kiracı tanımlayıcıları ve organizasyon rolleridir:
custom:tenantId— Kullanıcının ait olduğu kiracıcustom:orgRole— Kullanıcının kiracı içindeki rolü (admin, editor, viewer)custom:tenantTier— Kiracının abonelik katmanı (free, pro, enterprise)
Bu nitelikler kullanıcı kaydı sırasında veya bir admin API’si aracılığıyla ayarlanır. Kullanıcı tarafından değiştirilemez (uygulama istemcisinde salt okunur) ve kimlik doğrulamadan sonra JWT token’lara dahil edilir.
Pre Token Generation Trigger
Pre Token Generation Lambda trigger’ı, Cognito ile AVP arasındaki anahtar entegrasyon noktasıdır. Cognito access token’ı vermeden önce çalışır ve Cedar politikalarının tükettiği ek claim’lerle token’ı zenginleştirmenize olanak tanır.
// Pre Token Generation V2 trigger -- token'ları kiracı bağlamıyla zenginleştir
// Cognito, access token'ı vermeden önce bu Lambda'yı çağırır
import { PreTokenGenerationV2TriggerEvent } from "aws-lambda";
export const handler = async (
event: PreTokenGenerationV2TriggerEvent
) => {
const tenantId = event.request.userAttributes["custom:tenantId"];
const orgRole = event.request.userAttributes["custom:orgRole"];
const tenantTier = event.request.userAttributes["custom:tenantTier"];
// Kiracı bağlamını claim olarak ekle -- AVP Cedar politikaları bunları okur
event.response = {
claimsAndScopeOverrideDetails: {
accessTokenGeneration: {
claimsToAddOrOverride: {
tenantId: tenantId,
orgRole: orgRole,
tenantTier: tenantTier,
},
scopesToAdd: orgRole === "admin" ? ["tenant:admin"] : [],
},
},
};
return event;
};
Tip: Özel claim’leri minimal tutun. Her ek claim token boyutunu artırır. Cognito access token’larının boyut limiti vardır ve şişkin token’lar her API çağrısına gecikme ekler. Yalnızca Cedar politikalarının aktif olarak değerlendirdiği claim’leri dahil edin.
User Pool vs. Identity Pool
Cognito’nun farklı amaçlara hizmet eden iki bileşeni vardır:
- User Pool: Kullanıcı kimlik doğrulamasını yönetir (kayıt, giriş, MFA, parola kurtarma). JWT token’ları verir. Kiracı bağlamı burada yaşar.
- Identity Pool: Kimliği doğrulanmış kullanıcıları geçici AWS kimlik bilgilerine (IAM rolleri) eşler. Doğrudan AWS kaynak erişimi (S3, DynamoDB) için kullanılır.
AVP ile SaaS yetkilendirmesi için öncelikle User Pool kullanılır. Identity Pool yalnızca uygulamanızın istemci tarafından doğrudan AWS kaynak erişimine ihtiyacı varsa geçerlidir.
AWS Verified Permissions Derinlemesine İnceleme
AVP, Cedar politika dilini kullanan yönetilen bir yetkilendirme servisidir. Yetkilendirme isteklerini Cedar politikalarına göre değerlendirir ve izin ver veya reddet kararları döndürür.
Cedar Politika Dili
Cedar bildirimsel, statik olarak analiz edilebilir ve formal olarak doğrulanmıştır. Politikalar kimin (principal) ne yapabileceğini (action) hangi kaynağa (resource) hangi koşullar altında ifade eder.
Temel bir Cedar politikası:
// Kiracı yöneticilerinin kendi kiracılarındaki tüm kaynakları yönetmesine izin ver
permit(
principal,
action in [Action::"ViewReport", Action::"EditReport", Action::"DeleteReport"],
resource
)
when {
principal.orgRole == "admin" &&
principal.tenantId == resource.tenantId
};
Cedar iki politika türünü destekler:
- permit: Koşullar eşleştiğinde erişim verir
- forbid: Bir permit politikası eşleşse bile erişimi reddeder (forbid her zaman kazanır)
Bu “reddet, izni geçersiz kılar” modeli güvenlik kısıtlamaları eklemeyi basitleştirir:
// Rolden bağımsız olarak arşivlenmiş kaynaklara erişimi yasakla
forbid(
principal,
action,
resource
)
when {
resource.status == "archived"
};
Şema Tanımı
AVP, varlık türlerinizi, niteliklerini ve geçerli eylem-varlık kombinasyonlarını tanımlamak için bir Cedar şeması kullanır. Şema isteğe bağlıdır ancak üretim ortamı için kesinlikle önerilir. Politika oluşturma zamanında doğrulama sağlayarak, yazım hatalarını ve yapısal hataları üretime ulaşmadan yakalar.
{
"SaasApp": {
"entityTypes": {
"User": {
"shape": {
"type": "Record",
"attributes": {
"tenantId": { "type": "String", "required": true },
"orgRole": { "type": "String", "required": true },
"tenantTier": { "type": "String", "required": true },
"email": { "type": "String", "required": true }
}
},
"memberOfTypes": ["TenantGroup"]
},
"TenantGroup": {
"shape": {
"type": "Record",
"attributes": {
"tenantId": { "type": "String", "required": true }
}
}
},
"Document": {
"shape": {
"type": "Record",
"attributes": {
"tenantId": { "type": "String", "required": true },
"ownerId": { "type": "String", "required": true },
"status": { "type": "String", "required": true },
"sensitivity": { "type": "String", "required": false }
}
}
}
},
"actions": {
"ViewDocument": {
"appliesTo": {
"principalTypes": ["User"],
"resourceTypes": ["Document"]
}
},
"EditDocument": {
"appliesTo": {
"principalTypes": ["User"],
"resourceTypes": ["Document"]
}
},
"DeleteDocument": {
"appliesTo": {
"principalTypes": ["User"],
"resourceTypes": ["Document"]
}
}
}
}
}
Policy Store Yapılandırması
Policy store, Cedar şemanız, politikalarınız ve kimlik kaynağı yapılandırmanızın konteyneridir. Temel mimari karar, kiracı başına bir policy store mu yoksa tüm kiracılar için paylaşımlı bir policy store mu kullanılacağıdır.
SaaS Çok Kiracılı Desenler
Çok kiracılık, SaaS yetkilendirmesindeki temel zorluktur. Soru, kiracıları birbirinden nasıl izole edecek ve yetkilendirme altyapısını yönetilebilir tutmaktır.
Pool Modeli vs. Silo Modeli
Pool modeli: custom:tenantId niteliğiyle tek Cognito User Pool. Kiracı kapsamlı Cedar politikalarıyla tek AVP policy store.
- Yönetmesi ve dağıtması daha basit
- Daha düşük maliyet (tek User Pool, tek policy store)
- Kiracı izolasyonu Cedar politika seviyesinde sağlanır
- Çoğu B2B SaaS ürünü için yeterli
- Risk: bir politika hatası kiracılar arası veri sızıntısına yol açabilir
Silo modeli: Kiracı başına ayrı User Pool ve policy store.
- Daha güçlü izolasyon sınırı (altyapı seviyesinde ayrım)
- Uyumluluk gereksinimleri yoğun sektörler için gerekli (sağlık, finans, kamu)
- Daha yüksek operasyonel yük ve maliyet
- Her kiracının özelleştirilmiş politikaları olabilir
- Daha karmaşık dağıtım ve yönetim
Tip: Pool modeliyle başlayın. Çoğu durumu iyi yönetir. Silo modeline yalnızca uyumluluk veya sözleşme gereksinimleri altyapı seviyesinde kiracı izolasyonu talep ettiğinde geçin.
Çok Kiracılık için Cedar Politikaları
Pool modelinde, kiracı izolasyonu tamamen politika güdümlüdür. Her kaynak erişim politikası bir kiracı kontrolü içermelidir:
// Temel politika: belge görüntüleme için kiracı izolasyonu
// Her kaynak politikası tenantId eşleşmesini doğrulamalı
permit(
principal,
action == Action::"ViewDocument",
resource is SaasApp::Document
)
when {
principal.tenantId == resource.tenantId &&
principal.orgRole in ["admin", "editor", "viewer"]
};
// Editörler kendi kiracılarındaki belgeleri değiştirebilir
permit(
principal,
action == Action::"EditDocument",
resource is SaasApp::Document
)
when {
principal.tenantId == resource.tenantId &&
principal.orgRole in ["admin", "editor"]
};
// Yalnızca yöneticiler belgeleri silebilir
permit(
principal,
action == Action::"DeleteDocument",
resource is SaasApp::Document
)
when {
principal.tenantId == resource.tenantId &&
principal.orgRole == "admin"
};
Katman bazlı özellik sınırlama için Cedar politikaları kiracı katmanını kontrol edebilir:
// Yalnızca enterprise kiracılar gelişmiş analizlere erişebilir
permit(
principal,
action == Action::"ViewAdvancedAnalytics",
resource
)
when {
principal.tenantId == resource.tenantId &&
principal.tenantTier == "enterprise"
};
Kiracılar Arası Erişim
Bazı SaaS ürünleri kontrollü kiracılar arası erişime ihtiyaç duyar — örneğin, birden fazla müşteri kiracısına erişen bir danışman. Bu, açık kiracılar arası politikalar gerektirir:
// Açık paylaşım yoluyla kiracılar arası erişime izin ver
// Bu politika yalnızca sharedTenants niteliğine sahip kullanıcılar için geçerlidir
permit(
principal,
action == Action::"ViewDocument",
resource is SaasApp::Document
)
when {
resource.tenantId in principal.sharedTenants
};
Warning: Kiracılar arası politikalar güçlü ve risklidir. Standart kiracı izolasyon sınırını aşarlar. Bunları dikkatle gözden geçirin ve özel entegrasyon testleriyle test edin.
Entegrasyon Mimarisi
Aşağıdaki diyagram, Cognito token’larının yetkilendirme kararları için AVP’ye nasıl ulaştığını gösterir.
Akış iki katmanlı çalışır:
- API Gateway + Cognito Authorizer (kaba taneli): JWT token’ı doğrular, kullanıcının kimliğinin doğrulandığını ve token’ın süresinin dolmadığını kontrol eder. Kimliği doğrulanmamış istekleri Lambda’ya ulaşmadan reddeder.
- Lambda + AVP (ince taneli): Doğrulanmış token’dan kiracı bağlamını çıkarır, principal, action ve resource ile AVP’yi çağırır. AVP Cedar politikalarını değerlendirir ve izin ver veya reddet döndürür.
JWT Çıkarma ve Kiracı Bağlamı
// Doğrulanmış Cognito JWT'den kiracı bağlamını çıkar
// API Gateway Cognito Authorizer token'ı zaten doğrulamıştır
import { APIGatewayProxyEventV2WithJWTAuthorizer } from "aws-lambda";
interface TenantContext {
userId: string;
tenantId: string;
orgRole: string;
tenantTier: string;
email: string;
}
function extractTenantContext(
event: APIGatewayProxyEventV2WithJWTAuthorizer
): TenantContext {
const claims = event.requestContext.authorizer.jwt.claims;
return {
userId: claims.sub as string,
tenantId: claims.tenantId as string,
orgRole: claims.orgRole as string,
tenantTier: claims.tenantTier as string,
email: claims.email as string,
};
}
IsAuthorized ve IsAuthorizedWithToken
AVP iki yetkilendirme API’si sağlar:
- IsAuthorized: Principal varlığını manuel olarak oluşturursunuz. Çağıran bir backend servisi olduğunda, JWT’si olan bir kullanıcı olmadığında kullanışlıdır.
- IsAuthorizedWithToken: Ham Cognito JWT token’ını geçersiniz. AVP token’ı doğrular ve principal’ı otomatik olarak çıkarır. Kullanıcıya yönelik istekler için daha basit ve daha güvenlidir.
import {
VerifiedPermissionsClient,
IsAuthorizedCommand,
IsAuthorizedWithTokenCommand,
BatchIsAuthorizedCommand,
} from "@aws-sdk/client-verifiedpermissions";
const avpClient = new VerifiedPermissionsClient({ region: "eu-central-1" });
const POLICY_STORE_ID = "ps-your-store-id";
// Seçenek 1: IsAuthorizedWithToken -- ham JWT gönder
// AVP token'ı doğrular ve claim'lerden principal'ı çıkarır
async function checkWithToken(
accessToken: string,
action: string,
resourceType: string,
resourceId: string,
resourceAttrs: Record<string, { string: string }>
): Promise<boolean> {
const command = new IsAuthorizedWithTokenCommand({
policyStoreId: POLICY_STORE_ID,
accessToken: accessToken,
action: {
actionType: "SaasApp::Action",
actionId: action,
},
resource: {
entityType: `SaasApp::${resourceType}`,
entityId: resourceId,
entityAttributes: resourceAttrs,
},
});
const response = await avpClient.send(command);
return response.decision === "ALLOW";
}
// Seçenek 2: IsAuthorized -- principal'ı manuel olarak oluştur
// Kullanıcı JWT'si olmadan servisler arası çağrılar için kullanışlı
async function checkWithPrincipal(
userId: string,
userAttrs: Record<string, { string: string }>,
action: string,
resourceType: string,
resourceId: string,
resourceAttrs: Record<string, { string: string }>
): Promise<boolean> {
const command = new IsAuthorizedCommand({
policyStoreId: POLICY_STORE_ID,
principal: {
entityType: "SaasApp::User",
entityId: userId,
entityAttributes: userAttrs,
},
action: {
actionType: "SaasApp::Action",
actionId: action,
},
resource: {
entityType: `SaasApp::${resourceType}`,
entityId: resourceId,
entityAttributes: resourceAttrs,
},
});
const response = await avpClient.send(command);
return response.decision === "ALLOW";
}
UI Oluşturma için BatchIsAuthorized
Birden fazla kaynak içeren bir UI oluştururken (belge listesi, izin kapılı özelliklerle pano), tek tek yetkilendirme çağrıları yapmak pahalıdır. BatchIsAuthorizedCommand tek bir API çağrısında 30’a kadar kontrol gönderir.
Kısıtlama: batch’teki tüm isteklerde principal veya resource aynı olmalıdır. UI oluşturma için genellikle principal’ı (mevcut kullanıcı) sabitler ve action/resource’u değiştirirsiniz.
// UI oluşturma için batch yetkilendirme
// Tek bir API çağrısında tek kullanıcı için birden fazla izni kontrol et
async function checkBatchPermissions(
userId: string,
userAttrs: Record<string, { string: string }>,
checks: Array<{
action: string;
resourceType: string;
resourceId: string;
resourceAttrs: Record<string, { string: string }>;
}>
): Promise<boolean[]> {
const command = new BatchIsAuthorizedCommand({
policyStoreId: POLICY_STORE_ID,
requests: checks.map((check) => ({
principal: {
entityType: "SaasApp::User",
entityId: userId,
entityAttributes: userAttrs,
},
action: {
actionType: "SaasApp::Action",
actionId: check.action,
},
resource: {
entityType: `SaasApp::${check.resourceType}`,
entityId: check.resourceId,
entityAttributes: check.resourceAttrs,
},
})),
});
const response = await avpClient.send(command);
return response.results!.map((r) => r.decision === "ALLOW");
}
// Kullanım: kullanıcının belge listesiyle neler yapabileceğini kontrol et
const permissions = await checkBatchPermissions(
"user-123",
{ tenantId: { string: "tenant-abc" }, orgRole: { string: "editor" } },
[
{
action: "ViewDocument",
resourceType: "Document",
resourceId: "doc-1",
resourceAttrs: { tenantId: { string: "tenant-abc" } },
},
{
action: "EditDocument",
resourceType: "Document",
resourceId: "doc-1",
resourceAttrs: { tenantId: { string: "tenant-abc" } },
},
{
action: "DeleteDocument",
resourceType: "Document",
resourceId: "doc-1",
resourceAttrs: { tenantId: { string: "tenant-abc" } },
},
]
);
// permissions: [true, true, false] -- görüntüleyebilir ve düzenleyebilir, silemez
API Middleware Deseni
Cognito kimlik doğrulamasını AVP yetkilendirmesiyle birleştiren yeniden kullanılabilir bir middleware:
// Cognito JWT ile AVP yetkilendirmesini birleştiren middleware
// Lambda handler'ları otomatik izin kontrolüyle sarar
import { APIGatewayProxyEventV2WithJWTAuthorizer } from "aws-lambda";
interface AuthorizationConfig {
action: string;
resourceType: string;
getResourceId: (event: APIGatewayProxyEventV2WithJWTAuthorizer) => string;
getResourceAttrs: (
event: APIGatewayProxyEventV2WithJWTAuthorizer
) => Record<string, { string: string }>;
}
function withAuthorization(config: AuthorizationConfig) {
return function (
handler: (
event: APIGatewayProxyEventV2WithJWTAuthorizer
) => Promise<unknown>
) {
return async (event: APIGatewayProxyEventV2WithJWTAuthorizer) => {
const context = extractTenantContext(event);
const allowed = await checkWithPrincipal(
context.userId,
{
tenantId: { string: context.tenantId },
orgRole: { string: context.orgRole },
tenantTier: { string: context.tenantTier },
},
config.action,
config.resourceType,
config.getResourceId(event),
config.getResourceAttrs(event)
);
if (!allowed) {
return {
statusCode: 403,
body: JSON.stringify({ error: "Access denied" }),
};
}
return handler(event);
};
};
}
// Lambda handler'da kullanım
export const getDocument = withAuthorization({
action: "ViewDocument",
resourceType: "Document",
getResourceId: (event) => event.pathParameters?.documentId ?? "",
getResourceAttrs: (event) => {
// Pratikte, yetkilendirme kontrolünden önce
// kaynak niteliklerini veritabanından getirin
return { tenantId: { string: "tenant-abc" }, status: { string: "active" } };
},
})(async (event) => {
// Handler yalnızca yetkilendirme geçerse çalışır
const documentId = event.pathParameters?.documentId;
// ... belgeyi getir ve döndür
return { statusCode: 200, body: JSON.stringify({ id: documentId }) };
});
Entra ID Alternatifi
Microsoft ekosistemindeki takımlar için eşdeğer desen, kimlik doğrulama için Microsoft Entra External ID ve ince taneli kararlar için ayrı bir yetkilendirme katmanı kullanır.
Temel Farklar
| Konu | AWS (Cognito + AVP) | Microsoft (Entra + özel yetkilendirme) |
|---|---|---|
| Kimlik doğrulama | Cognito User Pool | Entra External ID |
| Yetkilendirme motoru | Cedar ile AVP (yönetilen) | Yerel eşdeğer yok — Cerbos, OPA veya özel kullanın |
| Politika dili | Cedar (formal olarak doğrulanmış) | Seçilen motora bağlı |
| Kiracı izolasyonu | Cedar politikaları veya ayrı policy store’lar | App role’leri + gruplar + harici PDP |
| Token zenginleştirme | Pre Token Generation Lambda trigger | Uygulama kaydında claim eşleme |
| Fiyatlandırma modeli | MAU başına (Cognito) + istek başına (AVP) | MAU başına (Entra) + harici PDP maliyeti |
| Çok kiracı desteği | Özel nitelikler + Cedar politikaları | Çok kiracılı uygulama kaydı |
Microsoft altyapısındaki kritik eksiklik, yönetilen ince taneli bir yetkilendirme servisinin olmamasıdır. Entra kimlik doğrulama ve kaba taneli yetkilendirmeyi (app role’leri, grup üyelikleri, Conditional Access) yönetir, ancak “kullanıcı X, kiracı Z’deki belge Y’yi düzenleyebilir mi?” gibi kaynak seviyesinde kararlar için harici bir PDP gereklidir.
Pratikte Microsoft altyapısı kullanan takımlar, ince taneli kararlar için Entra’yı Cerbos veya OPA ile birleştirir. Entra token’ı kimlik bağlamını (kullanıcı ID, roller, gruplar, kiracı ID) sağlar ve harici PDP bu bağlam ile kaynak niteliklerini kullanarak politikaları değerlendirir.
// Entra ID token claim'leri ince taneli yetkilendirme için Cerbos'a beslenir
// Entra kimliği sağlar; Cerbos yetkilendirme kararını verir
import { GRPC as Cerbos } from "@cerbos/grpc";
const cerbos = new Cerbos("localhost:3593");
async function checkAccess(
entraToken: { oid: string; roles: string[]; tid: string; groups: string[] },
resource: { type: string; id: string; ownerId: string; tenantId: string }
) {
const decision = await cerbos.checkResource({
principal: {
id: entraToken.oid,
roles: entraToken.roles,
attr: {
tenantId: entraToken.tid,
groups: entraToken.groups,
},
},
resource: {
kind: resource.type,
id: resource.id,
attr: {
owner: resource.ownerId,
tenantId: resource.tenantId,
},
},
actions: ["read", "update", "delete"],
});
return decision.isAllowed("update");
}
AWS burada net bir avantaja sahiptir: Cognito + AVP tam entegre, yönetilen bir yetkilendirme altyapısıdır. Microsoft ekosisteminde ise birden fazla parçadan birleştirmeniz gerekir.
Maliyet Analizi
AVP Fiyatlandırması
Amazon Verified Permissions, tek yetkilendirme API’leri, toplu (batch) yetkilendirme API’leri ve politika yönetimi API’leri için farklı tarifeler uygular. Her API türü için tek bir “sabit” oran yoktur. Ayrıntılar için bkz. Amazon Verified Permissions Pricing.
Tek yetkilendirme (IsAuthorized, IsAuthorizedWithToken): Her API çağrısı, faturalanan tek bir yetkilendirme isteğidir; istek başına 0,000005 USD (milyon başına 5 USD).
Toplu yetkilendirme (BatchIsAuthorized, BatchIsAuthorizedWithToken): Her batch API çağrısı tek bir istek olarak sayılır; çağrının içinde kaç kontrol olduğu (servis limitine kadar) fatura birimini çoğaltmaz. Batch çağrıları kademeli istek başına fiyatlandırılır (örneğin yayındaki ABD tarifesinde ayda ilk 40 milyon batch çağrısı için batch çağrısı başına 0,00015 USD). Bu, içerideki her kontrol için tek yetkilendirme tarifesinin uygulanması anlamına gelmez.
Aşağıdaki tablo, her ince taneli kararın bir IsAuthorized veya IsAuthorizedWithToken çağrısına karşılık geldiği varsayımıyla geçerlidir.
| Aylık tek yetkilendirme API çağrısı | Aylık AVP maliyeti (tek API’ler) |
|---|---|
| 1 milyon | 5$ |
| 10 milyon | 50$ |
| 100 milyon | 500$ |
| 1 milyar | 5.000$ |
Not: İş yükünüzde batch API’lere ağırlıklı olarak güveniyorsanız maliyeti fiyatlandırma sayfasındaki batch kademeleriyle modelleyin. Politika oluşturma, güncelleme, listeleme gibi politika yönetimi çağrıları ayrı faturalandırılır.
Cognito Fiyatlandırması
Cognito fiyatlandırması katmana bağlıdır:
| Katman | Ücretsiz MAU | MAU Başına Fiyat (ücretsiz üstü) | Temel Özellikler |
|---|---|---|---|
| Lite | 10.000 | 0,0055$ | Temel kimlik doğrulama, özel nitelikler |
| Essentials | 10.000 | 0,015$ | Parolasız, yönetilen giriş |
| Plus | 0 | 0,02$ | Tehdit koruması, risk tabanlı kimlik doğrulama |
Note: Kasım 2024 öncesinde aktif Cognito user pool’ları olan hesaplar 50.000 MAU’luk daha yüksek bir ücretsiz katman için uygundur.
Toplam SaaS Kimlik Doğrulama Maliyeti Örneği
Günde ortalama 200 API çağrısı yapan 5.000 MAU’lu bir B2B SaaS ürünü için:
- Cognito (Lite): Ücretsiz (10.000 MAU eşiğinin altında)
- AVP: 5.000 kullanıcı x 200 çağrı x 30 gün = 30 milyon tek yetkilendirme API çağrısı/ay = 150$/ay (her çağrının
IsAuthorizedveyaIsAuthorizedWithTokenve tek yetkilendirme tarifesiyle faturalandığı varsayımıyla) - Toplam: Kimlik doğrulama + ince taneli yetkilendirme için ~150$/ay
Aynı kontrolleri batch API’lerle karşılıyorsanız AWS, iç yetkilendirme sayısı yerine batch API çağrılarını batch tarifesine göre faturalandırır.
Karşılaştırma olarak, kendi sunucularınızda barındırılan bir çözüm (Kubernetes üzerinde SpiceDB + PostgreSQL) yalnızca altyapı olarak aylık 500-2.000$ tutar, artı operasyonlar için mühendislik zamanı.
Tip: Her API çağrısının AVP kontrolüne ihtiyacı yoktur. İki katmanlı deseni kullanın: API Gateway kaba taneli kontrolleri yönetir (kullanıcı kimliği doğrulanmış mı? token doğru scope’a sahip mi?). Yalnızca ince taneli kararları AVP’ye yönlendirin. Bu, AVP istek hacmini %60-80 azaltabilir.
Yaygın Hatalar
Policy Store’ları Aşırı Kapsamlama
Mikroservis başına ayrı bir policy store oluşturmak politika parçalanmasına yol açar. Birden fazla servisi kapsayan yetkilendirme kararları tek bir policy store içinde imkansız hale gelir. Çoğu durumda ortam başına (dev, staging, production) tek bir policy store yeterlidir. Politikaları mantıksal olarak düzenlemek için Cedar ad alanlandırmasını (varlık türü ön ekleri) kullanın.
Politikalarda Kiracı İzolasyonunu Atlamak
Çok kiracılı SaaS’ta en tehlikeli hata: kiracı kontrolü olmadan permit politikası yazmak.
// TEHLİKELİ: kiracı izolasyonu yok
permit(
principal,
action == Action::"ViewDocument",
resource is SaasApp::Document
)
when {
principal.orgRole in ["admin", "editor", "viewer"]
};
Bu politika, kiracıdan bağımsız olarak kimliği doğrulanmış herhangi bir kullanıcının herhangi bir belgeyi görüntülemesine izin verir. Düzeltme basittir ama unutulması kolaydır:
// DOĞRU: kiracı izolasyonu uygulanmış
permit(
principal,
action == Action::"ViewDocument",
resource is SaasApp::Document
)
when {
principal.tenantId == resource.tenantId &&
principal.orgRole in ["admin", "editor", "viewer"]
};
Warning: Kiracılar arası erişimin reddedildiğini açıkça doğrulayan bir Cedar politika testi yazın. CI/CD’de çalıştırın. Bu, yanlışlıkla kiracı verisi sızıntısına karşı güvenlik ağınızdır.
Token Şişkinliği
Pre Token Generation trigger aracılığıyla Cognito token’larına çok fazla claim eklemek token boyutunu artırır. Büyük token’lar her API çağrısına gecikme ekler ve boyut limitlerini aşabilir. Claim’leri Cedar politikalarının gerçekten değerlendirdiğiyle sınırlı tutun. Yetkilendirme için ek bağlama ihtiyacınız varsa, token claim’leri yerine AVP isteğinde kaynak nitelikleri olarak geçirin.
IsAuthorizedWithToken Kullanmamak
JWT claim’lerini manuel olarak çıkarmak ve principal varlıkları oluşturmak hataya açıktır. IsAuthorizedWithToken, AVP’nin token doğrulamasını ve claim çıkarmasını yönetmesini sağlar. Daha güvenlidir (AVP token imzasını doğrular) ve bakımı gereken daha az kod vardır.
UI için Batch Yetkilendirmeyi Göz Ardı Etmek
UI oluşturma için bir döngüde tek tek IsAuthorized çağrıları yapmak gecikme sorunları yaratır ve tek yetkilendirme fatura birimlerini artırır. Aynı principal için birçok kontrol gerekiyorsa BatchIsAuthorizedCommand tek bir batch çağrısında en fazla 30 kontrol paketler; bu çağrı faturalamada tek bir batch isteği olarak sayılır (kendi kademeli fiyatıyla). Trafik profilinize göre tek ve batch toplamlarını fiyatlandırma sayfasında karşılaştırın.
Şema Doğrulamasını Atlamak
Cedar politikalarını şemasız dağıtmak, nitelik adlarındaki yazım hatalarının sessizce başarısız olması anlamına gelir. principal.tenantId yerine principal.tenantid (küçük ‘d’) kontrol eden bir politika hiçbir zaman eşleşmez ve hiçbir hata raporlanmaz. Bu sorunları politika oluşturma zamanında yakalamak için şema doğrulamasını etkinleştirin.
Sonuç
Cognito + AVP, AWS üzerindeki SaaS ürünleri için yönetilen, entegre bir yetkilendirme altyapısı sağlar. Bu kombinasyon, kendi sunucularınızda barındırılan altyapı olmadan kimlik doğrulama, kiracı bağlamı zenginleştirme ve ince taneli politika değerlendirmesini yönetir.
Temel çıkarımlar:
- Pre Token Generation trigger’ını kullanın ve access token’ları Cedar politikalarının tükettiği kiracı bağlamıyla zenginleştirin.
- Pool modeliyle başlayın (tek User Pool, tek policy store) ve yalnızca uyumluluk gerektirdiğinde silo modeline geçin.
- Her Cedar politikası kiracı kontrolü içermeli çok kiracılı uygulamalarda. Kiracılar arası izolasyonu CI/CD’de test edin.
- Kullanıcıya yönelik istekler için IsAuthorizedWithToken kullanın. Servisler arası çağrılar için IsAuthorized kullanın.
- İki katmanlı deseni kullanın (kaba kontroller için API Gateway, ince taneli için AVP) ve maliyeti ve gecikmeyi kontrol edin.
- UI oluşturma için BatchIsAuthorized kullanarak API çağrılarını ve gecikmeyi azaltın.
Bu serinin sonraki yazısı, burada ele alınan nitelik tabanlı yaklaşımdan temelden farklı bir yetkilendirme modeli olan ilişki tabanlı erişim kontrolü için SpiceDB vs Auth0 FGA konusunu kapsar.
Kaynaklar
- Amazon Verified Permissions Documentation - AVP kavramları, şema tanımı ve politika değerlendirmesi için resmi rehber
- Cedar Policy Language Documentation - Resmi Cedar dil referansı, gramer spesifikasyonu ve politika yazma rehberleri
- Amazon Verified Permissions Policy Store Schema - Varlık türleri, nitelikler ve eylem-varlık eşlemeleri için şema tanımı
- Working with Amazon Cognito Identity Sources - AVP için kimlik kaynağı olarak Cognito yapılandırması
- IsAuthorizedWithToken API Reference - Token tabanlı yetkilendirme istekleri için API dokümantasyonu
- Cognito Multi-Tenant Application Best Practices - Cognito ile çok kiracılık desenleri için AWS rehberi
- Custom-Attribute Multi-Tenancy Best Practices - Cognito’da kiracı izolasyonu için özel niteliklerin kullanımı
- Amazon Verified Permissions Pricing - Tek ve batch yetkilendirme ile politika yönetimi tarifeleri (yayındaki ABD tarifesinde
IsAuthorized/IsAuthorizedWithTokeniçin milyon başına 5$) - Amazon Cognito Pricing - Cognito fiyatlandırma katmanları (Lite, Essentials, Plus)
- AWS Prescriptive Guidance - Multi-tenant SaaS Authorization - SaaS uygulamaları için PDP dağıtım modelleri
- Microsoft Entra External ID Overview - Azure AD B2C’nin yerini alan Microsoft’un müşteriye yönelik kimlik platformu
Harici Yetkilendirme Sistemleri
Dağıtık sistemler için harici yetkilendirme platformlarına kapsamlı bir rehber. Platform seçimi, politika dili karşılaştırması, AWS ile bulut tabanlı yetkilendirme ve SpiceDB ile Auth0 FGA kullanarak ilişki tabanlı erişim kontrolünü kapsar.
Serideki tüm yazılar
İlgili yazılar
AWS Verified Permissions, SpiceDB, OpenFGA, Cerbos ve OPA dahil harici yetkilendirme platformlarının tarafsız değerlendirmesi. Mimari desenler, maliyet analizi ve mühendislik ekipleri için karar çerçevesi.
Cedar, Rego, OpenFGA DSL ve Cerbos YAML/CEL politika dillerinin derinlemesine teknik karşılaştırması. Söz dizimi, performans kıyaslamaları, biçimsel doğrulama, araç desteği ve her dil için TypeScript entegrasyon örneklerini kapsar.
SpiceDB ve Auth0 FGA (OpenFGA) arasında detaylı bir teknik karşılaştırma -- şema tasarımı, tutarlılık modelleri, dağıtım ve ölçeklenebilirlik açısından farklı tercihler yapan iki Zanzibar tabanlı yetkilendirme sistemi.
Authentication ve authorization farkı, yaygın izin sistemi tuzakları, fail-closed prensibi ve her izin sisteminin karşılaması gereken hedefler.
Dağınık izin kontrollerini merkezi bir service layer'a taşıyın, Next.js middleware guard'ları ekleyin ve derinlemesine savunma yetkilendirme mimarisi oluşturun.