// Package parser contains a parser for Pomerium Policy Language. // // The Pomerium Policy Language is a JSON or YAML document containing rules, // actions, logical operators and criteria. // // The document contains zero or more rules. // // A rule has an action and zero or more logical operators. // // An action is either "allow" or "deny". // // The logical operators are "and", "or" and "not" and contain zero or more criteria. // // A criterion has a name and arbitrary JSON data. // // An example policy: // // allow: // and: // - domain: example.com // - group: admin // deny: // or: // - user: user1@example.com // - user: user2@example.com // // The JSON Schema for the language: // // { // "$ref": "#/definitions/policy", // "definitions": { // "policy": { // "anyOf": [ // { "$ref": "#/definitions/rules" }, // { // "type": "array", // "items": { "$ref": "#/definitions/rules" } // } // ] // }, // "rules": { // "type": "object", // "properties": { // "allow": { "$ref": "#/definitions/rule_body" }, // "deny": { "$ref": "#/definitions/rule_body" } // } // }, // "rule_body": { // "type": "object", // "properties": { // "and": { // "type": "array", // "items": { "$ref": "#/definitions/criteria" } // }, // "not": { // "type": "array", // "items": { "$ref": "#/definitions/criteria" } // }, // "or": { // "type": "array", // "items": { "$ref": "#/definitions/criteria" } // } // }, // "additionalProperties": false // }, // "criteria": { // "type": "object", // "additionalProperties": true, // "minProperties": 1, // "maxProperties": 1 // } // } // } package parser import ( "bytes" "encoding/json" "io" "gopkg.in/yaml.v3" ) // A Parser parses raw policy definitions into a Policy. type Parser struct{} // New creates a new Parser. func New() *Parser { p := &Parser{} return p } // ParseJSON parses a raw JSON document into a policy. func (p *Parser) ParseJSON(r io.Reader) (*Policy, error) { doc, err := ParseValue(r) if err != nil { return nil, err } return PolicyFromValue(doc) } // ParseYAML parses a raw YAML document into a policy. func (p *Parser) ParseYAML(r io.Reader) (*Policy, error) { var obj interface{} err := yaml.NewDecoder(r).Decode(&obj) if err != nil { return nil, err } bs, err := json.Marshal(obj) if err != nil { return nil, err } return p.ParseJSON(bytes.NewReader(bs)) } // ParseJSON creates a parser and calls ParseJSON on it. func ParseJSON(r io.Reader) (*Policy, error) { return New().ParseJSON(r) } // ParseYAML creates a parser and calls ParseYAML on it. func ParseYAML(r io.Reader) (*Policy, error) { return New().ParseYAML(r) }