Secure Developer Access to Hosted Services via Conjur and Pow
| DevOps |
Conjur’s HTTP service authorization capability, aka Software Defined Firewall (SDF), is a high performance and highly available way to protect services and micro-services against unauthorized access. The SDF consists of two parts: the forwarder, and the gatekeeper. The forwarder runs on the client end of the transaction. All outbound traffic from the client is sent through the forwarder, which:
Authenticates the client with Conjur, obtaining a Conjur auth token
Puts the auth token on the outbound request, in the HTTP Authorization header
The gatekeeper runs on the server side. It’s a lightweight reverse proxy which intercepts each inbound request, verifies authenticity of the auth token, and verifies the client’s access privilege using the Conjur web service.
The gatekeeper is installed on the server-side in accordance with the server-side hosting architecture. For example, for Heroku apps, the gatekeeper is installed as a custom buildpack. In Docker clusters, the gatekeeper is a Docker container which is outward-facing, and has a Docker “link” to the protected service.
In server-to-server scenarios, the forwarder can also run embedded in the server stack (e.g. Docker cluster). A key aspect of all Conjur technology is our emphasis on consistent workflows through development/stage/production, and uniform access controls for people, machines and code. Therefore, it’s important for developers to have an easy way to run a local forwarder and thereby access SDF-protected services.
After brainstorming and experimenting with some different approaches, we’ve discovered pow.cx, “a zero-config Rack server for Mac OS X”. It’s a self-contained web server that automatically launches Rack-based applications, and assigns them locally resolvable DNS names like “myapp.dev”.
Let’s take a look at the entire workflow: setting up Pow, using it to run a Conjur forwarder, and invoking a protected web service using cURL.
The Conjur ReleaseBot is a good example of a protected web service. It’s a Sinatra app which runs in Heroku and performs Conjur code pushes to RubyGems, NPM, and Heroku. It has a simple REST interface:
- POST /npm/releases release to NPM
- POST /rubygems/releases release to RubyGems
- DELETE /rubygems/releases/:name yank a Ruby gem
- POST /heroku/releases push a Heroku app
To access this protected web service from a developer machine (on MacOS), the first step is to install Pow:
$ curl get.pow.cx | sh
conjur-asset-proxywhich runs as a plugin to the Conjur CLI.
source "https://rubygems.org" gem 'conjur-cli' gem 'conjur-asset-proxy'
proxy = Conjur::Proxy.new("https://releasebot-conjur.herokuapp.com", api) proxy.configure run proxy
~/.powdirectory and create a symlink to the Rack application:
$ cd ~/.pow $ ln -s ~/source/sdf-forwarders/releasebot .
So, how is ReleaseBot used to publish a new Ruby gem version of the Conjur CLI? First, here’s what it looks like without any authorization:
$ curl -i -X POST https://releasebot-conjur.herokuapp.com/rubygems/releases --data "name=conjur-cl" HTTP/1.1 401 Unauthorized Server: Cowboy Date: Fri, 24 Apr 2015 19:56:03 GMT Connection: keep-alive Content-Type: text/html;charset=utf-8 X-Xss-Protection: 1; mode=block X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN Content-Length: 0 Via: 1.1 vegur
By changing the base URL to
http://releasebot.dev, which is running automatically under Pow, we can successfully perform the Gem release without having to worry about authorization:
$ curl -X POST releasebot.dev/rubygems/releases --data "name=conjur-cli" Gem version 4.21.1 released