Skip to content

Commit

Permalink
Adds wrapped secret approle authentiation (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
abedra authored Nov 23, 2019
1 parent 965a4fd commit bd664b5
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 40 deletions.
13 changes: 9 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.9)
project(vault VERSION 0.0.5 DESCRIPTION "Vault library for C++")
project(vault VERSION 0.0.6 DESCRIPTION "Vault library for C++")

set(CMAKE_CXX_STANDARD 14)

Expand All @@ -22,12 +22,16 @@ add_library(vault SHARED
src/HttpClient.cpp
src/KeyValue.cpp
src/Transit.cpp
src/AppRole.cpp)
src/AppRole.cpp
src/Unwrap.cpp
src/WrappedSecretAppRole.cpp
)

set_target_properties(vault PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION 0
PUBLIC_HEADER "include/VaultClient.h")
PUBLIC_HEADER "include/VaultClient.h"
)

target_include_directories(vault PRIVATE include)
target_include_directories(vault PRIVATE src)
Expand All @@ -36,7 +40,8 @@ target_link_libraries(vault PRIVATE nlohmann_json::nlohmann_json)

install(TARGETS vault
LIBRARY DESTINATION ${CMAKE_INSTALL_DIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

configure_file(vault.pc.in vault.pc @ONLY)

Expand Down
28 changes: 19 additions & 9 deletions example/example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ void transit_sign(VaultClient vaultClient) {
print_response(transit.sign("mykey", sha_512, parameters));
}

void unwrap(VaultClient vaultClient, std::string token) {
print_response(Unwrap::unwrap(vaultClient, token));
}

static std::string getOrDefault(const char *name, std::string defaultValue) {
auto value = std::getenv(name);

Expand All @@ -152,20 +156,26 @@ auto main() -> int {

auto roleId = getOrDefault("APPROLE_ROLE_ID", "");
auto secretId = getOrDefault("APPROLE_SECRET_ID", "");
auto wrappedToken = getOrDefault("APPROLE_WRAPPED_TOKEN", "");

auto config = VaultConfigBuilder()
.withHost("192.168.1.20")
.withTlsEnabled(false)
.build();

auto authStrategy = AppRole{roleId, secretId};
auto vaultClient = VaultClient{config, authStrategy, httpErrorCallback};
// auto authStrategy = AppRole{roleId, secretId};
// auto vaultClient = VaultClient{config, authStrategy, httpErrorCallback};

// kv1(vaultClient);
// kv2(vaultClient);
// transit_encrypt_decrypt(vaultClient);
// transit_keys(vaultClient);
// transit_random(vaultClient);
// transit_hash(vaultClient);
// transit_hmac(vaultClient);

auto wrappedAuthStrategy = WrappedSecretAppRole{roleId, wrappedToken};
auto wrappedVaultClient = VaultClient{config, wrappedAuthStrategy, httpErrorCallback};

kv1(vaultClient);
kv2(vaultClient);
transit_encrypt_decrypt(vaultClient);
transit_keys(vaultClient);
transit_random(vaultClient);
transit_hash(vaultClient);
transit_hmac(vaultClient);
kv2(wrappedVaultClient);
}
26 changes: 22 additions & 4 deletions include/VaultClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,13 +223,14 @@ class VaultClient {
VaultClient(VaultConfig& config, AuthenticationStrategy& authStrategy);
VaultClient(VaultConfig& config, AuthenticationStrategy& authStrategy, HttpErrorCallback httpErrorCallback);

const HttpClient& getHttpClient() const { return httpClient_; }

bool is_authenticated() const { return !token_.empty(); }

std::string getToken() const { return token_; }
std::string getNamespace() const { return namespace_; }
std::string getUrl(std::string base, std::string path) const;
std::string getUrl(const std::string& base, const std::string& path) const;

const HttpClient& getHttpClient() const { return httpClient_; }
private:
bool debug_;
bool tls_;
Expand Down Expand Up @@ -266,13 +267,30 @@ class Token : public AuthenticationStrategy {
class AppRole : public AuthenticationStrategy {
public:
AppRole(std::string role_id, std::string secret_id);

optional<std::string> authenticate(const VaultClient& vaultClient) override;

private:
static std::string getUrl(const VaultClient& vaultClient, const std::string& path);
std::string role_id_;
std::string secret_id_;
};

class Unwrap {
public:
static optional<std::string> unwrap(const VaultClient &client, std::string token);

static std::string getUrl(const VaultClient& vaultClient, std::string path);
private:
static std::string getUrl(const VaultClient& client, const std::string& path);
};

class WrappedSecretAppRole : public AuthenticationStrategy {
public:
WrappedSecretAppRole(std::string role_id, std::string token);
optional<std::string> authenticate(const VaultClient& vaultClient) override;

private:
std::string role_id_;
std::string token_;
};

class KeyValue {
Expand Down
10 changes: 5 additions & 5 deletions src/AppRole.cpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
#include <nlohmann/json.hpp>
#include <utility>
#include <nlohmann/json.hpp>
#include "VaultClient.h"

AppRole::AppRole(std::string role_id, std::string secret_id)
: role_id_(std::move(role_id))
, secret_id_(std::move(secret_id))
{}

std::string AppRole::getUrl(const VaultClient& client, std::string path) {
return client.getUrl("/v1/auth/approle", std::move(path));
}

optional<std::string> AppRole::authenticate(const VaultClient& client) {
nlohmann::json j;
j = nlohmann::json::object();
Expand All @@ -29,3 +25,7 @@ optional<std::string> AppRole::authenticate(const VaultClient& client) {
return std::experimental::nullopt;
}
}

std::string AppRole::getUrl(const VaultClient& client, const std::string& path) {
return client.getUrl("/v1/auth/approle", path);
}
27 changes: 27 additions & 0 deletions src/Unwrap.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include <VaultClient.h>
#include <nlohmann/json.hpp>

std::string Unwrap::getUrl(const VaultClient& client, const std::string& path) {
return client.getUrl("/v1/sys/wrapping", path);
}

optional<std::string>
Unwrap::unwrap(const VaultClient& client, std::string token) {
nlohmann::json j;
j = nlohmann::json::object();
j["token"] = token;

auto response = client
.getHttpClient()
.post(getUrl(client, "/unwrap"),
client.getToken(),
client.getNamespace(),
j.dump()
);

if (HttpClient::is_success(response)) {
return nlohmann::json::parse(response.value().body)["data"]["secret_id"];
} else {
return std::experimental::nullopt;
}
}
41 changes: 23 additions & 18 deletions src/VaultClient.cpp
Original file line number Diff line number Diff line change
@@ -1,36 +1,41 @@
#include <utility>
#include "VaultClient.h"

VaultClient::VaultClient(VaultConfig& config,
AuthenticationStrategy& authStrategy) :
host_(config.getHost()),
port_(config.getPort()),
namespace_(config.getNamespace()),
tls_(config.getTls()),
authStrategy_(authStrategy),
httpClient_(HttpClient(config))
VaultClient::VaultClient(
VaultConfig& config,
AuthenticationStrategy& authStrategy)
: host_(config.getHost())
, port_(config.getPort())
, namespace_(config.getNamespace())
, tls_(config.getTls())
, authStrategy_(authStrategy)
, httpClient_(HttpClient(config))
, debug_(config.getDebug())
{
auto result = authStrategy_.authenticate(*this);
if (result) {
token_ = result.value();
}
}

VaultClient::VaultClient(VaultConfig& config,
AuthenticationStrategy& authStrategy,
HttpErrorCallback httpErrorCallback) :
host_(config.getHost()),
port_(config.getPort()),
namespace_(config.getNamespace()),
tls_(config.getTls()),
authStrategy_(authStrategy),
httpClient_(HttpClient(config, httpErrorCallback))
VaultClient::VaultClient(
VaultConfig& config,
AuthenticationStrategy& authStrategy,
HttpErrorCallback httpErrorCallback)
: host_(config.getHost())
, port_(config.getPort())
, namespace_(config.getNamespace())
, tls_(config.getTls())
, authStrategy_(authStrategy)
, httpClient_(HttpClient(config, std::move(httpErrorCallback)))
, debug_(config.getDebug())
{
auto result = authStrategy_.authenticate(*this);
if (result) {
token_ = result.value();
}
}

std::string VaultClient::getUrl(std::string base, std::string path) const {
std::string VaultClient::getUrl(const std::string& base, const std::string& path) const {
return (tls_ ? "https://" : "http://") + host_ + ":" + port_ + base + path;
}
15 changes: 15 additions & 0 deletions src/WrappedSecretAppRole.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include <utility>
#include "VaultClient.h"

WrappedSecretAppRole::WrappedSecretAppRole(std::string role_id, std::string token)
: role_id_(std::move(role_id))
, token_(std::move(token))
{}

optional<std::string> WrappedSecretAppRole::authenticate(const VaultClient &vaultClient) {
auto secret_id = Unwrap::unwrap(vaultClient, token_);

return secret_id
? AppRole(role_id_, secret_id.value()).authenticate(vaultClient)
: std::experimental::nullopt;
}

0 comments on commit bd664b5

Please sign in to comment.