Vault Kullanarak Secret Depolama ve Spring Boot Hashicorp Entegrasyonu

Abdullah Çiçekli
Sahibinden Technology
7 min readJun 25, 2024

Merhabalar,
Bu yazımda vault kullanarak web uygulamalarında gizli bilgiler nasıl depolanır, alternatif ve mevcut kullanım senaryoları nelerdir, neden önemlidir gibi konulara değineceğim. Ardından vault alternatiflerininden HashiCorp Vault’un nasıl kullanılacağını anlatmaya çalışacağım. Keyifli okumalar. 🙂

Secret Saklama

Yazılım geliştiriciler olarak, programlarımızın birçok değere ihtiyacı oluyor ve bu değerlerin bazılarını gizli tutmamız gerekiyor. Örneğin, veritabanı bağlantı bilgileri (kullanıcı adı, şifre, port vb.), sunucu adresleri, SSH anahtarları ve yönetici bilgileri gibi hassas bilgileri açığa çıkarmak istemiyoruz. Peki gizli bilgilerimizi sıklıkla nerede ve nasıl depoluyoruz ? Gelin bunlara, avantaj ve dezavantajlarına bakalım.

Kaynak Kod İçerisinde Secret Saklama

Basitlik, yazılım geliştirme aşamasında arzu edilen bir özelliktir. Secret bilgileri direkt olarak kaynak koda koymakta bu basitliğin en iyi hali sayılabilir. Ama bu yöntem güvenlik açısından durumu tam tersine çevirebilir. Mesela uygulamamızın istemci tarafında çalıştığı bir senaryo düşünelim. Bazı gizli bilgilerin bir js dosyasında tutulduğunu varsayalım. Bu durumda gizli bilginin ifşa olması için bir saldırganın sadece sayfayı inspect etmesi yeterli olur. Bunun yaşanmayacak kötü bir örnek olarak gördüyseniz web arşivde yer alan weather.com’un kaynak kodunu inceleyin 🙂 (SECRET_KEY araması yapabilirsiniz.)

İkinci senaryo, private bir repoda çalıştığınız durumdur. Bu, biraz daha güvenli görünse de Apiiro’nun “Yazılım Tedarik Zincirinde Gizli Bilgiler Raporu”na göre, 25.000'den fazla repository üzerinde yapılan incelemede private repolardaki gizli bilgilerin %50'sinin, saldırganların ağa erişim sağlaması durumunda hemen ulaşılabilir olduğu bulunmuştur. Bu gizli bilgilerin %38'i Kişisel Tanımlayıcı Bilgiler (PII) içeriyor. Ayrıca, ifşa edilen tüm gizli bilgilerin %42'si düz metin olarak saklanan şifrelerdir.

Yapılandırma Dosyalarında Secret Saklama

Yapılandırma dosyaları, ortamlar arasında dağıtımları hızlı ve sorunsuz hale getirir. Örneğin, prod ve test ortamlarımız farklı veritabanları kullanıyorsa, bu ayarları yapılandırma dosyalarında kolayca özelleştirebiliriz. İlk bakışta, yapılandırma dosyaları gizli bilgileri saklamak için uygun görünebilir. Ancak, güvenlik açısından yapılandırma dosyalarında gizli bilgi saklamak, kaynak kodunda saklamak kadar risklidir. Bunun nedeni, yapılandırma dosyalarının da repository’e gönderilebilmesidir. Bu riski azaltmak için .gitignore gibi yöntemler kullanılabilir, fakat küçük bir ihmal veya dikkatsizlikle gizli bilgiler repository’e dahil edilebilir. Özellikle büyük ekiplerde bu olasılık daha yüksektir. Ayrıca, bir saldırgan ağa erişim sağladığında, yapılandırma dosyalarına da hızla ulaşabilir.

Vault Nasıl Çalışır ?

Vault, sırları yönetme sorununu çözmek çıkarılmış uygulamalardır. Kullanıcı kimliklerini ve gerçekliğini doğrulayabilir, bireysel bir kullanıcın erişebileceği öğeleri tanımlayan politikaları uygulayabilir, izin verilen işlem kümesini belirleyebilir, şifreleri güvenli bir şekilde saklayabilir. Vault’u kişisel bir şifre yöneticisinin tüm kuruluşa hizmet etmek üzere uyarlanmış versiyonu olarak düşünebiliriz.

