Some Basic Security Considerations for Cloud Foundry Services

In this post, I’m going to discuss some of the basic security considerations for using Cloud Foundry services.

In a nutshell, Cloud Foundry currently supports two different kinds of services.  First, there are Managed Services.  These are the “native” services that are part of Cloud Foundry, and implement the Cloud Foundry service broker API.  The canonical example of a managed service is the MySQL database service.  Upon request, Cloud Foundry is able to provision capacity for a MySQL database instance, provision credentials, and bind this newly created instance to an application.

In addition, Cloud Foundry also supports User-Provided Services.  These are enterprise services that do not implement the Cloud Foundry service broker API, and (probably) exist outside the perimeter of the Cloud Foundry deployment.  An example would be, say, an existing Oracle database that runs on another platform, but is accessed by the application(s) deployed into Cloud Foundry.

Finally, it is important to note that there are no restrictions on the number or types of services that an application may bind.  Cloud Foundry applications are able to use any combination of these two service types, if and as needed.

Now, having introduced the basic idea of the two different service types, I’d like to use the remainder of this post to discuss some of their security implications.  What are the basic security considerations that an architect should think about when using these Cloud Foundry service types? What are their pros and cons? What are the implications for your existing security mechanisms? Your technical control procedures?

Some Security Considerations When Using Managed Services

One advantage of using a managed service is that, in general, the credentials that are needed to access that service will not need to be pre-configured into your applications. Rather, these can be dynamically provisioned and injected into the application at runtime.

This was the case with my most recent PoC, in which I leveraged a MySQL database. Because MySQL is available as a managed service in Cloud Foundry, I was able to use the cf create-service command line interface to create the needed service instance in the appropriate organization and space, and then I just needed to do a cf bind-service. My application would be supplied with the necessary JDBC connection string and credentials at runtime. In the specific case of MySQL, the credentials created by the service broker were both unique to the instance, and strongly chosen (i.e., my application received a user id of “5GhaoxJwtCymalOI,” with an equally obtuse password, for use when accessing a schema named “cf_f8e2b861_2070_47bf_bfd0_b8c863f4d5d2.”  Nice.)

If your current deployment process for application database login details involves manually provisioning and distributing the credentials (e.g. via an email to the deployer), then moving to a managed service will likely improve your overall risk profile. You won’t need to have a valid userid and password for your production database sitting around in an email or a properties file somewhere.  The credentials are made available just in time, via the VCAP_SERVICES environment variable, and should not need to be persisted anywhere else in the application configuration.

Since the credentials can be strongly chosen, and do not need to be persisted, it is unlikely that an attacker could obtain these through routine leakage, or directly penetrate your production service by brute-force guessing.  They likely contain enough entropy to ensure that anyone trying to directly guess the service credentials will likely wind up triggering an alarm, or at least getting noticed in your log monitoring solution.

Of course, keep in mind that old saying about “your mileage may vary.”  The specific algorithm used by your service broker may differ, and those supplied credentials may have more or less entropy than you actually expected.  Whether you use one of the existing service brokers, or build your own, be sure to check whether the entropy is sufficient for your required level of assurance.  The service broker may provision credentials using a low entropy approach, or may even use an existing account database, so don’t assume these will always be unguessable.

Finally, it is still important to maintain a meaningful audit trail.  For regulatory compliance reasons, you may have to periodically produce (and review) reports that list all the production database accounts that are being used, along with their access rights. In the case of Cloud Foundry managed services, all these account mappings are maintained by the Cloud Controller.  To continue to satisfy these existing reporting requirements you may find that you have to build the necessary integration(s) and collect these details using the cf command line interface or the PCF console.  Alternatively, perhaps you can work with your auditor to amend your reporting requirements, so that the control procedures you’ll follow with the cloud based applications are updated to reflect the new reality.  For example, instead of reporting on specific applications and corresponding database accounts, one could provide evidence that the application in question always uses service bindings, and therefore no hardcoded database credentials are being persisted to disk in properties files.

