Using CyberArk Conjur Service Broker for VMware Tanzu

This topic describes how to use CyberArk Conjur Service Broker for VMware Tanzu.

Using CyberArk Conjur Service Broker for VMware Tanzu

The CyberArk Conjur Service Broker for VMware Tanzu provides the interface between VMware Tanzu applications and a Conjur appliance.

Deploy a VMware Tanzu Application with Secrets from Conjur

This procedure enables a PCF application to obtain secrets and manage authorization privileges from an existing Conjur appliance.

You can push the same application to multiple spaces. After you prepare the application as described in Step 1 below, target your desired orgs and spaces and perform the remaining steps for each space.

Step 1: Prepare the Application

The CyberArk Conjur Service Broker for PCF uses the Summon application included in the Conjur Buildpack by default to fetch secrets from the Conjur appliance and inject the values into your application’s environment.

The secrets, fetched at application startup, are available only to the application process (not to users), and are gone when the process exits. Summon requires a secrets.yml file in the application’s root folder.

If your application requires the secrets.yml file to be placed in a non-root directory, the runtime location for secrets.yml can be configured by setting the SECRETS_YAML_PATH environment variable for the Cloud Foundry application. You can find more information on this in Configuring the secrets.yml Location.

If your application uses another method to access secrets, such as Conjur API calls, you do not need a secrets.yml file.

  1. Create a file named secrets.yml.

  2. Add entries to the file to define the secrets that the application will fetch. Secrets to fetch from Conjur are specified with a !<tag> and a pathname indicating the Conjur policy path. More information on the format for secrets.yml is available below.

  3. Store the secrets.yml file in the root folder of your application.

    NOTE: If you deploy your application in a packaged format (e.g. as a JAR file), you will want to ensure your secrets.yml configuration file is available in the root application directory at deploy time (e.g. for a JAR file, you can store secrets.yml in the src/main/resources directory of your application if using Spring Boot versions below 1.4).

  4. If the secrets that your application needs are not already available in Conjur policy, create a policy file my-app.yml that adds the secrets to Conjur. The my-app policy can also create a Group that is entitled to fetch the secret values; the Org layer, Space, layer or application Host can be added to that Group in a later step to grant it access to the secret values.

  5. If you created a my-app.yml policy file, load it into Conjur under the dedicated Conjur policy for PCF. For example, if your dedicated Conjur policy for PCF is called pcf:

    For Enterprise Conjur v4:

    Add !include my-app.yml to the body of the pcf policy (defined in pcf.yml in the example below) and reload the policy as follows:

    $ conjur policy load --as-group security_admin pcf.yml

    If pcf.yml contains only the pcf policy, and if we have set that policy so that it is owned by the pcf-admin-group group, you could also reload by calling:

    $ conjur policy load --as-group pcf-admin-group pcf.yml

    For Open Source Conjur and Enterprise Conjur v5:

    For Conjur Enterprise v5 and Open Source, the recommendation is to store the policy for resources and secrets outside of the service broker managed policy branch.

    To accomplish this with my-app.yml, first create a policy branch, for example apps, and then load the app policy to that branch:

    $ conjur policy load apps my-app.yml

Example: secrets.yml

The following example of a secrets.yml file describes several types of allowed entries.

DB_USERNAME: !var apps/my-app/db/username
DB_PASSWORD: !var apps/my-app/db/password
REGION: us-east-1
SSL_CERT: !var:file apps/my-app/ssl/certs/private
  • Lines 1 and 2 specify fully qualified secret IDs. In this case, assume that a my-app policy was loaded into the apps policy. Each secret ID is given by the full path to the secret in Conjur, using the apps policy as the first component, followed by other IDs in the policy hierarchy.
  • Line 3 specifies a literal string value for the secret.
  • Line 4 specifies a fully qualified secret ID, and indicates that the value of the secret should be written to a temp file and SSL_CERT should be set to the temp file path.

In the context of a PCF environment, the above example could produce the following results, with the first two values and the contents of the file retrieved from Conjur:

REGION: us-east-1
SSL_CERT: pcf/tmp/ssl-cert.pem

For more information about syntax and options for a secrets.yml file, see the secrets.yml section in the Summon documentation.

Example: my-app.yml