Alternatif Vault Uygulamaları

Vault uygulamarı arasıda, özellikleri, kurulum yöntemleri ve kaynak kodu erişimleri açısından farklılık gösteren birçok alternatif bulunmaktadır. Gartner PAM(Privileged Access Managemet) grafiği aşağıdaki gibidir.

Magic Quadrant for Privileged Access Managemet | Gartner, 2023

HashiCorp ve CyberArk, yukarıdaki çözümlerden açık kaynaklı olanlardır. Eğer büyük ölçekli bir proje yerine bireysel projeler üzerinde çalışıyorsanız, 1Password CLI ‘uda alternatif olarak tercih edebilirsiniz.

Vault İle İletişim

Genel olarak vaultlar, kullanıcıların istekte bulunabilmesi için herkese açık bir HTTP API sunar. Bu sayede, kullanıcılar ister web uygulaması, ister doğrudan API çağrısı, isterse de bir programlama kütüphanesi ile vault işlemlerini gerçekleştirebilir.

Şimdi, vault’un nasıl kullanıldığını göstermek için HashiCorp Vault kullanarak yukarıdaki diyagramdaki senaryo üzerinde çalışalım. Bir Spring Boot projesine sahip olduğumuzu ve vault’a yazdığımız secret’ları basit CRUD işlemleriyle konsolda görmek istediğimizi varsayalım. Bu şekilde, Vault’un nasıl çalıştığını daha iyi anlayabiliriz ve programlarımızda nasıl kullanabileceğimizi görebiliriz.

Spring Uygulaması Başlatmak

Yukarıda gerekli bağımlılıkları ekledik. Bu bağımlılıklar arasında Vault bağlantımızı sağlayacak olan Vault Configuration da bulunuyor.

Vault Kurulumu

Şimdi HashiCorp’un Vault’unu kurmaya geçelim. Linkteki bağlantıyı kullanarak, istediğiniz yöntemle Vault’u kurabilirsiniz. Kurulumu tamamladıktan sonra, vault -h komutunu kullanarak kurulumun doğrulamasını yapabiliriz.

vault -h command

Dev Server Mod

“Vault’u geliştirme modunda başlatmak için vault server -dev komutunu kullanabiliriz. Bu şekilde, ek bir kurulum gerektirmeden Vault'u deneyebilir veya geliştirme amaçlı örnek bir Vault oluşturabiliriz. Geliştirme modunda Vault'un tüm özellikleri mevcuttur.

Önemli Not: Geliştirme modu kesinlikle production ortamında kullanılmamalıdır. Güvenlik açısından risklidir ve verileri RAM’de depoladığı için her yeniden başlatmada veriler sıfırlanır. Bu nedenle, yalnızca geliştirme ortamı için tasarlanmış bir moddur.

Yukarıda görüldüğü gibi, terminalimize vault server -dev komutunu yazdığımızda, yerel bir sunucu başlatılır. Bu işlem, bize arayüze erişim sağlayabileceğimiz bir link ve giriş yapabileceğimiz bir token verir. (Bu token, spring yapılandırmasında da kullanılacaktır.)

Terminalden aldığımız root token’ı girdikten sonra aşağıdaki gibi arayüze erişebiliriz. Buradan secrets engines menüsüne tıklayarak var olan secrets engine’leri görebilir ve yeni bir tane oluşturabiliriz. Secrets engine’ler, verileri depolayan, üreten veya şifreleyen bileşenlerdir.

Enable a Secrets Engine

Bu aşamada yeni bir engine oluşturabiliriz. Şimdilik var olan secret/ (key-value) engine ile devam edeceğiz. Buna tıklayıp yeni secret oluşturabiliriz. Örneğin, veritabanı bağlantımız için değerleri burada oluşturalım.

Arayüzden Secret Oluşturmak

Terminal’den Secret Oluşturmak

Veritabanı bilgilerimizi sakladığımız secret’ı oluşturduk. Eğer bu değerleri arayüz yerine terminal üzerinden oluşturmak istersek, aşağıdaki komutu kullanabiliriz:

vault kv put secret/vaultAppDemo example=abdullah