It is also worth noting that security operations teams looking for suspicious activity will typically seek to correlate log events across related user ids, services, IP address, and geographies, and so on.  One can be sure that a user id that is dynamically bound via the VCAP_SERVICES environment variable should always be used from the corresponding DEA node, and not also be being used to access the database from IP address that is not part of the DEA pool.

Similarly, you may need to correlate the backend user id that accessed a service with the front end user id that initiated the original request.  Establishing that linkage may require traversing (and/or correlating) yet another level of indirection.  In addition, that linkage may also vary over time, as the service is bound, unbound and rebound.   In summary, consider your requirements for log correlation, and take advantage of any new opportunities that the cloud deployment makes possible, but be aware that some of your existing correlations may not work as well when service credentials are being dynamically assigned.

Some Security Considerations for User-Provided Services

It is possible for a Cloud Foundry application to access an external service without creating a corresponding user-provided service definition. The application can continue to use whatever configuration technique it used before, likely by “hard-coding” the necessary connection details into the application configuration. For example, the application may still have a JSON or XML properties file, or a Spring Java configuration class that captures the details of where to find an Oracle database. However, because these credentials are statically maintained in the application configuration, and will likely be associated with manual workflow processes, they may be susceptible to data leakage. It would work, but you’re not really getting all the advantages of being in the cloud.

Creating a corresponding user-provided service definition is simply a way to tell Cloud Foundry about the service access. Once this is done, the applications deployed into the cloud can look to leverage the presence of the VCAP_SERVICES environment variable. Just as in the case of a managed service, the application can use the credentials found there, in order to access the service endpoint. Thus, defining a user-provided service simply enables Cloud Foundry to inject the necessary credentials, and this means that the credentials no longer have to be carried in a properties file within the application war file. The actual service itself can remain unchanged.

Of course the application would likely need to be upgraded to take advantage of the presence of the VCAP_SERVICES environment variable, but this can easily be done in every programming language, and in Java it can be made even simpler via the use of a connector component like Spring Cloud.

It’s also important to point out that the actual credential provisioning process is still entirely up to you. Once the service credentials are known, these are stored in the Cloud Controller database, via the command cf create-user-provided-service. If you have established account provisioning control procedures that are mature, and well integrated, then it might make perfect sense to just continue to leverage those. The responsibility of keeping custody of the credentials shifts from the application configuration, to the Cloud Controller database. That would seem to be a good thing. It is safe to say that whenever something security-related can be factored out of your developers’ day, then we should probably choose to do that.

Since Cloud Foundry introduces the native access control concepts of the Organization and Space, a decision needs to be made about how those existing services will be administered as user-provided services. Administrators, developers, and applications can only see and bind services that they have permission for within their space, and so you’ll need to think about how to administer that user-provided service definition in the Cloud Foundry environment. How does the maintenance of that proxy or placeholder record in the Cloud Controller correlate with the administration of the real resource(s)?  Does the administrator who is responsible for the real resource also administer the user-provided service definition in the cloud?  What new audit reports and record keeping correlations will be needed?

Will the user-provided service require the application to use SSL/TLS for access?  If so, then that client application deployed to the Cloud Foundry environment may need to be pushed (deployed) with a customized build pack.  Just as we prefer to factor out the login credentials from the application configuration, we’d also prefer to factor out the certificate management functions.  (This is not hard to do, but would be out of scope for the current post, so I’ll cover that in my next post).

Conclusion

Moving your applications to Cloud Foundry will clearly help your organization optimize both infrastructure utilization, and developer productivity.  But, in addition, I would assert that the proper use of managed- and user-provided services within Cloud Foundry has the potential to make your application deployments even more secure than they would have been, if you weren’t running in the cloud.  Using both managed services and user-provided services has many potential advantages, including:

  • reducing an application’s attack surface
  • improving the confidentiality of production service credentials
  • improving the consistency of operational procedures
  • enabling improvements in security event monitoring
  • improving visibility, thereby enabling more efficient audit processes

