Як безпечно зберігати та використовувати секреті дані за допомогою Azure Key Vault
Під час розробки практично будь якого рішення, нам потрібно зберігати певні секретні дані. Це може буде як рядок підключення до БД з обліковими даними про користувача (логін/пароль), так і дані про платіжні системи. В кожному додатку це буде те що потрібно для виконання автоматизації тих чи інших задач. Зазвичай, і це є небезпечно та погана практика, ці дані зберігаються в файлах налаштувань додатку, і (на жаль дуже часто) ці дані додають до систем контролю версій (git). Чому це не правильно? - Перш за все вся команда розробників які працюють над додатком мають копію цих даних, коли та чи інша людина звільнюється ви не можете бути впевненими що ваші секретні дані не будуть використані або розповсюджені. Звісно ви може замінити секретні дані на нові і попередні будуть не актуальні, але це займає час і також інколи може бути не надто простим процесом, якщо у вас є залежності в інших додатках. Також, якщо вихідний код вашого додатку буде викрадено, всі ваші секретні дані, а також персональні дані користувачів які його використовують будуть під загрозою.
Як зберігати секретні дані безпечно?
Існує багато механізмів які забезпечують безпечне зберігати секретних даних, це може бути змінні середовища (Environment variables, якщо ми говоримо про .net), певні механізми шифрування та розшифровування, але як на мене, одним із найпростіших варіантів, а особливо якщо ви використовуєте Azure, є Azure Key Vault. Azure Key Vault - це хмарна сервіс, в якому ви можете безпечно зберігати паролі, ключі, сертифікати і всю необхідну секретну інформацію.
Для того щоб зберегти дані в Azure Key Vault його потрібно створити, для цього перейдіть на портал Azure, натисніть “створити новий ресурс” і виберіть “Key Vault”, заповніть обов’язкові поля та натисніть створити.
За декілька секунд ваш ресурс буде створено і ви зможете почати його використовувати. Для збереження секретних даних у вигляді ключ -> значення, перейдіть в розділ Secrets
та натисніть Generate/Import
.
Ви також маєте можливість встановити коли дані почнуть бути активними для використання і також термін придатності, але в нашому випадку нам це не потрібно.
І так, ми створили новий Key Vault ресурс та додали новий секретний запис.
Як отримати дані з Key Vault у нашому додатку?
Для того щоб почати використовувати дані з Key Vault у .net додатку, який буде розгорнуто і доступний для користувачів, нам потрібно створити в Azure Active Directory
новий додаток який буде мати доступ до сервісу де знаходяться наші секретні дані. Щоб це зробити перейдіть в розділ Azure Active Directory -> App registrations
та натисніть створити нову реєстрацію. У вікні що появиться нам достатньо вказати імя і натиснути кнопку “зареєструвати”.
Після успішного створення нового Active Directory додатку нам потрібно додати SSL сертифікат, і з допомогою сертифікату ми будемо перевіряти чи можемо ми отримати доступ до секретних даних які будуть знаходитися у нас в Azure Key Vault.
Як створити сертифікат ви можете прочитати у моїй попередній статті Використання TLS/SSL сертифікатів в .net додатку для Azure App Service
Сертифікат потрібний для підтвердження того, що додаток який хоче отримати дані з Key Vault це дійсно наш додаток і він має встановлений сертифікат (Як додати сертифікат до Azure App Service ви також можете подивитися в попередній статті).
І так у нас є новий зареєстрований Active Directory App, для того щоб отримати дані з Key Vault нам буде потрібна ще інформація про цей додаток. Для початку нам потрібний Thumbprint
нашого сертифікату, ви повинні його побачити відразу після додавання його до App Active Directory, а також нам потрібні Application (client) ID
та Directory (tenant) ID
, для цього перейдіть в розділ “Overview”.
Щоб дозволити нашій Active Directory App отримувати секретні дані з Azure Key Vault, потрібно створити нову політику доступу.
Поверніться до нашого створеного Azure Key Vault, перейдіть в розділ “Access policies” та натисніть “Створити”. У новому вікні виберіть з спадного списку Key & Secret Management
та натисніть “Далі”. На наступному крокові створення політики доступу виберіть нашу Active Directory App. Перейдіть на останній крок створення та натисніть “Створити”.
Key & Secret Management - надасть доступ не тільки на читання але також на модифікацію, видалення. Якщо вам це не потрібно тоді виберіть тільки необхідні дозволи.
Ми налаштували політику доступу і тепер можемо написати код який буде отримувати доступ до наших секретних даних.
Написання коду
Для роботі з Azure Key Vault нам потрібно встановити два NuGet пакети:
1
2
dotnet add package Azure.Identity
dotnet add package Azure.Extensions.AspNetCore.Configuration.Secrets
Azure.Identity - надає змогу працювати з Active Directory, у нашому випадку автентифікація. Azure.Extensions.AspNetCore.Configuration.Secrets - безпосередньо робота з Azure Key Vault.
Наступним кроком змінимо appsettings.json
файл та додамо інформацію про Azure Key Vault та AD App.
1
2
3
4
5
6
7
8
{
"KeyVault": {
"Vault": "taras-kv",
"TenantId": "e4e08b73-e6c2-4c56-8cc0-b3813a030420",
"ClientId": "36fc9800-c4b3-46a7-8f7e-b245a38ddc04",
"Thumbprint": "67F592325E454FDE9B43FFEA5AFB6168"
}
}
appsettings.json
містить інформацію таку як назва нашого Key Vault, Application (client) ID
та Directory (tenant) ID
нашого Active Directory App та Thumbprint
сертифікату який ми створили та завантажили.
Тепер нам потрібно написати код який буде використовувати ці дані та завантажувати в секретні дані з Azure Key Vault. Для цього нам потрібно викликати метод розширення AddAzureKeyVault
для IConfigurationBuilder
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using System.Security.Cryptography.X509Certificates;
using Azure.Identity;
var builder = WebApplication.CreateBuilder(args);
var env = builder.Environment;
builder.Configuration.AddJsonFile($"appsettings.{env.EnvironmentName}.json");
var root = builder.Configuration;
builder.Configuration.AddAzureKeyVault(
new Uri($"https://{root["KeyVault:Vault"]}.vault.azure.net/"),
new ClientCertificateCredential(
root["KeyVault:TenantId"],
root["KeyVault:ClientId"],
GetX509Certificate(root["KeyVault:Thumbprint"])
)
);
var app = builder.Build();
app.Run();
Реалізацію методу
GetX509Certificate
можна знайти у моїй попередній статті Використання TLS/SSL сертифікатів в .net додатку для Azure App Service
Що даний код виконує? - спочатку ми додаємо до конфігурації appsettings.json
файл який містить інформацію про Key Vault та AD App. Формуємо Uri
для Key Vault та створюємо екземпляр класу ClientCertificateCredential
щоб автентифікуватися в Azure Active Directory за допомогою вказаного сертифіката.
Сертифікат повинен бути встановленим на ваш ПК щоб ви отримали доступ до даних KV.
Даний підхід дозволяє нам зберігати секретні дані в захищеному середовищі Key Vault і тільки якщо ви маєте встановлений SSL сертифікат ви зможете зчитати з нього дані.
Але тут виникає наступна проблема, нам потрібно надати доступ до сертифікату всім розробникам і це знову ж таки проблема безпеки. Щоб уникнути даної проблеми ми можемо модифікувати код таким чином, щоб усі хто працює з додатком використовували власний обліковий запис Azure і для цього нам достатньо змінити ClientCertificateCredential
на AzureCliCredential
.
1
2
3
4
5
var root = builder.Configuration;
builder.Configuration.AddAzureKeyVault(
new Uri($"https://{root["KeyVault:Vault"]}.vault.azure.net/"),
new AzureCliCredential()
);
Тепер, якщо ви спробуєте запустити ваш додаток система буде перевіряти чи ви увійшли в Azure з допомогою Azure CLI
1
az login
і відповідно доступ до Key Vault буде базуватися на ваших Azure дозволах.
Висновок
Збереження секретних конфігураційних даних є дуже важливим процесом в розробці програмного забезпечення, а також реалізація подібних механізмів не потребує великих зусиль та коштів. Не додавайте ваші секретні дані до систем контролю версій тому що ви не можете бути впевненими в їх безпеці.
Ми розібрали як створити Azure Key Vault сервіс, додати в нього запис та отримати цей запис з вашого додатку. Також як реалізувати механізм при якому не потрібно надавати доступ до SSL сертифікату усім розробникам проекту.
Якщо ви не хочете додавати до систем контролю версій інформацію яку ми додали до appsettings.json
, а саме Key Vault імя, TenantId, ClientId та Thumbprint, тоді ви можете використовувати змінні середовища (Environment variables) і отримувати їх безпосередньо звідти, для прикладу - Environment.GetEnvironmentVariable("Vault")
.