forked from hashicorp/vault-guides
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Moving the folder location (hashicorp#35)
- Loading branch information
Showing
13 changed files
with
601 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
using System; | ||
using MySql.Data.MySqlClient; | ||
|
||
namespace RewrapExample | ||
{ | ||
public class AppDb : IDisposable | ||
{ | ||
public readonly MySqlConnection Connection; | ||
|
||
public AppDb() | ||
{ | ||
Connection = new MySqlConnection("host=127.0.0.1;port=3306;user id=vault;password=vaultpw;database=my_app;"); | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
Connection.Close(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Data.Common; | ||
using System.Threading.Tasks; | ||
|
||
namespace RewrapExample | ||
{ | ||
|
||
class DBHelper | ||
{ | ||
public static async Task CreateTablesAsync() | ||
{ | ||
using (var db = new AppDb()) | ||
{ | ||
await db.Connection.OpenAsync(); | ||
using (var cmd = db.Connection.CreateCommand()) | ||
{ | ||
string command = "CREATE TABLE IF NOT EXISTS `user_data`(" + | ||
"`user_id` INT(11) NOT NULL AUTO_INCREMENT, " + | ||
"`user_name` VARCHAR(256) NOT NULL," + | ||
"`first_name` VARCHAR(256) NULL, " + | ||
"`last_name` VARCHAR(256) NULL, " + | ||
"`address` VARCHAR(256) NOT NULL, " + | ||
"`city` VARCHAR(256) NOT NULL," + | ||
"`state` VARCHAR(256) NOT NULL," + | ||
"`postcode` VARCHAR(256) NOT NULL," + | ||
"`email` VARCHAR(256) NOT NULL," + | ||
"`dob` VARCHAR(256) NULL," + | ||
"PRIMARY KEY (user_id) " + | ||
") engine=InnoDB;"; | ||
cmd.CommandText = command; | ||
|
||
|
||
await cmd.ExecuteNonQueryAsync(); | ||
Console.WriteLine("Create (if not exist) user_data table"); | ||
} | ||
} | ||
} | ||
|
||
public static async Task CreateDBAsync() | ||
{ | ||
using (var db = new AppDb()) | ||
{ | ||
await db.Connection.OpenAsync(); | ||
using (var cmd = db.Connection.CreateCommand()) | ||
{ | ||
string command = "CREATE DATABASE IF NOT EXISTS my_app"; | ||
cmd.CommandText = command; | ||
|
||
|
||
await cmd.ExecuteNonQueryAsync(); | ||
Console.WriteLine("Created (if not exist) my_app DB"); | ||
} | ||
} | ||
} | ||
|
||
public static async Task InsertRecordAsyc(Record r) | ||
{ | ||
using (var db = new AppDb()) | ||
{ | ||
await db.Connection.OpenAsync(); | ||
using (var cmd = db.Connection.CreateCommand()) | ||
{ | ||
|
||
string command = "INSERT INTO `user_data` " + | ||
"(`user_name`, `first_name`, `last_name`, `address`, " + | ||
"`city`, `state`, `postcode`, `email`, `dob`) " + | ||
$"VALUES (\"{r.Login.Username}\", \"{r.Name.First}\", \"{r.Name.Last}\", " + | ||
$"\"{r.Location.Street}\", \"{r.Location.City}\", \"{r.Location.State}\", " + | ||
$"\"{r.Location.Postcode}\", \"{r.Email}\", \"{r.DOB}\");"; | ||
|
||
cmd.CommandText = command; | ||
|
||
var rowsAffected = await cmd.ExecuteNonQueryAsync(); | ||
//Console.WriteLine($"Created {rowsAffected} rows"); | ||
} | ||
} | ||
} | ||
|
||
// update encrypted fields with rewrapped data | ||
public static async Task UpdateRecordAsyc(Record r) | ||
{ | ||
using (var db = new AppDb()) | ||
{ | ||
await db.Connection.OpenAsync(); | ||
using (var cmd = db.Connection.CreateCommand()) | ||
{ | ||
|
||
string command = "UPDATE `user_data` " + | ||
$"SET `address` = \"{r.Location.Street}\", " + | ||
$"`dob` = \"{r.DOB}\", " + | ||
$"`email` = \"{r.Email}\" " + | ||
$"WHERE `user_id` = {r.Id.Value}"; | ||
|
||
cmd.CommandText = command; | ||
|
||
await cmd.ExecuteNonQueryAsync(); | ||
} | ||
} | ||
} | ||
|
||
// Find records that need to be rewrapped | ||
public static async Task<List<Record>> FindRecordsToRewrap(int keyVersion) | ||
{ | ||
// select fields that are encrypted | ||
using (var db = new AppDb()) | ||
{ | ||
var users = new List<Record>(); | ||
await db.Connection.OpenAsync(); | ||
using (var cmd = db.Connection.CreateCommand()) | ||
{ | ||
int count = 0; | ||
string command = "SELECT `user_id`, `email`,`dob`, `address` " + | ||
"FROM `user_data` " + | ||
$"WHERE `dob` NOT LIKE \"vault:v{keyVersion}:%\" " + | ||
$"OR `email` NOT LIKE \"vault:v{keyVersion}:%\" " + | ||
$"OR `address` NOT LIKE \"vault:v{keyVersion}:%\" "; | ||
|
||
|
||
cmd.CommandText = command; | ||
|
||
var reader = await cmd.ExecuteReaderAsync(); | ||
|
||
while (reader.Read()) | ||
{ | ||
count++; | ||
var user_id = reader.GetInt32(0); | ||
var email = reader.GetString(1); | ||
var dob = reader.GetString(2); | ||
var address = reader.GetString(3); | ||
|
||
RewrapExample.Location addr = new Location(); | ||
addr.Street = address; | ||
RewrapExample.Id id = new Id(); | ||
id.Value = user_id.ToString(); | ||
|
||
Record r = new Record | ||
{ | ||
Id = id, | ||
DOB = dob, | ||
Email = email, | ||
Location = addr, | ||
}; | ||
users.Add(r); | ||
} | ||
} | ||
return users; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Net.Http; | ||
using System.Net.Http.Headers; | ||
using System.Threading.Tasks; | ||
using Newtonsoft.Json; | ||
|
||
namespace RewrapExample | ||
{ | ||
class Program | ||
{ | ||
static VaultClient client = null; | ||
static void Main(string[] args) | ||
{ | ||
// Get our env vars | ||
string vaultUri = Environment.GetEnvironmentVariable("VAULT_ADDR"); | ||
string token = Environment.GetEnvironmentVariable("VAULT_TOKEN"); | ||
string transitKeyName = Environment.GetEnvironmentVariable("VAULT_TRANSIT_KEY"); | ||
string shouldSeed = Environment.GetEnvironmentVariable("SHOULD_SEED_USERS"); | ||
string numRecords = Environment.GetEnvironmentVariable("NUMBER_SEED_USERS"); | ||
|
||
Console.WriteLine("Connecting to Vault server..."); | ||
|
||
// initialize Vault client | ||
if (null == client) | ||
{ | ||
client = new VaultClient(vaultUri, token, transitKeyName); | ||
} | ||
|
||
InitDBAsync().GetAwaiter().GetResult(); | ||
|
||
// seed the database with random user records if necessary | ||
if (null != shouldSeed) { | ||
SeedDB(numRecords).GetAwaiter().GetResult(); | ||
Console.WriteLine("Seeded the database..."); | ||
} | ||
|
||
// get latest key version and rewrap if necessary | ||
Console.WriteLine("Moving rewrap..."); | ||
RewrapAsync().GetAwaiter().GetResult(); | ||
} | ||
|
||
static async Task InitDBAsync() | ||
{ | ||
await DBHelper.CreateDBAsync(); | ||
await DBHelper.CreateTablesAsync(); | ||
|
||
} | ||
|
||
// Download records from the randomuser api, and encrypt some | ||
// fields so we can rewrap them later | ||
static async Task SeedDB(string numRecords) | ||
{ | ||
WebHelper.ApiResults apiResults = await WebHelper.GetUserRecordsAsync(numRecords); | ||
var tasks = new List<Task>(); | ||
foreach (var record in apiResults.Records) { | ||
ICollection<Task> encryptValues = new List<Task>(); | ||
record.DOB = await client.EncryptValue(record.DOB); | ||
record.Location.Street = await client.EncryptValue(record.Location.Street); | ||
record.Email = await client.EncryptValue(record.Email); | ||
tasks.Add(DBHelper.InsertRecordAsyc(record)); | ||
} | ||
await Task.WhenAll(tasks); | ||
|
||
} | ||
static async Task RewrapAsync() { | ||
int v = await client.GetLatestTransitKeyVersion(); | ||
Console.WriteLine($"Current Key Version: {v}"); | ||
List<Record> users = await DBHelper.FindRecordsToRewrap(v); | ||
Console.WriteLine($"Found {users.Count} records to rewrap."); | ||
await client.ReWrapRecords(users); | ||
|
||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Vault Transit Rewrap Record After Key Rotation Example | ||
|
||
These assets are provided to perform the tasks described in the [Transit Secret Re-wrapping](https://www.vaultproject.io/guides/encryption/transit-rewrap.html) guide. | ||
|
||
--- | ||
|
||
## Demo Script Guide | ||
|
||
The following files are provided as demo scripts: | ||
|
||
- `demo_setup.sh` performs [Step 1 through 3](https://www.vaultproject.io/guides/encryption/transit-rewrap.html#steps) in the guide | ||
* Pull and run mysql server 5.7 docker container | ||
* Enable transit secret engine | ||
* Create `my_app_key` encryption key | ||
* Create `rewrap_example` policy | ||
* Generate a token to be used by the app | ||
- `run-app.sh` performs [Step 4](https://www.vaultproject.io/guides/encryption/transit-rewrap.html#step4) in the guide | ||
* Runs the example app | ||
* Prints out the commends to explore the MySQL DB | ||
- `rewrap_example.sh` performs [Step 5](https://www.vaultproject.io/guides/encryption/transit-rewrap.html#step-5-rotate-the-encryption-keys) in the guide | ||
* Read the `my_app_key` details BEFORE the key rotation | ||
* Rotate the `my_app_key` encryption key | ||
* Read the `my_app_key` details AFTER the key rotation | ||
* Prints out the command to set the `min_decryption_version` | ||
- `cleanup.sh` re-set your environment | ||
|
||
|
||
### Demo Workflow | ||
|
||
> **NOTE:** DON'T FORGET that this demo requires [.NET Core and Docker](https://www.vaultproject.io/guides/encryption/transit-rewrap.html#prerequisites) to run the sample app. | ||
1. Run `demo_setup.sh` | ||
|
||
2. Run `run_app.sh` | ||
- Open another terminal | ||
- Copy and paste the suggested commands to explorer the `user_data` table in mysql | ||
|
||
3. Run `rewrap_example.sh` a couple of times and review the key version | ||
|
||
4. Run `run_app.sh` again | ||
- See the data in the `user_data` table are now rewrapped with the _latest_ encryption key version | ||
|
||
To demonstrate the minimum key version restriction feature, repeat #3 and then run the commands suggested in the output (`vault write transit/keys/my_app_key/config min_decryption_version=3`). And then, repeat #4. | ||
|
||
Finally, run `cleanup.sh` to re-set your environment so that you can repeat the demo as necessary. | ||
|
||
> **WARNING:** The `cleanup.sh` disables the transit secret engine. All encryption keys will be deleted. If you are working against a shared Vault server, you might want to ***manually*** clean up the environment instead. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
namespace RewrapExample | ||
{ | ||
public class Name | ||
{ | ||
public string Title { get; set; } | ||
public string First { get; set; } | ||
public string Last { get; set; } | ||
} | ||
|
||
public class Location | ||
{ | ||
public string Street { get; set; } | ||
public string City { get; set; } | ||
public string State { get; set; } | ||
public string Postcode { get; set; } | ||
} | ||
|
||
public class Login | ||
{ | ||
public string Username { get; set; } | ||
public string Password { get; set; } | ||
public string Salt { get; set; } | ||
public string Md5 { get; set; } | ||
public string Sha1 { get; set; } | ||
public string Sha256 { get; set; } | ||
} | ||
|
||
public class Id | ||
{ | ||
public string Name { get; set; } | ||
public string Value { get; set; } | ||
} | ||
|
||
public class Picture | ||
{ | ||
public string Large { get; set; } | ||
public string Medium { get; set; } | ||
public string Thumbnail { get; set; } | ||
} | ||
|
||
public class Record | ||
{ | ||
public string Gender { get; set; } | ||
public Name Name { get; set; } | ||
public Location Location { get; set; } | ||
public string Email { get; set; } | ||
public Login Login { get; set; } | ||
public string DOB { get; set; } | ||
public string Registered { get; set; } | ||
public string Phone { get; set; } | ||
public string Cell { get; set; } | ||
public Id Id { get; set; } | ||
public Picture Picture { get; set; } | ||
public string Nationality { get; set; } | ||
} | ||
} |
Oops, something went wrong.