The following example shows a Conjur application policy declaring two secrets as variables for Conjur to manage and a group with access to those secrets.

- !policy
  id: my-app
    - &variables
      - !variable db/username
      - !variable db/password

    - !group secrets-users

    # secrets-users can read and execute
    - !permit
      resource: *variables
      privileges: [ read, execute ]
      role: !group secrets-users

Values can be stored in these variables using the Conjur CLI, for example:

$ conjur variable values add "my-app/db/username" "My username value"
Value added

Step 2: Create a Service Instance

In the PCF space where you intend to deploy the application, create a service instance.

$ cf create-service cyberark-conjur community conjur

In the command above:

  • The service-name is cyberark-conjur.
  • There is a single free service plan called community.
  • For convenience, you may use the same instance-name (e.g. conjur) in multiple PCF spaces, so that the same application manifest works in all spaces. The instance name may be any value you choose, and does not have to be conjur, but must match the service name you bind applications in that space to.

If you do not yet have a space for the application, you may create a one with:

cf create-space "My Space"

And then target the space with:

cf target -s "My Space"

Step 3: Permit Secret Access by Org and Space (Conjur Open Source and Conjur EE v5+ only)

Adding a service instance to a space automatically creates resources within Conjur to allow privileging all of the apps in that org or space to access a secret in Conjur. These resources are Conjur layers named using the Globally Unique Identifiers (GUIDs) for the Org and Space.

The Org and Space GUIDs may be retrieved from CloudFoundry using the cf CLI tool. For example: “` $ cf org –guid my-org 8f366b77-d826-4522-8cc6-261bf9b02cba

$ cf space –guid my-space 4b02b69c-ba35-4069-b634-ded5644740c9 ”`

If the Service Broker policy branch is pcf/production, the org and space layers may be used to access variables in Conjur policy. For example:

   # org-space-entitlements.yml

   # Entitle all applications in my-org
   - !grant
     role: !group my-app/secrets-users
     member: !layer /pcf/production/8f366b77-d826-4522-8cc6-261bf9b02cba

   # Entitle all applications in my-space
   - !grant
     role: !group my-app/secrets-users
     member: !layer /pcf/production/8f366b77-d826-4522-8cc6-261bf9b02cba/4b02b69c-ba35-4069-b634-ded5644740c9

This can then be loaded into conjur with:

conjur policy load root org-space-entitlements.yml

Step 4: Edit Application Manifest

Add the instance-name from the previous step to the list of services in the application manifest (if you are using a manifest). If you are using the Conjur Summon buildpack, it must also be specified in the manifest.

For example:

 - name: my-app
   - conjur
   - conjur_buildpack
   - ... other buildpacks

More information on using the Conjur Summon buildpack can be found here.

Step 5: Push Application to PCF Space

Target your desired orgs and spaces and push the application and its associated files.

cf push ...

If you’re using Conjur EE v5+ or Conjur OSS v1+ and you’re entitling your applications to access secrets in Conjur at the org or space level, then you’re done!

If you plan to have Conjur secrets entitled specifically to this application, use the --no-start option to avoid starting the application before it has the privileges it needs.

Configuring the secrets.yml Location

Some final buildpacks do not allow deploying the secrets.yml file to the application root directory at runtime. In this case, the runtime location of the secrets.yml file may be configured by setting the SECRETS_YAML_PATH environment variable to its relative path.

This can be configured in the application’s manifest.yml:

- name: my-app
  - conjur
  - conjur_buildpack
  - php_buildpack
    SECRETS_YAML_PATH: lib/secrets.yml

Alternatively, this may be set using the Cloud Foundry CLI: $ cf set-env {Application Name} SECRETS_YAML_PATH {Relative Path to secrets.yml} $ cf restage {Application Name}

Entitle Individual Applications to Access Secrets

NOTE: These steps are optional for Conjur Open Source or Conjur EE v5+

NOTE: Applications cannot be individually entitled when Space Host Identities are enabled.

These steps enable you to entitle a specific application to access secrets in Conjur, rather than entitling an org or space and allowing the application to inherit those permissions.

Step 1: Obtain the Binding ID

Binding occurs automatically if the application manifest contains the correct service instance name. If you are not using a manifest, run the cf bind-service command to bind the application manually. For example:

