Tutorial - Enrolling an Application
A very common question is: how do I add new secrets and apps to my infrastructure?
At Conjur, we refer to this process of adding new stuff as “enrollment”. The basic flow works in four steps:
- Define protected resources, such as Webservices and Variables, using a policy. Call this “Policy A”.
- In “Policy A”, create a group which has access to the protected resources.
- Define an application, generally consisting of a Layer (group of hosts), in another policy. Call this “Policy B”.
- In “Policy A”, add the Layer from “Policy B” to a group which has access to the protected resources.
Step (4) has a special name, “entitlement”, because in this step existing objects are linked together, and no new objects are created. An entitlement is always one of the following:
- Grant a policy Group to a Layer.
- Grant a policy Group to a different Group (usually a group of Users).
Organizing policy management into three categories - protected resources, applications, and entitlements - helps to keep the workflow organized and clear. It also satisfies the essential security requirements of separation of duties and least privilege.
- Separation of duties Management of protected resources is separated from management of client applications. Different teams can be responsible for each of these tasks. In addition, policy management can also be delegated to machine roles if desired.
- Least privilege The client applications are granted exactly the privileges that they need to perform their work. And policy managers (whether humans or machines) have management privileges only on the objects that rightfully belong under their control.
Install the self-hosted Conjur software.
We will model a simple application in which a
frontend service connects to a
db server. The
db policy defines a
password, which the
frontend application uses to log in to the database.
Here is a skeleton policy for this scenario, which simply defines two empty policies:
frontend. Save this policy as “conjur.yml”:
Then load it using the following command:
conjur list command to view all the objects in the system:
Define Protected Resources
Having defined the policy framework, we can load the specific data for the database.
Create the following file as “db.yml”:
Now load it using the following command:
db/password has been created, but it doesn’t contain any data. So the next step is to load the password value:
Define an Application
For this example, the “frontend” policy will simply define a Layer and a Host. Create the following file as “frontend.yml”:
Now load the frontend policy using the following command:
With the preceding steps completed, we now have the following objects and permissions in place:
variable:db/passwordis created and populated with a value.
group:db/secrets-userscan “read” and “execute” the database password.
layer:frontendis created, and
host:frontend/frontend-01exists and belongs to the layer. We have an API key for it, so we can authenticate as this host.
When a frontend application is deployed to
host:frontend/frontend-01, it can authenticate with the
api_key printed above and attempt to fetch the db password. You can simulate this using the following CLI command:
Is the “error: 403 Forbidden” a mistake? No, it’s demonstrating that the host is able to authenticate, but it’s not permitted to fetch the secret.
What’s needed is an entitlement to grant
layer:frontend. You can verify that this role grant does not yet exist by listing the members of the role
And by listing the role memberships of the host:
Add the role grant by updating policy “db.yml” to the following:
Then load it using the CLI:
Now you can verify that the policy has taken effect. We will look at this in several different ways. First, verify that
layer:frontend has been granted the role
And, you can see that the
execute privilege on
The important line here is myorg:host:frontend/frontend-01.
Now we can finish the tutorial by fetching the password while authenticated as the host:
Success! The host has the necessary (and minimal) set of privileges it needs to fetch the database password.
This pattern can be extended in the following ways:
- Add more variables to the
- Add more hosts to the
- Automatically enroll hosts into the
frontendlayer by adding a Host Factory.
- Add more applications that need access to the database password, and grant them access by adding entitlements to the
- Create user groups such as
frontend-developers, and give them management rights on their respective policies. In this way, policy management can be federated and scaled.