Pola Kunci layanan

Azure
Azure Storage

Gunakan token yang memberi akses langsung klien secara terbatas ke sumber daya tertentu, untuk melakukan transfer data dari aplikasi. Ini sangat berguna dalam aplikasi yang menggunakan sistem penyimpanan atau antrean yang ditanam di cloud, dan dapat meminimalkan biaya serta memaksimalkan skalabilitas dan kinerja.

Konteks dan masalah

Program klien dan web browser sering membaca dan menulis file atau aliran data ke dan dari penyimpanan aplikasi. Biasanya, aplikasi akan menangani pergerakan data - baik dengan mengambilnya dari penyimpanan dan mengalirkannya ke klien, atau dengan membaca aliran yang diunggah dari klien dan menyimpannya di penyimpanan data. Namun, pendekatan ini memerlukan sumber daya tinggi seperti komputasi, memori, dan bandwith.

Penyimpanan data memiliki kemampuan untuk menangani pengunggahan dan pengunduhan data secara langsung, tanpa mengharuskan aplikasi melakukan pemrosesan apa pun untuk memindahkan data ini. Tapi, ini biasanya mengharuskan klien memiliki akses ke penyimpanan keamanan data kredensial. Ini merupakan teknik yang berguna untuk meminimalkan biaya transfer data dan persyaratan untuk meningkatkan aplikasi, dan untuk memaksimalkan kinerja. Namun, itu berarti bahwa aplikasi tidak lagi dapat mengelola keamanan data. Setelah klien memiliki koneksi ke penyimpanan data secara langsung, aplikasi tidak lagi dapat bertindak sebagai penjaga. Tidak lagi mengendalikan proses dan tidak dapat mencegah unggahan atau unduhan berikutnya dari penyimpanan data.

Ini bukan pendekatan realistis dalam sistem terdistribusi dalam melayani klien yang tidak terpercaya. Sebaliknya, aplikasi harus dapat mengontrol akses data dengan aman secara utuh, tetapi masih mengurangi beban pada server dengan mengatur koneksi dan kemudian memungkinkan klien untuk berkomunikasi langsung dengan penyimpanan data untuk melakukan operasi baca atau tulis yang diperlukan.

Solusi

Anda perlu menyelesaikan masalah pengendalian akses ke penyimpanan data di mana toko tidak dapat mengelola autentikasi dan otorisasi klien. Salah satu solusi yang dapat dilakukan adalah membatasi akses ke koneksi publik penyimpanan data dan memberi klien kunci atau token yang dapat divalidasi oleh penyimpanan.

Kunci atau token ini biasanya disebut sebagai kunci layanan. Kunci ini menyediakan akses terbatas ke sumber daya tertentu dan hanya memungkinkan operasi yang telah ditentukan seperti membaca dan menulis ke penyimpanan atau antrian, atau mengunggah dan mengunduh di browser. Aplikasi dapat membuat dan mengeluarkan kunci ke perangkat klien dan browser web dengan cepat dan mudah, memungkinkan klien untuk melakukan operasi tanpa aplikasi untuk menangani transfer data secara langsung. Ini akan mengurangi pemrosesan berlebih, dan dampak kinerja dan skalabilitas, dari aplikasi dan server.

Klien menggunakan token untuk mengakses sumber daya tertentu di penyimpanan data hanya untuk periode tertentu, dan dengan batasan khusus izin akses, seperti yang ditunjukkan pada gambar. Setelah periode yang ditentukan, kunci menjadi tidak valid dan tidak mengizinkan akses ke sumber daya.

 Gambar 1 - Gambaran pola

Dimungkinkan juga untuk mengkonfigurasi kunci yang memiliki dependensi lain, seperti ruang lingkup data. Misalnya, tergantung pada kemampuan penyimpanan data, kunci dapat berupa tabel lengkap di penyimpanan data, atau hanya baris tertentu dalam tabel. Dalam sistem penyimpanan cloud, kunci dapat menentukan kontainer, atau item tertentu dalam wadah.

