An asynchronous Rust client library for the Hashicorp Vault API

Overview

vaultrs

An asynchronous Rust client library for the Hashicorp Vault API

The following features are currently supported:

See something missing? Open an issue.

Installation

Add vaultrs as a dependency to your cargo.toml:

[dependencies]
vaultrs = "0.5.4"

Usage

Basic

The client is used to configure the connection to Vault and is required to be passed to all API calls for execution. Behind the scenes it uses an asynchronous client from Reqwest for communicating to Vault.

use vaultrs::client::{VaultClient, VaultClientSettingsBuilder};

// Create a client
let client = VaultClient::new(
    VaultClientSettingsBuilder::default()
        .address("https://127.0.0.1:8200")
        .token("TOKEN")
        .build()
        .unwrap()
).unwrap();

Secrets

The library currently supports all operations available for version 2 of the key/value store.

use serde::{Deserialize, Serialize};
use vaultrs::kv2;

// Create and read secrets
#[derive(Debug, Deserialize, Serialize)]
struct MySecret {
    key: String,
    password: String,
}

let secret = MySecret {
    key: "super".to_string(),
    password: "secret".to_string(),
};
kv2::set(
    &client,
    "secret",
    "mysecret",
    &secret,
).await;

let secret: MySecret = kv2::read(&client, "secret", "mysecret").await.unwrap();
println!("{}", secret.password) // "secret"

PKI

The library currently supports all operations available for the PKI secrets engine.

use vaultrs::api::pki::requests::GenerateCertificateRequest;
use vaultrs::pki::cert;

// Generate a certificate using the PKI backend
let cert = cert::generate(
    &client,
    "pki",
    "my_role",
    Some(GenerateCertificateRequest::builder().common_name("test.com")),
).await.unwrap();
println!("{}", cert.certificate) // "{PEM encoded certificate}"

Wrapping

All requests implement the ability to be wrapped. These can be passed in your application internally before being unwrapped.

use vaultrs::api::ResponseWrapper;
use vaultrs::api::sys::requests::ListMountsRequest;

let endpoint = ListMountsRequest::builder().build().unwrap();
let wrap_resp = endpoint.wrap(&client).await; // Wrapped response
assert!(wrap_resp.is_ok());

let wrap_resp = wrap_resp.unwrap(); // Unwrap Result<>
let info = wrap_resp.lookup(&client).await; // Check status of this wrapped response
assert!(info.is_ok());

let unwrap_resp = wrap_resp.unwrap(&client).await; // Unwrap the response
assert!(unwrap_resp.is_ok());

let info = wrap_resp.lookup(&client).await; // Error: response already unwrapped
assert!(info.is_err());

Error Handling and Tracing

All errors generated by this crate are wrapped in the ClientError enum provided by the crate. API warnings are automatically captured via tracing and API errors are captured and returned as their own variant. Connection related errors from rustify are wrapped and returned as a single variant.

All top level API operations are instrumented with tracing's #[instrument] attribute.

Testing

See the the tests directory for tests. Run tests with cargo test.

Note: All tests rely on bringing up a local Vault development server using Docker. In order to run tests Docker must be running locally (Docker Desktop works).

Contributing

