Package: lockbox-proxy
LockboxLockbox is a forward proxy for making third party API calls.Why?Automation or workflow platforms likeZapierandIFTTTallow
"webhook" actions for interacting with third party APIs.IFTTT webhooksZapier webhooksThey require you to provide your third party API keys so they can act on your behalf. You are trusting them to keep your
API keys safe, and that they do not misuse them.May be you don't want that.How Lockbox helpsYou run your own Lockbox server.When a workflow platform needs to make a third party API call on your behalf, it makes a Lockbox API call instead.
Lockbox makes the call to the third party API, and returns the result to the workflow platform.Main benefitsThird party API keys are never exposed to the workflow platformYou canauditall API calls made on your behalf[Planned] You can restrict access to external APIs in a more fine grained manner[Planned] Rate limit third party API callsDrawbacksYou need to run an instance of Lockbox on your own infrastructure. You own its performance, security and reliability.Centralization of YOUR API credentials (with your Lockbox instance). However, consider this a different kind of
centralization. I.e. Workflow automation platforms centralize credentials for a large number of users in a single
system too, possibly presenting a valuable aggregate target for attackers.How to run LockboxInstallationpipinstalllockbox-proxyPrepare a services config fileMay be call itsample_config.json. Example:{
  "services": {
    // Access GitHub APIs that do not require auth
    "github_public": {
      "base_url": "api.github.com",
      "requires_service_token": false
    },
    // Access GitHub APIs that do not require auth - except Lockbox requires auth (by "service token')
    "github_public_behind_service_token": {
      "base_url": "api.github.com",
      "requires_service_token": true
    }
  }
}For reference, refer tolockbox/config.py.Choose a Lockbox secret keyThis secret key is used to generate signed service tokens. Service tokens are used to authenticate API calls to Lockbox.echo"YOUR_SUPER_SECRET_VALUE">signing_key.txtRun Lockbox serverThis snippet runs Lockbox server onlocalhost:8000.# set config env varsexportLOCKBOX_SIGNING_KEY_FILE=signing_key.txtexportLOCKBOX_CONFIG_PATH=sample_config.json# start the servergunicornlockbox.app:app--preloadAccessing third-party APIs via LockboxExample: Call to GitHub API
tolist an organization's public repos.Without Lockbox, the request would have beenGET https://api.github.com/orgs/google/reposfor Google's repos.Configureapi.github.comin service config file.See exampleabove.Generate a Lockbox service tokenEach Lockbox service token allows access to a single service (e.g.github_public_behind_service_token).This command generates a Lockbox service token that authorizes the bearer to access GitHub API through Lockbox.The service token is saved to theSERVICE_TOKENenvironment variable.exportSERVICE_TOKEN=$(pythonlockbox/generate_service_token.py\--service-namegithub_public_behind_service_token\--signing-key-filesigning_key.txt\--audiencewalkthrough)Note:audienceidentifies the intended recipient of the service token.Make the Lockbox API call# Lockbox URL structure: /s/{service_name}/{path}curllocalhost:8000/s/github_with_auth/orgs/google/repos-v-H"Authorization: Bearer$SERVICE_TOKEN"How to revoke service tokensRevocation is done through checking theaudienceclaim of the service token.In the service config file (e.g.sample_config.json), each service may specify a list ofaudiencesthat are valid:{
  "services": {
    // Access GitHub APIs that DO require auth - and Lockbox requires auth (by "service token") to protect access to that.
    // Additionally, only service tokens with audience "zapier_webhook" will be accepted by Lockbox.
    "github_private_behind_service_token": {
      // ...
      // ...
      "requires_service_token": true,
      "valid_audiences": [
        "walkthrough"
      ]
    },
  }
}Ifvalid_audiencesis unset, or set tonull, it means all audiences are valid.Ifvalid_audiencesis set to a list, then only audiences in the list are valid.In the example above, only service tokens with audiencewalkthroughis valid for the servicegithub_private_behind_service_token.To revoke ALL service tokens for a service, setvalid_audiencesto[].Notesample_config.jsonupdates are not automatically reloaded. You need to restart Lockbox server for changes to
take.AuditingAuditing can be enabled by settingaudit_login the config file.{
  "services": {
    // ...
  },
  "audit_log": {
    "type": "local_dir",
    // Lockbox will try to create this directory if it does not exist
    "root_dir": "/var/tmp/lockbox_audit_log"
  }
}Events are logged in JSON format to the file path:<root_dir>/service_name/YYYY-MM-DD/HH-MM-SS-<uuid>.json.<uuid>ensures filename uniqueness for events logged within the same second.Design philosophyThis is very much a prototype implementation to explore the concept of abstracting out third party API calls. E.g. Is it
even a common need?Therefore, the main priorities are:CorrectnessSimplicity (in configuration, usage)Security (avoid blatant shortcomings)Minimize to essential features only (which may evolve with feedback!)We will consider other factors later, such as:Performance (e.g. may be not Python?)FlexibilityDeployment scripts / walkthroughsAlternatives / Prior artNginx - battle testing web server, which can be configured to behave like Lockbox. Especially with various scripting
options. E.g.OpenResty / Nginx with LuaNjs scripting