TUTORIAL – DELEGATING POLICY MANAGEMENT
Introduction
For small teams, it’s fine for two or three people to have “admin” access to Conjur and perform all the policy management.
But when Conjur is used in a large organization, it’s important that the security administrators be able to delegate management of Conjur to experienced members of other teams. In this way, the security team doesn’t get overwhelmed by change requests to Conjur. In addition, as operating Conjur becomes a wider organizational concern, better discussions will occur within the organization about how to use it most effectively.
Prerequisites
Install the self-hosted Conjur software.
It’s advisable, but not required, to step through the Enrolling an Application tutorial before this one.
Setup
Most Conjur deployments will begin with a small number of users working as administrators, loading all the policy data. All the policies can be kept in a single source control repository. Let’s set up a simple example of this.
First, a top-level policy defines two empty policies: db
and frontend
. Save this policy as “conjur.yml”:
Then create the following file as “db.yml”:
And “frontend.yml”:
Finally, load all the policies using the CLI:
Then as a sanity check, list all the objects in the system:
Delegation Concepts
So far, we’ve run all commands as the account “admin” user. This is fine for small environments, but as the system grows bigger we would like to enable other trusted users to manage the security configuration and secret data of their own applications.
To do this, we start by creating more User and Group objects in Conjur. Once there are Groups in the system, we can start changing the ownership of policies.
Default policy ownership works like this:
- If the policy doesn’t have a parent (it’s defined in a top-level policy file), then it’s owned by the user who created the policy.
- If the policy is created within another policy, it’s owned by the containing policy.
So, following rule (1), our policies “db” and “frontend” are owned by the account “admin” user. You can verify this using the CLI:
Ownership of any object can be changed by using the owner
field in policy YAML. For example:
Ownership of the “db” policy is assigned to the role “group:dba”.
Now any role which has the role “group:dba” can fully manage the “db” policy. Policy owners can do all of the following:
- Create, update, and delete objects in the policy.
- Fully manage all objects in the policy, including variables and host factories.
- Grant privileges on policy objects to other roles (e.g. application layers).
So what does it mean to be “in the policy”? Each object and annotation has a policy
attribute which indicates which policy that data belongs to. When you create an object, the policy
attribute is set to the policy that created the data.
You can use the CLI to find out which policy an object is in. For example, the object “policy:db” is in the “root” policy, whereas the object “variable:db/password” is in the “db” policy:
If you try and modify or delete an object from the wrong policy, the object is not affected. One way to think about this is that during policy loading, the object primary key (unique identifier) is composed of both the object’s id
and the object’s policy
. So, during policy loading, two object references using the same id
but different policy
are not equivalent; therefore an attempt to modify an object from the wrong policy is either and error or is ignored.
Delegation Demonstration
To see this in action, let’s add some users and groups to the policy “conjur.yml”:
Update the root policy:
Save the API keys for “frank” and “donna” in shell variables:
Now the following CLI command will attempt to update the “db” policy while authenticated as “donna”:
This is not a bug! We’ve created the users and groups, but we haven’t changed the ownership of the policies.
Update the owner
fields in “conjur.yml”:
Then update the root policy again:
Now the the “db” policy can be updated while authenticated as “donna”:
Summary
In this tutorial, we showed how to assign the owner
attribute of a policy to a group. The owner of a policy has full privileges on the objects in the policy, and we showed how a user can be permitted to manage her own policy.
In this way, users can be empowered to manage their own machines, variables, and web services without weakening the security of the overall system.
This type of delegated / federated workflow can allow for superior velocity in a development organization, without compromising on security and compliance controls.