Resource access control using
row level security
Resource access control using row level security
Introduction
Some
of the shortcomings in Infrastructure-as-code come directly from the resources
in the public cloud that they manage. For example, a resource like key-vault
allows access control via both role-based access control as well as access
control policy and the IaC can specify but there is no built-in feature to
allow selective access to secrets between users who are all granted access.
Compare this with file-level security and additional checks can be placed on
the individual files for enabling individual access control. This is a write-up
on how to enable fine grained resource access control using row level security
as borrowed from databases. It might be useful to consider non-differentiable
resources with path-qualified files as names for their naming convention. Next,
consider that we want to ACL them in the storage much the same way as we do
files/folders on Windows with each file system entry pertaining to a key in the
key-vault. Specifically, we allow for different permissions, grantee and even
inheritance on resources/sub-resources that do not have primary built-in access
control.
How it works
Row
level security in database is defined in the online documentation and comes
with a readymade schema for such use - please see reference. In our case, we
want to add a column/attribute/tag to our resource that is equivalent to the
type of control that we want to apply to this resource. It could be a user name,
or it could be a label or a foreign key to a set of markings that represent the
sensitivity or the permissions of the data.
Keeping track of usernames, for example, is helpful in the case
where all accesses are directly isolated per user. In other words, users do not
have to share the ownership of the folders and that their accesses are to
manage the lifetime of their folders
We can also create a label for each resource if we know that the
labels are distinct and symbolic. In most cases where the operations are predefined,
but their actors are not, we can use different labels. For example, we can say
whether the resource is read-only or read-write.
However, users and their access are both dynamic and they can be
hierarchical. In this case, hierarchical means that entries can inherit top
down or gain incremental privileges bottom up. In addition, a user may grant or
revoke permission, take ownership, etc.
In such a case, it is better to view the labels as an output
resulting from a schema of categories and markings.
The categories and markings are predefined in a system. The
categories represent a domain of markings. This can be a classification that is
hierarchical or compartment that are distinct, they can be one-to-one or
zero-to-many in how many values can be applied and may have a comparison rule -
such as any or all. The markings are the compartment or classification values
we would like to division the resources into. Resources can belong to one or
more of these. They can have a name.
We
may have only one category and one compartment. Categories can be hierarchical
as in our case, but compartments are mutually exclusive. Note that the default
or guest low privileged access corresponding to public marking may not be
sufficient for security provisioning of all out of box features and hence it
may need to be split or refined into more classifications. The classification
hierarchy is expressed in the marking hierarchy table as opposed to the marking
table. Next, we have the unique label table that assigns a unique label to a
combination of markings and roles.
Database roles will be at least one for each value of any
or all comparison rule of a non-hierarchical category. For hierarchical
categories, again there will be one for each value, but the roles will also be
nested. Some examples of roles are guest, dev, test, production support,
reporting, owners, administrator, security administrator etc.
When using label-based security model, it is important to note
that the labels are assigned directly to each row of the base table. The labels
are small, often a short byte or an integer and can have a non-clustered index
on them. Sometimes, tags are not kept together in a base table but in a
junction table of the base identifier and the label marking identifier. The
reason this does not scale well is because it creates a duplicate column of the
identifier. Moreover, if the identifier column is of type guid, then we cannot
even build an index on them, and performance can suffer with scanning and full comparison
between guids. Therefore, it is advisable to spend time and effort one time to
add labels at the row level directly to the base table.
A particular combination of markings could translate to a unique
label for the resource. Usually, this table is populated on demand by say a
stored procedure. If there is no corresponding row to the combination of
markings, then a new row is added, and a unique ID is returned as the label.
We join the label and mark in a LabelMarking table to facilitate
the translation of the labels.
A combination of markings can make up a permission.
We
continue this a little bit more by enumerating the access permissions as Full
Control, Modify, Read & Execute, List folder contents, Read, Write and
Special Permissions. We also define the built-in users and groups. Note that
these permissions directly translate to the classifications mentioned earlier
and hence the markings. Permissions can be granted or denied. Therefore, the
markings must allow either of those states. Also note that the classification
can be considered hierarchical. For example, a write may include a read. Similarly,
a read and execute may include a read. Full control may include everything.
Ownership and inheritance of resources are not mentioned in this section
because they are more pertinent to users and groups. It is possible that only
one security principal and/or group to be treated as the owner while others may
have administrative access, therefore there is only one selection possible for
owner but those do not belong in this schema because here we talk about
permissions.
Another
thing is that the grant and the deny are mutually exclusive and this means that
our markings will be different whether a permission is granted or denied.
Moreover, distinct sets of markings can be attributed to different users and
groups. This mapping between markings and user/group may need to be stored as
well. The diverse types of markings possible are finite. The mapping between
user/group and markings can be arbitrary and therefore exist as rows in the
mapping table that maps markings between users and groups. In addition to
having an owner, a resource can also be shared. Sharing means that other
users/groups may have access to it. A default permission may be endowed with
sharing. Something like 'write' for 'Everyone' may be considered implicit with
sharing.
We
concern ourselves with the resources only and not with the user / groups which
is beyond the scope of this document. This is for two reasons: one that
users/groups/roles are part of the role-based access security which is not in
this scope and two we focus on resources only because we are concerned with
granularity of the labels we can assign to the resources. Similarly, when we
consider resources and permissions, we do not consider the attributes of the
resources. If we take a resource as a path qualifier, there are certain other
attributes possible. For example, a folder can be read-only or . den. It may be
archive-able, compressed or encrypted. It may be a candidate for the contents
to be indexed.
References
MSDN:
http://technet.microsoft.com/library/Cc966395
Previous
articles: IaCResolutionsPart93.docx
#codingexercise: CodingExercise-03-16-2024.docx
No comments:
Post a Comment