Load and Manage Policy

To implement and change policy, you load the policy files into DAP. You can use the CLI or the API for this task. We use the CLI for examples in this guide.

Load command

The conjur policy load command loads and updates policy.

Syntax

conjur policy load [--delete] [--replace] <policy-id> <policy-file-name.yml>

The options are: 

  • (without options)

    Creates new objects. If there are objects that already exist in the database (they were loaded into the branch previously) but are not specified in the policy file being loaded, those objects are left alone. The loading role needs create privilege on the policy id.

  • --delete option

    Creates new objects and also implements any !delete statements in the policy being loaded. The loader's role needs the update privilege on the policy id.

  • --replace option

    Replaces all previously loaded policy under the named policy id (in root or in a branch). Any policy objects, grants, and permits that exist in the database from previous loads but are not specified in the new policy file are deleted. The loader role needs update privilege on the policy id.

Other attributes in the command are:

  • policy-id (required)

    Is either the value root or the identifier of a previously created policy branch. The root policy exists by default. All other policy ids must be explicitly declared in policy statements. They become branches of a policy hierarchy under root. Aside from the root policy, policy ids are not valid until a policy is loaded that declares that policy id.

    The first time you load a policy, use the policy-id root. This is a special policy name that is used to define root-level data. To define policy branches under root, load the first-level policy branches under root to declare the new policy ids (the namespaces for the branches). You can later populate the branch with its own data by loading policy under the branch's policy id.

  • policy-file-name (required)

    Is the file containing DAP policy statements in YAML format. To read the policy from STDIN, use a single dash (-).

 
  • If a mistaken replace or delete occurs, see View Policy History to retrieve previous policy.

  • After you change an annotation in a policy, you need to reload your adjusted policy file using the '--replace' (PUT) option for the changes to take effect. For more information about policy load modes, see Policy load modes.

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 Mode CLI option Description Privilege Required
POST conjur policy load without options

DAP only creates new data.
If the policy contains deletion statements, such as !delete, !revoke, or !deny, they are treated as errors.
If there are objects that already exist in the database but are not specified in the policy, those objects are left alone.

create
PATCH conjur policy load --delete ...

DAP both creates and deletes data.
Objects and grants that already exist in the database but are not specified in the policy are left alone.

update
PUT conjur policy load --replace ...

DAP replaces the data in the database with the data specified in the policy file being loaded.

Objects, grants, and privileges that exist in the database but are not specified in the policy file are deleted.

update
GET conjur list Reads data read

 

Who can load policy?

Policy statements are loaded into either the DAP root policy or a branch policy. The loading role must have appropriate privileges on the policy. 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) should have 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 sections in the Policy Statement Reference for the Policy, User, Host, Group, and Layer statements.

Default admin user

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

  • The installer logged into DAP 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: The default admin is 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 that you set up a group role as the owner of root policy. You never want a situation where one user owns important policies and nobody else has access to them. It is also easier to add and remove individuals from role membership than change permissions at the individual user level.

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.

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
        member: !user alice
        member: !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 DAP:

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

    $ conjur policy load root 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. In addition, 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 root root-policy-file-name.yml

To load updated versions of the same root policy file:

  $ conjur policy load --replace root 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.

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

    $ conjur policy load --replace root policy-file-name.yml
    

Branches can contain additional branches. To create a branch off of the aws branch:

  1. Add statements to an 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 aws policy-file-name.yml
    

    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 aws/dev1 entitlements-dev1.yml
    

Load Policy Into a Branch

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

  • Initially:

     $ conjur policy load aws 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 aws policy-file-name.yml
    
  • To load policy into a branch two or more levels down from root, branch, the entire policy path must be supplied in the load command:

    $ conjur policy load aws/dev1 entitlements-dev1.yml
    

Example for Root and Branches

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

- !group dev
- !policy aws

Then, load the following statement into the aws branch to create 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.

Multi-file policies

It is 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 dev db.yml
Policy loaded
$ conjur policy load dev myapp.yml
Policy loaded
$ conjur policy load dev entitlements.yml
Policy loaded

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 show policy:<policy-id>

Example:

  
  $ conjur show policy:root
  {
    "created_at": "2018-05-20T16:24:24.018+00:00",
    "id": "acct21:policy:root",
    "owner": "acct21:user:admin",
    "permissions": [

    ],
    "annotations": [

    ],
    "policy_versions": [
      {
        "version": 1,
        "created_at": "2018-05-25T16:24:24.018+00:00",
        "policy_text": "..."
        .
        .
      },
      {
        "version": 2,
        "created_at": "2018-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.