Using YAML instead of JSON in OPA*

While working with OPA we looked into different options for integration with the agent. For my specific use case it did make sense to use the Golang module:

github.com/open-policy-agent/opa

Adding a module does require some minor integration work, but overall you do have access to the core functionality of the OPA and flexibility when it comes to the Data part in OPA.

One of the negatives of working with JSON, is that you need to be able to keep a track of nested blocks and “{” “}”. I had my share of experience with lengthy JSON documents, and at times hours finding that one of “{” “}” were omitted. Besides, when trying to decide on the content of the Query Input or Data, it is easier to work with YAML.

In our environment, we decided that it shouldn’t matter when it comes to the content – it should be either JSON or YAML at any given time. To bridge this requirement a simple utility method comes in handy:

import (
    "encoding/json"
    "errors"
    "io/ioutil"
    "github.com/open-policy-agent/opa/util"      
)


// Loads the specified entitlements from the file system.
// The entitlements data is loaded as YAML
func LoadEntitlemetns(fileName string) (result interface(), err error) {
    yamlFile, err = ioutil.ReadFile(fileName)
    if err != nil {
        return nil, err
    }

    json, err := yaml.YAMLToJSON(yamlFile)
    if err != nil {
         return nil, err   
    }

    var loadedData interface{}
    err = util.Unmarshal(json, &loadedData)
    if err != nil {
        return nil, err
    }

    // return the result
    return loadedData, nil
}

The beauty of this approach is that JSON in this case is generated and guaranteed to be well formatted! Feel free to share your experience and thoughts on the topic.

Leave a Reply

%d bloggers like this: