Load and manage policy

To implement and change policy, you load policy files into Conjur. To load policy, you can use the Conjur CLI or the REST APIs.

We use the Conjur CLI in the examples in this topic.

Policy files

You define policy in files that can be checked into source control. We recommend establishing a process and review around changing policy files just like other controlled files.

After saving policy in text files with the .yml extension, you load the file into Conjur using the Client CLI or REST API. Conjur interprets and transforms your policy statements into definitive database records. You can safely re-apply policy any number of times.

A policy file is declarative, meaning that the rules become data in the database; it is not an executable code. Therefore, loading a policy file does not have any effect other than to create and update the role-based access control model in Conjur. These properties make policy files automation-friendly.

  • Policy files do not contain secret or password values. They contain only the declaration of the variable that stores the values and rules defining which roles can access the values.

  • Conjur retains a maximum of 20 versions of each policy.

Load command

The conjur policy load command loads and updates policy. For more information about policy command, see policy.

Policy load modes

The Rest API uses policy load modes that align with HTTP verbs. The CLI implements the API, using option flags to indicate the load modes.

API modes:

Who can load policy?

Policy statements are loaded into either the Conjur root policy branch or a policy branch under root. The loading role must have appropriate privileges on the policy branch. Appropriate privileges are create for creating new objects and update for changing existing policy. Privileges are assigned in permit statements for specific roles. A role can be a policy, a user, a group, a host, or a layer.

  • The default admin can load any policy.
  • The root admin role (if established as we recommend) can update and create privileges on the root policy. You could set this role to have update and create privileges on all policy.

  • The policy branch owner can load policy into that policy branch. Owners are named explicitly or are inherited from a parent policy.
  • Other roles that have specific create or update privileges on a policy branch can load policy into it.

For details about required permissions, see the Permissions section in the policy statement reference for each of the following: Policy, User, Host, Group, and Layer.

Default admin user

The default admin is the user created when Conjur was installed. As part of the installation:

  • The installer logged into Conjur for the first time using the admin account.
  • The installer was prompted to set a password for the admin account.
  • Thereafter, you can log on using these credentials:

    • User name : admin
    • password: API key OR the password

NOTE: admin is the owner of root policy by default.

Create a root admin group role

The policy structure starts at root. The default admin user is initially the owner of root policy.

We recommend creating sub-policies under the root policy. You can define specific roles (groups, users ) as owners of these sub-policies.

This way you can avoid a situation where one user owns important policies and no other user has access to them. It is also easier to add and remove individual users from role membership than to change permissions at the individual user level.

These roles are not owners of the root policy, but they have strong permissions on the policies under root.

For example: The following statements create a policy under root and set its ownership to a group of users. You can add similar statements to your root policy file.

!policy id: my-policy owner: !group admins

The root admin role has the following characteristics:

  • It is the owner of root policy. Therefore, its members can load policy under root.
  • It owns all policy unless an explicit owner role is named for a branch of policy off of root.

We call this role the root admin role throughout the documentation. The actual role name can be of your choosing.

For example:

The following statements create a root admin group role. You can add statements similar to this to your root policy file.

# add the following to your root policy file
# declare two users and a group
- !user alice
- !user bob
- !group conjur-root-admins
# add members to the group
- !grant
  role: !group conjur-root-admins
  members:
    - !user alice
    - !user bob
# give the group privileges on some resources
- !permit
  role: !group conjur-root-admins
  privileges:
    - create
    - update
    - read
  resources:
    - !policy root

To load this policy into Conjur:

  1. Add policy similar to the above to your root policy file.
  2. Run the following command:

     
    conjur policy load -b root -f policy-file-name.yml

Root versus Branches

The root policy exists by default. Initially, it has nothing in it.

Policy that applies to your entire enterprise would be loaded into root. For example, there might be admin users for the whole organization. The policy that defines the root admin role definitely belongs in root policy. The first level of policy branches must be defined in the root policy.

Loading and managing the root policy

Recommended practice is to have only one policy file for root. Maintain all root policy in that file. Also recommended is to create a root admin group role that owns root. See Create a root admin group role.

