bradley

bradley

Are there any generic KMS libraries out there?

I really like the adapter patterns that ecto, nebulex, waffle, etc. use and would love find something similar for a key management service but I’m not finding any. Ideally I’d be able to switch from say Google Cloud KMS to AWS KMS seamlessly with minimal configuration.

I’ve thought about open sourcing something that does this but I’m hesitant to create yet another project that may or may not be useful so I figure I’d check here first!

I already have a Google KMS adapter written using the elixir-google-api library and the following interface:

defmodule KMS do
  @type key_details :: KMS.KeyDetails.t()
  @type public_key :: JOSE.JWK.t()
  @type list_keys_response :: {:ok, [key_details]} | {:error, any}
  @type public_key_response :: {:ok, public_key} | {:error, any}
  @type sign_response :: {:ok, KMS.Signature.t()} | {:error, any}

  @client Application.compile_env!(:my_app, [__MODULE__, :client])

  @callback list_keys(opts :: keyword) :: list_keys_response
  @callback get_public_key(key_id :: String.t(), opts :: keyword) :: public_key_response
  @callback sign(String.t(), key_id :: String.t(), opts :: keyword) :: sign_response

  @spec list_keys(keyword) :: list_keys_response
  def list_keys(opts), do: @client.list_keys(opts)

  @spec list_keys!(keyword) :: [key_details]
  def list_keys!(opts) do
    case list_keys(opts) do
      {:ok, keys} -> keys
      {:error, error} -> raise KMS.NoKeyDetailsFoundError, message: "#{inspect(error)}"
    end
  end

  @spec get_public_key(String.t(), keyword) :: public_key_response
  def get_public_key(key_id, opts), do: @client.get_public_key(key_id, opts)

  @spec get_public_key!(String.t(), keyword) :: public_key
  def get_public_key!(key_id, opts) do
    case get_public_key(key_id, opts) do
      {:ok, public_key} -> public_key
      {:error, error} -> raise KMS.NoPublicKeyFoundError, message: "#{inspect(error)}"
    end
  end

  @spec sign(String.t(), String.t(), keyword) :: sign_response
  def sign(message, key_id, opts), do: @client.sign(message, key_id, opts)
end

First Post!

chulkilee

chulkilee

I don’t know if there is one for KMS - but you may use adapter pattern (like Tesla for HTTP client) to have general interface and specific implementation modules.

However I’m not sure we can have a good abstraction of KMS; I’ve used three KMS but they are slightly different - especially auth and details on options. I’ve built own domain/context module for my abstraction/policy etc. wrapping existing library instead of making generic wrapper for all KMS provider for that reason.

Do you have any similar libraries for KMS in other languages?

Where Next?

Popular in Questions Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
Werner
Hi, I’m using Ubuntu 18.04 and after updating to OTP-24.0 yesterday i have this warning when I run “mix local.hex”: 14:57:30.512 [warn] ...
New
Kagamiiiii
Student & New to elixir. Nice language. I want to convert a english character, e.g. “a”, which is stored in a variable, to it’s asci...
New
dokuzbir
Hello, I am trying to convert my lists to string without losing brackets.For start i have 3 map. They look like these buyer = %{ id: ...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
hpopp
To simplify some tasks at work, I wrote and published this package yesterday. It’s a simple macro that enables Access behaviour on struct...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New

Other popular topics Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list....
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
977 41022 311
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 30048 115
New
yurko
Here are few pieces of (common) Linux knowledge that we use for reasonably small one server apps. We use Ubuntu but this should work for ...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> someth...
New

We're in Beta

About us Mission Statement