Amaç: API’yi anahtar paylaşmadan güvenli çağırmak
Sunucusuz (serverless) mimarilerde API yayınlamak hızlıdır; ancak güvenlik çoğu projede “sonra bakarız” diye ertelenir. Özellikle AWS API Gateway + Lambda ile bir REST/HTTP API açtığınızda, istekleri kimlerin çağırabildiğini belirlemenin en temiz yollarından biri JWT (JSON Web Token) doğrulamasıdır. Bu yazıda, API Gateway’in önüne Lambda Authorizer koyarak Bearer token doğrulaması yapan pratik ve ileri seviye bir kurulum anlatıyorum. Hedefimiz: Her istekte token’ı kontrol etmek, geçerliyse isteği arka uç Lambda’ya iletmek, değilse daha kapıdayken kesmek.
JWT ve Lambda Authorizer mantığı
JWT, genellikle bir kimlik sağlayıcı (Auth0, Cognito, Keycloak veya kendi servisiniz) tarafından imzalanan ve istemcinin “ben buyum” iddiasını taşıyan bir tokendir. Token’ın güvenliği, içeriğinin şifreli olmasından değil, imzasının doğrulanabilir olmasından gelir. API Gateway tarafında bunu iki şekilde çözebilirsiniz: HTTP API kullanıyorsanız çoğu durumda yerleşik JWT Authorizer yeterlidir; REST API veya özel doğrulama ihtiyaçlarında ise Lambda Authorizer daha esnektir. Lambda Authorizer, gelen isteğin Authorization header’ını okur, token’ı doğrular, ardından “Allow/Deny” kararı döner.
Ön koşullar
Bu öğreticinin akıcı ilerlemesi için şu bileşenlere ihtiyacınız var: AWS hesabı, bir API Gateway (REST API veya HTTP API), en az bir backend Lambda (asıl iş mantığınız), bir de doğrulama için Authorizer Lambda. Ayrıca token’ı imzalayan tarafın kullandığı anahtara erişebilmelisiniz: HS256 kullanıyorsanız “shared secret”, RS256/ECDSA kullanıyorsanız public key veya JWKS endpoint.
Adım 1: Authorizer Lambda’nın temel yapısı
Önerim, üretimde RS256 + JWKS yaklaşımını kullanmanızdır; böylece gizli anahtar API tarafında tutulmaz. Authorizer Lambda’da yapılacak iş mantığı kısaca şöyledir: (1) Authorization header’dan “Bearer ” kısmını ayıklayın, (2) token’ın header bölümünden “kid” değerini okuyun, (3) JWKS’ten doğru public key’i çekip cache’leyin, (4) imzayı ve kritik claim’leri doğrulayın: iss (issuer), aud (audience), exp (süre), gerekiyorsa scope veya rol bilgisi. Doğrulama geçerse Allow policy; geçmezse Deny.
Node.js örnek akışında popüler kütüphaneler: jose (JWT doğrulama), JWKS için jwks-rsa benzeri çözümler. Python tarafında PyJWT veya python-jose iş görür. Buradaki kritik detay, Lambda’nın her çağrılışında JWKS’e gitmemek için global değişkende cache tutmaktır. API trafiğiniz yükseldiğinde en çok farkı bu optimizasyon yaratır.
Adım 2: Policy üretimi ve “context” taşıma
REST API “Lambda Authorizer” kullanıyorsanız dönüşte IAM policy belgesi üretirsiniz. Bu policy, hangi method ARN’lerine izin verildiğini söyler. Ayrıca kullanıcının kimliğini backend Lambda’ya taşımak için “context” alanını kullanabilirsiniz. Örneğin doğrulanan token’dan sub (kullanıcı id) ve email gibi bilgileri seçip context’e koyarsınız. Backend Lambda’da bu değerler event’in authorizer bölümünde gelir ve tekrar token parse etmeye gerek kalmaz. Bu hem performans hem de kod sadeliği sağlar.
HTTP API kullanıyorsanız format farklıdır; ancak mantık aynı kalır: Doğrulama sonucu “isAuthorized” ve “context” ile döndürülür. Hangisini seçerseniz seçin, mümkün olduğunca az veri taşıyın: id, rol ve gerekliyse tenant bilgisi çoğu senaryo için yeterlidir.
Adım 3: API Gateway’e Authorizer bağlama
AWS konsolunda API Gateway’in ilgili endpoint/method ayarlarına girip “Authorization” kısmında Lambda Authorizer seçersiniz. REST API’de method bazlıdır; HTTP API’de route bazlıdır. Burada dikkat edilmesi gereken iki nokta var: Identity source olarak “Authorization” header’ını seçmek ve gerekiyorsa authorizer caching ayarlarını doğru yapmak. Token başına cache kullanacaksanız TTL’i çok yüksek tutmayın; rol değişikliği gibi durumlarda eski izinler bir süre daha geçerli kalabilir.
Güvenlikte ince ayar: iss, aud, clock skew ve scope
Sadece imza doğrulamak yeterli değildir. En sık yapılan hata, token’ın kimin tarafından üretildiğini doğrulamadan kabul etmektir. Mutlaka iss değerini sabit bir beklenen değerle karşılaştırın. Benzer şekilde aud, token’ın hangi uygulama için üretildiğini gösterir; yanlış audience kabul edilirse başka bir uygulamanın token’ı sizin API’nize sızabilir. Saat kayması (clock skew) için 30–60 saniyelik tolerans pratikte işleri kolaylaştırır. Ayrıca “scope” veya “permissions” claim’lerinden endpoint bazlı yetkilendirme yapabilirsiniz: Örneğin /admin route’u için “admin:read” yoksa Deny döndürmek gibi.
Test ve hata ayıklama ipuçları
İlk testte Postman veya curl ile iki senaryoyu deneyin: geçerli token ile 200, geçersiz/expired token ile 401/403. CloudWatch Logs’ta Authorizer Lambda loglarını izleyin. Üretimde loglara token’ın tamamını basmayın; güvenlik açısından sadece token’ın “sub” gibi kimlik alanlarını veya hash’lenmiş bir parçasını yazdırmak daha sağlıklıdır. Ayrıca JWKS erişimi için VPC içinde çalışıyorsanız NAT gereksinimi doğabilir; bu tür ağ detayları doğrulamanın “durduk yere çalışmıyor” gibi görünmesine neden olur.
Sonuç
Lambda Authorizer ile JWT doğrulaması, serverless API’lerde güvenliği kapıdan başlatmanın en esnek yollarından biri. Doğru yapılandırıldığında hem maliyeti düşük tutar hem de kimlik doğrulama/yetkilendirme kararlarını merkezi hâle getirir. JWKS cache, iss-aud kontrolü ve minimal context taşıma gibi detaylara dikkat ettiğinizde, performans ve güvenlik tarafında “profesyonel seviye” bir kurulum elde edersiniz.