Kunci juga dapat dibatalkan oleh aplikasi. Pendekatan akan berguna jika klien memberi tahu server bahwa operasi transfer data selesai. Server dapat membatalkan kunci itu untuk mencegah akses lebih lanjut.

Penggunaan pola ini dapat menyederhanakan pengelolaan akses ke sumber daya karena tidak ada persyaratan untuk membuat dan mengautentikasi pengguna, memberikan izin, dan kemudian menghapus pengguna. Ini juga memudahkan untuk membatasi lokasi, izin, dan masa berlaku — semua hanya dengan membuat kunci saat aplikasi berjalan. Faktor penting lainnya adalah membatasi masa berlaku, dan terutama lokasi sumber daya, seketat mungkin sehingga penerima hanya dapat menggunakannya untuk tujuan yang dimaksud.

Masalah dan pertimbangan

Pertimbangkan poin-poin berikut saat memutuskan cara menerapkan pola ini:

Kelola status validitas dan periode kunci. Jika bocor atau disusupi, kunci tersebut secara efektif akan membuka item target dan membuatnya tersedia untuk penggunaan jahat selama periode validitas. Kunci biasanya dapat dicabut atau dinonaktifkan, tergantung pada bagaimana cara dikeluarkannya. Kebijakan sisi server dapat diubah atau, kunci server yang ditandatanganinya dapat dibatalkan. Tentukan masa berlaku untuk meminimalkan risiko membiarkan operasi tidak sah terhadap penyimpanan data. Namun, jika masa berlaku terlalu singkat, klien tidak dapat menyelesaikan operasi sebelum kunci berakhir. Izinkan pengguna untuk memperbarui kunci sebelum masa berlaku berakhir jika beberapa akses ke sumber daya yang dilindungi diperlukan.

Kontrol tingkat akses yang akan diberikan oleh kunci. Biasanya, kunci harus memastikan pengguna untuk melakukan tindakan yang diperlukan untuk menyelesaikan operasi, seperti akses baca-saja jika klien tidak dapat mengunggah data ke penyimpanan data. Untuk unggah file, biasanya ditentukan kunci yang memberikan izin tulis, serta lokasi dan periode validitas. Sangat penting secara akurat menentukan sumber daya atau kumpulan sumber daya yang diterapkan kunci.

Pertimbangkan cara mengontrol perilaku pengguna. Menerapkan pola ini berarti kehilangan kendali atas sumber daya yang diberikan akses kepada pengguna. Tingkat kontrol yang diberikan dibatasi oleh kebijakan dan izin yang tersedia untuk layanan atau penyimpanan data target. Misalnya, biasanya tidak mungkin membuat kunci yang membatasi ukuran data yang akan ditulis ke penyimpanan, atau berapa kali kunci dapat digunakan untuk mengakses file. Hal ini akan mengakibatkan biaya tak terduga yang sangat besar untuk transfer data, bahkan ketika digunakan oleh klien yang dituju, dan disebabkan oleh kesalahan dalam kode yang menyebabkan unggah atau unduh berulang. Untuk membatasi berapa kali file dapat diunggah, jika memungkinkan, paksa klien untuk memberi tahu aplikasi ketika satu operasi telah selesai. Misalnya, beberapa penyimpanan data memunculkan peristiwa yang dapat digunakan kode aplikasi untuk memantau operasi dan mengontrol perilaku pengguna. Namun, sulit untuk menerapkan kuota untuk pengguna individu dalam skenario multipenyewa di mana kunci yang sama digunakan oleh semua pengguna dari satu penyewa.

Memvalidasi, dan secara opsional membersihkan, semua data yang diunggah. Pengguna jahat yang mendapatkan akses ke kunci dapat mengunggah data yang dapat membahayakan sistem. Atau, pengguna mungkin mengunggah data yang tidak valid dan, saat diproses, dapat mengakibatkan kesalahan atau kegagalan sistem. Untuk melindungi dari hal ini, pastikan bahwa semua data yang diunggah divalidasi dan diperiksa untuk konten berbahaya sebelum digunakan.