The only major caveat here is to consider how your existing operational controls will need to evolve in view of an ever-accelerating application lifecycle.   Most organizations find that some existing control procedures will be obviated, and others will need to be amended. But the real gains come from the new and more efficient controls that are made possible by the improved visibility that comes from having consistent service bindings.

Configuring SSL/TLS for Cloud Foundry

Whenever we deploy an enterprise Java Web application we should consider turning on SSL/TLS.  In the case of Tomcat, that means going through the certificate issuance process with the CA of your choice, and then editing your /conf/server.xml file, and adding an SSL/TLS-enabled connector.  The required configuration will look something like this:

<Connector port="8443" maxThreads="42" scheme="https" secure="true" 
SSLEnabled="true“ keystoreFile="/path/to/my/keystore" 
keystorePass="Don'tPanic!" clientAuth="false" sslProtocol="TLS"/>

However, as mentioned in my previous post, things are different in Cloud Foundry.

In the case of deploying your application to Pivotal Cloud Foundry, you don’t have the requirement to directly configure the Tomcat server.xml file. We will explain in detail why this is, but first it must be said that the whole point of deploying to the PaaS is that the developer does not need to deal with these things.

Instead, the approach is that the SSL/TLS connection from the user’s browser will terminate at the entry point to Cloud Foundry.  The application itself runs inside the perimeter of the Cloud Foundry deployment.  In my case, this is behind the HA Proxy server instance that serves as the front door for all the applications that are running in the cloud.   To understand this, let’s take a look at the way a typical enterprise application URL is remapped when it is deployed to the cloud.

Typical Enterprise Application URL Format

When the user accesses an application that has been deployed to a standalone Tomcat instance (or a cluster) the URL typically has the form:

https://hostname.com:8443/myapplication/page.html

Thus, the X.509 certificate that is presented to the users browser authenticates the hostname of the Tomcat server that is hosting the application.  The application itself is  identified by the context portion of the URL, the “/myapplication” part.  If you host another application on the same Tomcat server, it will likely be located at, say:

https://hostname.com:8443/my-other-application/page.html

…And so on.  There are likely a number of such applications on that enterprise Tomcat instance.  (We should mention that it’s also possible to use different ports and virtual hosts, though that is less common with the enterprise applications deployed inside a typical data center).   The key point here is that the SSL/TLS server certificate actually identifies the Tomcat server instance, and the SSL/TLS session is terminated at a port on the server that hosts the application.

Application URL Format in Pivotal Cloud Foundry

When that same enterprise application has been deployed to Pivotal Cloud Foundry, the URL will have the format:

https://myapplication.my-cf.com/page.html

And my other application would have the URL:

https://my-other-application.my-cf.com/page.html

Notice how the Tomcat application context now becomes a subdomain.  The user’s HTTP request for that application is routed (via the client’s DNS) — not to the Web application server — but to the entry point of Cloud Foundry.  In my deployment, that is the IP address of the Cloud Foundry HA Proxy server.  You can also choose to use a hardware load balancer, or another software proxy.  All the applications exist on a subnet behind that designated proxy server.  So the SSL/TLS session from the users browser is terminated by the proxy server, and the traffic to the application server itself (through the Cloud Foundry Router, and on through to the DEA) happens inside the perimeter of the cloud.  The subject name in the SSL/TLS certificate is the cloud subdomain.

Now, don’t panic.  Before we jump up and demand that the user’s SSL/TLS connection be set up end-to-end — from the browser all the way to the Tomcat server instance — we should consider that there is a precedent for this.  It is actually quite common for enterprise SSL/TLS connections to be terminated at a proxy server. This may be done to leverage a dedicated host (that contains SSL/TLS accelerator hardware), or perhaps for security monitoring purposes.  In fact, many enterprise security operations teams will also terminate any outbound SSL/TLS connections at an enterprise perimeter firewall such as a Blue Coat box.

