Skip to content

Commit

Permalink
feat: read token from file and remove config from upload command
Browse files Browse the repository at this point in the history
  • Loading branch information
helder-moreira committed Oct 24, 2023
1 parent f167e65 commit f36253b
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 69 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Build docker image

on:
push:
branches:
- feat/add-vault-support

jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

- name: Login to GitHub Container Registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push
id: docker_build
uses: docker/build-push-action@v2
with:
push: true
platforms: linux/amd64,linux/arm64
tags: ghcr.io/nibiruchain/tmkms:hashicorp
4 changes: 2 additions & 2 deletions src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ impl Configurable<KmsConfig> for KmsCommand {
KmsCommand::Yubihsm(yubihsm) => yubihsm.config_path(),
#[cfg(feature = "ledger")]
KmsCommand::Ledger(ledger) => ledger.config_path(),
#[cfg(feature = "hashicorp")]
KmsCommand::Hashicorp(hashicorp) => hashicorp.config_path(),
// #[cfg(feature = "hashicorp")]
// KmsCommand::Hashicorp(hashicorp) => hashicorp.config_path(),
_ => return None,
};

Expand Down
13 changes: 6 additions & 7 deletions src/commands/hashicorp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ pub use self::upload::UploadCommand;

use abscissa_core::{Command, Runnable};
use clap::Subcommand;
use std::path::PathBuf;

/// `hashicorp` subcommand
#[derive(Command, Debug, Runnable, Subcommand)]
Expand All @@ -21,12 +20,12 @@ pub enum HashicorpCommand {
}

