TUTORIAL – CLOUD FOUNDRY INTEGRATION
Introduction
Cloud Foundry is an open source platform designed to make it easy for developers to run, scale, and maintain applications. Integrating with Conjur makes it easy for these apps to securely retrieve the secrets and credentials that they need.
Cloud Foundy installations are divided into orgs, which serve as accounts that can be shared amongst multiple users. Each org can have any number of spaces, which are where developer applications get deployed.
Applications can enhance their capabilities by binding with services such as Conjur. Each org has a marketplace that lists the services to applications deployed within that org. Services connect to applications through a service broker, which is a standalone application that exposes service functionality by implementing the Open Service Broker API.
Cloud Foundry apps can connect with an existing Conjur deployment using the Conjur service broker. The broker must be installed into the Cloud Foundry deployment and registered with a marketplace. Applications can then bind to the service broker, at which point Conjur will create a Host identity for the app that can be used with Conjur policy to grant the application access to secrets stored in Conjur.
We also offer the Conjur Buildpack, which can be used to automatically inject secret values into your application’s environment at runtime. Alternatively, we offer client libraries in several languages that may be used to deliver secrets to your application. For the purposes of this tutorial, we will use the buildpack.
Prerequisites
Before getting started with the tutorial, you must:
- Install Conjur locally or sign up for a hosted evaluation Conjur account
- Install the Cloud Foundry CLI
- Install CF Dev
Configure Conjur
Conjur uses role-based access control (RBAC) driven by declarative policy files to control which identities are allowed to access secrets. When working in Cloud Foundry, policy structure mimics the org, space, and application layers of a Cloud Foundry installation to provide fine-grained access to secrets at whichever scope best fits an application’s needs. For more information about the benefits of using declarative policy, please visit our blog.
First, we create our root policy. This defines a Host to represent the Conjur service broker as well as an admin group that will later be granted permission to create additional hosts. We add the service broker to this group because it needs to create Host identities for any applications that bind to it. Save the following to policy.yml
:
Now we will load the policy, this can be done by copying the policy file to the client container you should have started while running through the Conjur setup instructions. Login to Conjur from the client container as an admin user and load the policy with the following command:
The output will look something like this:
Take note of the API key for the cf-service-broker
shown in this response. We will need it later when configuring our service broker.
Next we load a simple policy that will act as a parent for our Cloud Foundry policies. Save the following to cf.yml
:
Load the policy using:
Now we will load a policy to creates secrets that will be scoped to the org level. All apps deployed to our sample org will be granted access to these
secrets. The policy defines two variables to hold a pair of username and password secret variables. It then defines two Groups to which Users or Hosts can be added, one that has read-only permission (secrets-users
) and one that can also write secret values to the variables (secrets-managers
). Save the following to org.yml
:
Load it with:
We will also load a policy to hold secrets scoped to the space level. Any apps deployed to our sample space will be granted access to these secrets. Save the following to space.yml
:
Load it with:
Now we will load a policy to hold secrets scoped to the app level. These secrets will only be available to a single application. Save the following to app.yml
:
Load it with:
Finally, run the following commands to store secret values in the variables created during the previous steps:
Configure Conjur Service in Cloud Foundry
Next, we will need to start CF Dev and log in via the cf
CLI.
Note: If you already have CF Dev running and want to start with a clean installation, you can run cf dev stop
before calling the commands below.
Run cf dev start
to start a local Cloud Foundry environment. The output of this command should include a cf login
line as well as some credentials, which will look something like this:
Copy and paste the cf login
line from your own output to login to your local Cloud Foundry environment. When prompted, provide the admin credentials and select any of the existing orgs and spaces.
Step 1: Deploy the Conjur Service Broker to its own org and space
Create and target the space and org in which the service broker will be deployed:
Install the service broker by downloading the repository and running cf push
to push the service broker to your Cloud Foundry environment:
The service broker uses HTTP basic auth to talk to other Cloud Founry components. We must provide these credentials in its environment:
The service broker must communicate with Conjur to create identities for any applications that bind to it. We will need to configure it with the account and endpoint of your Conjur installation. The values here depend on how you chose to run Conjur.
If you followed the instructions to set up your own local Conjur instance, you should use:
If you are using the hosted eval Conjur, you should use:
The service broker will use the Host identity we defined earlier in Conjur policy to login to Conjur. It will also need the API key that was printed out when loading the policy that created the Host:
When the service broker binds to an application, it creates a Host identity to represent that app in Conjur policy. We need to provide the name of the policy under which these hosts should be created:
We should provide the Conjur version, which is 5 in this tutorial:
When connecting to a Conjur instance that is secured by TLS, the service broker will also need to be configured with a Conjur SSL certificate. If you are using hosted Conjur, the easiest way to do this is to copy the ~/conjur-<ACCOUNT>.pem
file that was produced when running conjur init
out of the client container and provide it like so:
If you are running Conjur in a local Docker container, you can just set this environment variable to a blank string:
Now that the service broker environment is configured, start the service broker application with:
Now we must register the service broker application to make it available as aservice broker in the Cloud Foundry environment. Note that TEMP_USER
and TEMP_PASS
should be replaced with the HTTP basic auth credentials we set in the service broker environment during a previous step:
To make the Conjur service listing available in all orgs and spaces, run:
To confirm that the service has been enabled, check the marketplace:
You should be able to see the cyberark-conjur
service listed in the marketplace from any org / space:
Step 2: Upload the Conjur Buildpack
Once installed, an application configured to use the Conjur buildpack and bound
to a Conjur service instance will have the secrets specified in its secrets.yml
file automatically injected into its environment when it starts. To install the buildpack into your Cloud Foundry environment, run:
Step 3: Create an org / space for deploy the demo app
Typically the admin of a Cloud Foundry environment would set up orgs and spaces and install service brokers, but apps would be deployed by a developer. In the following section we will relinquish our admin privileges and assume the role of a humble developer to deploy our demo app.
But before switching users, let’s create an org and space for the demo app and then grant the non-admin account a developer role in our newly-created space:
Uploading the Demo Application to Cloud Foundry
The demo application that we are using is simple – it just echoes three environment variables to the browser window. It will allow us to demonstrate that the Conjur service successfully loads the secret values from Conjur into the application environment.
Step 1: Log in with the developer account
First we’ll need to login with the non-admin account that was listed when you started your Cloud Foundry environment. Run cf login
and use the non-admin credentials (typically user
/ pass
) and target the demo-org
and demo-space
when prompted:
Step 2: Create a Conjur service instance in the org / space for the demo app
Use cf marketplace
to verify that the Conjur service listing is available and then create a service instance like so:
Step 3: Entitling the org and space
Conjur policy includes a Layer primitive that can be used to group Host identities together to grant collective access to a secret. When an application binds to a Conjur service broker instance, the broker creates Layers for the app’s org and space and adds the app’s Host identity to those layers in order to grant the app access to any secrets scoped to the app’s org or space.
To enable this feature, we must entitle the newly-created org and space by adding their layers to the secrets-users
group of their respective policies. Get the org GUID by running:
Save the following to org-entitlements.yml
, replacing <ORG_LAYER_NAME>
with the GUID from the previous step:
Load it with:
To entitle the space, we must first retrieve the space GUID with:
Since the Layer created for the space will be a child of the Layer created for the org, the name of the space in policy must include the org GUID as a prefix. That is, the space name will take the form of ORG_GUID/SPACE_GUID
. Save the following to space-entitlements.yml
, replacing <SPACE_LAYER_NAME>
with ORG_GUID/SPACE_GUID
:
Load it with:
Step 4: Deploy the demo application and bind it to the Conjur service instance
The demo application we will use is part of our demo repository, which includes demos for testing our Cloud Foundry integration locally using CF Dev or against an existing Cloud Foundry installation.
The app includes a Cloud Foundry deployment manifest that binds it to the Conjur service:
As soon as we cf push
the app, it will be bound to the Conjur service instance we created in the last step and it will be granted a host identity in Conjur.
Note: We use cf push --no-start
here to ensure the app will not start until we have added entitlements for the application Host in Conjur policy so that it will have access to the secrets that it needs.
Step 5: Retrieve the application’s Host identity
When the app binds to the Conjur service instance during start up, the service created a Host to represent the app in Conjur policy. We can use this Host to add the app as a member of the cf/app/secrets-users
group, which will grant it access to the secrets defined in the cf/app
policy.
The Host identity can be found in the demo application’s environment under the authn_login
field in the cyberark-conjur
credentials. It will take the form of host/cf/<ORG_GUID>/<SPACE_GUID>/<APP_GUID>
and can be retrieved by running:
The Host identity is the last three sections of the authn_login
value, so just the <ORG_GUID>/<SPACE_GUID>/<APP_GUID>
part with the host/cf/
prefix removed.
Step 6: Update Conjur policy to privilege the app
Save the following to app-entitlements.yml
, replacing <APP_HOST_NAME>
with the <ORG_GUID>/<SPACE_GUID>/<APP_GUID>
Host identity retrieved in the previous
step:
Load the policy as an admin Conjur user using the following command:
Step 7: Start the demo app and watch it retrieve secrets!
Start the demo app by running:
Get the URL of the hello-world app by running:
Open the URL in your browser and you should see the secret values we loaded earlier in the exercise.
Summary
Developers love Cloud Foundry for the ease of deploying applications, and the Conjur integration enables them to do so securely. Once the Conjur Service Broker and Conjur Buildpack have been installed in Cloud Foundry by an admin user and the Conjur service listing has been made available in the marketplace, it is easy for developers to bind their applications to a Conjur service instance. This gives their application a unique Host identity in Conjur, and that Host identity can be granted access to the secrets that the application needs. At runtime the Conjur Buildpack will automatically load secret values into the running application’s environment. With Cloud Foundry and Conjur together, developers can focus on releasing features while security and operations teams can rest assured that credentials are secure.