rename SecureVariables to Variables throughout

This commit is contained in:
Tim Gross
2022-08-26 14:03:56 -04:00
parent 91c81ba984
commit d1faead371
53 changed files with 1201 additions and 1208 deletions

View File

@@ -61,8 +61,8 @@ type ACL struct {
// We use an iradix for the purposes of ordered iteration.
wildcardHostVolumes *iradix.Tree
secureVariables *iradix.Tree
wildcardSecureVariables *iradix.Tree
variables *iradix.Tree
wildcardVariables *iradix.Tree
agent string
node string
@@ -131,8 +131,8 @@ func NewACL(management bool, policies []*Policy) (*ACL, error) {
}
}
if ns.SecureVariables != nil {
for _, pathPolicy := range ns.SecureVariables.Paths {
if ns.Variables != nil {
for _, pathPolicy := range ns.Variables.Paths {
key := []byte(ns.Name + "\x00" + pathPolicy.PathSpec)
var svCapabilities capabilitySet
if globDefinition || strings.Contains(pathPolicy.PathSpec, "*") {
@@ -241,8 +241,8 @@ func NewACL(management bool, policies []*Policy) (*ACL, error) {
acl.wildcardNamespaces = wnsTxn.Commit()
acl.hostVolumes = hvTxn.Commit()
acl.wildcardHostVolumes = whvTxn.Commit()
acl.secureVariables = svTxn.Commit()
acl.wildcardSecureVariables = wsvTxn.Commit()
acl.variables = svTxn.Commit()
acl.wildcardVariables = wsvTxn.Commit()
return acl, nil
}
@@ -358,13 +358,13 @@ func (a *ACL) AllowHostVolume(ns string) bool {
return !capabilities.Check(PolicyDeny)
}
func (a *ACL) AllowSecureVariableOperation(ns, path, op string) bool {
func (a *ACL) AllowVariableOperation(ns, path, op string) bool {
if a.management {
return true
}
// Check for a matching capability set
capabilities, ok := a.matchingSecureVariablesCapabilitySet(ns, path)
capabilities, ok := a.matchingVariablesCapabilitySet(ns, path)
if !ok {
return false
}
@@ -372,22 +372,21 @@ func (a *ACL) AllowSecureVariableOperation(ns, path, op string) bool {
return capabilities.Check(op)
}
// AllowSecureVariableSearch is a very loose check that the token has
// *any* access to a secure variables path for the namespace, with an
// expectation that the actual search result will be filtered by
// specific paths
func (a *ACL) AllowSecureVariableSearch(ns string) bool {
// AllowVariableSearch is a very loose check that the token has *any* access to
// a variables path for the namespace, with an expectation that the actual
// search result will be filtered by specific paths
func (a *ACL) AllowVariableSearch(ns string) bool {
if a.management {
return true
}
iter := a.secureVariables.Root().Iterator()
iter := a.variables.Root().Iterator()
iter.SeekPrefix([]byte(ns))
_, _, ok := iter.Next()
if ok {
return true
}
iter = a.wildcardSecureVariables.Root().Iterator()
iter = a.wildcardVariables.Root().Iterator()
iter.SeekPrefix([]byte(ns))
_, _, ok = iter.Next()
return ok
@@ -461,20 +460,20 @@ func (a *ACL) matchingHostVolumeCapabilitySet(name string) (capabilitySet, bool)
return a.findClosestMatchingGlob(a.wildcardHostVolumes, name)
}
// matchingSecureVariablesCapabilitySet looks for a capabilitySet that matches the namespace and path,
// matchingVariablesCapabilitySet looks for a capabilitySet that matches the namespace and path,
// if no concrete definitions are found, then we return the closest matching
// glob.
// The closest matching glob is the one that has the smallest character
// difference between the namespace and the glob.
func (a *ACL) matchingSecureVariablesCapabilitySet(ns, path string) (capabilitySet, bool) {
func (a *ACL) matchingVariablesCapabilitySet(ns, path string) (capabilitySet, bool) {
// Check for a concrete matching capability set
raw, ok := a.secureVariables.Get([]byte(ns + "\x00" + path))
raw, ok := a.variables.Get([]byte(ns + "\x00" + path))
if ok {
return raw.(capabilitySet), true
}
// We didn't find a concrete match, so lets try and evaluate globs.
return a.findClosestMatchingGlob(a.wildcardSecureVariables, ns+"\x00"+path)
return a.findClosestMatchingGlob(a.wildcardVariables, ns+"\x00"+path)
}
type matchingGlob struct {

View File

@@ -448,7 +448,7 @@ func TestWildcardHostVolumeMatching(t *testing.T) {
}
}
func TestSecureVariablesMatching(t *testing.T) {
func TestVariablesMatching(t *testing.T) {
ci.Parallel(t)
tests := []struct {
@@ -462,7 +462,7 @@ func TestSecureVariablesMatching(t *testing.T) {
{
name: "concrete namespace with concrete path matches",
policy: `namespace "ns" {
secure_variables { path "foo/bar" { capabilities = ["read"] }}}`,
variables { path "foo/bar" { capabilities = ["read"] }}}`,
ns: "ns",
path: "foo/bar",
op: "read",
@@ -471,7 +471,7 @@ func TestSecureVariablesMatching(t *testing.T) {
{
name: "concrete namespace with concrete path matches for expanded caps",
policy: `namespace "ns" {
secure_variables { path "foo/bar" { capabilities = ["read"] }}}`,
variables { path "foo/bar" { capabilities = ["read"] }}}`,
ns: "ns",
path: "foo/bar",
op: "list",
@@ -480,7 +480,7 @@ func TestSecureVariablesMatching(t *testing.T) {
{
name: "concrete namespace with wildcard path matches",
policy: `namespace "ns" {
secure_variables { path "foo/*" { capabilities = ["read"] }}}`,
variables { path "foo/*" { capabilities = ["read"] }}}`,
ns: "ns",
path: "foo/bar",
op: "read",
@@ -489,7 +489,7 @@ func TestSecureVariablesMatching(t *testing.T) {
{
name: "concrete namespace with non-prefix wildcard path matches",
policy: `namespace "ns" {
secure_variables { path "*/bar" { capabilities = ["read"] }}}`,
variables { path "*/bar" { capabilities = ["read"] }}}`,
ns: "ns",
path: "foo/bar",
op: "read",
@@ -498,7 +498,7 @@ func TestSecureVariablesMatching(t *testing.T) {
{
name: "concrete namespace with overlapping wildcard path prefix over suffix matches",
policy: `namespace "ns" {
secure_variables {
variables {
path "*/bar" { capabilities = ["list"] }
path "foo/*" { capabilities = ["write"] }
}}`,
@@ -510,7 +510,7 @@ func TestSecureVariablesMatching(t *testing.T) {
{
name: "concrete namespace with overlapping wildcard path prefix over suffix denied",
policy: `namespace "ns" {
secure_variables {
variables {
path "*/bar" { capabilities = ["list"] }
path "foo/*" { capabilities = ["write"] }
}}`,
@@ -522,7 +522,7 @@ func TestSecureVariablesMatching(t *testing.T) {
{
name: "concrete namespace with wildcard path matches most specific only",
policy: `namespace "ns" {
secure_variables {
variables {
path "*" { capabilities = ["read"] }
path "foo/*" { capabilities = ["read"] }
path "foo/bar" { capabilities = ["list"] }
@@ -535,7 +535,7 @@ func TestSecureVariablesMatching(t *testing.T) {
{
name: "concrete namespace with invalid concrete path fails",
policy: `namespace "ns" {
secure_variables { path "bar" { capabilities = ["read"] }}}`,
variables { path "bar" { capabilities = ["read"] }}}`,
ns: "ns",
path: "foo/bar",
op: "read",
@@ -544,7 +544,7 @@ func TestSecureVariablesMatching(t *testing.T) {
{
name: "concrete namespace with invalid wildcard path fails",
policy: `namespace "ns" {
secure_variables { path "*/foo" { capabilities = ["read"] }}}`,
variables { path "*/foo" { capabilities = ["read"] }}}`,
ns: "ns",
path: "foo/bar",
op: "read",
@@ -553,7 +553,7 @@ func TestSecureVariablesMatching(t *testing.T) {
{
name: "wildcard namespace with concrete path matches",
policy: `namespace "*" {
secure_variables { path "foo/bar" { capabilities = ["read"] }}}`,
variables { path "foo/bar" { capabilities = ["read"] }}}`,
ns: "ns",
path: "foo/bar",
op: "read",
@@ -562,7 +562,7 @@ func TestSecureVariablesMatching(t *testing.T) {
{
name: "wildcard namespace with invalid concrete path fails",
policy: `namespace "*" {
secure_variables { path "bar" { capabilities = ["read"] }}}`,
variables { path "bar" { capabilities = ["read"] }}}`,
ns: "ns",
path: "foo/bar",
op: "read",
@@ -571,7 +571,7 @@ func TestSecureVariablesMatching(t *testing.T) {
{
name: "wildcard in user provided path fails",
policy: `namespace "ns" {
secure_variables { path "foo/bar" { capabilities = ["read"] }}}`,
variables { path "foo/bar" { capabilities = ["read"] }}}`,
ns: "ns",
path: "*",
op: "read",
@@ -580,7 +580,7 @@ func TestSecureVariablesMatching(t *testing.T) {
{
name: "wildcard attempt to bypass delimiter null byte fails",
policy: `namespace "ns" {
secure_variables { path "foo/bar" { capabilities = ["read"] }}}`,
variables { path "foo/bar" { capabilities = ["read"] }}}`,
ns: "ns*",
path: "bar",
op: "read",
@@ -589,7 +589,7 @@ func TestSecureVariablesMatching(t *testing.T) {
{
name: "wildcard with more specific denied path",
policy: `namespace "ns" {
secure_variables {
variables {
path "*" { capabilities = ["list"] }
path "system/*" { capabilities = ["deny"] }}}`,
ns: "ns",
@@ -600,11 +600,11 @@ func TestSecureVariablesMatching(t *testing.T) {
{
name: "multiple namespace with overlapping paths",
policy: `namespace "ns" {
secure_variables {
variables {
path "*" { capabilities = ["list"] }
path "system/*" { capabilities = ["deny"] }}}
namespace "prod" {
secure_variables {
variables {
path "*" { capabilities = ["list"]}}}`,
ns: "prod",
path: "system/is-allowed",
@@ -618,24 +618,24 @@ func TestSecureVariablesMatching(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
policy, err := Parse(tc.policy)
require.NoError(t, err)
require.NotNil(t, policy.Namespaces[0].SecureVariables)
require.NotNil(t, policy.Namespaces[0].Variables)
acl, err := NewACL(false, []*Policy{policy})
require.NoError(t, err)
require.Equal(t, tc.allow, acl.AllowSecureVariableOperation(tc.ns, tc.path, tc.op))
require.Equal(t, tc.allow, acl.AllowVariableOperation(tc.ns, tc.path, tc.op))
})
}
t.Run("search over namespace", func(t *testing.T) {
policy, err := Parse(`namespace "ns" {
secure_variables { path "foo/bar" { capabilities = ["read"] }}}`)
variables { path "foo/bar" { capabilities = ["read"] }}}`)
require.NoError(t, err)
require.NotNil(t, policy.Namespaces[0].SecureVariables)
require.NotNil(t, policy.Namespaces[0].Variables)
acl, err := NewACL(false, []*Policy{policy})
require.NoError(t, err)
require.True(t, acl.AllowSecureVariableSearch("ns"))
require.False(t, acl.AllowSecureVariableSearch("no-access"))
require.True(t, acl.AllowVariableSearch("ns"))
require.False(t, acl.AllowVariableSearch("no-access"))
})
}

View File

@@ -69,13 +69,13 @@ var (
const (
// The following are the fine-grained capabilities that can be
// granted for a secure variables path. When capabilities are
// granted for a variables path. When capabilities are
// combined we take the union of all capabilities.
SecureVariablesCapabilityList = "list"
SecureVariablesCapabilityRead = "read"
SecureVariablesCapabilityWrite = "write"
SecureVariablesCapabilityDestroy = "destroy"
SecureVariablesCapabilityDeny = "deny"
VariablesCapabilityList = "list"
VariablesCapabilityRead = "read"
VariablesCapabilityWrite = "write"
VariablesCapabilityDestroy = "destroy"
VariablesCapabilityDeny = "deny"
)
// Policy represents a parsed HCL or JSON policy.
@@ -104,17 +104,17 @@ func (p *Policy) IsEmpty() bool {
// NamespacePolicy is the policy for a specific namespace
type NamespacePolicy struct {
Name string `hcl:",key"`
Policy string
Capabilities []string
SecureVariables *SecureVariablesPolicy `hcl:"secure_variables"`
Name string `hcl:",key"`
Policy string
Capabilities []string
Variables *VariablesPolicy `hcl:"variables"`
}
type SecureVariablesPolicy struct {
Paths []*SecureVariablesPathPolicy `hcl:"path"`
type VariablesPolicy struct {
Paths []*VariablesPathPolicy `hcl:"path"`
}
type SecureVariablesPathPolicy struct {
type VariablesPathPolicy struct {
PathSpec string `hcl:",key"`
Capabilities []string
}
@@ -184,11 +184,11 @@ func isNamespaceCapabilityValid(cap string) bool {
}
// isPathCapabilityValid ensures the given capability is valid for a
// secure variables path policy
// variables path policy
func isPathCapabilityValid(cap string) bool {
switch cap {
case SecureVariablesCapabilityWrite, SecureVariablesCapabilityRead,
SecureVariablesCapabilityList, SecureVariablesCapabilityDestroy, SecureVariablesCapabilityDeny:
case VariablesCapabilityWrite, VariablesCapabilityRead,
VariablesCapabilityList, VariablesCapabilityDestroy, VariablesCapabilityDeny:
return true
default:
return false
@@ -266,15 +266,15 @@ func expandHostVolumePolicy(policy string) []string {
}
}
func expandSecureVariablesCapabilities(caps []string) []string {
func expandVariablesCapabilities(caps []string) []string {
var foundRead, foundList bool
for _, cap := range caps {
switch cap {
case SecureVariablesCapabilityDeny:
return []string{SecureVariablesCapabilityDeny}
case SecureVariablesCapabilityRead:
case VariablesCapabilityDeny:
return []string{VariablesCapabilityDeny}
case VariablesCapabilityRead:
foundRead = true
case SecureVariablesCapabilityList:
case VariablesCapabilityList:
foundList = true
}
}
@@ -327,21 +327,21 @@ func Parse(rules string) (*Policy, error) {
ns.Capabilities = append(ns.Capabilities, extraCap...)
}
if ns.SecureVariables != nil {
if len(ns.SecureVariables.Paths) == 0 {
return nil, fmt.Errorf("Invalid secure variable policy: no secure variable paths in namespace %s", ns.Name)
if ns.Variables != nil {
if len(ns.Variables.Paths) == 0 {
return nil, fmt.Errorf("Invalid variable policy: no variable paths in namespace %s", ns.Name)
}
for _, pathPolicy := range ns.SecureVariables.Paths {
for _, pathPolicy := range ns.Variables.Paths {
if pathPolicy.PathSpec == "" {
return nil, fmt.Errorf("Invalid missing secure variable path in namespace %s", ns.Name)
return nil, fmt.Errorf("Invalid missing variable path in namespace %s", ns.Name)
}
for _, cap := range pathPolicy.Capabilities {
if !isPathCapabilityValid(cap) {
return nil, fmt.Errorf(
"Invalid secure variable capability '%s' in namespace %s", cap, ns.Name)
"Invalid variable capability '%s' in namespace %s", cap, ns.Name)
}
}
pathPolicy.Capabilities = expandSecureVariablesCapabilities(pathPolicy.Capabilities)
pathPolicy.Capabilities = expandVariablesCapabilities(pathPolicy.Capabilities)
}

View File

@@ -56,7 +56,7 @@ func TestParse(t *testing.T) {
capabilities = ["deny", "read-logs"]
}
namespace "apps" {
secure_variables {
variables {
path "jobs/write-does-not-imply-read-or-delete" {
capabilities = ["write"]
}
@@ -137,25 +137,25 @@ func TestParse(t *testing.T) {
},
{
Name: "apps",
SecureVariables: &SecureVariablesPolicy{
Paths: []*SecureVariablesPathPolicy{
Variables: &VariablesPolicy{
Paths: []*VariablesPathPolicy{
{
PathSpec: "jobs/write-does-not-imply-read-or-delete",
Capabilities: []string{SecureVariablesCapabilityWrite},
Capabilities: []string{VariablesCapabilityWrite},
},
{
PathSpec: "project/read-implies-list",
Capabilities: []string{
SecureVariablesCapabilityRead,
SecureVariablesCapabilityList,
VariablesCapabilityRead,
VariablesCapabilityList,
},
},
{
PathSpec: "project/explicit",
Capabilities: []string{
SecureVariablesCapabilityRead,
SecureVariablesCapabilityList,
SecureVariablesCapabilityDestroy,
VariablesCapabilityRead,
VariablesCapabilityList,
VariablesCapabilityDestroy,
},
},
},
@@ -201,12 +201,12 @@ func TestParse(t *testing.T) {
{
`
namespace "dev" {
secure_variables "*" {
variables "*" {
capabilities = ["read", "write"]
}
}
`,
"Invalid secure variable policy: no secure variable paths in namespace dev",
"Invalid variable policy: no variable paths in namespace dev",
nil,
},
{