Pomerium Policy Language (#2202)

* policy: add parser and generator for Pomerium Policy Language

* add criteria

* add additional criteria
This commit is contained in:
Caleb Doxsey 2021-05-17 15:30:51 -06:00 committed by GitHub
parent 9fe941ccee
commit e138054cb9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
33 changed files with 2758 additions and 0 deletions

117
pkg/policy/rules/rules.go Normal file
View file

@ -0,0 +1,117 @@
// Package rules contains useful pre-defined rego AST rules.
package rules
import "github.com/open-policy-agent/opa/ast"
// GetSession the session for the given id.
func GetSession() *ast.Rule {
return ast.MustParseRule(`
get_session(id) = v {
v := get_databroker_record("type.googleapis.com/user.ServiceAccount", id)
} else = v {
v := get_databroker_record("type.googleapis.com/session.Session", id)
} else = v {
v := {}
}
`)
}
// GetUser returns the user for the given session.
func GetUser() *ast.Rule {
return ast.MustParseRule(`
get_user(session) = v {
v := get_databroker_record("type.googleapis.com/user.User", session.impersonate_user_id)
} else = v {
v := get_databroker_record("type.googleapis.com/user.User", session.user_id)
} else = v {
v := {}
}
`)
}
// GetUserEmail gets the user email, either the impersonate email, or the user email.
func GetUserEmail() *ast.Rule {
return ast.MustParseRule(`
get_user_email(session, user) = v {
v := session.impersonate_email
} else = v {
v := user.email
} else = v {
v := ""
}
`)
}
// GetDirectoryUser returns the directory user for the given session.
func GetDirectoryUser() *ast.Rule {
return ast.MustParseRule(`
get_directory_user(session) = v {
v := get_databroker_record("type.googleapis.com/directory.User", session.impersonate_user_id)
} else = v {
v := get_databroker_record("type.googleapis.com/directory.User", session.user_id)
} else = v {
v := {}
}
`)
}
// GetDirectoryGroup returns the directory group for the given id.
func GetDirectoryGroup() *ast.Rule {
return ast.MustParseRule(`
get_directory_group(id) = v {
v := get_databroker_record("type.googleapis.com/directory.Group", id)
} else = v {
v := {}
}
`)
}
// GetGroupIDs returns the group ids for the given session or directory user.
func GetGroupIDs() *ast.Rule {
return ast.MustParseRule(`
get_group_ids(session, directory_user) = v {
v := session.impersonate_groups
} else = v {
v := directory_user.group_ids
} else = v {
v := []
}
`)
}
// ObjectGet recursively gets a value from an object.
func ObjectGet() *ast.Rule {
return ast.MustParseRule(`
# object_get is like object.get, but supports converting "/" in keys to separate lookups
# rego doesn't support recursion, so we hard code a limited number of /'s
object_get(obj, key, def) = value {
segments := split(key, "/")
count(segments) == 2
o1 := object.get(obj, segments[0], {})
value = object.get(o1, segments[1], def)
} else = value {
segments := split(key, "/")
count(segments) == 3
o1 := object.get(obj, segments[0], {})
o2 := object.get(o1, segments[1], {})
value = object.get(o2, segments[2], def)
} else = value {
segments := split(key, "/")
count(segments) == 4
o1 := object.get(obj, segments[0], {})
o2 := object.get(o1, segments[1], {})
o3 := object.get(o2, segments[2], {})
value = object.get(o3, segments[3], def)
} else = value {
segments := split(key, "/")
count(segments) == 5
o1 := object.get(obj, segments[0], {})
o2 := object.get(o1, segments[1], {})
o3 := object.get(o2, segments[2], {})
o4 := object.get(o3, segments[3], {})
value = object.get(o4, segments[4], def)
} else = value {
value = object.get(obj, key, def)
}
`)
}