Upcoming Webinar: The New Framework for Modern Data Privacy and Security·Sign Up
Blog

Introducing HAPI

Fernando Magno Quintão Pereira

Fernando Pereira got his Ph.D at the University of California, Los Angeles, in 2008. Since 2009 he is an associate professor at the Department of Computer Science of the Federal University of Minas Gerais, where he leads the Compiler’s Lab (http://lac.dcc.ufmg.br/).

Why another policy language?

The design and specification of access policies is an important aspect of the construction of distributed systems and services. Developers currently can use different approaches to fulfill this task. And yet, most of these approaches rely on general purpose data-description languages, such as YAML, JSON and XML. Such formats are employed in systems of vast importance, such as Amazon’s AWS CloudFormation, Microsoft’s Azure and Google’s Firebase. Yet, it is our understanding that such formats, not having been conceived to this particular domain, could be replaced with more expressive specification languages. Such is the goal of the Hapi Project.

What is HAPI?

Hapi (short for Hierarchical Access Policy Implementation), is a specification language that lets users define access policies. In a distributed system, an access policy defines the actions that each actor can perform on the available resources. Such policies are important because they ensure the preservation of the integrity and the privacy of personal information that users might store into remotely accessed databases. As an example, the specification below indicates that Bob can read all resources, Interns can read emails and credit card numbers, but Alice, who is an intern cannot read emails.:

main =
  DENY
  EXCEPT
    ALLOW {
      Actor = Bob
      Actions = Reads
      Resources
    }
    ALLOW {
      Actor = Intern
      Actions = Reads
      Resources = EMAIL, CCN
    }
    EXCEPT
      DENY {
        Actor = Alice
        Actions = Reads
        Resources = EMAIL
      }

Hapi is strongly based on Sen et al.‘s Legalease, a domain-specific language that supports the specification of hierarchies of access policies. In Hapi, Actors might have their rights either increased or decreased as they move down this hierarchy. Syntactically, the position of actors within this hierarchy is given by indentation; which like in Python, has semantic meaning in Hapi. Access hierarchies determine partial orders between actors and groups of resources. Thus, partial ordering emerges as a powerful metaphor to specify the access rights of groups and subgroups of users.

How does Hapi compare with other policy languages?

Legalease

Hapi extends Legalease in several different ways. Mostly, the original specification of Legalease is not sufficiently explicit about the language’s grammar and usability. Hapi fills a number of omissions along these directions. Additionally, Hapi also extends Legalease with a number of practical functionalities, namely, the ability to compose policies in multiple files, and a more concise syntax to specify conjunctions of access rights. Finally, Hapi provides users with syntactic extensions that let them define the so-called concept lattices. Concept lattices define the data types that are manipulated in a policy specification, namely, which actors, resources and actions can be referred to in that specification.

OPA/Rego

OPA/Rego is a tool focused on creating complex policy queries. Given a JSON with the policy rules, an OPA/Rego query can inform whether and which data could be accessed by some input. Then, here there is an auditing tool to check the policy properties. Using the OPA/Rego website’s example we can describe the boss order with the following Hapi policy:

main = 
  ALLOW
  EXCEPT
    DENY {
      Servers
      Ports
      Network = public
      Protocols = http
    }
    DENY {
      Servers
      Ports
      Network
      Protocols = telnet
    }

With OPA/Rego, we must code the query to consult which servers are allowing the http protocol for some public network, then the JSON policy rules should be changed. The same fact will occur to check which servers have allowed telnet for any port and any network. The boss order can be coded by:

boss_order[servers] {
    some i, j
    server := input.servers[ _ ]
    input.servers[ _ ].protocols[ _ ] = "http"
    server.ports[ _ ] == input.ports[i].id
    input.ports[i].network == input.networks[j].id
    input.networks[j].public
}

boss_order[servers] {
    server := input.servers[ _ ]
    input.servers[ _ ].protocols[ _ ] = "telnet"
}

When the boss_order is called, then all listed servers must be changed in the JSON. But, when we are using HAPI, we just need to specify the data hierarchy describing the Servers, Networks, Ports and the Protocols concept lattices. After that, the policy can be written as well as shown above.

Actually, Hapi and OPA/Rego can be integrated. Our first approach is print an YAML file (that can be translated to a JSON) and using the OPA/Rego we can check any property of our rule description.

Use Cases

Specifying policies in Hapi almost feels like writing them in plain English. Below we provide a few examples of such specifications. Notice how indentation defines a hierarchy between policies, and how lower-level policies might either increase or constraint rights granted to higher-level policies. We start with a simple example: “Everyone can read emails. Bob can read and delete all data but only updates credit card numbers. Alice can perform all actions in emails“:

main = 
  DENY
  EXCEPT
    ALLOW {
      Actor = Bob
      Resources
      Actions = Reads, Deletes
    }
    ALLOW {
      Actor = Bob
      Resources = CCN
      Actions = Updates
    }
    ALLOW {
      Actor
      Resources = EMAIL
      Actions = Reads
    }
    ALLOW {
      Actor = Alice
      Resources = EMAIL
      Actions
    }

Below we see another specification: “Bob, Alex and Jeff can read all resources, but Alex can’t read emails.” Notice how Hapi supports factoring out particular rules into a default behavior. Such rules can be compiled in different files, and merged into a single specification through Hapi’s module system:

alexCantReadEmails =
  DENY {
        Actors = Alex
        Resources = EMAIL
        Actions = Reads
      }

main = 
  DENY
  EXCEPT
    ALLOW {
      Actor = Bob, Alex, Jeff
      Resources
      Actions = Reads

Resources

Project Hapi is sponsored by Cyral and developed at UFMG‘s Compilers Lab, which exists as part of the Department of Computer Science. This project is fully open source, and the interested users can find all our code base in publicly available repositories. 

Stay Connected