The threat model here is that the entry point to the cloud is a high availability, secured proxy server.  Once the traffic traverses that perimeter, it is on a trusted subnet.  In fact, the actual  IP address and port number where the Tomcat application server are running are not visible from outside of the cloud. The only way to get an HTTP request to that port is to go via the secure proxy. This pattern is a well established best practice amongst security architecture practitioners.

In addition, we need to keep in mind that there are additional security capabilities — such as a Warden container — that are present in the Cloud Foundry deployment, that typically don’t exist on the average enterprise Tomcat instance.  (Discussing Warden containers in more detail would be out of scope for this post, but I’ll be sure to revisit this topic — along with Docker — in a future post).

So, now, let’s finally take a look at how the administrator will configure that SSL/TLS certificate in Pivotal Cloud Foundry.

Configuring SSL/TLS Certificate in Pivotal Cloud Foundry

Configuring the SSL/TLS certificate for Pivotal Cloud Foundry may be done using the Pivotal Operations Manager UI.  From the Installation Dashboard, click on Pivotal Elastic Runtime tile, and then the settings tab, and “HA Proxy.” This makes it easy for the administrator to supply a certificate PEM file, or choose to let PCF generate the certificate for you.  Below is a screen shot that shows the page.

pcf-opsmgr-haproxy-crt

If you happen to be are deploying your Cloud Foundry instance using the open source code, e.g. using Bosh, then the PEM certificate file for the HA proxy may be configured manually.  Look in the /templates subdirectory of the haproxy job to find the configuration details.  When the instance is deployed, the certificate and private key will ultimately find their way to the bosh manifest file.  The PEM encoded certificate and private key are found in the manifest under “jobs”, i.e.

jobs:
- name: ha_proxy
  template: haproxy
  release: cf
  lifecycle: service
  instances: 1
  resource_pool: ha_proxy
  persistent_disk: 0
  networks:
  - name: default
    static_ips:
    - 10.x.y.z
  properties:
    networks:
      apps: default
  ha_proxy:
    timeout: 300
    ssl_pem: "-----BEGIN CERTIFICATE——
          ....foo bar....
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
      ...foo bat...
-----END RSA PRIVATE KEY-----"
router:
 servers:

In either case — whether you are using PCF or the open source code base — it’s important to recognize that this is a task needs to be done once by the security administrator for the cloud — and not by every developer that deploys an application, or another instance of Tomcat.

Conclusion

Moving your enterprise application deployments into Cloud Foundry will mean that your developers will have the benefit of always having an SSL/TLS connection from their users’ browsers, to the “front door” of the cloud infrastructure, for free.  One of the key benefits of a PaaS is that your busy developers do not have to waste valuable time dealing with configuration details such as provisioning server certificates, and editing their Tomcat server configurations. The developers can spend their time writing code that drives revenue for the business, and then just do “cf push <my-application>”.  Dealing with the operational security of the application server infrastructure is factored out of their workday.

Finally, it’s important to note that while using Cloud Foundry makes things easy by eliminating routine configuration tasks like enabling SSL/TLS, it is still possible to customize your Tomcat server configuration, if and as needed. This would be done by creating and deploying a customized Cloud Foundry Buildpack, which contains your enterprise-specific changes.  In my next post, I’ll describe a use case scenario in which a customized build pack is necessary, and we’ll describe how this is done.

Migrating a Secure Java Web Application into Cloud Foundry

It’s been quite a while since I’ve had the time to write a new post here, but that’s not because there is nothing interesting to discuss.  On the contrary, the absence of any new posts was actually a reflection of how busy I have been over the summer.  For at least the last 4 or 5 months, I’ve been pretty much “heads down,” working on some interesting security challenges for our Pivotal Cloud Foundry customers.  The good news for all my loyal readers is that, in that time, I’ve built up quite a backlog of interesting stuff to write about.  And now that fall is in the air, I’ve finally gotten to the point where I’ll have some time to share what I’ve been up to.  I promise that it will have been worth the wait.

My Most Recent PoC Effort