Audit semua operasi. Banyak mekanisme berbasis kunci yang dapat mencatat operasi seperti unggahan, unduhan, dan kegagalan. Log ini biasanya dimasukkan ke dalam proses audit, dan digunakan untuk penagihan jika pengguna dikenai biaya berdasarkan ukuran file atau volume data. Gunakan log untuk mendeteksi kegagalan autentikasi yang disebabkan oleh masalah dengan penyedia kunci, atau penghapusan kebijakan akses tersimpan yang tidak disengaja.

Kirim kunci dengan aman. Itu dapat disematkan dalam URL yang diaktifkan pengguna di halaman web, atau digunakan dalam operasi pengalihan server sehingga unduhan terjadi secara otomatis. Selalu gunakan HTTPS untuk mengirimkan kunci melalui saluran yang aman.

Lindungi data sensitif saat transit. Data sensitif yang dikirimkan melalui aplikasi biasanya akan berlangsung menggunakan TLS, dan ini harus diberlakukan untuk klien yang mengakses penyimpanan data secara langsung.

Masalah lain yang harus diperhatikan saat menerapkan pola ini adalah:

  • Jika klien tidak, atau tidak dapat, memberi tahu server tentang penyelesaian operasi, dan satu-satunya batasan adalah periode kedaluwarsa kunci, aplikasi tidak dapat melakukan operasi audit seperti menghitung jumlah unggahan atau unduhan, atau mencegah beberapa unggahan atau unduhan.

  • Fleksibilitas kebijakan utama yang dapat dihasilkan mungkin terbatas. Misalnya, beberapa mekanisme hanya mengizinkan penggunaan waktu kedaluwarsa sesuai jadwal. Lainnya tidak dapat menentukan perincian izin baca/tulis yang memadai.

  • Jika waktu memulai periode validitas kunci atau token ditentukan, pastikan bahwa sedikit lebih awal dari waktu server saat ini untuk memungkinkan jam klien yang mungkin tidak sinkron. Standarnya, jika tidak ditentukan, biasanya menggunakan waktu pada server.

  • URL yang berisi kunci akan direkam dalam file log server. Meskipun kunci biasanya akan kedaluwarsa sebelum file log digunakan untuk analisis, pastikan Anda membatasi akses ke sana. Jika data log ditransmisikan ke sistem pemantauan atau disimpan di lokasi lain, pertimbangkan untuk menerapkan penundaan untuk mencegah kebocoran kunci hingga masa berlakunya habis.

  • Jika kode klien berjalan di browser web, browser perlu mendukung cross-origin resource sharing (CORS) untuk mengaktifkan kode yang dijalankan dalam browser web untuk mengakses data di domain berbeda dari domain yang melayani. Beberapa browser lama dan beberapa penyimpanan data tidak mendukung CORS, dan kode yang berjalan di browser ini mungkin tidak dapat menggunakan kunci layanan untuk menyediakan akses ke data di domain yang berbeda, seperti akun penyimpanan cloud.

Kapan menggunakan pola ini

Pola ini berguna untuk situasi berikut:

  • Untuk meminimalkan pemuatan sumber daya dan memaksimalkan kinerja dan skalabilitas. Menggunakan kunci layanan tidak memerlukan sumber daya untuk dikunci, tidak diperlukan panggilan server jarak jauh, tidak ada batasan jumlah kunci layanan yang dikeluarkan, dan dapat menghindari satu titik kegagalan akibat melakukan transfer data melalui kode aplikasi. Membuat kunci layanan merupakan operasi kriptografi sederhana untuk menandai rangkaian dengan kunci.

  • Meminimalkan biaya operasional Mengaktifkan akses langsung ke toko dan antrean merupakan sumber daya dan hemat biaya, dapat menghasilkan lebih sedikit perjalanan keluar masuk pada jaringan, dan memungkinkan pengurangan jumlah sumber daya komputasi.

  • Ketika klien secara teratur mengunggah atau mengunduh data, terutama jika ada volume besar atau ketika setiap operasi melibatkan file besar.

  • Ketika aplikasi memiliki sumber daya komputasi yang terbatas, baik karena keterbatasan hosting atau pertimbangan biaya. Dalam skenario ini, polanya bahkan lebih membantu jika ada banyak unggahan atau unduhan data secara bersamaan karena akan membebaskan aplikasi dari penanganan transfer data.

  • Ketika data disimpan di penyimpanan data jarak jauh atau pusat data yang berbeda. Jika aplikasi diminta untuk bertindak sebagai penjaga, bisa saja ada biaya untuk kecepatan tambahan mentransfer data antara pusat data, atau di seluruh jaringan publik atau pribadi antara klien dan aplikasi, dan kemudian antara aplikasi dan penyimpanan data.