Bu komut, secret/vaultAppDemo adında bir secret oluşturur ve içine example=abdullah şeklinde bir anahtar-değer çifti ekler. Doğrulamak için arayüzden baktığımız zaman aşağıdaki gibi oluşturulan değeri görebiliriz.

Terminalden Secret’a Erişmek

vault kv get komutu ile tanımlanan key-value secretlere erişebiliriz. Örneğin, ilk oluşturduğumuz db secret'ine erişmek için vault kv get secret/db komutunu yazabiliriz. Aşağıdaki gibi secret bilgilerini görebiliriz:

Şimdi uygulamamızdan oluşturmuş olduğumuz secret’a erişelim ve bu değerleri kullanalım.

Spring Boot Vault Configuration

Uygulamamızı açalım ve application.properties dosyamızda Vault bağlantı bilgilerini girelim.

spring.application.name=db: Bu, secret'e verdiğimiz isimdir. Secret oluştururken db olarak isimlendirdiğimiz için db yazıyoruz.

spring.cloud.vault.token=hvs.9QGeqfMoccVeAzFC5dDdYzKW: Vault'a giriş yapabilmek için kullanacağınız özel erişim anahtarını (token) ifade eder. Bu token, vault server -dev komutunun çıktısında yer almaktadır.

spring.cloud.vault.url=127.0.0.1:8200: Vault servisinin nerede çalıştığını belirtir. Biz default değerleri girerek devam ediyoruz.

spring.config.import=vault://: Bu ayar, uygulamamızın yapılandırma ayarlarını Vault'tan otomatik olarak almasını sağlar. Yani, uygulamanızı başlatırken gerekli olan yapılandırmaları doğrudan Vault üzerinden çekebilmemize olanak tanır.

Şimdi gerekli konfigürasyonlarımızı yapalım. Aşağıdaki gibi Vault’a girdiğimiz değerleri alabiliriz.

Şimdi uygulamamıza bir REST API yazalım. API’a istek atıldığı zaman Vault’taki verileri konsola loglayalım. Bu sayede Vault’a düzgün bir şekilde bağlandığımızı ve secret’ları okuyabildiğimizi doğrulayabiliriz.

Yukarıda görüldüğü gibi, curl http://localhost:8080/api/getDataFromVault isteğini attığımızda, Vault'a yazdığımız secret'lar başarılı bir şekilde konsola yazıldı. Bu sayede, uygulamamızın içinde konfigürasyon veya ortam dosyalarında belirtmediğimiz gizli bilgileri Vault üzerinde saklayarak, çalışma sırasında erişilebilir hale getirdik. Bu aşamada, basit bir uygulama ile HashiCorp Vault'a nasıl secret girileceğini ve mevcut secret'lara Spring Boot üzerinden nasıl erişileceğini öğrendik. Kullanım senaryolarımıza göre Vault'un kullanımını özelleştirebiliriz.

Ne Kazandık ?

Secretlarımızı saklamak için bir vault kullandık. Ama vault’ ile iletişime geçmek için yine bir token kullandık. Bu mantıksız gelebilir ama vaultlar secretları ortadan kaldırmak yerine onları daha sistematik yönetebilmeyi sağlar. Sistemde authantication için kullanılan bir tokenın olması bir çok secret’ın kaynak kodunda olmasından çok daha güvenli bir senaryodur. Çünkü authantication token belirlenen politikalara göre iptal edilebilir, yenilenmeye zorlanabilir ve yönetilmesi kolaydır. Ek olarak büyük bir mimari içerisinde çalışıldığı ve mikroservislerinde sisteme dahil olduğu durumlarda secretlar tek bir uygulamada kalmaz ve bir çok servise yayılması gerekir. Buda yine secret güvenliği açısından sorunlu ve güvensiz bir senaryodur. Vault kullanarak bu durumdada güvenli şekilde yönetebiliriz.

Bu yazıda Vault’un önemine ve Hashicorp Vault’un Spring Boot entegrasyonuna değinmeye çalıştım. Github’dan örnek projeye ulaşabilirsiniz. Umarım keyif aldığınız ve yeni bir şeyler öğrendiğiniz bir yazı olmuştur. Bir sonraki yazımda görüşmek üzere, hoşça kalın! 👋🏼

--

--