I’ve recently completed an interesting project in which I’ve successfully migrated a secure enterprise Java Web application into Cloud Foundry.  This was a Proof-of-Concept effort, but it was by no means a “Hello, World!” exercise.   The application was non-trivial, and had a number of interesting security requirements.  The overall goal was to demonstrate to a customer how an existing Java Web application (one that already followed all the current best practices for securing enterprise deployments) could be successfully migrated into the Cloud Foundry environment.  And now that it’s happily running in Cloud Foundry, the application benefits from all the additional capabilities of the PaaS, while still maintaining all the same enterprise security features as before.

In order to respect the privacy of the customer, I won’t be able to discuss the actual customer application, which is proprietary.  Instead, I’ve decided to describe this effort in terms of another, equivalent, secure Java Web application — one that has the benefit of being available in open source, and has the same basic security properties as the real customer application.  The sample application we’ll be using is the FortressDemo2 application, written by my colleague Shawn McKinney.  As noted, this code is available in open source (with good license terms 🙂 ) and it is an excellent example of how to properly implement a secure Java Web application.

The Target Application Requirements

The FortressDemo2 application uses an RDBS for storing customer data, and depends on OpenLDAP as it’s policy and identity store.  The application uses JEE container-based security (e.g. a custom Tomcat Realm) for authentication and coarse-grained authorization. Internally, the application leverages Spring Security to implement its page-level policy enforcement points.  All interprocess communications are secured via SSL/TLS.  Thus, the user’s browser connection, and the connections made from the application to the database, and the application to the OpenLDAP server are all secured using SSL/TLS. Finally, the certificates used for these SSL/TLS connections have all been issued by the enterprise security operations team, and so have been signed by a Certificate Authority that is maintained internally to the enterprise.  As noted, this application is a perfect proxy for the real thing, and so if we can show how to run this application in Cloud Foundry, then we can successfully run a real customer application.

So, to summarize, the requirements we face are as follows.  Deploy a secure Java Web application to Cloud Foundry, including:

  1. Use of SSL/TLS for all inter-process communication, with locally issued certificates.
  2. Secure provisioning of SQL database credentials for access to production database.
  3. Configuration of a customized JSSE trust store.
  4. Configuration of a custom Tomcat Realm provider for JEE container-based security.

In the next few posts, I’ll be describing what you need to know to achieve these security requirements, and successfully migrate your own secure enterprise Java application into Cloud Foundry.

 

Cloud Foundry SAML Login via the Shibboleth IdP

Over the last decade or so, many large and mid-sized enterprise organizations have invested in identity federation and cross-domain single sign-on solutions that are based on the SAML2 standard from OASIS.   With the trend towards cloud computing, and the emergence of PAAS offerings like Cloud Foundry, it only makes sense that we’d want to be able to leverage that investment as a way to authenticate to the cloud.   In this post, I describe the configuration steps needed to enable a user to log in into a Cloud Foundry  environment, using a SAML assertion issued from a Shibboleth Identity Provider (IdP).

As background, the Cloud Foundry side of the equation basically consists of three services:  the (original) login-server, the new saml-login-server, and the uaa.  In this post we focus only on the configuration needed for the saml-login-server.  Each of these can be deployed as a WAR file in your favorite servlet container —  Cloud Foundry uses Tomcat.  On the Identity Provider side of the equation, we have the Shibboleth IdP service, which is also deployed as a WAR file.

There are basically five key items that need to be configured.

  1. Configure the saml-login-server via editing the login.yml as needed.
  2. Update the idp.xml file in the saml-login-server, and do a build/deploy.
  3. Start the saml-login-server, and use your browser to generate the required Service Provider (SP) metadata.
  4. Move the generated SP metadata over to the IdP.
  5. If needed, update the IdP configuration to release a suitable NameID attribute (e.g. corresponding to what was configured in login.yml, above).

We’ll go through each of these steps in a bit more detail below.

1. Configuring login.yml