Pola ini mungkin tidak berguna dalam situasi berikut:

  • Jika aplikasi harus melakukan beberapa tugas pada data sebelum disimpan atau dikirim ke klien. Misalnya, jika aplikasi perlu melakukan validasi, mencatat keberhasilan akses, atau menjalankan transformasi pada data. Namun, beberapa penyimpanan data dan klien dapat dinegosiaskani dan melakukan transformasi sederhana seperti kompresi dan dekompresi (misalnya, browser web dapat menangani format gzip).

  • Jika desain aplikasi yang sudah ada membuat sulit untuk menggabungkan pola. Menggunakan pola ini biasanya memerlukan pendekatan arsitektur yang berbeda untuk pengiriman dan penerimaan data.

  • Jika perlu untuk mempertahankan jejak audit atau mengontrol berapa kali operasi transfer data dijalankan, dan mekanisme kunci layanan yang digunakan tidak mendukung pemberitahuan yang dapat digunakan server untuk mengelola operasi ini.

  • Jika perlu untuk membatasi ukuran data, terutama selama kegiatan mengunggah. Satu-satunya solusi untuk ini adalah agar aplikasi memeriksa ukuran data setelah operasi selesai, atau memeriksa ukuran unggahan setelah periode tertentu atau berdasarkan jadwal.

Desain beban kerja

Arsitek harus mengevaluasi bagaimana pola Kunci Valet dapat digunakan dalam desain beban kerja mereka untuk mengatasi tujuan dan prinsip yang tercakup dalam pilar Azure Well-Architected Framework. Contohnya:

Pilar Bagaimana pola ini mendukung tujuan pilar
Keputusan desain keamanan membantu memastikan kerahasiaan, integritas, dan ketersediaan data dan sistem beban kerja Anda. Pola ini memungkinkan klien untuk langsung mengakses sumber daya tanpa memerlukan kredensial yang tahan lama atau berdiri. Semua permintaan akses dimulai dengan transaksi yang dapat diaudit. Akses yang diberikan kemudian dibatasi dalam cakupan dan durasi. Pola ini juga memudahkan untuk mencabut akses yang diberikan.

- Manajemen identitas dan akses SE:05
Pengoptimalan Biaya difokuskan untuk mempertahankan dan meningkatkan pengembalian beban kerja Anda pada investasi. Desain ini membongkar pemrosesan sebagai hubungan eksklusif antara klien dan sumber daya tanpa menambahkan komponen untuk langsung menangani semua permintaan klien. Manfaatnya paling dramatis ketika permintaan klien sering atau cukup besar untuk memerlukan sumber daya proksi yang signifikan.

- Biaya Alur CO:09
Efisiensi Performa membantu beban kerja Anda memenuhi tuntutan secara efisien melalui pengoptimalan dalam penskalaan, data, kode. Tidak menggunakan sumber daya perantara untuk memproksi pemrosesan offload akses sebagai hubungan eksklusif antara klien dan sumber daya tanpa memerlukan komponen duta besar yang perlu menangani semua permintaan klien dengan cara yang berkinerja. Manfaat menggunakan pola ini paling signifikan ketika proksi tidak menambahkan nilai ke transaksi.

- Pe:07 Kode dan infrastruktur

Seperti halnya keputusan desain apa pun, pertimbangkan tradeoff terhadap tujuan pilar lain yang mungkin diperkenalkan dengan pola ini.

Contoh