To load the root policy file the first time:

 
conjur policy load -b root -f root-policy-file-name.yml

To load updated versions of the same root policy file:

 
conjur policy load replace -b root -f root-policy-file-name.yml

Creating and managing branches

To create a branch under root:

  1. Add statements to your root policy file to create the new branch. The id is the branch name, for example, aws.

     
    - !policy
      id: aws
  2. Use the following command to load your altered root policy file:

     
    conjur policy load replace -b root -f policy-file-name.yml

Branches can contain additional branches.

For example, to create a branch off of the aws branch:

  1. Add statements to the aws policy file to create a new branch.

     
    - !policy
      id: dev1
    
  2. Use the following command to load this new file under the aws branch:

     
    conjur policy load -f aws policy-file-name.yml
  3. The fully qualified name of the branch you just created is aws/dev1. To load policy into the aws/dev1 branch, the entire policy path must be supplied in the load command:

     
    conjur policy load -b aws/dev1 -f entitlements-dev1.yml

Load policy into a branch

To add objects into a branch after the branch is declared:

  • Initially:

     
    conjur policy load -b aws -f policy-file-name.yml
  • Altering existing policy: (you are replacing all policy for aws with new policy, which means deleting unwanted objects and adding new objects):

     
    conjur policy load replace -b aws -f policy-file-name.yml
  • To load policy into a branch two or more levels down from root, the entire policy path must be supplied in the load command:

     
    conjur policy load -b aws/dev1 -f entitlements-dev1.yml

Example

Loading the following policy statements into root creates two objects in the root policy:

 
- !group dev
- !policy aws

Then, loading the following statement into the aws branch creates an object in the aws policy:

 
- !variable secret_access_key

The above two loads are the same as loading the following into root:

 
- !group dev
- !policy
  id: aws
  body:
    - !variable secret_access_key

The difference is that when you use the two load commands, the opportunity exists for different roles (different users) to load. Someone who has permission to change the root policy creates the branch. Someone whose permissions are limited to changing the aws branch can load the variable.

Multifile policies

It's natural and recommended to split up policy for a branch into multiple files.

You can initially load each file separately. However, if you want to make updates to that policy branch using the --replace option (PUT mode), you need to reload all of the files associated with the branch, even if only some of the files were modified.

The following example illustrates this situation and shows a way to concatenate the files for the purpose of reloading them.

For now, assume that you have a set of files that describes policy for a branch:

  • db.yml
  • myapp.yml
  • entitlements.yml

Initially, you could load this set of files into a policy branch named dev as follows:

 
conjur policy load -f dev db.yml
conjur policy load -f dev entitlements.yml
conjur policy load -f dev myapp.yml

Over time, you may need to make changes to these files, such as update the entitlements or add or revoke privileges. Because you are replacing the policy, all of the files associated with the policy branch must be loaded together.

The easiest way to do this is to concatenate the associated files before reloading. For example, in a Linux environment, you would run:

 
$ cat db.yml myapp.yml entitlements.yml | conjur policy load replace dev -
Policy loaded

View policy history

When you load policy, the policy YAML is stored in the Conjur database. As you make updates to the policy branch, the subsequent versions of policy for that branch are stored as well.

Previous versions of policy can be useful in case of mistaken policy changes. This policy history is available by fetching the policy resource using the conjur show command.

 
conjur list --inspect -kind policy --search <Policy_Name>

Example:

  
  $ conjur list --inspect -kind policy --search root
  {
    "created_at": "2022-05-20T16:24:24.018+00:00",
    "id": "acct21:policy:root",
    "owner": "acct21:user:admin",
    "permissions": [

    ],
    "annotations": [

    ],
    "policy_versions": [
      {
        "version": 1,
        "created_at": "2022-05-25T16:24:24.018+00:00",
        "policy_text": "..."
        .
        .
      },
      {
        "version": 2,
        "created_at": "2022-05-28T18:51:05.923+00:00",
        "policy_text": "..."
        .
        .
      }
    ]

You can recreate previous policy using the policy_text in the version information, or use the timestamp to retrieve previous versions from your source control system. Then reload your adjusted policy file using the --replace (PUT) option.