impl HashicorpCommand {
pub(super) fn config_path(&self) -> Option<&PathBuf> {
match self {
HashicorpCommand::Test(init) => init.config.as_ref(),
HashicorpCommand::Upload(init) => init.config.as_ref(),
}
}
// pub(super) fn config_path(&self) -> Option<&PathBuf> {
// match self {
// HashicorpCommand::Test(init) => init.config.as_ref(),
// HashicorpCommand::Upload(_init) => None,
// }
// }

pub(super) fn verbose(&self) -> bool {
match self {
Expand Down
8 changes: 6 additions & 2 deletions src/commands/hashicorp/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::prelude::*;
use abscissa_core::{Command, Runnable};
use clap::Parser;
use signature::SignerMut;
use std::{path::PathBuf, process, time::Instant};
use std::{fs, path::PathBuf, process, time::Instant};

/// The `hashicorp test` subcommand
#[derive(Command, Debug, Default, Parser)]
Expand All @@ -17,6 +17,7 @@ pub struct TestCommand {
help = "/path/to/tmkms.toml"
)]
pub config: Option<PathBuf>,

/// enable verbose debug logging
#[clap(short = 'v', long = "verbose")]
pub verbose: bool,
Expand Down Expand Up @@ -54,9 +55,12 @@ impl Runnable for TestCommand {

let started_at = Instant::now();

let token = fs::read_to_string(&config.token_file)
.expect("Failed to read token from file");

let app = crate::keyring::providers::hashicorp::client::TendermintValidatorApp::connect(
&config.api_endpoint,
&config.access_token,
&token,
&self.pk_name,
"",
)
Expand Down
70 changes: 18 additions & 52 deletions src/commands/hashicorp/upload.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
//! Test the Hashicorp is working by performing signatures successively
use crate::{config::provider::hashicorp::HashiCorpConfig, prelude::*};
use crate::prelude::*;
use abscissa_core::{Command, Runnable};
use aes_kw;
use clap::Parser;
use serde::Serialize;
use std::{path::PathBuf, process};
use std::process;

use crate::keyring::providers::hashicorp::{client, error};
use rsa::{pkcs8::DecodePublicKey, PaddingScheme, PublicKey, RsaPublicKey};
Expand All @@ -18,15 +18,6 @@ const PKCS8_HEADER: &[u8; 16] = b"\x30\x2e\x02\x01\x00\x30\x05\x06\x03\x2b\x65\x
/// The `hashicorp test` subcommand
#[derive(Command, Debug, Default, Parser)]
pub struct UploadCommand {
/// path to tmkms.toml
#[clap(
short = 'c',
long = "config",
value_name = "CONFIG",
help = "/path/to/tmkms.toml"
)]
pub config: Option<PathBuf>,

/// enable verbose debug logging
#[clap(short = 'v', long = "verbose")]
pub verbose: bool,
Expand All @@ -49,60 +40,43 @@ struct ImportRequest {
}

impl Runnable for UploadCommand {
/// Perform a import using the current TMKMS configuration
/// Perform a import
fn run(&self) {
if self.pk_name.is_empty() {
status_err!("pk_name cannot be empty!");
process::exit(1);
}

let config = APP.config();

//finding key in config will point to correct Vault's URL
let config = if let Some(c) = config
.providers
.hashicorp
.iter()
.find(|c| c.pk_name == self.pk_name)
{
c
} else {
let cfg_path = if let Some(path) = self.config.as_ref() {
path.clone()
} else {
PathBuf::from("./tmkms.toml")
};
status_err!(
"pk_name is not configured in provided \"{}\"!",
cfg_path.as_path().to_str().unwrap()
);
process::exit(1);
};

self.upload(config);
self.upload();
}
}

impl UploadCommand {
fn upload(&self, config: &HashiCorpConfig) {
fn upload(&self) {
//https://www.vaultproject.io/docs/secrets/transit#bring-your-own-key-byok
//https://learn.hashicorp.com/tutorials/vault/eaas-transit

// API address
let vault_addr = std::env::var("VAULT_ADDR")
.expect("vault address \"VAULT_ADDR\" is not set!");

//root token or token with enough admin rights
let vault_token = std::env::var("VAULT_TOKEN")
.expect("root token \"VAULT_TOKEN\" is not set (confg token is NOT used)!");
.expect("root token \"VAULT_TOKEN\" is not set!");

// path to vault CA cert
let vault_ca = std::env::var("VAULT_CACERT").unwrap();

let ed25519_input_key = input_key(&self.payload)
.expect("secret: error converting \"key-to-upload\"[ed25519] with PKCS8 wrapping");

//create app instance
let app = client::TendermintValidatorApp::connect(
&config.api_endpoint,
&vault_addr,
&vault_token,
&self.pk_name,
&config.ca_cert,
&vault_ca,
)
.unwrap_or_else(|_| panic!("Unable to connect to Vault at {}", config.api_endpoint));
.unwrap_or_else(|_| panic!("Unable to connect to Vault at {}", vault_addr));

use aes_gcm::KeyInit;
let v_aes_key = aes_gcm::Aes256Gcm::generate_key(&mut aes_gcm::aead::OsRng);
Expand Down Expand Up @@ -234,7 +208,6 @@ mod tests {

const PK_NAME: &str = "upload-test";
const VAULT_TOKEN: &str = "access-token";
const CHAIN_ID: &str = "mock-chain-id";
const ED25519: &str =
"4YZKJ/pfJj42tdcl40dXz/ugRgrBR0/Pp5C2kjHL6AZhBFozq5EspBwCb44zef0cLEO/WuLf3dI+BPCNOPwxRw==";

Expand All @@ -245,18 +218,11 @@ mod tests {
let cmd = UploadCommand {
verbose: false,
pk_name: PK_NAME.into(),
config: None,
payload: ED25519.into(),
};

let config = HashiCorpConfig {
access_token: "crazy-long-string".into(),
api_endpoint: format!("http://{}", server_address()),
pk_name: PK_NAME.into(),
chain_id: tendermint::chain::Id::try_from(CHAIN_ID).unwrap(),
};

std::env::set_var("VAULT_TOKEN", VAULT_TOKEN);
std::env::set_var("VAULT_ADDR", format!("http://{}", server_address()));

//init
let lookup_self = mock("GET", "/v1/auth/token/lookup-self")
Expand All @@ -279,7 +245,7 @@ mod tests {
.create();

//test
cmd.upload(&config);
cmd.upload();

lookup_self.assert();
export.assert();
Expand Down
4 changes: 2 additions & 2 deletions src/commands/init/templates/keyring/hashicorp.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
chain_id = "$CHAIN_ID"
#Vault's api url - VAULT_ADDR
api_endpoint= "http://127.0.0.1:8200"
#Vault's access token - vault token create -policy=<tmkms-transit-sign-policy>
access_token="hvs.CAESINi91lCOFj-_dOGiUfpdZUPKk93LD8YyHz-qZcYLVwH_Gh4KHGh2cy5kdXV1T2tpcXliakFFblU1SUpqanczYjU"
#Vault's access token path - path to file containing vault token
token_file="path/to/token/file"
#Vault's transit secret engine key - vault write transit/keys/<cosmoshub-sign-key> type=ed25519
pk_name="cosmoshub-sign-key"
#Path to CA certificate to be used to connect to vault
Expand Down
2 changes: 1 addition & 1 deletion src/config/provider/hashicorp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub struct HashiCorpConfig {
pub api_endpoint: String,

/// Access token for authenticating to HashiCorp Vault
pub access_token: String,
pub token_file: String,

/// Vault's key name with ed25519 pub+priv key
pub pk_name: String,
Expand Down
6 changes: 5 additions & 1 deletion src/keyring/providers/hashicorp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pub(crate) mod client;
pub(crate) mod error;
pub(crate) mod signer;

use std::fs;
use crate::{
chain,
config::provider::hashicorp::HashiCorpConfig,
Expand Down Expand Up @@ -40,9 +41,12 @@ pub fn init(
chains.push(config.chain_id.to_string())
}

let token = fs::read_to_string(&config.token_file)
.expect("Failed to read token from file");

let mut app = client::TendermintValidatorApp::connect(
&config.api_endpoint,
&config.access_token,
&token,
&config.pk_name,
&config.ca_cert,
)
Expand Down
4 changes: 2 additions & 2 deletions tmkms-hashicorp.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ state_file = "/home/soleinik/work/rust/tmkms/state/cosmoshub-3-consensus.json"
[[providers.hashicorp]]
chain_id = "cosmoshub-4"
api_endpoint= "http://127.0.0.1:8200"
access_token="hvs.CAESIBwDAKQh2JKuxibeHOV-jmc2T68loAKLNWO2_QX1l7L3Gh4KHGh2cy5iYnRJRVVLdHBqTVMwUGdLZFNGWjNCZkc"
token="path/to/token/file"
pk_name="cosmoshub-sign-key"

[[providers.hashicorp]]
chain_id = "cosmoshub-4"
api_endpoint= "http://127.0.0.1:8200"
access_token="hvs.CAESIBwDAKQh2JKuxibeHOV-jmc2T68loAKLNWO2_QX1l7L3Gh4KHGh2cy5iYnRJRVVLdHBqTVMwUGdLZFNGWjNCZkc"
token="path/to/token/file"
pk_name="cosmoshub-sign-key"


Expand Down

0 comments on commit f36253b

Please sign in to comment.