Azure mendukung tanda tangan akses bersama di Azure Storage untuk kontrol akses terbatas ke data dalam gumpalan, tabel, dan antrean, serta untuk antrean dan topik Bus Layanan. Token tanda tangan akses bersama dapat dikonfigurasi untuk memberikan hak akses tertentu seperti membaca, menulis, memperbarui, dan menghapus ke tabel tertentu; rentang kunci dalam tabel; antrian; gumpalan; atau wadah gumpalan. Validitas dapat berupa periode waktu yang ditentukan. Fungsionalitas ini sangat cocok untuk menggunakan kunci valet untuk akses.

Pertimbangkan beban kerja yang memiliki ratusan klien seluler atau desktop yang sering mengunggah biner besar. Tanpa pola ini, beban kerja pada dasarnya memiliki dua opsi. Yang pertama adalah menyediakan akses dan konfigurasi yang berdiri ke semua klien untuk melakukan unggahan langsung ke akun penyimpanan. Yang lain adalah menerapkan pola Perutean Gateway untuk menyiapkan titik akhir di mana klien menggunakan akses yang diproksi ke penyimpanan, tetapi ini mungkin tidak menambahkan nilai tambahan ke transaksi. Kedua pendekatan mengalami masalah yang ditangani dalam konteks pola:

  • Berumur panjang, rahasia prabayar. Berpotensi tanpa banyak cara untuk memberikan kunci yang berbeda untuk klien yang berbeda.
  • Menambahkan pengeluaran untuk menjalankan layanan komputasi yang memiliki sumber daya yang memadai untuk menangani penerimaan file besar saat ini.
  • Berpotensi memperlambat interaksi klien dengan menambahkan lapisan komputasi dan hop jaringan tambahan ke proses pengunggahan.

Menggunakan pola Kunci Valet mengatasi masalah keamanan, pengoptimalan biaya, dan performa.

Diagram memperlihatkan klien yang mengakses akun penyimpanan setelah terlebih dahulu mendapatkan token akses dari API.

  1. Klien, pada saat bertanggung jawab terakhir, mengautentikasi ke API yang dihosting Azure Function ringan ke nol untuk meminta akses.

  2. API memvalidasi permintaan lalu mendapatkan dan mengembalikan token SaS terbatas waktu &lingkup.

    Token yang dihasilkan oleh API membatasi klien ke batasan berikut:

    • Akun penyimpanan mana yang akan digunakan. Artinya, klien tidak perlu mengetahui informasi ini sebelumnya.
    • Kontainer dan nama file tertentu untuk digunakan; memastikan bahwa token dapat digunakan dengan, paling banyak, satu file.
    • Jendela operasi pendek, seperti tiga menit. Periode waktu singkat ini memastikan bahwa token memiliki TTL yang tidak diperpanjang melewati utilitasnya.
    • Izin untuk hanya membuat blob; bukan mengunduh, memperbarui, atau menghapus.
  3. Token tersebut kemudian digunakan oleh klien, dalam jendela waktu yang sempit, untuk mengunggah file langsung ke akun penyimpanan.

API menghasilkan token ini ke klien yang berwenang menggunakan kunci delegasi pengguna berdasarkan identitas terkelola ID Microsoft Entra API sendiri. Pengelogan diaktifkan pada akun penyimpanan dan API pembuatan token memungkinkan korelasi antara permintaan token dan penggunaan token. API dapat menggunakan informasi autentikasi klien atau data lain yang tersedia untuk memutuskan akun penyimpanan atau kontainer mana yang akan digunakan, seperti dalam situasi multipenyewa.

Sampel lengkap tersedia di GitHub pada contoh pola Kunci Valet. Cuplikan kode berikut diadaptasi dari contoh tersebut. Yang pertama ini menunjukkan bagaimana Azure Function (ditemukan di ValetKey.Web) menghasilkan token tanda tangan akses bersama yang didelegasikan pengguna menggunakan identitas terkelola Azure Function sendiri.