First, we’ll need to edit the login.yml file to customize it to your local environment.   Of course, this will include updates to the hostname and port numbers from their default values, as appropriate (I won’t detail all those routine steps here.) In addition, you should be sure to set a value for the login:entityBaseUrl.  This will be the servlet context, e.g. the place where the Cloud Foundry saml-login-server is running.  You’ll also need a value for the login:entityID key. This will be the unique name of this saml-login-server instance, within your SAML-based SSO environment.  I chose the unimaginative designations shown below:

login:
...<snip>...
  # The entity base url is the location of this application
  # (The host and port of the application that will accept assertions) 
  entityBaseURL: http://<hostname>:8080/saml-login-server
  # The entityID of this SP
  entityID: cloudfoundry-saml-login-server

Finally, you may want to set the value of the key login:saml:nameID.  The default setting is “unspecified” as shown below:

nameID: urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified

At run time, this setting means that the Cloud Foundry saml-login-server will accept whatever <NameID> attribute the IdP chooses to send in the SAML assertion.  Depending upon how your IdP is configured, this default configuration may be just fine.  My IdP was initially configured to release only a transientID, and while this basically worked, it meant that my session was not linked to my existing Cloud Foundry user id, which was previously registered as my email (e.g. for doing the straight HTML form-based login via my username/password, or for doing a vmc login or a cf login prior to doing a cf push command line operation).   For consistency in my configuration I changed this value to be emailAddress as shown below:

nameID: urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress

Now, the Cloud Foundry saml-login-server will specifically request that the <NameID> element contained in the SAML assertion returned from the IdP contain the user’s email address.  This can then be correlated to the user’s existing account in the Cloud Foundry UAA database, when later doing OAuth token grants for applications.

2. Copy your idp.xml to the Cloud Foundry SAML login server

Metadata files are essentially the “secret sauce” of federated SSO.  These files contain, among other things, the PEM-encoded X.509 certificates needed to establish digital trust in the messages exchanged via the SAML Web SSO protocol.   Of course this step is needed in order to tell the saml-login-server about the IdP, and establish the first leg of that digital trust.  You can move a copy of your local idp.xml file into the appropriate place in the saml-login-server deployment.  I simply replaced the sample idp.xml that was supplied in the /src/main/resources/security directory when I cloned the saml-login-server project from GitHub.

Once you’ve updated these items, do a maven build, and deploy the WAR to your servlet container.

3. Generate the Service Provider Metadata

The Cloud Foundry saml-login-server is playing the role of the Service Provider (a.k.a. the Relying Party).  We’ve already provided the saml-login-server with the metadata it needs in order to trust the IdP.  Now we’ll need to give the IdP a copy of the saml-login-server’s SAML metadata.  This step will make their digital trust relationship mutual.  Point your browser at the URL for the metadata generator.  In my deployment it looks like:

http://<hostname>:8080/saml-login-server/saml/metadata/alias/cloudfoundry-saml-login-server

Where the leaf part of the resource URL (the part after “alias”) corresponds to the unique name used for the login:entityID key within the login.yml file, above.  (BTW, this metadata generator resource is a nice convenience that is actually enabled via a bean provided by the underlying Spring Security SAML Extension).

Depending upon your browser, you may see the XML metadata rendered as a page or you may be prompted to save this file.  In any case, you’ll want to save the file to a meaningful name such as cf-login-server-sp-metadata.xml, as you’ll need to put copy of this file on the IdP machine next.

4.  Move the generated SP Metadata over to the IdP.

Using your favorite file transfer method, copy the SP Metadata file over to the IdP host.  In a typical installation it needs to be placed in the location <IDP_HOME>/metadata.

Make sure you update the <IDP_HOME>/conf/relying-party.xml file to include this new Service Provider and refer to the corresponding metadata file at the correct location.  My IdP happens to be running on a Windows server and the configuration looks like the following:

<metadata:MetadataProvider id="cloudfoundry-saml-login-server" xsi:type="metadata:FileBackedHTTPMetadataProvider"
     metadataURL="http://hostname:8080/saml-login-server/saml/metadata/alias/cloudfoundry-saml-login-server"
     backingFile="C:\shibboleth-identityprovider-2.3.5/metadata/cf-login-server-sp-metadata.xml">