$ cf bind-service my-app my-service-instance-name

The binding process generates a binding ID that becomes the Conjur host ID, used as a unique application identity for this application running in this space.

The ID is stored in the authn_login string found under the VCAP_SERVICES environment variable. The authn_login string has the format host/global-policy-id/binding_id. For example, host/pcf/0299a19d-7de4-4e98-89f6-372ac7c0521f would be the value of authn_login if the tile was configured to add hosts to the pcf Conjur Policy.

The following command extracts just the binding ID value that you need.

$ cf env $APP_NAME | grep authn_login | awk '{print $NF}' | sed 's/host.*\///g; s/"//g; s/,$//g'

Step 2: Update Conjur Policy Grants

The binding ID obtained in the previous step becomes the host ID to use in Conjur policies.

For Conjur Open Source and Conjur Enterprise v5: The application binding ID host is automatically added to the layers for the Organization and Space where the application is deployed. The application inherits the permissions of the Org and Space without requiring additional entitlements. These steps may still be used to permit specific applications to access Conjur secrets.

  1. Log into the Conjur appliance.

  2. Update policy to grant read and execute privileges to the new host ID on a set of secrets. For example, the following policy adds the new host to the existing secrets-users group. You can save these lines in a separate file, such as app-entitlements.yml.

For Conjur Enterprise v4:

    # app-entitlements.yml

   - !grant
     role: !group my-app/secrets-users
     member: !host /pcf/production/0299a19d-7de4-4e98-89f6-372ac7c0521f

Load the policy with:

   conjur policy load --as-group security_admin app-entitlements.yml

For Conjur Open Source and Conjur Enterprise v5:

The application host will be loaded into the Org and Space policy hierarchy:

   - !grant
     role: !group my-app/secrets-users
     member: !host /pcf/production/8f366b77-d826-4522-8cc6-261bf9b02cba/4b02b69c-ba35-4069-b634-ded5644740c9/0299a19d-7de4-4e98-89f6-372ac7c0521f

Load the policy with:

   conjur policy load root app-entitlements.yml
  1. Load the policy change. The following command loads the grant in entitlements.yml into the apps Conjur policy:
    $ conjur policy load apps entitlements.yml

In Enterprise Conjur (v4), you could also choose to use an !include statement in the existing PCF Policy.

Step 4: Restage the Application

Start or restage the application.

$ cf restage my-app

On application startup, the service loads the secrets that are defined in the application’s secrets.yml into the PCF environment.

Rotate Host Identity Credentials

Application Host Identities

When using application host identities (Enable Spaced-scoped App Identities is not checked), the host API key may be rotated by simply re-binding the application to the Conjur service:

cf unbind-service <app-name> conjur
cf bind-service <app-name> conjur

NOTE: This issues a new identity to the application, not just a new API key, so any application specific permissions need to be granted again. Any permissions granted to the org or space layers is automatically inherited by the new identity.

Space Host Identities

To rotate the host API key if Space Host Identities are enabled (Enable Spaced-scoped App Identities is checked) requires coordinating the host credential update with all apps in a space.

  1. Rotate the Space Host API key using the Conjur CLI. This returns the new API key for the host:

    conjur host rotate_api_key --host <cf policy root>/<org-guid>/<space-guid>
    # for example
    $ conjur host rotate_api_key --host cf/prod/6b40649e-331b-424d-afa0-6d569f016f51/72a928f6-bf7c-4732-a195-896f67bd1133
  2. Update the Space API key secret in Conjur:

    conjur variable values add "<cf policy root>/<org-guid>/<space-guid>/space-host-api-key" "<api-key-value>"
    # For example:
    conjur variable values add "cf/prod/6b40649e-331b-424d-afa0-6d569f016f51/72a928f6-bf7c-4732-a195-896f67bd1133/space-host-api-key" "1p9c5443sy1bg93ek2e062wsnmvy3p9k9j83nq841sj1sp2vasze1r"
  3. Re-bind each application in the space to Conjur

    This provides the updated credentials to each application

    cf unbind-service <app-name> conjur
    cf bind-service <app-name> conjur
  4. Re-stage each application in the space

    This causes each app to retrieve its secrets using the rotated credentials

    cf restage <app-name>