Check out the issues for items needing attention or submit your own and then:

  1. Fork the repo (https://github.com/jmgilman/vaultrs/fork)
  2. Create your feature branch (git checkout -b feature/fooBar)
  3. Commit your changes (git commit -am 'Add some fooBar')
  4. Push to the branch (git push origin feature/fooBar)
  5. Create a new Pull Request

See CONTRIBUTING for extensive documentation on the architecture of this library and how to add additional functionality to it.

Comments
  • Add auth/kubernetes

    Add auth/kubernetes

    Implements auth via Kubernetes serviceaccount (https://www.vaultproject.io/api-docs/auth/kubernetes)

    Also: Added basic tests for all endpoints, except login. The reason being that it seems to require a dockertest server with a webserver that can simulate a TokenReviewResponse from a k8s apiserver. I think adding something like "httpmock" to you dockertest-server repository could do the trick? Perhaps, except that Vault requires TLS-connections to the APIserver, so it would require a TLS-proxy container as well, or a specialized docker image for handling all of the above.

    tldr, it was too much work for me to find a fitting solution for this at the moment. I would like to request help/suggestions for implementing the login test later at some point.

    opened by johanot 10
  • Panic when building `VaultClientSettings` without an address

    Panic when building `VaultClientSettings` without an address

    Hi!

    I found an issue with the builder for VaultClientSettings.

    The following code panics:

    fn main() {
        // VAULT_TOKEN and VAULT_ADDR are both set in the environment
    
        println!("Building without specifying a token...");
        let settings = VaultClientSettingsBuilder::default()
            .address("https://127.0.0.1:8200")
            .build()
            .unwrap(); // works
    
        println!("{settings:?}");
    
        println!("Building without specifying an addr...");
        let settings = VaultClientSettingsBuilder::default()
            .token("TOKEN")
            .build() // panics!
            .unwrap();
    
        println!("{settings:?}");
    }
    

    The panic comes from VaultClientSettingsBuilder::validate which unwrap()s self.address.as_ref().

    The problem is that according to derive_builder's documentation

    Default values are applied after validation, and will therefore not be validated!

    So, validate() is called before default_addr() sets anything, making the unwrap panic.

    I have created an issue with derive_builder, because I think validation should happen after applying defaults. However, I think the panic here is still avoidable.

    See this PR: #30

    opened by r-arias 8
  • AWS auth method

    AWS auth method

    Implements AWS auth (https://www.vaultproject.io/api-docs/auth/aws).

    I'm still working on the tests and I'm going to use localstack for this. Vault AWS API has some deprecated endpoints. Do you have any suggestions on how to support them (and whether to support them at all)?

    opened by Anexen 7
  • feat: add tracing support.

    feat: add tracing support.

    Thought I'd take a shot at this one. Closes #8.

    I've added spans to every operation I can find, but I haven't added any additional log messages yet.

    Looks like it would be good to implement this in the rustify crate as well. In Client::execute for example.

    opened by fourbytes 5
  • feat: add support for transit secrets engine

    feat: add support for transit secrets engine

    Resolves #5

    This implements most of the transit secrets engine API, minus importing external keys or batch_input parameters (but would be easy enough to add on top).

    opened by taheris 4
  • feat: allow timeout setting on client builder

    feat: allow timeout setting on client builder

    Unfortunately, the reqwest default is "no timeout", which causes apps to hang indefinitely for us.

    I figured setting the generic timeout is sufficient for now (not implementing a separate connection-timeout settings mapping on purpose), since reqwest "timeout" covers the entire connection lifecycle.

    cc @jmgilman

    opened by johanot 4
  • Support /sys/unseal

    Support /sys/unseal

    I am writing a program to unseal Vault(s) over the API. For this purpose, I need Unseal support for the API so I made it.

    As per my own testing with my own code, unseal works with these changes.

    The Vault Unseal API doc can be found here: https://www.vaultproject.io/api-docs/system/unseal

    Thanks & sorry :-)

    opened by sjm42 4
  • Implemented Key Value v1 APIs

    Implemented Key Value v1 APIs

    Added support for key value v1. I inspired code structure from existing kv2 implementation and tried to follow contributing guide.

    I'm quite new to Rust, sorry if some things are messy. Feel free to point them out I'll happily improve them :)

    opened by PierreBeucher 3
  • Support for cas option in `SetSecretRequest`?

    Support for cas option in `SetSecretRequest`?

    I need to use the compare-and-swap feature of vault and see that it is not currently supported.

    I think it would be fairly simple to add here via something like:

    #[derive(Builder, Debug, Endpoint)]
    #[endpoint(
        path = "{self.mount}/data/{self.path}",
        response = "SecretVersionMetadata",
        method = "POST",
        builder = "true"
    )]
    #[builder(setter(into))]
    pub struct SetSecretRequest {
        #[endpoint(skip)]
        pub mount: String,
        #[endpoint(skip)]
        pub path: String,
        pub data: Value,
        pub options: Option<SetSecretRequestOptions>,
    }
    
    #[derive(Builder, Clone, Debug, serde::Serialize)]
    #[builder(setter(into))]
    pub struct SetSecretRequestOptions {
        pub cas: u32,
    }
    

    is this a feature that would be accepted if I open a PR?

    opened by bodymindarts 3
  • Set TLS verification according to VAULT_SKIP_VERIFY

    Set TLS verification according to VAULT_SKIP_VERIFY

    Hi,

    This is an attempt to fix the issue #31.

    The difference here (when compared to strconv.ParseBool) is that in the original Vault implementation any other value returns an error, and here I'm keeping the default as true (at least for now) to avoid modifying the function's signature.

    I added serial_test to dev-dependencies to make the tests related to this feature run sequentially, and avoid one test to overwrite the VAULT_SKIP_VERIFY value previously set by the other.

    Please let me know if there is anything I need to fix.

    opened by mrioqueiroz 3
  • Allow building VaultClientSettings without address

    Allow building VaultClientSettings without address

    Hi,

    this is the PR attempting to solve #29

    Let me know, if you'd like me to make any changes. The test file I've added is kept fairly simple...

    Cheers, R

    opened by r-arias 3
  • Allow client certificates for mTLS connections

    Allow client certificates for mTLS connections

    Hi, our infrastructure configures the vault server to require mTLS connections, which requires configuring client certificates for the http connection.

    Also, our client certificates are encrypted with a passphrase, so they need to be decrypted before configuring them in the reqwest builder.

    We started a contribution to this project (now closed), but soon we realised that it was not enough and the implementation was a bit trickier than expected, so we decided to use a custom Client in our side until this feature is fully supported here.

    We are still aiming at helping with that, but it definitively requires some guidance from the maintainers:

    • How can we decrypt the certificates when the rustls feature is enabled?
    • In case that we leave the decryption out of this lib, is it ok to change String to be a Vec<u8> for the settings involving the client cert, key and passphrase? That would allow the client decrypt them and pass the raw bytes to the lib.
    • What about changing the ca_cert into a Vec<u8> in case we leave the reading of the CA stack to the user too?

    Thanks!

    opened by plankton6 0
  • Set api call fails when kv versioning is not enabled and a new key is created

    Set api call fails when kv versioning is not enabled and a new key is created

    It may also fail during other times as well, but it definitely doesn't work in that configuration.

    A line of documentation somewhere prominent that versioning is required would be nice.

    opened by rwthompsonii 1
  • Adds LDAP auth engine

    Adds LDAP auth engine

    Adds new auth engine: LDAP.

    Also attempt at adding a test for said engine but while manual test seems to work just fine (example added in a comment) but automated test fails to bind as a user (probably missing some knowledge on how docker_servertest localstack works)

    opened by vasyl-purchel 5
  • RUSTSEC-2021-0139: ansi_term is Unmaintained

    RUSTSEC-2021-0139: ansi_term is Unmaintained

    ansi_term is Unmaintained

    | Details | | | ------------------- | ---------------------------------------------- | | Status | unmaintained | | Package | ansi_term | | Version | 0.12.1 | | URL | https://github.com/ogham/rust-ansi-term/issues/72 | | Date | 2021-08-18 |

    The maintainer has adviced that this crate is deprecated and will not receive any maintenance.

    The crate does not seem to have much dependencies and may or may not be ok to use as-is.

    Last release seems to have been three years ago.

    Possible Alternative(s)

    The below list has not been vetted in any way and may or may not contain alternatives;

    Dependency Specific Migration(s)

    See advisory page for additional details.

    opened by github-actions[bot] 0
