Heroku

QuotaGuard is an add-on for proxying API requests so they don’t originate from Heroku IP addresses.

Services like Google Maps Geocoding will now work as if you had your own dedicated server with dedicated IP address.

QuotaGuard is accessible as an HTTP Proxy so is language and platform agnostic. There is native support across Ruby, Python, Node.js, Scala, Java and every other mainstream language.

Which QuotaGuard should I use?

We offer three products on Heroku, QuotaGuard, QuotaGuard Static, and [QuotaGuard Shield] (https://elements.heroku.com/addons/quotaguardshield).

QuotaGuard routes your traffic through a dynamic set of IP addresses that may change at any time and is intended for accessing APIs like Google Maps that restrict usage based on your IP address. It should be used if you want to access these APIs without your limit being shared with other Heroku apps.

QuotaGuard Static IP’s routes your Heroku traffic through a pair of static IP addresses that never change. It should be used if you need your traffic to pass through a known static IP address for the purpose of firewall ingress rules or application allowlisting with a third party. QuotaGuard Static IP’s uses HTTP and SOCKS5 for outbound service and SSL Termination for inbound service.

QuotaGuard Shield Static IP’s are HIPAA compliant and built to handle Heroku traffic that contains PII and other sensitive information. QuotaGuard Shield routes your traffic through a pair of static IP addresses that never change with a higher level of security over QuotaGuard Static. The service uses HTTPS and SOCKS over TLS for outbound service and SSL Passthrough for inbound service. Like QuotaGuard Static, QuotaGuard Shield should be used if you need your traffic to pass through a known IP address for the purpose of firewall ingress rules or application allowlisting with a third party. Shield allows you to utilize Heroku’s ACM for your site or bring your own certificate.

Please send us email if you’d like more guidance on what service fits your needs best.

Provisioning the add-on

QuotaGuard can be attached to a Heroku application via the CLI:

callout A list of all plans available can be found here.

$ heroku addons:create quotaguard:starter
-----> Adding quotaguard:starter to sharp-mountain-4005... done, v18 (free)

Once QuotaGuard has been added a QUOTAGUARD_URL setting will be available in the app configuration and will contain the full URL you should use to proxy your API requests. This can be confirmed using the heroku config:get command.

$ heroku config:get QUOTAGUARD_URL
http://user:pass@proxy.quotaguard.com:9292

After installing QuotaGuard the application should be configured to fully integrate with the add-on.

Local setup

Environment setup

After provisioning the add-on it can be necessary to locally replicate the config vars so your development environment can operate against the service. This should be used for initial testing only as usage will count against your daily limits.

Though less portable it’s also possible to set local environment variables using export QUOTAGUARD_URL=value.

Use the Heroku Local command-line tool to configure, run and manage process types specified in your app’s Procfile. Heroku Local reads configuration variables from a .env file. To view all of your app’s config vars, type heroku config. Use the following command to add the QUOTAGUARD_URL value retrieved from heroku config to your .env file.

$ heroku config -s | grep QUOTAGUARD_URL >> .env
$ more .env

warning Credentials and other sensitive configuration values should not be committed to source-control. In Git exclude the .env file with: echo .env >> .gitignore.

For more information, see the Heroku Local article.

Using with Rails

Geocoding is the most common usage for QuotaGuard so this tutorial will focus on that use case.

To add geocoding to your Rails project we recommend the Geocoder gem.

Once you have completed the standard setup of Ruby Geocoder you can use QuotaGuard by adding the following to your geocoder initializer:

# config/initializers/geocoder.rb
Geocoder.configure(
  ...
  :http_proxy => ENV['QUOTAGUARD_URL'],
  :timeout => 5 
)

All geocoding requests will now go via QuotaGuard automatically.

Using with Python/Django

There are many geocoding libraries available for Python but the most used is geopy which uses urllib2 environment variables to set a proxy service.

In your application initialization you should set the http_proxy variable to match the QUOTAGUARD_URL. If using Geopy you also need to force it to use the http version of Google’s API, not https by passing in scheme="http" to the Geocoder constructor.

# Assign QuotaGuard to your environment's http_proxy variable
import os
from geopy import geocoders
os.environ['http_proxy'] = os.environ['QUOTAGUARD_URL'] 
g = geocoders.GoogleV3(scheme="http")
place, (lat, lng) = g.geocode("10900 Euclid Ave in Cleveland")  
print "%s: %.5f, %.5f" % (place, lat, lng)

Testing in the Python interpreter

This code will check the IP your requests originate from with and without using the QuotaGuard proxy. If the IP addresses are different then you are successfully routing requests through QuotaGuard.

import urllib2
import os
url = 'http://ip.jsontest.com/'
heroku_ip_request = urllib2.urlopen(url)
print "Heroku IP:"
heroku_ip_response = heroku_ip_request.read()
print heroku_ip_response
os.environ['http_proxy'] = os.environ['QUOTAGUARD_URL']
proxy = urllib2.ProxyHandler()
opener = urllib2.build_opener(proxy)
in_ = opener.open(url)
qg_response = in_.read()
print "QuotaGuard IP:"
print qg_response
if heroku_ip_response != qg_response:
	print "SUCCESS! The IP addresses are different so everything is working!"
else:
	print "SOMETHING WENT WRONG. The IP addresses are the same. Are you sure you have a QUOTAGUARD_URL environment variable set?"

Using with Node.js

Accessing an HTTP API with Node.js

To access an HTTP API you can use the standard HTTP library in Node.js but must ensure you correctly set the “Host” header to your target hostname, not the proxy hostname.

var http, options, proxy, url;

http = require("http");

url = require("url");

proxy = url.parse(process.env.QUOTAGUARD_URL);
target  = url.parse("http://ip.jsontest.com/");

options = {
  hostname: proxy.hostname,
  port: proxy.port || 80,
  path: target.href,
  headers: {
    "Proxy-Authorization": "Basic " + (new Buffer(proxy.auth).toString("base64")),
    "Host" : target.hostname
  }
};

http.get(options, function(res) { 
  res.pipe(process.stdout);
  return console.log("status code", res.statusCode);  
});

Accessing an HTTPS API with Node.js

The standard Node.js HTTPS module does not handle making requests through a proxy very well. If you need to access an HTTPS API we recommend using the Request module (npm install request). Please note accessing an HTTPS endpoint requires our Enterprise plan.

var request = require('request');

var options = {
    proxy: process.env.QUOTAGUARD_URL,
    url: 'https://api.github.com/repos/joyent/node',
    headers: {
        'User-Agent': 'node.js'
    }
};

function callback(error, response, body) {   
    if (!error && response.statusCode == 200) {
        console.log(body);     
    }
}

request(options, callback);

Using with PHP

PHP cURL is the easiest way to make HTTP requests via a proxy. This Geocoding example assumes that you have set the QUOTAGUARD_URL environment variable.

<?php

function lookup($string){
  $quotaguard_env = getenv("QUOTAGUARD_URL"); 
  $quotaguard = parse_url($quotaguard_env);

  $proxyUrl       = $quotaguard['host'].":".$quotaguard['port'];
  $proxyAuth       = $quotaguard['user'].":".$quotaguard['pass']; 
 
   $string = str_replace (" ", "+", urlencode($string));
   $details_url = "http://maps.googleapis.com/maps/api/geocode/json?address=".$string."&sensor=false";
 
   $ch = curl_init();
   curl_setopt($ch, CURLOPT_URL, $details_url);
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
   curl_setopt($ch, CURLOPT_PROXY, $proxyUrl);
   curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
   curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxyAuth);
   $response = json_decode(curl_exec($ch), true);
 
   // If Status Code is ZERO_RESULTS, OVER_QUERY_LIMIT, REQUEST_DENIED or INVALID_REQUEST
   if ($response['status'] != 'OK') {
    return null;
   }
 
   print_r($response);
   $geometry = $response['results'][0]['geometry'];
 
    $longitude = $geometry['location']['lng'];
    $latitude = $geometry['location']['lat'];
 
    $array = array(
        'latitude' => $latitude,
        'longitude' => $longitude,
        'location_type' => $geometry['location_type'],
    );
 
    return $array;
 
}
 
