open-vault/vault/acl_test.go

532 lines
12 KiB
Go
Raw Normal View History

2015-03-18 01:31:20 +00:00
package vault
import (
2016-03-05 05:03:55 +00:00
"reflect"
2015-03-18 01:31:20 +00:00
"testing"
"github.com/hashicorp/vault/logical"
)
2016-03-05 05:03:55 +00:00
func TestACL_Capabilities(t *testing.T) {
// Create the root policy ACL
policy := []*Policy{&Policy{Name: "root"}}
acl, err := NewACL(policy)
if err != nil {
t.Fatalf("err: %v", err)
}
actual := acl.Capabilities("any/path")
expected := []string{"root"}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: got\n%#v\nexpected\n%#v\n", actual, expected)
}
policies, err := Parse(aclPolicy)
if err != nil {
t.Fatalf("err: %v", err)
}
acl, err = NewACL([]*Policy{policies})
if err != nil {
t.Fatalf("err: %v", err)
}
actual = acl.Capabilities("dev")
expected = []string{"deny"}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: path:%s\ngot\n%#v\nexpected\n%#v\n", "deny", actual, expected)
}
actual = acl.Capabilities("dev/")
expected = []string{"sudo", "read", "list", "update", "delete", "create"}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: path:%s\ngot\n%#v\nexpected\n%#v\n", "dev/", actual, expected)
}
actual = acl.Capabilities("stage/aws/test")
expected = []string{"sudo", "read", "list", "update"}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: path:%s\ngot\n%#v\nexpected\n%#v\n", "stage/aws/test", actual, expected)
}
}
2015-03-18 01:31:20 +00:00
func TestACL_Root(t *testing.T) {
// Create the root policy ACL
policy := []*Policy{&Policy{Name: "root"}}
acl, err := NewACL(policy)
if err != nil {
t.Fatalf("err: %v", err)
}
request := new(logical.Request)
request.Operation = logical.UpdateOperation
request.Path = "sys/mount/foo"
allowed, rootPrivs := acl.AllowOperation(request)
if !rootPrivs {
2015-03-18 01:31:20 +00:00
t.Fatalf("expected root")
}
if !allowed {
2016-10-30 22:09:45 +00:00
t.Fatalf("expected permissions")
2015-03-18 01:31:20 +00:00
}
}
func TestACL_Single(t *testing.T) {
policy, err := Parse(aclPolicy)
if err != nil {
t.Fatalf("err: %v", err)
}
acl, err := NewACL([]*Policy{policy})
if err != nil {
t.Fatalf("err: %v", err)
}
// Type of operation is not important here as we only care about checking
// sudo/root
request := new(logical.Request)
request.Operation = logical.ReadOperation
request.Path = "sys/mount/foo"
_, rootPrivs := acl.AllowOperation(request)
if rootPrivs {
2015-03-18 01:31:20 +00:00
t.Fatalf("unexpected root")
}
type tcase struct {
op logical.Operation
path string
allowed bool
rootPrivs bool
2015-03-18 01:31:20 +00:00
}
tcases := []tcase{
{logical.ReadOperation, "root", false, false},
{logical.HelpOperation, "root", true, false},
2015-03-18 01:31:20 +00:00
{logical.ReadOperation, "dev/foo", true, true},
{logical.UpdateOperation, "dev/foo", true, true},
2015-03-18 01:31:20 +00:00
{logical.DeleteOperation, "stage/foo", true, false},
{logical.ListOperation, "stage/aws/foo", true, true},
{logical.UpdateOperation, "stage/aws/foo", true, true},
{logical.UpdateOperation, "stage/aws/policy/foo", true, true},
2015-03-18 01:31:20 +00:00
{logical.DeleteOperation, "prod/foo", false, false},
{logical.UpdateOperation, "prod/foo", false, false},
{logical.ReadOperation, "prod/foo", true, false},
{logical.ListOperation, "prod/foo", true, false},
{logical.ReadOperation, "prod/aws/foo", false, false},
{logical.ReadOperation, "foo/bar", true, true},
{logical.ListOperation, "foo/bar", false, true},
{logical.UpdateOperation, "foo/bar", false, true},
{logical.CreateOperation, "foo/bar", true, true},
2015-03-18 01:31:20 +00:00
}
for _, tc := range tcases {
request := new(logical.Request)
request.Operation = tc.op
request.Path = tc.path
allowed, rootPrivs := acl.AllowOperation(request)
if allowed != tc.allowed {
t.Fatalf("bad: case %#v: %v, %v", tc, allowed, rootPrivs)
}
if rootPrivs != tc.rootPrivs {
t.Fatalf("bad: case %#v: %v, %v", tc, allowed, rootPrivs)
2015-03-18 01:31:20 +00:00
}
}
}
func TestACL_Layered(t *testing.T) {
policy1, err := Parse(aclPolicy)
if err != nil {
t.Fatalf("err: %v", err)
}
policy2, err := Parse(aclPolicy2)
if err != nil {
t.Fatalf("err: %v", err)
}
2016-11-02 02:48:00 +00:00
acl, err := NewACL([]*Policy{policy1, policy2})
2015-03-18 01:31:20 +00:00
if err != nil {
t.Fatalf("err: %v", err)
2016-11-02 02:48:00 +00:00
}
2015-03-18 19:17:03 +00:00
testLayeredACL(t, acl)
}
func testLayeredACL(t *testing.T, acl *ACL) {
// Type of operation is not important here as we only care about checking
// sudo/root
request := new(logical.Request)
request.Operation = logical.ReadOperation
request.Path = "sys/mount/foo"
_, rootPrivs := acl.AllowOperation(request)
if rootPrivs {
2015-03-18 01:31:20 +00:00
t.Fatalf("unexpected root")
}
type tcase struct {
op logical.Operation
path string
allowed bool
rootPrivs bool
2015-03-18 01:31:20 +00:00
}
tcases := []tcase{
{logical.ReadOperation, "root", false, false},
{logical.HelpOperation, "root", true, false},
2015-03-18 01:31:20 +00:00
{logical.ReadOperation, "dev/foo", true, true},
{logical.UpdateOperation, "dev/foo", true, true},
{logical.ReadOperation, "dev/hide/foo", false, false},
{logical.UpdateOperation, "dev/hide/foo", false, false},
2015-03-18 01:31:20 +00:00
{logical.DeleteOperation, "stage/foo", true, false},
{logical.ListOperation, "stage/aws/foo", true, true},
{logical.UpdateOperation, "stage/aws/foo", true, true},
{logical.UpdateOperation, "stage/aws/policy/foo", false, false},
2015-03-18 01:31:20 +00:00
{logical.DeleteOperation, "prod/foo", true, false},
{logical.UpdateOperation, "prod/foo", true, false},
{logical.ReadOperation, "prod/foo", true, false},
{logical.ListOperation, "prod/foo", true, false},
{logical.ReadOperation, "prod/aws/foo", false, false},
2015-07-05 23:34:34 +00:00
{logical.ReadOperation, "sys/status", false, false},
{logical.UpdateOperation, "sys/seal", true, true},
{logical.ReadOperation, "foo/bar", false, false},
{logical.ListOperation, "foo/bar", false, false},
{logical.UpdateOperation, "foo/bar", false, false},
{logical.CreateOperation, "foo/bar", false, false},
2015-03-18 01:31:20 +00:00
}
for _, tc := range tcases {
request := new(logical.Request)
request.Operation = tc.op
request.Path = tc.path
allowed, rootPrivs := acl.AllowOperation(request)
if allowed != tc.allowed {
t.Fatalf("bad: case %#v: %v, %v", tc, allowed, rootPrivs)
}
if rootPrivs != tc.rootPrivs {
t.Fatalf("bad: case %#v: %v, %v", tc, allowed, rootPrivs)
2015-03-18 01:31:20 +00:00
}
}
}
func TestPolicyMerge(t *testing.T) {
2016-11-02 02:48:00 +00:00
policy, err := Parse(permissionsPolicy2)
if err != nil {
2016-10-30 22:09:45 +00:00
t.Fatalf("err: %v", err)
}
acl, err := NewACL([]*Policy{policy})
if err != nil {
t.Fatalf("err: %v", err)
}
2016-11-02 02:48:00 +00:00
type tcase struct {
op logical.Operation
pathName string
parameter string
2016-11-02 02:48:00 +00:00
allowed bool
rootPrivs bool
}
tcases := []tcase{
{logical.UpdateOperation, "foo/bar", "baz", false, false},
2016-11-06 23:16:08 +00:00
{logical.UpdateOperation, "foo/bar", "zip", false, false},
{logical.CreateOperation, "foo/bar", "baz", false, false},
{logical.CreateOperation, "foo/bar", "zip", false, false},
{logical.DeleteOperation, "foo/bar", "baz", false, false},
{logical.DeleteOperation, "foo/bar", "zip", false, false},
{logical.UpdateOperation, "hello/universe", "bob", true, false},
{logical.UpdateOperation, "hello/universe", "tom", true, false},
{logical.CreateOperation, "hello/universe", "bob", true, false},
{logical.CreateOperation, "hello/universe", "tom", true, false},
{logical.DeleteOperation, "hello/universe", "bob", true, false},
{logical.DeleteOperation, "hello/universe", "tom", true, false},
{logical.UpdateOperation, "rainy/day", "bob", true, false},
{logical.UpdateOperation, "rainy/day", "tom", true, false},
{logical.CreateOperation, "rainy/day", "bob", true, false},
{logical.CreateOperation, "rainy/day", "tom", true, false},
{logical.DeleteOperation, "rainy/day", "bob", true, false},
{logical.DeleteOperation, "rainy/day", "tom", true, false},
{logical.UpdateOperation, "cool/bike", "frank", false, false},
{logical.UpdateOperation, "cool/bike", "two", false, false},
{logical.CreateOperation, "cool/bike", "frank", false, false},
{logical.CreateOperation, "cool/bike", "four", false, false},
{logical.DeleteOperation, "cool/bike", "frank", false, false},
{logical.DeleteOperation, "cool/bike", "six", false, false},
{logical.UpdateOperation, "clean/bed", "one", false, false},
{logical.UpdateOperation, "clean/bed", "two", false, false},
{logical.CreateOperation, "clean/bed", "three", false, false},
{logical.CreateOperation, "clean/bed", "four", false, false},
{logical.DeleteOperation, "clean/bed", "five", false, false},
{logical.DeleteOperation, "clean/bed", "six", false, false},
{logical.UpdateOperation, "coca/cola", "john", false, false},
{logical.UpdateOperation, "coca/cola", "two", false, false},
{logical.CreateOperation, "coca/cola", "john", false, false},
{logical.CreateOperation, "coca/cola", "four", false, false},
{logical.DeleteOperation, "coca/cola", "john", false, false},
{logical.DeleteOperation, "coca/cola", "six", false, false},
2016-11-02 02:48:00 +00:00
}
for _, tc := range tcases {
request := new(logical.Request)
request.Operation = tc.op
request.Path = tc.pathName
paramMap := make(map[string]interface{})
paramMap[tc.parameter] = ""
request.Data = paramMap
allowed, rootPrivs := acl.AllowOperation(request)
2016-11-02 02:48:00 +00:00
if allowed != tc.allowed {
t.Fatalf("bad: case %#v: %v, %v", tc, allowed, rootPrivs)
}
if rootPrivs != tc.rootPrivs {
t.Fatalf("bad: case %#v: %v, %v", tc, allowed, rootPrivs)
}
}
}
2016-10-30 22:09:45 +00:00
//test merging
var permissionsPolicy2 = `
name = "ops"
path "foo/bar" {
policy = "write"
permissions = {
2016-11-06 23:16:08 +00:00
deniedparameters = {
"baz" = {}
}
}
}
path "foo/bar" {
policy = "write"
permissions = {
2016-11-06 23:16:08 +00:00
deniedparameters = {
"zip" = {}
}
}
}
path "hello/universe" {
policy = "write"
permissions = {
2016-11-06 23:16:08 +00:00
allowedparameters = {
"bob" = {}
}
}
}
path "hello/universe" {
policy = "write"
permissions = {
2016-11-06 23:16:08 +00:00
allowedparameters = {
"tom" = {}
}
}
}
path "rainy/day" {
policy = "write"
permissions = {
2016-11-06 23:16:08 +00:00
allowedparameters = {
"bob" = {}
}
}
}
path "rainy/day" {
policy = "write"
permissions = {
2016-11-06 23:16:08 +00:00
allowedparameters = {
"*" = {}
}
}
}
path "cool/bike" {
policy = "write"
permissions = {
2016-11-06 23:16:08 +00:00
deniedparameters = {
"frank" = {}
}
}
}
path "cool/bike" {
policy = "write"
permissions = {
2016-11-06 23:16:08 +00:00
deniedparameters = {
"*" = {}
}
}
}
path "clean/bed" {
policy = "write"
permissions = {
2016-11-06 23:16:08 +00:00
deniedparameters = {
"*" = {}
}
}
}
path "clean/bed" {
policy = "write"
permissions = {
2016-11-06 23:16:08 +00:00
allowedparameters = {
"*" = {}
}
}
}
path "coca/cola" {
policy = "write"
permissions = {
2016-11-06 23:16:08 +00:00
deniedparameters = {
"john" = {}
}
}
}
path "coca/cola" {
policy = "write"
permissions = {
2016-11-06 23:16:08 +00:00
allowedparameters = {
"john" = {}
}
}
}
`
2016-08-02 19:21:15 +00:00
var tokenCreationPolicy = `
name = "tokenCreation"
path "auth/token/create*" {
capabilities = ["update", "create", "sudo"]
}
`
2015-03-18 01:31:20 +00:00
var aclPolicy = `
name = "dev"
path "dev/*" {
2015-03-18 01:31:20 +00:00
policy = "sudo"
}
path "stage/*" {
2015-03-18 01:31:20 +00:00
policy = "write"
}
path "stage/aws/*" {
2015-03-18 01:31:20 +00:00
policy = "read"
capabilities = ["update", "sudo"]
2015-03-18 01:31:20 +00:00
}
path "stage/aws/policy/*" {
2015-03-18 01:31:20 +00:00
policy = "sudo"
}
path "prod/*" {
2015-03-18 01:31:20 +00:00
policy = "read"
}
path "prod/aws/*" {
2015-03-18 01:31:20 +00:00
policy = "deny"
}
2015-07-05 23:34:34 +00:00
path "sys/*" {
policy = "deny"
}
path "foo/bar" {
capabilities = ["read", "create", "sudo"]
}
2015-03-18 01:31:20 +00:00
`
var aclPolicy2 = `
name = "ops"
path "dev/hide/*" {
2015-03-18 01:31:20 +00:00
policy = "deny"
}
path "stage/aws/policy/*" {
2015-03-18 01:31:20 +00:00
policy = "deny"
# This should have no effect
capabilities = ["read", "update", "sudo"]
2015-03-18 01:31:20 +00:00
}
path "prod/*" {
2015-03-18 01:31:20 +00:00
policy = "write"
}
2015-07-05 23:34:34 +00:00
path "sys/seal" {
policy = "sudo"
}
path "foo/bar" {
capabilities = ["deny"]
2015-07-05 23:34:34 +00:00
}
2015-03-18 01:31:20 +00:00
`
2016-11-02 02:48:00 +00:00
2016-10-30 22:09:45 +00:00
//allow operation testing
var permissionsPolicy = `
name = "dev"
path "dev/*" {
policy = "write"
permissions = {
2016-11-06 23:16:08 +00:00
allowedparameters = {
"zip" = {}
2016-10-30 22:09:45 +00:00
}
}
}
path "foo/bar" {
policy = "write"
permissions = {
2016-11-06 23:16:08 +00:00
deniedparameters = {
"zap" = {}
2016-10-30 22:09:45 +00:00
}
}
}
path "foo/baz" {
policy = "write"
permissions = {
2016-11-06 23:16:08 +00:00
allowedparameters = {
"hello" = {}
2016-10-30 22:09:45 +00:00
}
2016-11-06 23:16:08 +00:00
deniedparameters = {
"zap" = {}
2016-10-30 22:09:45 +00:00
}
}
}
path "broken/phone" {
policy = "write"
permissions = {
2016-11-06 23:16:08 +00:00
allowedparameters = {
"steve" = {}
2016-10-30 22:09:45 +00:00
}
2016-11-06 23:16:08 +00:00
deniedparameters = {
"steve" = {}
2016-10-30 22:09:45 +00:00
}
}
}
path "hello/world" {
2016-10-30 22:09:45 +00:00
policy = "write"
permissions = {
2016-11-06 23:16:08 +00:00
allowedparameters = {
"*" = {}
2016-10-30 22:09:45 +00:00
}
2016-11-06 23:16:08 +00:00
deniedparameters = {
"*" = {}
2016-10-30 22:09:45 +00:00
}
}
}
path "tree/fort" {
2016-10-30 22:09:45 +00:00
policy = "write"
permissions = {
2016-11-06 23:16:08 +00:00
allowedparameters = {
"*" = {}
2016-10-30 22:09:45 +00:00
}
2016-11-06 23:16:08 +00:00
deniedparameters = {
"beer" = {}
2016-10-30 22:09:45 +00:00
}
}
}
path "fruit/apple" {
2016-10-30 22:09:45 +00:00
policy = "write"
permissions = {
2016-11-06 23:16:08 +00:00
allowedparameters = {
"pear" = {}
2016-10-30 22:09:45 +00:00
}
2016-11-06 23:16:08 +00:00
deniedparameters = {
"*" = {}
2016-10-30 22:09:45 +00:00
}
}
}
path "cold/weather" {
2016-10-30 22:09:45 +00:00
policy = "write"
permissions = {
2016-11-06 23:16:08 +00:00
allowedparameters = {}
deniedparameters = {}
2016-10-30 22:09:45 +00:00
}
}
`