diff --git a/src/go/pkg/conf/conf.go b/src/go/pkg/conf/conf.go
index 4d3f1c4172..48452a4a48 100644
--- a/src/go/pkg/conf/conf.go
+++ b/src/go/pkg/conf/conf.go
@@ -211,27 +211,35 @@ func setStructValue(value reflect.Value, node *Node) (err error) {
 
 func setMapValue(value reflect.Value, node *Node) (err error) {
 	m := reflect.MakeMap(reflect.MapOf(value.Type().Key(), value.Type().Elem()))
-	for _, child := range node.nodes {
-		k := reflect.New(value.Type().Key())
-		if err = setBasicValue(k.Elem(), nil, &child.name); err != nil {
-			return
-		}
-		v := reflect.New(value.Type().Elem())
-		if err = setValue(v.Elem(), nil, child); err != nil {
-			return
+	for _, v := range node.Nodes {
+		if child, ok := v.(*Node); ok {
+			k := reflect.New(value.Type().Key())
+			if err = setBasicValue(k.Elem(), nil, &child.Name); err != nil {
+				return
+			}
+			v := reflect.New(value.Type().Elem())
+			if err = setValue(v.Elem(), nil, child); err != nil {
+				return
+			}
+			m.SetMapIndex(k.Elem(), v.Elem())
 		}
-		m.SetMapIndex(k.Elem(), v.Elem())
 	}
 	value.Set(m)
 	return
 }
 
 func setSliceValue(value reflect.Value, node *Node) (err error) {
-	size := len(node.values)
+	tmpValues := make([][]byte, 0)
+	for _, v := range node.Nodes {
+		if val, ok := v.(*Value); ok {
+			tmpValues = append(tmpValues, val.Value)
+		}
+	}
+	size := len(tmpValues)
 	values := reflect.MakeSlice(reflect.SliceOf(value.Type().Elem()), 0, size)
 
-	if len(node.values) > 0 {
-		for _, data := range node.values {
+	if len(tmpValues) > 0 {
+		for _, data := range tmpValues {
 			v := reflect.New(value.Type().Elem())
 			str := string(data)
 			if err = setBasicValue(v.Elem(), nil, &str); err != nil {
@@ -240,12 +248,14 @@ func setSliceValue(value reflect.Value, node *Node) (err error) {
 			values = reflect.Append(values, v.Elem())
 		}
 	} else {
-		for _, child := range node.nodes {
-			v := reflect.New(value.Type().Elem())
-			if err = setValue(v.Elem(), nil, child); err != nil {
-				return
+		for _, n := range node.Nodes {
+			if child, ok := n.(*Node); ok {
+				v := reflect.New(value.Type().Elem())
+				if err = setValue(v.Elem(), nil, child); err != nil {
+					return
+				}
+				values = reflect.Append(values, v.Elem())
 			}
-			values = reflect.Append(values, v.Elem())
 		}
 	}
 	value.Set(values)
@@ -398,7 +408,6 @@ func loadInclude(root *Node, path string) (err error) {
 func parseConfig(root *Node, data []byte) (err error) {
 	const maxStringLen = 2048
 	var line []byte
-	var keyAccessRule int = 0
 
 	root.level++
 
@@ -433,17 +442,6 @@ func parseConfig(root *Node, data []byte) (err error) {
 			if err = loadInclude(root, string(value)); err != nil {
 				return
 			}
-		} else if string(key) == "AllowKey" || string(key) == "DenyKey" {
-			var ruleType []byte
-
-			if string(key) == "DenyKey" {
-				ruleType = []byte("true")
-			} else {
-				ruleType = []byte("false")
-			}
-			root.add([]byte(fmt.Sprintf("KeyAccessRules.%d.Pattern", keyAccessRule)), value, num)
-			root.add([]byte(fmt.Sprintf("KeyAccessRules.%d.Deny", keyAccessRule)), []byte(ruleType), num)
-			keyAccessRule++
 		} else {
 			root.add(key, value, num)
 		}
@@ -476,20 +474,18 @@ func Unmarshal(data interface{}, v interface{}, args ...interface{}) (err error)
 	switch u := data.(type) {
 	case nil:
 		root = &Node{
-			name:   "",
+			Name:   "",
 			used:   false,
-			values: make([][]byte, 0),
-			nodes:  make([]*Node, 0),
+			Nodes:  make([]interface{}, 0),
 			parent: nil,
-			line:   0}
+			Line:   0}
 	case []byte:
 		root = &Node{
-			name:   "",
+			Name:   "",
 			used:   false,
-			values: make([][]byte, 0),
-			nodes:  make([]*Node, 0),
+			Nodes:  make([]interface{}, 0),
 			parent: nil,
-			line:   0}
+			Line:   0}
 
 		if err = parseConfig(root, u); err != nil {
 			return fmt.Errorf("Cannot read configuration: %s", err.Error())
diff --git a/src/go/pkg/conf/conf_test.go b/src/go/pkg/conf/conf_test.go
index 746c4287a4..c74af4dba3 100644
--- a/src/go/pkg/conf/conf_test.go
+++ b/src/go/pkg/conf/conf_test.go
@@ -22,7 +22,9 @@
 package conf
 
 import (
+	"fmt"
 	"reflect"
+	"sort"
 	"strings"
 	"testing"
 
@@ -461,3 +463,51 @@ func TestKeyAccessRules(t *testing.T) {
 	var expected Options = Options{[]KeyAccessRule{{"system.localtime", false}, {"vfs.*[*]", false}, {"*", true}}}
 	checkUnmarshal(t, []byte(input), &expected, &options)
 }
+
+func TestRawAccess(t *testing.T) {
+	type Options struct {
+		LogFile  string
+		LogLevel int
+		Timeout  int
+		AllowKey interface{} `conf:"optional"`
+		DenyKey  interface{} `conf:"optional"`
+	}
+
+	input := `
+		LogFile = /tmp/log
+		LogLevel = 3
+		Timeout = 10
+		AllowKey = system.run1
+		DenyKey = system.run2
+		AllowKey = system.run3
+	`
+	var o Options
+	if err := Unmarshal([]byte(input), &o); err != nil {
+		t.Errorf("Failed unmarshaling options: %s", err)
+	}
+
+	values := make([]*Value, 0)
+	if node, ok := o.AllowKey.(*Node); ok {
+		for _, v := range node.Nodes {
+			if value, ok := v.(*Value); ok {
+				values = append(values, value)
+			}
+		}
+	}
+	if node, ok := o.DenyKey.(*Node); ok {
+		for _, v := range node.Nodes {
+			if value, ok := v.(*Value); ok {
+				values = append(values, value)
+			}
+		}
+	}
+
+	sort.SliceStable(values, func(i, j int) bool {
+		return values[i].Line < values[j].Line
+	})
+
+	for _, value := range values {
+		fmt.Printf("value: %s\n", string(value.Value))
+	}
+
+}
diff --git a/src/go/pkg/conf/node.go b/src/go/pkg/conf/node.go
index b2e5182180..ebc219aa3f 100644
--- a/src/go/pkg/conf/node.go
+++ b/src/go/pkg/conf/node.go
@@ -27,20 +27,25 @@ import (
 
 // Node structure is used to store parsed conf file parameters or parameter components.
 type Node struct {
-	name        string
+	Name  string
+	Nodes []interface{}
+	Line  int
+
 	used        bool
-	values      [][]byte
-	nodes       []*Node
 	parent      *Node
-	line        int
 	level       int
 	includeFail bool
 }
 
+type Value struct {
+	Value []byte
+	Line  int
+}
+
 // get returns child node by name
 func (n *Node) get(name string) (node *Node) {
-	for _, child := range n.nodes {
-		if child.name == name {
+	for _, v := range n.Nodes {
+		if child, ok := v.(*Node); ok && child.Name == name {
 			return child
 		}
 	}
@@ -61,41 +66,44 @@ func (n *Node) add(name []byte, value []byte, lineNum int) {
 
 	if node = n.get(key); node == nil {
 		node = &Node{
-			name:   string(key),
+			Name:   string(key),
 			used:   false,
-			values: make([][]byte, 0),
-			nodes:  make([]*Node, 0),
+			Nodes:  make([]interface{}, 0),
 			parent: n,
-			line:   lineNum}
-		n.nodes = append(n.nodes, node)
+			Line:   lineNum}
+		n.Nodes = append(n.Nodes, node)
 	}
 
 	if split != -1 {
 		node.add(name[split+1:], value, lineNum)
 	} else {
-		node.values = append(node.values, value)
+		node.Nodes = append(node.Nodes, &Value{Value: value, Line: lineNum})
 	}
 }
 
 // checkUsage checks if all conf nodes were recognized.
 // This is done by recursively checking 'used' flag for all nodes.
 func (n *Node) checkUsage() (err error) {
-	for _, node := range n.nodes {
-		if !node.used {
-			return node.newError("unknown parameter")
-		}
-		if err = node.checkUsage(); err != nil {
-			return
+	for _, v := range n.Nodes {
+		if child, ok := v.(*Node); ok {
+			if !child.used {
+				return child.newError("unknown parameter")
+			}
+			if err = child.checkUsage(); err != nil {
+				return
+			}
 		}
 	}
 	return
 }
 
 // markUsed marks node and its children as used
-func (n *Node) markUsed(v bool) {
-	n.used = v
-	for _, child := range n.nodes {
-		child.markUsed(v)
+func (n *Node) markUsed(used bool) {
+	n.used = used
+	for _, v := range n.Nodes {
+		if child, ok := v.(*Node); ok {
+			child.markUsed(used)
+		}
 	}
 }
 
@@ -103,9 +111,11 @@ func (n *Node) markUsed(v bool) {
 // metadata 'optional' tag is set. Otherwise error is returned.
 func (n *Node) getValue(meta *Meta) (value *string, err error) {
 	if n != nil {
-		count := len(n.values)
-		if count > 0 {
-			tmp := string(n.values[count-1])
+		var tmp string
+		for _, v := range n.Nodes {
+			if val, ok := v.(*Value); ok {
+				tmp = string(val.Value)
+			}
 			value = &tmp
 		}
 	}
@@ -132,11 +142,11 @@ func (n *Node) newError(format string, a ...interface{}) (err error) {
 	var name string
 	for parent := n; parent.parent != nil; parent = parent.parent {
 		if name == "" {
-			name = parent.name
+			name = parent.Name
 		} else {
-			name = parent.name + "." + name
+			name = parent.Name + "." + name
 		}
 	}
 	desc := fmt.Sprintf(format, a...)
-	return fmt.Errorf("invalid parameter %s at line %d: %s", name, n.line, desc)
+	return fmt.Errorf("invalid parameter %s at line %d: %s", name, n.Line, desc)
 }
