Quantcast
Channel: Planet Python
Viewing all articles
Browse latest Browse all 22462

Zato Blog: Securing APIs with Zato and Vault, part 1

$
0
0

Overview

One of fundamental principles of programming with Zato is that one's services are typically insulated from inner workings of underlying data formats or security schemes - after all, why bother with mundane tasks such as authentication or authorization, it should be the platform's job whereas user services should rather focus on their own job.

Conversely, once a security definition is created in web-admin, it can be applied in multiple places without requiring any changes to Python code.

All of that applies to a newly added feature of Zato that lets one keep API secrets in Vault and this blog post introduces key concepts behind it.

Screenshot

What is Vault?

Vault is a dedicated tool to store and make use of secrets that offers support for common authentication and authorization related workflows, such as secure storage and broad or fine-grained secrets management as well as policies describing what action a given holder of a secret can perform.

The system is open to customizations and makes for a great companion to Zato in letting one easily express who can access what, for how long, and under what conditions.

Vault needs to be installed separately to Zato. This post assumes that there is a Vault instance running on http://localhost:49517, already unsealed, using the configuration as below.

Essentially, this is a development server but unlike the Vault's default dev server, this one keeps data on disk instead of RAM.

disable_mlock = true

backend "file" {
  path = "./vault-dev.db"
}

listener "tcp" {
  address = "127.0.0.1:49517"
  tls_disable = 1
}

Creating Vault connections

The easiest way to create a new connection is through web-admin, simply fill out the form as below and a new connection to Vault will be created.

Screenshot
  • Name - an arbitrary name of the connection
  • URL - where Vault can be found
  • Token - Vault token, note that it should be possible for this token to look up tokens and credentials of incoming requests
  • Default authentication method - which authentication backend to use default to authenticate requests, can be Token, Username/password or GitHub. LDAP is coming up soon.
  • Service - a service that can be invoked if no default method was defined - the service can extract credentials from request and indicate what method to use.
  • Timeout - how long to wait for responses from Vault
  • TLS options - whether TLS connections should be verified and if so, using what CA certs unless default ones should be employed. Also, an optional client TLS key and certificate can be uploaded so that Zato itself authenticates with Vault using this key/cert pair.

Attaching Vault connections to channels

Authentication with Vault works with regular HTTP REST or SOAP channels as well as with WebSockets - pick the newly created Vault connection from the list, click OK, and this is it, your channels will now be secured by Vault.

If you have already existing channels, you can swap out their current security definitions for Vault-based ones and things will just work without server restarts.

Screenshot

Screenshot

Policies

The above is everything that is needed to define API endpoints backed by Vault which will now on behalf of Zato authenticate users according to what was provided on input when invoking a service.

However, a complementary aspect is that of authorization - i.e., assuming that in the incoming request there were valid credentials and the service can be invoked at all, we can do one better, go a step further, and define Vault policies to express business relations between objects exchanged in API calls. This will let one store rules in a central place accessible to any API endpoint.

This part of the Zato-Vault interface is still under active development - watch this space for more information!


Viewing all articles
Browse latest Browse all 22462

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>