[Function("FileServices")]
public async Task<StorageEntitySas> GenerateTokenAsync([HttpTrigger(...)] HttpRequestData req, ..., 
                                                        CancellationToken cancellationToken)
{
  // Authorize the caller, select a blob storage account, container, and file name.
  // Authenticate to the storage account with the Azure Function's managed identity.
  ...

  return await GetSharedAccessReferenceForUploadAsync(blobContainerClient, blobName, cancellationToken);
}

/// <summary>
/// Return an access key that allows the caller to upload a blob to this
/// specific destination for about three minutes.
/// </summary>
private async Task<StorageEntitySas> GetSharedAccessReferenceForUploadAsync(BlobContainerClient blobContainerClient, 
                                                                            string blobName,
                                                                            CancellationToken cancellationToken)
{
  var blobServiceClient = blobContainerClient.GetParentBlobServiceClient();
  var blobClient = blobContainerClient.GetBlockBlobClient(blobName);

  // Allows generating a SaS token that is evaluated as the union of the RBAC permissions on the managed identity
  // (for example, Blob Data Contributor) and then narrowed further by the specific permissions in the SaS token.
  var userDelegationKey = await blobServiceClient.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow.AddMinutes(-3),
                                                                            DateTimeOffset.UtcNow.AddMinutes(3),
                                                                            cancellationToken);

  // Limit the scope of this SaS token to the following:
  var blobSasBuilder = new BlobSasBuilder
  {
      BlobContainerName = blobContainerClient.Name,     // - Specific container
      BlobName = blobClient.Name,                       // - Specific filename
      Resource = "b",                                   // - Blob only
      StartsOn = DateTimeOffset.UtcNow.AddMinutes(-3),  // - For about three minutes (+/- for clock drift)
      ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(3),  // - For about three minutes (+/- for clock drift)
      Protocol = SasProtocol.Https                      // - Over HTTPS
  };
  blobSasBuilder.SetPermissions(BlobSasPermissions.Create);

  return new StorageEntitySas
  {
      BlobUri = blobClient.Uri,
      Signature = blobSasBuilder.ToSasQueryParameters(userDelegationKey, blobServiceClient.AccountName).ToString();
  };
}

Cuplikan berikut adalah objek transfer data (DTO) yang digunakan oleh API dan klien.

public class StorageEntitySas
{
  public Uri? BlobUri { get; internal set; }
  public string? Signature { get; internal set; }
}

Klien (ditemukan di ValetKey.Client) kemudian menggunakan URI dan token yang dikembalikan dari API untuk melakukan unggahan tanpa memerlukan sumber daya tambahan dan pada performa klien-ke-penyimpanan penuh.

...

// Get the SaS token (valet key)
var blobSas = await httpClient.GetFromJsonAsync<StorageEntitySas>(tokenServiceEndpoint);
var sasUri = new UriBuilder(blobSas.BlobUri)
{
    Query = blobSas.Signature
};

// Create a blob client using the SaS token as credentials
var blob = new BlobClient(sasUri.Uri);

// Upload the file directly to blob storage
using (var stream = await GetFileToUploadAsync(cancellationToken))
{
    await blob.UploadAsync(stream, cancellationToken);
}

...

Langkah berikutnya

Panduan berikut bisa jadi relevan saat menerapkan pola berikut ini:

Pola berikut mungkin juga relevan saat menerapkan pola ini:

  • Pola gatekeeper. Pola ini dapat digunakan bersama dengan pola Valley Key untuk melindungi aplikasi dan layanan dengan menggunakan instans host khusus yang bertindak sebagai broker antara klien dan aplikasi atau layanan. Penjaga gerbang memvalidasi dan membersihkan permintaan, dan meneruskan permintaan data antara klien dan aplikasi. Ini dapat memberikan lapisan keamanan tambahan, dan membatasi serangan sistem permukaan.
  • Pola Hosting Konten Statik. Menjelaskan cara menerapkan sumber daya statis ke layanan penyimpanan berbasis cloud yang dapat mengirimkan sumber daya langsung ke klien untuk mengurangi persyaratan instans komputasi yang mahal. Jika sumber daya tidak dimaksudkan untuk umum, pola Vallet Key dapat digunakan untuk mengamankannya.