voltone

voltone

PlugSignature - Plug implementation of IETF HTTP signature draft specification

Plug for verifying request signatures according to the IETF HTTP signatures draft specification.

Supports the following algorithms:

  • “hs2019”, using ECDSA, RSASSA-PSS or HMAC
  • “rsa-sha256”, using RSASSA-PKCS1-v1_5
  • “ecdsa-sha256”
  • “hmac-sha256”
  • “rsa-sha1”, using RSASSA-PKCS1-v1_5

Hex: https://hex.pm/packages/plug_signature
Hexdocs: https://hexdocs.pm/plug_signature/
GitHub: https://github.com/voltone/plug_signature

Signing the request body requires use of the HTTP Digest header, which can be added through the following package:

Hex: https://hex.pm/packages/plug_body_digest
Hexdocs: https://hexdocs.pm/plug_body_digest/
GitHub: https://github.com/voltone/plug_body_digest

A very simple sample app using both plugs is available in the PlugSignature GitHub repo. This code also includes two client implementations (one in Elixir using Tesla, and one as a shell script using OpenSSL/cURL) for testing.

Most Liked

voltone

voltone

Leaving aside projects where the use of this standard is prescribed, e.g. due to integration or compliance requirements…

Compared to other authentication mechanisms that work at the HTTP layer, signatures offer a number of benefits:

  • Credentials are not transmitted on the wire, unlike Basic or Bearer auth; this is generally a good thing regardless of whether the channel is encrypted
  • It does not require a challenge/response roundtrip and keeping state on the server, unlike Digest auth
  • It verifies the integrity of selected parts of the HTTP request, preventing modification of those parts by intermediaries
  • Support for non-repudiation (except when using HMAC)
  • Private key never leaves the client, so it is less likely to leak compared to symmetrical credentials that need to be defined in client and server (again, does not apply to HMAC)

Compared to authentication at the TLS layer, e.g. a client certificate:

  • Does not impose requirements on TLS proxies (e.g. cloud load balancers)
  • Works with browser-based clients

Of course you could implement the whole thing in a higher layer, using HTTP only as a dumb pipe. I generally try to avoid pushing functionality up the stack, preferring to leverage the services of lower layers (in this case HTTP) and handling only my business logic in the application layer. This allows me to delegate things like authentication and authorisation (e.g. to Plugs or API gateways) without impacting my APIs.

As for headers being manipulated between client and server, this hasn’t been an issue for me: headers that are likely to be modified often do not require integrity protection. In earlier versions of the spec the Date header was included in the signature, to limit the signature validity, and this could be problematic (also for AJAX clients), but the latest drafts use the created/expires parameters of the signature header instead.

tangui

tangui

Hi Voltone,

Great work! I’m very curious about the use-case it solves, if it’s no secret. I remember having to choose between such a scheme and signed JWT (which transforms the JSON payload to a base64 payload, is heavier, etc.). We finally chose not using this HTTP signature mainly because of a host of proxies that would have inevitably modified some signed headers and lack of implementation.

Also, I see you support RSA with PSS padding. So far I thought it wasn’t supported by Erlang. That’s good news! Thanks for the code and comment that goes with it, I’ll you use it soon :slight_smile:

anthonator

anthonator

From the IETF draft:

When communicating over the Internet using the HTTP protocol, it can
be desirable for a server or client to authenticate the sender of a
particular message. It can also be desirable to ensure that the
message was not tampered with during transit. This document
describes a way for servers and clients to simultaneously add
authentication and message integrity to HTTP messages by using a
digital signature.

It looks like this is similar to how companies like Shopify and GitHub allow you to verify the content of a payload by signing the body of the HTTP request with a private/secret key. I’ve seen this used mostly with webhooks. Apologies if that’s incorrect.

Looks awesome though!

Where Next?

Popular in Libraries Top

hpopp
After just over two years in development, this latest version of Pigeon is what I finally consider done in regards to my original vision ...
New
pkrawat1
Hey guyz We at @aviabird are working on a payment library in elixir/phoenix. We are targeting March 2018 to add 56 Gateways to it. Have...
New
mathieuprog
Hello :wave: Allow me to introduce you to Tz, an alternative time zone database support to Tzdata. Why another library? First and fore...
New
kelvinst
Hey everyone! Well, we made this lib a while ago and now we decided to finally go out and public with it! It’s a tool for creating and m...
New
arkgil
Hi all! I’m happy to announce that Telemetry v0.3.0 is out! This release marks the conversion from Elixir to Erlang so that all the libr...
New
danschultzer
In short Plug n’ play OAuth 2.0 provider library. Just set up a resource owner schema with Ecto (your user schema), install the dependen...
New
Qqwy
Solution is a library to help you with working with ok/error-tuples in case and with-expressions by exposing special matching macros, as ...
New
tmbb
PhoenixWS - Websockets over Phoenix Channels Source code on Github here: https://github.com/tmbb/phoenix_ws Phoenix channels are a great...
New
handnot2
Samly can be used to enable SAML 2.0 Single Sign On in a Plug/Phoenix application. This library uses Erlang esaml to provide plug enabl...
New
ostinelli
Let’s write a database! Well not really, but I think it’s a little sad that there doesn’t seem to be a simple in-memory distributed KV da...
New

Other popular topics 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
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 27727 240
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New

Sub Categories:

We're in Beta

About us Mission Statement