$city = 'San Francisco, USA';
 
$array = lookup($city);
print_r($array);
 
?>

Monitoring & logging

Real-time and historical usage stats can be displayed on the QuotaGuard Dashboard accessible from your Heroku Dashboard.

Dashboard

The QuotaGuard dashboard allows you to view your real-time and historical usage of every API.

The dashboard can be accessed via the CLI:

$ heroku addons:open quotaguard
Opening quotaguard for sharp-mountain-4005...

or by visiting the Heroku apps web interface and selecting the application in question. Select QuotaGuard from the Add-ons menu.

Troubleshooting

Once you pass your plan limit you will receive a response including the message ``` status: “PROXY_OVER_QUERY_LIMIT”


This will resolve itself at the end of the 24 hour period. You may also receive this message if you send excessive requests to rate-throttled services like Google Maps in a short period of time. If you see this message and believe you have not reached your limit raise a support ticket.

### HTTP vs HTTPS
HTTPS access is limited to our Enterprise plan. If you are accessing Google Maps you have the choice to use the HTTP or HTTPS endpoint so upgrading is not necessary unless you want to secure all requests between your app and the Google API.

## Migrating between plans

> note
> Application owners can migrate at any time with no interruption to your service. Your new limits/features will take effect immediately.

Use the `heroku addons:upgrade` command to migrate to a new plan.

```term
$ heroku addons:upgrade quotaguard:enterprise
-----> Upgrading quotaguard:enterprise to sharp-mountain-4005... done, v18 ($20/mo)
       Your plan has been updated to: quotaguard:enterprise

Removing the add-on

QuotaGuard can be removed via the CLI.

warning This will destroy all associated data and cannot be undone!

$ heroku addons:destroy quotaguard
-----> Removing quotaguard from sharp-mountain-4005... done, v20 (free)

Privacy - GDPR and CCPA

All three QuotaGuard services are a GDPR and CCPA compliant. Please review our Privacy Policy and GDPR/CCPA compliance information at [QuotaGuard.com’s Privacy Policy page] (https://www.quotaguard.com/privacy). In addition, we also answer many questions around Privacy, Security, and GDPR at [QuotaGuard.com FAQ’s] (https://www.quotaguard.com/privacy-security-and-gdpr-faqs). If you need a DPA for your customers, or from us as a sub-contractor of your services, please contact us via our Support channel (details below) so we can get you the right DPA contract for your review.

Support

All QuotaGuard support and runtime issues should be submitted via the Heroku Support channels. Any non-support related issues or product feedback is welcome at support@quotaguard.com or by visiting QuotaGuard.com.