diff --git a/config/components.yml b/config/components.yml
index 76f681c5b8..dd4e9cb643 100644
--- a/config/components.yml
+++ b/config/components.yml
@@ -52,7 +52,8 @@ frameworks:
- "JavaBuildpack::Framework::NewRelicAgent"
- "JavaBuildpack::Framework::PlayFrameworkAutoReconfiguration"
- "JavaBuildpack::Framework::PlayFrameworkJPAPlugin"
- - "JavaBuildpack::Framework::PostgresqlJDBC"
+ - "JavaBuildpack::Framework::PostgresqlJDBC
+ - "JavaBuildpack::Framework::ProtectAppSecurityProvider"
- "JavaBuildpack::Framework::SpringAutoReconfiguration"
- "JavaBuildpack::Framework::SpringInsight"
- "JavaBuildpack::Framework::YourKitProfiler"
diff --git a/config/protect_app_security_provider.yml b/config/protect_app_security_provider.yml
new file mode 100644
index 0000000000..1a4246313d
--- /dev/null
+++ b/config/protect_app_security_provider.yml
@@ -0,0 +1,19 @@
+# Cloud Foundry Java Buildpack
+# Copyright 2013-2016 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Configuration for the ProtectApp Security Provider framework
+---
+version: 8.4.+
+repository_root: http://files.cf-hsm.io/protectapp-installer
diff --git a/docs/framework-protect_app_security_provider.md b/docs/framework-protect_app_security_provider.md
new file mode 100644
index 0000000000..f8e9ace0de
--- /dev/null
+++ b/docs/framework-protect_app_security_provider.md
@@ -0,0 +1,100 @@
+# ProtectApp Security Provider Framework
+The ProtectApp Security Provider Framework causes an application to be automatically configured to work with a bound [ProtectApp Security Service][].
+
+
+
+ | Detection Criterion |
+ Existence of a single bound ProtectApp Security Provider service. The existence of an ProtectApp Security service defined by the VCAP_SERVICES payload containing a service name, label or tag with protectapp as a substring.
+ |
+
+
+ | Tags |
+ protect-app-security-provider=<version> |
+
+
+Tags are printed to standard output by the buildpack detect script
+
+## User-Provided Service
+When binding to the ProtectApp Security Provider using a user-provided service, it must have name or tag with `protectapp` in it. The credential payload can contain the following entries:
+
+| Name | Description
+| ---- | -----------
+| `client` | The client configuration
+| `trustedcerts` | An array of certs containing trust information
+| `NAE_IP.1` | A list of KeySecure server ips or hostnames to be used
+| `***` | (Optional) Any additional entries will be applied as a system property appended to `-Dcom.ingrian.security.nae.` to allow full configuration of the library.
+
+
+#### Client Configuration
+| Name | Description
+| ---- | -----------
+| `certificate` | A PEM encoded client certificate
+| `private-key` | A PEM encoded client private key
+
+#### Trusted Certs Configuration
+One or more PEM encoded certificate
+
+
+### Example Credentials Payload
+```
+{
+ "client": {
+ "certificate": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
+ "private-key": "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----",
+ },
+ "trustedcerts": [
+ "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
+ ,
+ "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
+ ],
+ "NAE_IP.1": "192.168.1.25:192.168.1.26"
+
+}
+```
+
+### Creating Credential Payload
+In order to create the credentials payload, you should collapse the JSON payload to a single line and set it like the following
+
+```
+$ cf create-user-provided-service protectapp -p '{"client":{"certificate":"-----BEGIN CERTIFICATE-----\n....\n-----END CERTIFICATE-----","private-key":"-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----\n"},"trustedcerts":["-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"],NAE_IP.1":"172.17.34.100"}
+```
+
+
+You may want to use a file for this
+
+Note the client portion is very exacting and needs line breaks in the body every 64 characters.
+
+ 1. The file must contain:
+ -----BEGIN CERTIFICATE-----
+ on a separate line (i.e. it must be terminated with a newline).
+ 2. Each line of "gibberish" must be 64 characters wide.
+ 3. The file must end with:
+ -----END CERTIFICATE-----
+ and also be terminated with a newline.
+ 4. Don't save the cert text with Word. It must be in ASCII.
+ 5. Don't mix DOS and UNIX style line terminations.
+
+So, here are a few steps you can take to normalize your certificate:
+ 1. Run it through dos2unix
+ dos2unix cert.pem
+ 2. Run it through fold
+ fold -w 64 cert.pem
+
+## Configuration
+For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][].
+
+The framework can be configured by modifying the [`config/protect_app_security_provider.yml`][] file in the buildpack. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there.
+
+| Name | Description
+| ---- | -----------
+| `repository_root` | The URL of the ProtectApp Security Provider repository index ([details][repositories]).
+| `version` | Version of the ProtectApp Security Provider to use.
+
+### Additional Resources
+The framework can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/pprotect_app_security_provider` directory in the buildpack fork.
+
+[`config/protect_app_security_provider.yml`]: ../config/protect_app_security_provider.yml
+[ProtectApp Security Service]: https://safenet.gemalto.com/data-encryption/protectapp-application-protection/
+[Configuration and Extension]: ../README.md#configuration-and-extension
+[repositories]: extending-repositories.md
+[version syntax]: extending-repositories.md#version-syntax-and-ordering
diff --git a/lib/java_buildpack/framework/protect_app_security_provider.rb b/lib/java_buildpack/framework/protect_app_security_provider.rb
new file mode 100644
index 0000000000..0edb4563c4
--- /dev/null
+++ b/lib/java_buildpack/framework/protect_app_security_provider.rb
@@ -0,0 +1,198 @@
+# Encoding: utf-8
+# Cloud Foundry Java Buildpack
+# Copyright 2013-2016 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require 'fileutils'
+require 'shellwords'
+require 'tempfile'
+require 'java_buildpack/component/versioned_dependency_component'
+require 'java_buildpack/framework'
+require 'java_buildpack/util/qualify_path'
+
+module JavaBuildpack
+ module Framework
+
+ # Encapsulates the functionality for enabling zero-touch Safenet ProtectApp Java Security Provider support.
+ class ProtectAppSecurityProvider < JavaBuildpack::Component::VersionedDependencyComponent
+ include JavaBuildpack::Util
+
+ # (see JavaBuildpack::Component::BaseComponent#compile)
+ def compile
+ download_zip
+
+ # copy default properties file
+ @droplet.copy_resources
+
+ credentials = @application.services.find_service(FILTER)['credentials']
+
+ write_client credentials['client']
+ write_trusted_certs credentials['trustedcerts']
+
+ certificates.each_with_index { |certificate, index| add_certificate certificate, index }
+
+ # setup java keystore with provided values
+ merge_clientcert
+ import_clientcert
+
+ end
+
+ # (see JavaBuildpack::Component::BaseComponent#release)
+ def release
+ credentials = @application.services.find_service(FILTER)['credentials']
+ java_opts = @droplet.java_opts
+ configuration = {}
+
+ filter_known_input(credentials, configuration)
+
+ write_java_opts(java_opts, configuration)
+ @droplet.java_opts
+ .add_system_property('java.ext.dirs', ext_dirs)
+ .add_system_property('com.ingrian.security.nae.IngrianNAE_Properties_Conf_Filename', @droplet.sandbox + 'IngrianNAE.properties')
+ .add_system_property('com.ingrian.security.nae.Key_Store_Location', key_store)
+ .add_system_property('com.ingrian.security.nae.Key_Store_Password', password)
+ end
+
+ protected
+
+ # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?)
+ def supports?
+ @application.services.one_service? FILTER, 'client', 'trustedcerts'
+ end
+
+ private
+
+ FILTER = /protectapp/.freeze
+
+ private_constant :FILTER
+
+ def merge_clientcert
+
+ shell "openssl pkcs12 -export -in #{client_certificate} -inkey #{client_private_key} -name #{myclientcert} -out #{myp12} -passout pass:#{password}"
+ end
+
+ def import_clientcert
+
+ shell "#{keytool} -importkeystore -noprompt -destkeystore #{key_store} -deststorepass #{password} " \
+ "-srckeystore #{myp12} -srcstorepass #{password} -srcstoretype pkcs12" \
+ " -alias #{myclientcert}"
+ end
+
+ def add_certificate(certificate, index)
+
+ file = write_certificate certificate
+ shell "#{keytool} -importcert -noprompt -keystore #{key_store} -storepass #{password} " \
+ "-file #{file.to_path} -alias certificate-#{index}"
+ end
+
+ def certificates
+ certificates = []
+
+ certificate = nil
+ File.open(trusted_certificates).each_line do |line|
+ if line =~ /BEGIN CERTIFICATE/
+ certificate = line
+ elsif line =~ /END CERTIFICATE/
+ certificate += line
+ certificates << certificate
+ certificate = nil
+ elsif !certificate.nil?
+ certificate += line
+ end
+ end
+
+ certificates
+ end
+
+ def keytool
+ @droplet.java_home.root + 'bin/keytool'
+ end
+
+ def password
+ 'nae-jks-password'
+ end
+
+ def key_store
+ @droplet.sandbox + 'keystore.jks'
+ end
+
+ def write_certificate(certificate)
+ file = Tempfile.new('certificate-')
+ file.write(certificate)
+ file.fsync
+ file
+ end
+
+ def ext_dir
+ @droplet.sandbox + 'ext'
+ end
+
+ def ext_dirs
+ "#{qualify_path(@droplet.java_home.root + 'lib/ext', @droplet.root)}:" \
+ "#{qualify_path(ext_dir, @droplet.root)}"
+ end
+
+ def client_certificate
+ File.join(Dir.tmpdir,'/client-certificate.pem')
+ end
+
+ def client_private_key
+ File.join(Dir.tmpdir,'/client-private-key.pem')
+ end
+
+ def trusted_certificates
+ File.join(Dir.tmpdir, 'trusted_certificates.pem')
+ end
+
+ def myclientcert
+ 'myclientcert'
+ end
+
+ def myp12
+ File.join(Dir.tmpdir,'/clientwrap.p12')
+ end
+
+ def write_client(client)
+ File.open(client_certificate, File::CREAT | File::WRONLY) do |f|
+ f.write "#{client['certificate']}\n"
+ end
+
+ File.open(client_private_key, File::CREAT | File::WRONLY) do |f|
+ f.write "#{client['private-key']}\n"
+ end
+ end
+
+ def write_trusted_certs(trusted_certs)
+ File.open(trusted_certificates,File::CREAT | File::WRONLY) do |f|
+ trusted_certs.each { |cert| f.write "#{cert}\n" }
+ end
+ end
+
+ def filter_known_input(credentials, configuration)
+ credentials.each do |key, value|
+ if key != "client" and key != "trustedcerts"
+ configuration[key] = value
+ end
+ end
+ end
+
+ def write_java_opts(java_opts, configuration2)
+ configuration2.each do |key, value|
+ java_opts.add_system_property("com.ingrian.security.nae.#{key}", value )
+ end
+ end
+
+ end
+ end
+end
diff --git a/resources/protect_app_security_provider/IngrianNAE.properties b/resources/protect_app_security_provider/IngrianNAE.properties
new file mode 100644
index 0000000000..be9e361c04
--- /dev/null
+++ b/resources/protect_app_security_provider/IngrianNAE.properties
@@ -0,0 +1,43 @@
+Version=2.4
+NAE_IP.1=
+NAE_Port=9000
+KMIP_Port=5696
+Protocol=ssl
+Verify_SSL_Certificate=no
+SSL_Handshake_Timeout=
+Use_Persistent_Connections=yes
+Size_of_Connection_Pool=300
+Load_Balancing_Algorithm=round-robin
+Connection_Idle_Timeout=600000
+Unreachable_Server_Retry_Period=60000
+Maximum_Server_Retry_Period=0
+Connection_Timeout=30000
+Connection_Read_Timeout=7000
+Connection_Retry_Interval=600000
+Client_Cert_Alias=
+Client_Cert_Passphrase=
+Key_Store_Location=
+Key_Store_Password=
+Cluster_Synchronization_Delay=100
+Symmetric_Key_Cache_Enabled=no
+Asymmetric_Key_Cache_Enabled=no
+Symmetric_Key_Cache_Expiry=43200
+Local_Cipher_Cache_Expiry=-1
+Local_Crypto_Provider=
+Persistent_Cache_Enabled=no
+Persistent_Cache_Expiry_Keys=43200
+Persistent_Cache_Directory=
+Persistent_Cache_Max_Size=100
+FIPS_Mode=off
+Credentials_Encrypted=no
+Passphrase_Encrypted=no
+Log_Level=NONE
+Log_File=
+Log_Rotation=Daily
+Log_GMT=no
+Log_Size_Limit=100k
+SysLog_IP=
+SysLog_Port=
+Log_Config_Advanced=
+Key_non_exportable_policy=no
+Log_MaxBackupIndex=-1
diff --git a/spec/fixtures/stub-protect-app-security-provider.zip b/spec/fixtures/stub-protect-app-security-provider.zip
new file mode 100644
index 0000000000..b116d22593
Binary files /dev/null and b/spec/fixtures/stub-protect-app-security-provider.zip differ
diff --git a/spec/java_buildpack/framework/protect_app_security_provider_spec.rb b/spec/java_buildpack/framework/protect_app_security_provider_spec.rb
new file mode 100644
index 0000000000..f978d2344c
--- /dev/null
+++ b/spec/java_buildpack/framework/protect_app_security_provider_spec.rb
@@ -0,0 +1,84 @@
+# Encoding: utf-8
+# Cloud Foundry Java Buildpack
+# Copyright 2013-2016 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require 'spec_helper'
+require 'component_helper'
+require 'java_buildpack/framework/pa_security_provider'
+
+describe JavaBuildpack::Framework::ProtectAppSecurityProvider do
+ include_context 'component_helper'
+
+ it 'does not detect without protectapp-n/a service' do
+ expect(component.detect).to be_nil
+ end
+
+ context do
+
+ before do
+ allow(services).to receive(:one_service?).with(/protectapp/, 'client', 'trustedcerts').and_return(true)
+
+ end
+
+ it 'detects with protectapp-n/a service' do
+ expect(component.detect).to eq("protectapp-security-provider=#{version}")
+ end
+
+ it 'copies resources',
+ cache_fixture: 'stub-protectapp-security-provider.zip' do
+
+ component.compile
+
+ expect(sandbox + 'IngrianNAE.properties').to exist
+ end
+
+ it 'unpacks the protectapp zip',
+ cache_fixture: 'stub-protectapp-security-provider.zip' do
+
+ component.compile
+
+ expect(sandbox + 'IngrianNAE-#{version}.jar').to exist
+ expect(sandbox + 'Ingrianlog4j-core-2.1.jar').to exist
+ expect(sandbox + 'Ingrianlog4j-api-2.1.jar').to exist
+ end
+
+ it 'write certificate files',
+ cache_fixture: 'stub-protectapp-security-provider.zip' do
+
+ component.compile
+
+ expect(sandbox + 'client-certificate.pem').to exist
+ expect(sandbox + 'client-private-key.pem').to exist
+ expect(sandbox + 'trusted_certificates.pem').to exist
+ expect(sandbox + 'clientwrap.p12').to exist
+
+ # transfer to keystore
+ expect(sandbox + 'keystore.jks').to exist
+
+ end
+
+
+ it 'updates JAVA_OPTS with additional options' do
+ allow(services).to receive(:find_service).and_return('credentials' => { '#{NAE_IP.1}' => 'server_ip',
+ '#{foo}' => 'bar' })
+
+ component.release
+
+ expect(java_opts).to include('-Dcom.ingrian.security.nae.NAE_IP.1=server_ip')
+ expect(java_opts).to include('-Dcom.ingrian.security.nae.foo=bar')
+ end
+
+ end
+end