Notion Offical API client library for rust

Notion API client library for rust.

Jake Swenson 65 Dec 26, 2022
🦀 Zulip API Library Rust Client

Zulip API Client Library Rust Crate This repo contains the code for an unofficial, third-party Zulip API client library crate written in the Rust prog

Manuel Nila 3 Oct 23, 2022
Modrinth API is a simple library for using, you guessed it, the Modrinth API in Rust projects

Modrinth API is a simple library for using, you guessed it, the Modrinth API in Rust projects. It uses reqwest as its HTTP(S) client and deserialises responses to typed structs using serde.

null 21 Jan 1, 2023
High-level, optionally asynchronous Rust bindings to llama.cpp

llama_cpp-rs Safe, high-level Rust bindings to the C++ project of the same name, meant to be as user-friendly as possible. Run GGUF-based large langua

Binedge.ai 4 Nov 21, 2023
Luno API Client written in Rust Language for Rustaceans :)

The Luno API provides developers with a wealth of financial information provided through the Luno platform

borngraced 4 Dec 22, 2022
Meteor Client Installer - Installer to automate the install of Fabric and Meteor Client

This is an installer that automates the install of Meteor and Fabric

Jake Priddle 3 Jun 23, 2021
API wrapper for the tankerkönig api

tankerkoenig-rs API wrapper for the tankerkoenig-api written in rust. Gives you ready deserialized structs and a easy to use and strictly typed api. I

