Project

dpop

0.0
The project is in a healthy, maintained state
Implementation of DPoP (Demonstrating Proof-of-Possession at the Application Layer) for Ruby and Rails
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

Runtime

 Project Readme

Gem Version

Dpop

Implementation of DPoP (Demonstrating Proof-of-Possession at the Application Layer) for Ruby and Rails apps.

Installation

Install the gem and add to the application's Gemfile by executing:

$ bundle add dpop

If bundler is not being used to manage dependencies, install the gem by executing:

$ gem install dpop

Usage

In general, this gem provides two concepts: A wrapper for creating private keys that this gem can consume, and an API for consuming those private keys to generate Proof JWT's for a given request.

Setup

This gem uses a configuration concept for setup, and then can be accessed through module methods on Dpop

Run the configurer to set with defaults:

Dpop.configure

Or pass a block to overwrite defaults:

Dpop.configure do |config|
  config.encryption_key = MY_SECURE_SECRET_PASSPHRASE
end
Configurable variable Description Default value
cookie_name Cookie saved on the browser when using the Rails controller concern "_proof_keys"
encryption_key Secure passphrase used for encrypting cookes with Rails ENV["DPOP_ENCRYPTION_KEY"]
generated_key_size Byte size of generated private keys 1024

Module methods

To generate a consumable private key, run Dpop.generate_key_pair. That will return a PEM string, which can be used with openssl by running OpenSSL::PKey::RSA.new(key)

To generate a Proof JWT, run Dpop.get_proof_with_key(key, htu: "https://www.website.call/path", htm: "GET". That will return a JWT string, which should be added to the Dpop header of your http request.

Rails

In Rails apps, this gem automatically configures on initialization using a Railtie. At any time, those configuration variables can be overwritten manually as described above, but running Dpop.configure to initialize the gem isn't mandatory.

The app provides a controller concern that can be used to ensure user's browsers have a private key saved in their cookies, which can be relied on to prove possession of their browser. A proof can then be generated using that key, to be attached to your HTTP requests.

In your ApplicationController, add include Dpop::Controller.

In your controllers where you'd like to ensure your user has a key set, or in your ApplicationController, add ensure_dpop!

When you want to create a proof signed with that key, use get_proof(htu: "https://www.website.call/path", htm: "GET")

Example using Net::HTTP:

class MyController < ApplicationController
  ensure_dpop!

  def index
    uri = URI("https://www.myresourcehost.com/index?page=1")
    proof = get_proof(htu: dpop_htu(uri), htm: "GET")

    req = Net::HTTP::Get.new(uri)
    req['authorization'] = "DPoP #{my_access_token}"
    req['dpop'] = proof

    res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
      http.request(req)
    end

    @data = res.body
  end

  def create
    uri = URI("https://www.myresourcehost.com/index?page=1")
    proof = get_proof(htu: dpop_htu(uri), htm: "GET")

    req = Net::HTTP::Post.new(uri)
    req['authorization'] = "DPoP #{my_access_token}"
    req['dpop'] = proof

    res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
      http.request(req)
    end

    @data = res.body
  end

  private

  # Only pass scheme, host, and path following DPoP spec
  def dpop_htu(uri)
    uri.fragment = dpop_uri.query = nil
    uri
  end

end

Development

bundle install to setup. Develop using bundle console for ruby, or by installing the gem through path: in your consuming app.

To release a new version, update the version number in version.rb, run bundle install to update Gemfile.lock, and add a CHANGELOG.md entry for your version.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/WilliamNHarvey/dpop-ruby. Please add clear testing instructions in your PR.

License

Apache Version 2.0