</metadata:MetadataProvider>

5.  Release the appropriate NameID and attributes from the IdP

Finally, we need to tell the IdP that it is OK to release the users email as the Name Identitfier in the SAML assertion that it issues.  We’ll need to update two files in the IdP configuration.

First, you need to edit <IDP_HOME>/conf/attribute-resolver.xml and add the attribute definition for the users emailAddress as a nameID.  A snippet from my configuration is shown below:

    <!-- Name Identifier related attributes -->
    <resolver:AttributeDefinition id="transientId" xsi:type="ad:TransientId">
        <resolver:AttributeEncoder xsi:type="enc:SAML1StringNameIdentifier" nameFormat="urn:mace:shibboleth:1.0:nameIdentifier"/>
        <resolver:AttributeEncoder xsi:type="enc:SAML2StringNameID" nameFormat="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"/>
    </resolver:AttributeDefinition>

    <resolver:AttributeDefinition xsi:type="ad:Simple" id="nameID_for_cf" sourceAttributeID="mail">    
        <resolver:Dependency ref="myLDAP" />
        <resolver:AttributeEncoder xsi:type="SAML2StringNameID" xmlns="urn:mace:shibboleth:2.0:attribute:encoder" nameFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" />
    </resolver:AttributeDefinition>

Notice that here I’ve chosen to release two NameID attributes, both a transientId and also the emailAddress.  As noted above, we’ve chosen to configure the Cloud Foundry saml-login-server to request the emailAddress, so I’ve named that element appropriately, as per the XML attribute @id=”nameID_for_cf”.  Of course this is just an arbitrary name in the XML, and could have been be set to anything.  The ref=”myLDAP” must point to a corresponding DataConnector element, found in the same file, e.g.:

<resolver:DataConnector id="myLDAP" xsi:type="dc:LDAPDirectory"
   <...snip...>
</resolver:DataConnector>

And last, but not least, we need to authorize the release of the attribute with a permit rule in <IDP_HOME>/cong/attribute-filter.xml.  For the sake of simplicity in my PoC configuration, I allow the release of the emailAddress nameID to any SP.  In a real production configuration, you will likely want to be more restrictive, in accordance with your company privacy policy.

<!-- Release nameID_for_cf to enable SSO to Cloud Foundry -->

    <afp:AttributeFilterPolicy id="Cf_share_nameID">

        <afp:PolicyRequirementRule xsi:type="basic:ANY"/>

        <afp:AttributeRule attributeID="nameID_for_cf">
            <afp:PermitValueRule xsi:type="basic:ANY" />
        </afp:AttributeRule>

    </afp:AttributeFilterPolicy>

That’s It!

Now, go ahead and restart your IdP and the saml-login-server and check for a clean startup. If all goes well, you should now be able to log in using either your existing Cloud Foundry user name and password, or a SAML assertion from your IdP.

To test this you can choose the link on the saml-login-server login page that says “Sign in with your organization’s credentials.”  Clicking on that link should do an HTTP redirect, and after the dynamic discovery protocol completes, you’ll be looking at your Shibboleth IdP log in page.  After you fill in your credentials and post the Shibboleth log in form, you’ll be redirected back to the Cloud Foundry log in page, with an opportunity to view your account profile.  If you started the use case by initially visiting an application running within Cloud Foundry, you’ll be redirected back to the application page you requested, with your log in session established.  For my testing I found it convenient to use the example applications found in the UAA samples directory.

Oh, yeah, ….one last thing… A common problem that I’ve encountered in configuring SAML in other situations is that the time of day settings between the IdP and the SP must be synchronized to within a reasonable tolerance, e.g. a few seconds.  In production you are likely using NTP so this wouldn’t be a problem.  However, when doing this in a development environment don’t just assume that you machines have the correct time.   If you see an error indicating that your assertion has (immediately) expired, you’ll know why.