Jonathan 2 Feb 27, 2022
A repository full of manually generated hand curated JSON files, which contain the API Types that the Discord API returns.

Discord API Types A repository full of manually generated hand curated JSON files, which contain the API Types that the Discord API returns. Also did

Unofficial Discord Documentation 1 Sep 16, 2022
Yet another ROS2 client library written in Rust

RclRust Target CI Status Document Foxy (Ubuntu 20.04) Introduction This is yet another ROS2 client library written in Rust. I have implemented it inde

rclrust 42 Dec 1, 2022
Ocular seeks to be the preferred cosmos client library UX for Rust projects

Ocular seeks to be the preferred cosmos client library UX for Rust projects. It is strongly based on lens, a go client library for blockchains built with the Cosmos SDK.

Peggy JV, Inc 34 Dec 26, 2022
Wrapper library for utilizing DigitalOcean API v2 in Rust

doapi-rs Wrapper library for utilizing DigitalOcean API v2 in Rust Disclaimer This library is in alpha - it may do anything up to, and including, eati

Kevin K. 30 Nov 5, 2022
Serenity is a Rust library for the Discord API

serenity Serenity is a Rust library for the Discord API. View the examples on how to make and structure a bot. Serenity supports bot login via the use

serenity 3.3k Jan 2, 2023
librdkafka - the Apache Kafka C/C++ client library

librdkafka - the Apache Kafka C/C++ client library Copyright (c) 2012-2020, Magnus Edenhill. https://github.com/edenhill/librdkafka librdkafka is a C

Magnus Edenhill 6.4k Dec 31, 2022
A library to access BGPKIT Broker API and enable searching for BGP data archive files over time from public available data sources.

BGPKIT Broker BGPKIT Broker is a online data API service that allows users to search for publicly available BGP archive files by time, collector, proj

BGPKIT 10 Nov 30, 2022
A library for working with alpaca.markets APIs, including the Broker API.

alpaca-rs, an unofficial Rust SDK for the Alpaca API (WIP) Features Easy to use - Minimal setup and no boilerplate. Cross-platform - can run on most p

null 4 Dec 2, 2023
Rust client for Pushover

Pushover RS Description It's a Rust client library you can use to interact with the Pushover messaging API. This client is unofficial and I'm in no wa

Emmanuel C. 4 Dec 9, 2022
A variation of the solana helloworld program example with a client written in Rust instead of Typescript

Simple Solana Smart Contract Example This repository demonstrates how to create and invoke a program on the Solana blockchain. In Solana the word prog

zeke 56 Dec 26, 2022
Feign-RS (Rest client of Rust)

Feign-RS (Rest client of Rust)

null 9 Aug 12, 2022
A Rust client for the NOAA Weather Wire Service Open Interface.

nwws-oi A Rust client for the NOAA Weather Wire Service Open Interface. NWWS-OI is one of several platforms through which the National Weather Service

Will Glynn 3 Sep 15, 2022